Shop OBEX P1 Docs P2 Docs Learn Events
Variables find the lowest — Parallax Forums

Variables find the lowest

Special_KSpecial_K Posts: 162
edited 2006-06-22 22:52 in BASIC Stamp
is there a way to put 5 or more variables into a table and then lookup the lowest value

LOOKUP find_lowest,[noparse][[/noparse]varx,vary,varz,varp,vard,varq,var1,var2,var2,var3], 'chose lowest
or could I use the branch statement.
I know I can do this with a bunch of if then statments but I know there has got to be a better way. the variables will change rather rapidly so the progran need to determin the losest variable and return to the main code.
any help would be great.

Comments

  • allanlane5allanlane5 Posts: 3,815
    edited 2006-06-19 02:28
    FindLowest:
    · LowVal = 0
    · FOR I = 1 TO 10
    ··· IF MyData(I) < LowVal THEN
    ····· LowVal = MyData(I)
    ··· END IF
    · NEXT
    RETURN ' LowVal will hold the lowest of the 10 values.

    ' Note this is a 'classic' problem.· You· can speed
    ' it up if you know something about the arrangement of the values
    ' -- like they're already sorted.
    '
    ' But if the arrangement of the numbers is random, or in any order,
    ' then a 'linear search' like the above is the fastest way to insure
    ' you've checked every number.
  • Special_KSpecial_K Posts: 162
    edited 2006-06-19 03:41
    so would the top part look like this.

    LOOKUP MyData,[noparse][[/noparse]varx,vary,varz,varp,vard,varq,var1,var2,var2,var3] 'variables

    FindLowest:
    LowVal = 0
    FOR I = 1 TO 10
    IF MyData(I) < LowVal THEN
    LowVal = MyData(I)
    END IF
    NEXT
    RETURN ' LowVal will hold the lowest of the 10 values.

    debug lowval ' should give me th lowest variable.
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-06-19 05:37
    No, the subroutine as listed assumes your values are stored in an array called, MyData.· The LOOKUP command has nothing to do with that part.· So the top part would look like:

    GOSUB FindLowest
    

    After which, the lowest value would be in the variable LowVal.· Again, these are assumed names, you can substitute your own variable names.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • allanlane5allanlane5 Posts: 3,815
    edited 2006-06-19 13:24
    Yes, the "Lookup" command doesn't work that way at all, so you can't use
    "Lookup" for this purpose.

    So, your program would look like

    MyData VAR BYTE(10) ' Allocate a 10-byte array
    I VAR NIBBLE
    LowVal VAR BYTE ' Result holder

    Main:
    · FOR I = 1 to 10
    ··· MyData(I) = 10 - I ' Pre-load MyData with something to test with...
    · NEXT

    · GOSUB FindLowest ' Find lowest value and put in LowVal

    · DEBUG [noparse][[/noparse]"Lowest value was ", LowVal, CR]

    · PAUSE(1000) ' Pause 1 second, so you can read the result
    · GOTO MAIN ' Do it again.

    FindLowest:
    · LowVal = 255·· ' Init to the HIGHEST possible value
    · FOR I = 1 TO 10
    ··· IF MyData(I) < LowVal THEN
    ····· LowVal = MyData(I)
    ··· END IF
    · NEXT
    RETURN ' LowVal will hold the lowest of the 10 values.

    Postscript: Correction from further down the page -- yes, "LowVal" should
    be initialized to the HIGHEST possible value (255, here) not the lowest.
    My bad, thanks for the correction.


    Post Edited (allanlane5) : 6/19/2006 1:59:49 PM GMT
  • SSteveSSteve Posts: 808
    edited 2006-06-19 13:49
    FindLowest:
      LowVal = 0
      FOR I = 1 TO 10
        IF MyData(I) < LowVal THEN
          LowVal = MyData(I)
        END IF
      NEXT
    RETURN ' LowVal will hold the lowest of the 10 values
    


    One change: The first line of the routine should be LowVal = 255. Otherwise it will always return 0. That's assuming MyData is an array of bytes. If it's an array of words, use LowVal = 65535

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows

    links:
    My band's website
    Our album on the iTunes Music Store
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-06-19 13:54
    One other note, as an afterthought...You could use lookup if you returned the index of the array element rather than the low value.· I'm not sure why you would want to do this, since it would be an extra, unnecessary step and use more code space, but it could be done.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2006-06-19 17:31
    Another way to find the minimum is by using the Stamp's MAX operator as follows:

    lowVal=65535
    FOR i=0 to 4
        lowVal = lowVal MAX myData(i)
    NEXT
    



    It may seem counterintuitive to use the MAX operator to find the minimum, but that is the way it works. Read it like this, "set the new lowVal equal to the old value of lowVal, but not to exceed myData(i)". So, MAX acts as a ceiling, and the ceiling can get lower and lower.

    If this is a situation where values enter the table one at a time in a process, and the minimum has to be found at each step, a faster approach may be to maintain a pointer to the current minimum value so that it only have to compare to that one. At least usually. It depends on how the values get into and out of the table.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Special_KSpecial_K Posts: 162
    edited 2006-06-19 17:37
    allanlane5 you said that further down in the text it says ....... can you tell me what text you are looking at.. this is a little above my head and I think I need to do more reading
    also thank you all for the help(chir,SSteve,allanlane5 )
    I am embarresd to say that I can not fiqe out where to bput my variables in this statementallanlane5 you said that further down in the text it says ....... can you tell me what text you are looking at.. this is a little above my head and I think I need to do more reading.

    also thank you all for the help

    I am embarrassed to say that I can not figure out where to put my variables in this statement. I think it should be this

    But I have a question would not this statement

    FOR I = 1 to 10
    MyData(I) = 10 - I ' Pre-load MyData with something to test with...
    NEXT
    Cause the program to input a variable from the array into the MyData(I)
    But then the next statement would send the program back to the for in FOR I = 1 to 10 without getting to the gosub findlowest


    Yes, the "Lookup" command doesn't work that way at all, so you can't use
    "Lookup" for this purpose.

    So, your program would look like

    MyData VAR BYTE(10) ' Allocate a 10-byte array
    MyData(0) = varx
    MyData(1) = vary
    MyData(2) = varz
    MyData(3) = var1
    MyData(4) = var2
    MyData(5) = var3
    MyData(6) = varp
    MyData(7) = vard
    MyData(8) = varq
    MyData(9) = varp

    I VAR NIBBLE
    LowVal VAR BYTE ' Result holder

    Main:
    FOR I = 1 to 10
    MyData(I) = 10 - I ' Pre-load MyData with something to test with...
    NEXT

    GOSUB FindLowest ' Find lowest value and put in LowVal

    DEBUG [noparse][[/noparse]"Lowest value was ", LowVal, CR]

    PAUSE(1000) ' Pause 1 second, so you can read the result
    GOTO MAIN ' Do it again.

    FindLowest:
    LowVal = 255 ' Init to the HIGHEST possible value
    FOR I = 1 TO 10
    IF MyData(I) < LowVal THEN
    LowVal = MyData(I)
    END IF
    NEXT
    RETURN ' LowVal will hold the lowest of the 10 values.

    Postscript: Correction from further down the page -- yes, "LowVal" should
    be initialized to the HIGHEST possible value (255, here) not the lowest.
    My bad, thanks for the correction.
  • SSteveSSteve Posts: 808
    edited 2006-06-19 17:46
    Special_K said...
    But then the next statement would send the program back to the for in FOR I = 1 to 10 without getting to the gosub findlowest
    Once I reaches the value 10, the for/next loop stops repeating and control gets to gosub findlowest

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows

    links:
    My band's website
    Our album on the iTunes Music Store
  • allanlane5allanlane5 Posts: 3,815
    edited 2006-06-19 18:09
    1. The reference to "further down the PAGE" was to the next message in the thread, which pointed out that LowVal should be initially set to 255, not to zero as I originally had it.

    2. The FOR loop should go from zero to nine, not 1 to 10. My fault.

    3. It would be faster not to use "varx", "vary", etc, but simply put the values into the array in the first place.
    This would save memory too. Or, you could use:
    varx VAR MyVal(0)
    vary VAR MyVal(1)

    Which would make each of your 'var' locations the same as one of the MyVal array locations -- creating an 'alias', as they say. Unfortunately, I don't have a BS2 here to test and debug this code, so there may still be some small gotcha's.

    Update:· Oops, just checked, the "varx VAR MyVal(0)" syntax does not work.· Sorry about that.

    Post Edited (allanlane5) : 6/19/2006 6:21:28 PM GMT
  • Special_KSpecial_K Posts: 162
    edited 2006-06-19 19:23
    the variables are sensor inputs ranging in number from 1- 5 so they change quickly and often. so I can not give them a preset value.

    this code.
    varx VAR MyVal(0)
    vary VAR MyVal(1)
    do I use this to set up the variable and if so when do i declare the variable varx as a nibble.

    thanks again
  • allanlane5allanlane5 Posts: 3,815
    edited 2006-06-20 01:15
    Yup, I'm done. I've given you enough to get a really good start. Now you have to code it yourself. The problem is, you haven't really given us enough detail to help you. If you can't extrapolate a 'nibble' based array, instead of a 'byte' based array, then you need to read the documentation more.

    You wanted 5 or more variables in a table, and how to find the least. You've got that.

    And I already said the "varx VAR MyVal(0)" syntax doesn't work.
  • Special_KSpecial_K Posts: 162
    edited 2006-06-20 03:03
    I thank you for the help you have given. I just do not get the last bit of code, It is just over my head. I guess I must find some more basic to intermediate resources.
  • ZootZoot Posts: 2,227
    edited 2006-06-20 13:19
    What part is still confusing? The definition of the array? Arrays are defined like this:

    SomeArray      VAR        Byte(5)
    
    



    The above creates an array with 5 bytes, indexed 0-4. You could access the elements of the array like this:

    FOR idx = 0 TO 4
    SomeArray(idx) = "A"
    NEXT
    
    'the above would be just like doing the following
    SomeArray(0) = "A"
    SomeArray(1) = "A"
    SomeArray(2) = "A"
    SomeArray(3) = "A"
    SomeArray(4) = "A"
    'each element is a byte
    
    



    If you need nibbles, or words, or bits, you can define arrays for those also:

    SomeArray    VAR     Nib(3)  'this would be an array of 3 nibbles
    
    



    Arrays are nice, because say you had 3 discrete variables like this...

    item1   VAR   Nib
    item2    VAR    Nib
    item3    VAR   Nib
    
    



    ...you wouldn't have a way to "loop" through them and, say, test each one to see if it's lowest, as in the examples above. Well you could, but you'd have to write lines for each variable, and if you changed the names you'd have to redo code. Also arrays are nice because if you are looking at and/or testing each element in an indexed loop, you can exit the loop when you've found what want, etc.

    On a Stamp, the maximum size of any array is 13 words, or 26 bytes, or 48 nibbles, or 96 bits, since that's all the memory there is.

    Does this help? Using the same example as above, to find a min. value, you loop through the array and look for the lowest value as compared to whatever the lowest "found" value already is. Start with 255 because nothing can be "higher":

    'I'm not showing variable declarations
    
    LowestVal = 255         'if you are testing Bytes, nothing can be higher than this
    FOR idx = 0 TO 4       'loop through the 5 bytes of the array
    IF ( SomeArray(idx) < LowestVal ) THEN    'is element "idx" of the array lower than LowestVal?
       LowestVal = SomeArray(idx)   'if it is, set LowestVal to be the value of element "idx"
    NEXT
    
    



    Here's a real world example for my own Bot where I use a lot of two element arrays for doing "left to right" sensor and motor work:

    sensor     VAR       Word(2)      'a two word array for sensor input
    motor      VAR       Byte(2)       ' a two byte array for my motors
    idx           VAR      Nib             ' a counter
    left          CON      0                'used for the index counter when accessing arrays (it reads nicely)
    right        CON       1
    
    SonarL     PIN        4              'PING input
    SonarR     PIN      5               'PING input - remember pin constants are numbers and can be treated like that
    
    FOR idx = left TO right        'loop from 0 to 1
       PULSOUT SonarL+idx, 5   'trigger the ping -- note the +idx -- on the first pass the pin will be SonarL+0 or Pin 4
                                               ' on the second loop the pin will be SonarL+1 or Pin 5 which is my "right" sensor
       PULSIN SonarL+idx, sensor(idx)   'store the input in sensor array - element 0 will be "left", element 1 will be "right"
       'more code here for converting PING that I'm not showing
    NEXT
    
    'at this point I have two sonar values in sensor(0) and sensor(1) which is sensor(left) and sensor(right) because I defined left/right constants
    
    IF ( sensor(left) < 30 AND sensor(right) < 30 ) THEN   'whoa, there's a wall there, better back up
       FOR idx = left TO right                        'loop through motors array
            motor(idx) = 0                              ' 0 = backwards, 128 = stop, 255 = forward for my motor controller
        NEXT
    ENDIF
    
    'and so on
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • Special_KSpecial_K Posts: 162
    edited 2006-06-20 16:25
    Ok... I get it... I GET IT... YES!. Thanks for the detailed (remedial) explanation. I really get it now. Zoot you have been a big help.
  • ZootZoot Posts: 2,227
    edited 2006-06-20 16:35
    Thanks... but real kudos go to Andy Lindsay, Jon Williams and the authors of the Pbasic Manual..... I learned all this from their examples in the documentation and at the forums and in Nuts & Volts smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-06-21 14:19
    In Zoot's example:

    item1   VAR   Nib
    item2    VAR    Nib
    item3    VAR   Nib
    
    

    You can in fact loop through these as an array by addressing it as follows:

    item1(0)
    item1(1)
    item1(2)
    

    This is completely valid as long as these variables are all the same size and declared in order.· Basically what you're doing is creating an implied array (for lack of a better word).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • ZootZoot Posts: 2,227
    edited 2006-06-21 17:42
    Chris, thanks for pointing that out. You've actually helped me solve a minor dilemma in working with Word arrays.

    I have an app where I track servo positions for the PSC, and had done a hack to be able to pass the bytes through SEROUT:

    work     VAR      Word
    servo    VAR     Word(3)     ' servo(1) is the position that will actually be sent
    ' do a bunch of stuff
    ' finally send servo, but move value to the work var because servo(1).LOWBYTE etc is not valid syntax
    work = servo(1)
    SEROUT serIO, Baud, [noparse][[/noparse] "!SC", channel, ramp, work.LOWBYTE, work.HIGHBYTE, CR]
    
    



    But if I maintain order and size on variable declarations, I could do something like this:

    servo    VAR     Word    'also the same registers as servo(0)
    spos     VAR      Word   'also the same registers as servo(1)
    setpos   VAR      Word   'also the same registers as servo(2)
    
    FOR idx = 0 TO 2        'loop through servo, spos, setpos as if they were a declared array
       servo(idx) = servo(idx)+1
    NEXT
    'etc
    
    'now send to PSC -- spos.LOWBYTE is the same as servo(1).LOWBYTE
    SEROUT serIO, Baud, [noparse][[/noparse] "!SC", channel, ramp, spos.LOWBYTE, spos.HIGHBYTE, CR]
    
    



    That is so cool. One thing I'm not clear on -- is the size of elements 1..N of the implied array the same size as the first element? Like the example above will always return Words in index loops? And the below would always return Nibs because the var used as element 0 is that size?

    sumBits  VAR   Nib        ' start of implied array
    snBits     VAR    sumBits 'implied sumBits(0)
    irBits      VAR    Nib       ' implied sumBits(1)
    liteBits    VAR    Nib       ' implied sumBits(2)
    idx         VAR    Byte
    
    FOR idx = 0 TO 2
       sumBits(idx) = sumBits(idx) >> 1    'sumBits(idx) will always be Nibs because sumBits aka sumBits(0) is a Nib?
       'more stuff 
    NEXT  
    
    



    A sort of related question, then -- you could loop through the nibs of an implied array too? Fr'instance this isn't valid syntax, nor is logically accurate:

    servo(1).LOWNIB(1)   'looking for the NIB1 of Word 1 of the array (implied or otherwise)
    



    But this is?

    servo.LOWNIB(6)  'this would be NIB1 of Word 1 of the array (implied or otherwise)
    



    There is a discussion of this technique in the Pbasic Manual, but I never quite grasped the utility of it before.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2006-06-21 18:35
    The nice thing about implied arrays is that the you can have your cake and eat it too. When you define an array explicitly, as in
    myarray VAR word(3)
     ' you can not then name the individual components:
    monkey VAR myarray(1)   '<-- BAD SYNTAX
    



    However, using implicit array,
    cat VAR Word
    monkey VAR Word
    zebra VAR Word
    myarray VAR cat  ' <-- alias, to use as myarray(), but you could also use cat()
    FOR idx=0 TO 2
      myarray(idx) = 0  ' as array
    NEXT
    monkey = 7    ' as individually named value
    



    It works with any size variable and yes the size of the chunk is determined by the first element.

    cat.bit0(17) = 1  ' same as monkey.bit1
    monkey.nib2(1)    ' same as monkey.highbyte.highnib
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Special_KSpecial_K Posts: 162
    edited 2006-06-22 18:46
    I really thought I had it.
    the concept makes sense to me but my lowval reading is stuck at 0
    here is the code I am using

    skull.gif
  • FranklinFranklin Posts: 4,747
    edited 2006-06-22 18:58
    I don't see where you are assigning the data to MyData. You have a section in the varables where you assign the (unknown) values to the array then you assign values to valXXXX but do not assign these to mydata. Am I missing something?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - Stephen
  • ZootZoot Posts: 2,227
    edited 2006-06-22 19:19
    In your particular code there is no place where you actually set the values of the array to anything other than 0, so of course LowVal will be 0 -- it's lower than 255 after all.

    This code was commented out --
    'populate:
    'LowVal=255
    'FOR I = 0 TO 3
    'MyData(I) = 3 - I ' Pre-load MyData with something to test with...
    'NEXT
    'RETURN
    
    


    Which *would* put some vals into MyData. Otherwise your lowval check looks OK. My question is the same as Franklin's -- MyData is a big array, not sure what you are doing with the valright..left etc vars.

    One other thing, though, remember that your variable for storing the "lowest" found needs to be the same size as what you are checking or you may get strange results. In your code LowVal is a Byte, but you are checking the MyData array -- which is Words. Additionally, your "initial" highest value would need to be $FFFF for Words, $FF for Bytes, $F for Nibs, etc.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • Special_KSpecial_K Posts: 162
    edited 2006-06-22 21:45
    I uncommented the code and renamed it. I still am not getting a Number in the debug statement

    MyData      VAR WORD(5) ' Allocate a 10-byte array   from forum
    MyData(0) = valright                                'from forum
    MyData(1) = valleft                               'from forum
    MyData(2) = valcenter                               'from forum
    MyData(3) = valback                                'from forum
    MyData(4) = valtop                               'from forum
    
    


    I know the array is large I thought I was getting the error because the array might have been too small.
    If the above code makes an array and tell the array that slot 0 is = to valright,
    slot 1 is = to valleft..ect
    then if I change the value of the variable then is it right that the value in the array will change.

    valleft  = 1400
    valright = 71
    valcenter = 56
    valtop   = 54
    valback  = 457
    


    at this point I thought the lowval run the first time though would return valtop or 54 the valtop equivalent

    if I change the array set up and place value in at the start




    ]MyData      VAR WORD(5) ' Allocate a 10-byte array   from forum
    MyData(0) = 448                                'from forum
    MyData(1) = 264                               'from forum
    MyData(2) = 280                               'from forum
    MyData(3) = 679                                'from forum
    MyData(4) = 3465                               'from forum
    


    I get a debug of 255 which i know it the highest value of a nibble. But I do not know how it got into lowval since the lowest value is 264
    full code follows.
  • ZootZoot Posts: 2,227
    edited 2006-06-22 22:52
    OK -- I think I see what you are trying to do. I think you think you're working with an implied array, or with variable references, but not how you set up your vars.

    You declare a bunch of Word vars, valright, valleft, etc. Then you declare a totally separate array MyArray. It's not like object oriented programming where:

    MyArray(0) = valleft
    



    could be a reference to valleft. An implied array would be like this:

    MyArray    VAR     Word   'one word, same as implied MyArray(0)
    valleft      VAR      MyArray 'alias of MyArray, so it's a word same as MyArray(0)
    valright     VAR     Word   'one word, same as implied MyArray(1) BECAUSE IT'S JUST THE NEXT WORD DEFINED AFTER MyArray
    
    



    Remember you're actually not defining an array per se, you're just defining a bunch of words IN ORDER. The Stamp lets you be sloppy --- if you ask for MyArray(1), you just get the next Word in memory after MyArray (which is the 0th element).

    You only need to do this if you want to be able to use the Word as an indexed element AND because it's handy to have a single variable name for the same element.

    In your code, you could dispense with one set or the other, and bring all your inputs into the array:

    FOR idx = 0 TO 4
        'do some stuff to get input
        val(idx) = work 'work is whatever your sensor or input is or whatever
    NEXT
    
    ' OK, now you've got 5 values in an array....loop through and get the lowest
    LowVal = $FFFF   'Word sized "max"
    FOR idx = 0 TO 4
       IF ( val(idx) < LowVal ) THEN
           LowVal = val(idx)
       ENDIF
    NEXT
    
    



    What may have thrown you is if you had an implied array you have nice mneumonic handles for your array elements, but you could just consider using constants for the index values like this:

    left   CON 0
    right  CON 1
    back  CON  2
    center CON  3
    val     VAR    Word(4)
    idx    VAR    Nib
    LowVal  VAr  Word
    
    FOR ( idx = 0 TO 3 )
       'get some values into...
        val (idx) = work
    NEXT
    
    LowVal = $FFFF
    FOR (idx = 0 TO 3 )
       IF ( val(idx) < LowVal ) THEN
          LowVal = val(idx)
       ENDIF
    NEXT
    
    'now instead of looping you could just work with each one for whatever reason
    IF ( val(center) = 40 ) THEN       ' center = 3, so val(center) = val(3)
       FREQOUT, Speaker, 200*/TmAdj, 3000*/FrAdj
    ENDIF
    
    IF ( val(left) < 30 AND val(right) < 30 ) THEN
       'do some stuff
    ENDIF
    
    




    I edited your code and put in a few comments that might help. There are two version -- one uses regular array with named index values, the other uses the implied array. I didn't edit this on my Pbasic machine, so I didn't tokenize them -- sorry if there are any typos.


    Is this helping at all smile.gif ??

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
Sign In or Register to comment.