Shop OBEX P1 Docs P2 Docs Learn Events
CASE vs IF THEN statements — Parallax Forums

CASE vs IF THEN statements

stumbling newbiestumbling newbie Posts: 1
edited 2007-08-16 01:02 in General Discussion
I have been tasked with writing code in pBASIC, which I am completely new to using. Infact, I haven't really programmed much of anything for a while. I could really use some help in understanding when a CASE statement would be better than an IF THEN statement. After pouring over the manuals, the two seem to be very similar, what am I missing? Any help and/or advice would be very much appreciated.

Comments

  • T&E EngineerT&E Engineer Posts: 1,396
    edited 2007-08-02 18:24
    Using CASE and SELECT statements are just another way to have a cleaner looking program and it's easier to follow then using many nested IF THEN ELSEIF loops. You could certainly use either one and your code would run the same. I would suspect that it does take more clock cycles for CASE and SELECT statements though. Although I prefer to use them if at all possible. Too bad sx/b doesn't·utilize them.

    Good luck.
  • DufferDuffer Posts: 374
    edited 2007-08-02 21:15
    One of the advantages of using the SELECT, CASE structure is that the first True CASE condition encountered causes the code following the CASE statement to be executed and then execution branches to the ENDCASE (or CASE ELSE statement, if present). If you use a series of IF clauses·and provide no exit by using a GOTO "a label" at the end of the IF statements, all the IF statements have to be executed, even after a True condition is encountered in a previous IF statement. And as T&E Engineer pointed out, it makes for cleaner, more easily understood code (remember, you may have to debug this stuff a year from now and the simpler it is now, the better!)

    Another technique that I have to remind myself·to use,·is to spend some time analysing the distribution and span of the values in the set you are testing. Coders tend to be very linear thinkers (IF 1, IF 2, IF 3, etc). If the set of values you're testing is weighted toward "7" being more likely to accur than "1", you can change the order of you tests to optimize the speed of you tests. Likewise, knowing the span (range of deltas) in you data can help determine the granularity (steps)·of the tests that you have to make to optimize the speed. These techniques apply equally to a series of IF statements or a SELECT, CASE structure.

    Cheers, Steve

    Post Edited (Duffer) : 8/2/2007 9:35:26 PM GMT
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-08-02 21:32
    In PBASIC the SELECT..CASE is translated into a series of IF..THEN statements, so there's no real functional difference. However is is suggested to use the SELECT..CASE when testing for more than one condition because it improves readability. Here is the comment portion of SELECT..CASE from the PBASIC tokenizer code:

     NOTE: The BS2 through BS2pe do not have SELECT CASE implemented in firmware.
           To achieve a SELECT CASE, the command is translated by the PBASIC 2.5 Tokenizer into the following (The actual source isn't modified,
           however the result is effectively equal to the following translation in source code):
     
           EXAMPLE:                                                  TRANSLATES TO:
           SELECT expression                                         IF expression condition1 THEN JumpLabel1
             CASE  condition1               : statement(s)             GOTO SkipLabel1
             CASE  condition2, condition3   : statement(s)           JumpLabel1:
             CASE  condition4 TO condition5 : statement(s)             statement(s)
             CASE  ELSE                     : statement(s)             GOTO ExitLabel
           ENDSELECT                                                 SkipLabel1:
                                                                     IF expression condition2 OR expression condition3 THEN JumpLabel2
                                                                       GOTO SkipLabel2
                                                                     JumpLabel2:
                                                                       statement(s)
                                                                       GOTO ExitLabel
                                                                     SkipLabel2:
                                                                     IF expression >= condition4 AND expression <= condition5 THEN JumpLabel3
                                                                       GOTO SkipLabel3
                                                                     JumpLabel3:
                                                                       statement(s)
                                                                       GOTO ExitLabel
                                                                     SkipLabel3:
                                                                       statement(s)
                                                                     ExitLabel:        }
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • ZootZoot Posts: 2,227
    edited 2007-08-02 22:41
    As a postscript to those who run out of space in your program slot(s) -- if/then and select/case statements are both (in my estimation) fairly byte hungry when tokenized. If you can deal with reading it, and space is tight, as Tracy Allen and Jon Williams have pointed out, LOOKDOWN/LOOKUP with ON may give the same results in less space, and with more consistent timing.

    If space and pure speed are less of an issue, then whatever is most legible and makes the most sense to a human reader may be the best approach. When I'm writing first versions of code I often write using SELECT...CASEs or multiple IF...ELSEIF...THENs. When I'm sure my logic is correct and the code is bug-free, I convert all that kind of code to something like the sample below and it can free up a *lot* of space.
    test VAR Byte
    idx  VAR test  'for legibility
    
    Start:
    DEBUGIN DEC test
    test = test//5  'pre process if need be for more logic/error checking
    LOOKUP test, [noparse][[/noparse] 0, 0, 1, 3, 2, 1, 1, 3, 4, 1, 4, 4 ], idx   'lookup test and choose jump label -- allows for virtual ANDs and ORs
    'LOOKDOWN test, <=[noparse][[/noparse] $0, $10, $AAA, $F000, $FFFF ], idx   'or this, or both, etc
    ON idx GOTO label0, label1, label2, label3  'label4 follows
    'above could also be ON...GOSUB as well, with below as subroutines with RETURNs, etc.
    
    label4:
       'do stuff
       GOTO labelsend
    label3:
       'do stuff
       'GOTO labelsend   'e.g. if "3" run "3" then "2"
    label2:
       'do stuff
       GOTO label0    'e.g. if "2" means run "2" then "0"
    label1:
       'do stuff
       GOTO labelsend
    label0:
       'do stuff
    labelsend:
       'done
    
    GOTO Start   'etc
    
    END
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • sam_sam_samsam_sam_sam Posts: 2,286
    edited 2007-08-03 16:27
    ·Zoot

    I would realy like for you or some one else to show this part in the
    ····································· IF THEN AND OR Statement
    if you would not mind do this for me· and put the part that you are testing for in RED

    I would like to THANK ANYONE that will take the time to explane it this way
    In this example·that you have here·



    What would this be in (IF THEN AND OR Statements )


    (DEBUGIN·DEC·test
    test·=·test//5··'pre·process·if·need·be·for·more·logic/error·checking
    LOOKUP·test,·[noparse][[/noparse]·0,·0,·1,·3,·2,·1,·1,·3,·4,·1,·4,·4·],·idx···'lookup·test·and·choose·jump·label·--·allows·for·virtual·ANDs·and·ORs
    'LOOKDOWN·test,·<=[noparse]/noparse][color=white]·[/color]$0,[color=white]·[/color]$10,[color=white]·[/color]$AAA,[color=white]·[/color]$F000,[color=white]·[/color]$FFFF[color=white]·[/color,·idx···'or·this,·or·both,·etc)



    ······································ smile.gif


    I·had a project awhile back where i had to many·IF THEN··Statements
    This would realy help me understand better
    ·I have put this project on hold because
    I·did not understand how to use this


    ·

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ··Thanks for any·idea.gif·that you may have and all of your time finding them

    ·
    ·
    ·
    ·
    Sam

    Post Edited (sam_sam_sam) : 8/3/2007 4:34:32 PM GMT
  • ZootZoot Posts: 2,227
    edited 2007-08-03 22:30
    This is probably *about* right -- didn't check it totally (it's my day off smile.gif)

    'the lookup versions...
    IF test = 0 OR test = 1 THEN
        'do stuff "0" -- lookup would give idx = 0, the ON...GOTO label "0"
    ELSEIF test = 2 OR test = 5 OR test = 6 OR test = 9 THEN
        'do stuff "1" -- lookup would give idx = 1, the ON...GOTO label "1"
    ELSEIF test = 3 or TEST = 7 THEN
        'do stuff  "3" -- lookup would give idx = 3, the ON...GOTO label"3"
        'do stuff  "2" -- cause it falls through in sample code
        'do stuff  "0" -- ditto
    ELSEIF test = 4 THEN
        'do stuff "2" -- lookup would give idx = 2, the ON...GOTO label "2"
        'do stuff "0" -- skps to 0 in sample
    ELESEIF test = 8 OR test = 9 OR test = 10 THEN
        'do stuff "4" -- lookup would give idx = 4, the ON....GOTO label "4"
    ENDIF
    
    



    Remember that where you *do stuff "x"* above, could be a lot of code....

    'the lookdown versions...
    IF test <= 0 THEN
        'do stuff "0" -- lookdown would give idx = 0, the ON...GOTO label "0"
    ELSEIF test <= $10 THEN
        'do stuff "1"
    ELSEIF test <= $AAA THEN
        'do stuff "2"
    ELSEIF test <= $F000 THEN
        'do stuff "3"
    ELSE
        'do stuff "4"
    ENDIF
    
    



    One of the nice things about lookdown/lookup in this context is that you can just easily choose to READ or I2CIN values for comparison (rather than a "hard-coded" list) which can make routines even more flexible.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • sam_sam_samsam_sam_sam Posts: 2,286
    edited 2007-08-04 19:45
    Zoot

    Thank You so much for taking the time to·Explane this to me·this way I can understand very well


    LOOKDOWN·test,·<=[noparse]/noparse][color=white]·[/color]$0,[color=white]·[/color]$10,[color=white]·[/color]$AAA,[color=white]·[/color]$F000,[color=white]·[/color]$FFFF[color=white]·[/color,·idx···'or·this,·or·both,·etc

    'the·lookdown·versions...
    IF·test·<=·0·THEN
    ····'do·stuff·"0"·--·lookdown·would·give·idx·=·0,·the·ON...GOTO·label·"0"
    ELSEIF·test·<=·$10·THEN
    ····'do·stuff·"1"
    ELSEIF·test·<=·$AAA·THEN
    ····'do·stuff·"2"
    ELSEIF·test·<=·$F000·THEN
    ····'do·stuff·"3"
    ELSE
    ····'do·stuff·"4"
    ENDIF


    ........................................................................................................................................................................

    Can you Please explane this PART a little more in How each····· [noparse][[/noparse]#,#,#,#,#,#,#,#,#,#,#,#]·

    and use this where each check would be······························ ·[noparse][[/noparse]A,B,C,D,E,F,G,H,I,J,K,L]


    test·=·test//5··'pre·process·if·need·be·for·more·logic/error·checking
    LOOKUP·test,·[noparse][[/noparse]·0,·0,·1,·3,·2,·1,·1,·3,·4,·1,·4,·4·],·idx···
    'lookup·test·and·choose·jump·label·--·allows·for·virtual·ANDs·and·ORs

    ·

    ·What·is·this testing· [noparse][[/noparse]·0,·0,·1,·3,·2,·1,·1,·3,·4,·1,·4,·4·],·' I am a little Lost here can you explane this a little more Please
    ...............................A..B..C..D..E..F..G..H..I..J...K..L.......................................................................................................
    'the·lookup·versions...
    IF·test·=·0·OR·test·=·1·THEN
    ·············A··············C·························································· 'do·stuff·"0"·--·lookup·would·give·idx·=·0,·the·ON...GOTO·label·"0"
    ELSEIF·test·=·2·OR·test·=·5·OR·test·=·6·OR·test·=·9·THEN
    ···················E··································································· ·'do·stuff·"1"·--·lookup·would·give·idx·=·1,·the·ON...GOTO·label·"1"
    ELSEIF·test·=·3·or·TEST·=·7·THEN
    ···················D
    ········································· 'do·stuff··"3"·--·lookup·would·give·idx·=·3,·the·ON...GOTO·label"3"

    ··I am a little lost here............'do·stuff··"2"·--·cause·it·falls·through·in·sample·code

    ··........................................'do·stuff··"0"·--·ditto


    ELSEIF·test·=·4·THEN
    ····'do·stuff·"2"·--·lookup·would·give·idx·=·2,·the·ON...GOTO·label·"2"
    ····'do·stuff·"0"·--·skps·to·0·in·sample


    ELESEIF·test·=·8·OR·test·=·9·OR·test·=·10·THEN
    ····'do·stuff·"4"·--·lookup·would·give·idx·=·4,·the·ON....GOTO·label·"4"
    ENDIF


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ··Thanks for any·idea.gif·that you may have and all of your time finding them

    ·
    ·
    ·
    ·
    Sam
  • ZootZoot Posts: 2,227
    edited 2007-08-04 20:24
    I think where you are getting hung up is in the LOOKUP:

    LOOKUP test, [noparse][[/noparse] 0, 0, 1, 3, 2, 1, 1, 3, 4, 1, 4, 4 ], idx 'lookup test and choose jump label -- allows for virtual ANDs and ORs

    It works like this:

    1. take the value of "test" and lookup the value in the list, starting with 0, based on test, put the value found in the list into idx.... so in the above, if test = 0, then lookup will find the 0th element in the list (the first element) and put the value found there into idx (in this case it is 0 by coincidence)

    2. take the value of idx, which in looking at all the possible values in the list, will be from 0 to 4 ---

    3. use idx to decide which label or subroutine to execute using ON...GOSUB.

    Essentially you are "mapping" one set of values to another, with the "translated" values being integers from 0 to some number.

    In the above:

    test = 0 --> idx = 0
    test = 1 --> idx = 0
    test = 2 --> idx = 1
    test = 3 --> idx = 3
    test = 4 --> idx = 2
    test = 5 --> idx = 1
    test = 6 --> idx = 1
    test = 7 --> idx = 3
    test = 8 --> idx = 4
    test = 9 --> idx = 1
    test = 10 --> idx = 4
    test = 11 --> idx = 4

    If this doesn't make sense, it might be easier to try it on some real code. Write your code with IF...THEN and/or SELECT...CASE, then convert it (or post here). Logically there will be no difference, btw.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • sam_sam_samsam_sam_sam Posts: 2,286
    edited 2007-08-04 23:20
    Zoot

    Thank You for your reply

    Now I understand what you are talking about

    This was the project that i put on hold because i did not understand how to use the lookup command

    What i want to do is make a look up table that would do·the following

    IF sun light·Hours =·9· ····and· 30 min··· then turn on relay for··7···· hours· And 30 min
    ·························· 10················································· ····7
    ·························· 10···········30········································6····················30
    ···························11···················································· ·6
    ···························11···········30······································· 5··················· 30
    ·························· 12.·················································· · 5
    ···························12···········30······································· 4··················· 30
    ·························· 13······················································4
    ···························13·········· 30······································· 3··················· 30
    ·························· 14····················································· 3
    And do this with out having to have·10 ·IF THEN Statements

    http://forums.parallax.com/showthread.php?p=601752


    ·Mike Green·had posted this to what i was asking but i did not understand all of what·he has here·so when i saw your post (Zoot)
    I had trying the same thing i was hopeing that you would explane in more detail and you have and
    I·want to Thank you for that i also want to Thank Mike Green·for his help in the past even if i do not always understand all of it

    Mike Green

    You can also use a lookup table with the READ and DATA statements. You could have a table with one entry for each number
    of hours there's sun. The table entry would have the number of hours the lights need to be on. Since you seem to want this
    in units of 1/2 hour, I'd make the table entries in terms of that. Here I assume there's never more than 19 hours of sunlight.
    [color=blue]Table  DATA  16, 16, 16, 16, 16, 16, 16, 16, 16, 16     ' Sun hours from 0 to 9 -> Half hours of on time
              DATA  14, 12, 10,  8,   7,    6,   5,   4,   3,   2    '  Sun hours from 10 to 19 -> Half hours of on time
    
    GetOnTime:
              READ  Table+SunHours, HalfHoursOn
    [/color]
    


    This code fragment sets up a table in EEPROM with bytes containing the number of 1/2 hours the lights should remain on.
    The offset in the table is the number of hours of sunlight seen [noparse][[/noparse]SunHours] (from 0 to 19). The result is put in "HalfHoursOn".

    The two variables "SunHours" and "HalfHoursOn" can be bytes or nibbles if the values are constrained to be 0-15.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ··Thanks for any·idea.gif·that you may have and all of your time finding them

    ·
    ·
    ·
    ·
    Sam

    Post Edited (sam_sam_sam) : 8/4/2007 11:51:19 PM GMT
  • ZootZoot Posts: 2,227
    edited 2007-08-04 23:54
    Can you post your whole program?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • sam_sam_samsam_sam_sam Posts: 2,286
    edited 2007-08-05 00:00
    Zoot

    I will post the code in half hour· Thanks

    Here is the code that I some what wrote but it only has the hours not the 1/2 hours in it

    When i frist wrote this code i test it with mins·not hours and seem to work alright but that as far as i got with it

    and i want to learn more



    Thank You for your· time that you are·give me so·I can learn this............................................smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ··Thanks for any·idea.gif·that you may have and all of your time finding them

    ·
    ·
    ·
    ·
    Sam

    Post Edited (sam_sam_sam) : 8/5/2007 1:25:40 AM GMT
  • ZootZoot Posts: 2,227
    edited 2007-08-06 15:51
    I'll take a look at this tonight when I'm back by Stamp PC.....

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • ZootZoot Posts: 2,227
    edited 2007-08-07 03:34
    sam_sam_sam: I'm sure you could simplify all the TimerX...Y routines into a single routine with some parameters. One thing I'm not clear on -- you check the time from the RTC·to determine hour of the day to pick a timer, then REset the time on the RTC to 0, I presume to use it as a kind of stopwatch. Do I have that right?

    Does this program work as you'd expect to, regardless of coding technique?

    Probably should start a new thread on this...


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • sam_sam_samsam_sam_sam Posts: 2,286
    edited 2007-08-07 15:44
    Zoot


    One thing I'm not clear on -- you check the time from the RTC·to determine hour of the day to pick a timer, then REset the time on the RTC to 0, I presume to use it as a kind of stopwatch. Do I have that right?


    Yes you have this right this because·I do not want have to reset the clock for day light saving or change the·ON and OFF·Time as the Season Change I want it to run by it self·NO·ADJ Need


    Does this program work as you'd expect to, regardless of coding technique


    What i had posted seem to work the way i was expect it to work but it was going to have to many IF THEN Statements


    Probably should start a new thread on this...

    What should the heading be named so you which one it is

    http://forums.parallax.com/showthread.php?p=666284


    Thanks For all of·your Time And Help in this matter


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ··Thanks for any·idea.gif·that you may have and all of your time finding them

    ·
    ·
    ·
    ·
    Sam

    Post Edited (sam_sam_sam) : 8/8/2007 1:09:22 AM GMT
  • sam_sam_samsam_sam_sam Posts: 2,286
    edited 2007-08-16 01:02
    Zoot

    Could·you give me·an Example of how you would do this

    I'm sure you could simplify all the TimerX...Y routines into a single routine with some parameters

    Thank For· All Of Your Help

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ··Thanks for any·idea.gif·that you may have and all of your time finding them

    ·
    ·
    ·
    ·
    Sam
Sign In or Register to comment.