Shop OBEX P1 Docs P2 Docs Learn Events
Compact use of #> - how to? — Parallax Forums

Compact use of #> - how to?

ErlendErlend Posts: 612
edited 2015-01-14 09:16 in Propeller 1
Is there a shorter way to use the minimum and maximum operators when you want both of them to apply?
snippet: (first line is not relevant to the question)
iHeat/= 100   
  iHeat #>= 20  
  iHeat <#= 100

Erlend

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-01-04 10:32
    iHeat := (iHeat / 100) <# 100 #> 20
    

    -Phil
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-01-04 10:42
    Stylistically, I order things minimum, value, maximum -- like this:
    iheat := 20 #> (iheat / 100) <# 100
    


    ... I find this helps me "see" the process a little easier (I'm a visually-oriented person)
  • David BetzDavid Betz Posts: 14,516
    edited 2015-01-04 10:44
    JonnyMac wrote: »
    Stylistically, I order things minimum, value, maximum -- like this:
    iheat := 20 #> (iheat / 100) <# 100
    


    ... I find this helps me "see" the process a little easier (I'm a visually-oriented person)
    Shouldn't this be:
      iheat := 20 #< (iheat / 100) <# 100
    
    Or am I misunderstanding Spin operators again? :-(
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2015-01-04 11:58
    The operators are #> and <#, with the # on the big side of the < or >.

    The arrow pointing left means the lowest value. X <# Y returns whichever is the lowest value. It is symmetric. Y <# X means exactly the same thing as X <# Y.

    Similarly, arrow pointing right means the highest value. X #> Y returns whichever is the highest value. Likewise symmetric.

    Read Phil's as, whichever is lower, heat/100 or 100, then, whichever is higher, that first result or 20.

    Read Jon's as, whichever is higher, heat/100 or 20, then, whichever is lower, that first result or 100.

    Similar confusion exists with the BASIC Stamp MAX and MIN operators, which act exactly the same, interpreted as floor and ceiling. X MAX Y in the Stamp is the same as Y MAX X and returns the lower of the two values, limited by the ceiling MAX value.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-01-04 11:58
    You have the MIN operator incorrect, David. I think Chip chose the # sign because it kind of looks like =, and makes sense in context.
  • David BetzDavid Betz Posts: 14,516
    edited 2015-01-04 12:01
    JonnyMac wrote: »
    You have the min operator incorrect, David. I think Chip chose the # sign because it kind of looks like =, and makes sense in context.
    Yeah, I figured I got it wrong. I was thinking it would be something like "20 <= x <= 100". Thanks for correcting me.
  • ErlendErlend Posts: 612
    edited 2015-01-04 13:30
    The operators are #> and <#, with the # on the big side of the < or >.

    The arrow pointing left means the lowest value. X <# Y returns whichever is the lowest value. It is symmetric. Y <# X means exactly the same thing as X <# Y.

    Similarly, arrow pointing right means the highest value. X #> Y returns whichever is the highest value. Likewise symmetric.

    Read Phil's as, whichever is lower, heat/100 or 100, then, whichever is higher, that first result or 20.

    Read Jon's as, whichever is higher, heat/100 or 20, then, whichever is lower, that first result or 100.

    Similar confusion exists with the BASIC Stamp MAX and MIN operators, which act exactly the same, interpreted as floor and ceiling. X MAX Y in the Stamp is the same as Y MAX X and returns the lower of the two values, limited by the ceiling MAX value.
    JonnyMac wrote: »
    Stylistically, I order things minimum, value, maximum -- like this:
    iheat := 20 #> (iheat / 100) <# 100
    


    ... I find this helps me "see" the process a little easier (I'm a visually-oriented person)

    Thanks, I put that right in. And thanks to Tracy for the syntax explananation. It ought to go into the Prop manual at next update.

    Erlend
  • msrobotsmsrobots Posts: 3,709
    edited 2015-01-04 18:03
    Yeah,

    this is one of the things I really love with the stamp and the propeller. Redefining the meaning of common used things.

    a >= b is not checking two values, it does change the first one. USE =>. How many times I made that mistake? How many hours debugging, because you do not see it, using other languages over the daytime job?

    MIN and MAX are complete opposite of what you think in Stamp and Propeller. It's Limit MIN and Limit Max or something like that. @Chip again.

    As Tracy states:
    Similar confusion exists with the BASIC Stamp MAX and MIN operators, which act exactly the same, interpreted as floor and ceiling. X MAX Y in the Stamp is the same as Y MAX X and returns the lower of the two values, limited by the ceiling MAX value.

    so x MAX y returns the minimum value and x MIN y the maximum value of both presented. Makes sense doesn't it?

    Anyways I do love to program the propeller. In opposite to my day job it is fun and helps me to remember why I wanted to be a programmer at all 30-40 years ago.

    Sadly I just have time to lurk around here, all my projects are on ice. Daytime Job is crushing me.

    Enjoy!

    Mike
  • ErlendErlend Posts: 612
    edited 2015-01-11 02:00
    So, now I've learned how to efficiently use the <# #> to limit maximum and minimum value, and I am happy with that, but is there also a compact way to limit the result of an increment using this operator?
     IF iPressWater > LiSPpress + 50         
        iFreqPump:= (iFreqPump - 5) #> 5     
     IF pressWater < LintSPpress             
        iFreqPump:= (iFreqPump + 5) <# 60
    

    Can this instead somehow be written using the += and -= operator?
    ...    
        iFreqPump+= 5 <# 60  'obviously does not work    
    ...
    

    Erlend
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-01-11 08:42
    iFreqPump += 5 <# 60
    


    ... will not do what you want because everything to the right side of = in an expression is evaluated first. What you're doing is...

    iFreqPump += 5
    


    ...because 5 is less than 60. What you're trying -- that isn't working -- is apply an assignment and max value at the same time with a single operator. The way you coded it the first time is correct.
  • ErlendErlend Posts: 612
    edited 2015-01-11 09:30
    JonnyMac wrote: »
    ... What you're trying -- that isn't working -- is apply an assignment and max value at the same time with a single operator. The way you coded it the first time is correct.

    Sometimes it is not so easy to understand how things in Spin can be written compact, ref advice I got at the start of the thread. This time I take comfort in that it is not my limited skills that stops me finding a more compact way, since you say there isn't one. Time to go on and learn more about other parts of Spin.
    Erlend
  • Mark_TMark_T Posts: 1,981
    edited 2015-01-11 11:37
    JonnyMac wrote: »
    Stylistically, I order things minimum, value, maximum -- like this:
    iheat := 20 #> (iheat / 100) <# 100
    


    ... I find this helps me "see" the process a little easier (I'm a visually-oriented person)
    Stylistically I'd put the unreadable min/max operators in a well named function so you can actually
    read the code at a later date without confusion:
      iheat := constrain (iheat/100, 20, 100)
    

    That way the code for constrain() remembers the unusual syntax on your behalf.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-01-11 13:43
    I don't find the syntax of #> and <# to be at all weird. If you think of them as "forcing" operators, the statement,
    x := (x + 5) #> 10 <# 30

    can be read naturally as, "Add 5 to x and force the result to be great than or equal to 10 and less than or equal to 30." Incorporating the terms "min" and "max" just confuses things, IMO.

    -Phil
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-01-11 14:15
    Sometimes it is not so easy to understand how things in Spin can be written compact,


    Writing compact code is not always advantageous. Remember, listings are for humans and rule #1 should be readability. Compact variations do not always mean an increase in speed -- the only sure what to know is to test which is easy to do with the Propeller using the cnt register.

    I suggest you focus on working code first, [possible] optimization later. BTW... I have to remind myself of this, too. The other day I optimized a bug into a program that wasn't finished and spent two days looking for it.

    Stylistically I'd put the unreadable min/max operators in a well named function so you can actually read the code at a later date without confusion:


    I'm not bothered by the min and max operators, so I do it inline, yet your suggestion is a good one.
    pub constrain(value, vmin, vmax)
    
      return vmin #> value <# vmax
    
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-01-12 13:34
    I don't find the syntax of #> and <# to be at all weird. If you think of them as "forcing" operators, the statement,
    x := (x + 5) #> 10 <# 30

    can be read naturally as, "Add 5 to x and force the result to be great than or equal to 10 and less than or equal to 30." Incorporating the terms "min" and "max" just confuses things, IMO.

    -Phil
    Everybody knows what the min and max functions do in other languages. The thing that is confusing in PASM is using the max mnemonic symbol for the "limit to the minimummaximum of" operation, and min for the "limit to the maximumminimum of" operation. Or maybe I have it backwards. I always have to look it up in the manual. This confusion carries over to the Spin #> and <# operators, which I also have to always look up in the manual. It would have been sooo much easier if Spin and PASM would just use the min and max keywords just like every other language, calculation utility and math book.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-01-12 14:12
    I suppose ulim and llim might have been a better choice of PASM mnemonics, since their meaning is unambiguous. But if min and max are the opposite of the way you learned them (as they were for me, except for PBASIC), it's easy enough just to remember them that way.

    -Phil
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2015-01-12 23:22
    I don't find the syntax of #> and <# to be at all weird. If you think of them as "forcing" operators, the statement,
    x := (x + 5) #> 10 <# 30

    can be read naturally as, "Add 5 to x and force the result to be great than or equal to 10 and less than or equal to 30." Incorporating the terms "min" and "max" just confuses things, IMO.

    -Phil

    I like to avoid reading it as "greater than or equal to", which suggests non-symmetry.

    Unfortunately, #>, which is symmetric, looks an awful lot like >, which is not. A #> B produces the same result as B #> A. I see the arrow pointing to the right up the number line and read, "take the bigger of A and B".
    x := (x + 5) #> 10 <# 30
    bigger of (x+5) and 10, then, the smaller of that and 30.
    x := 30 <# (x+5) #> 10
    smaller of 30 and (x+5), then, the bigger of that and 10. Same.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-01-12 23:50
    Unfortunately, #>, which is symmetric, looks an awful lot like >, which is not. A #> B produces the same result as B #> A.
    That's why you should always keep the "variable" part on the left and the "constant" (limiting) part on the right. :) Otherwise, yeah, it becomes a mind twister. But it's so freaking useful, I'm willing to forgive any syntactic -- or semantic -- idiosyncrasies.

    -Phil
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2015-01-13 08:38
    Of course, it can be "variable" on both sides. One's personal idiosyncratic mnemonic is necessary to counteract the syntactic and semantic deficiencies. :)
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2015-01-14 09:16
    I'm just going to replicate here an example that John Abshier brought up in another thread, about the quick median.

    Given a, b and c, the median value is,

    median_abc := (a #> b) <# (a <# b #> c)}

    In the following I've listed in the 1st column the 6 possible orderings of a, b and c lowest to highest. The second column is the result of evaluating the two terms in parentheses. The final column is the result of evaluating the final <#, which is in fact the median. Cases where two or three values are equal falls out naturally. While this can be done with a bunch of if-else constructs, the above is above all concise. In fact, John could, as he asked, win the enigmatic if not unreadable code award.
    abc       bc       b
    acb       bc       c
    bac       ac       a
    bca       ac       c
    cab       ba       a
    cba       ab       b
    
Sign In or Register to comment.