Codeabbey -- bmi

Oforth examples. Feel free to post your own code.

Codeabbey -- bmi

Postby sotolf » 16 Aug 2015 11:06

Code: Select all
: getLn { System.Console askln }                    // ( <stdin> -- string )
: getNumber { getLn asInteger }                     // ( <stdin> -- integer )
: pprint { apply(#.) printcr }                  // ( [a] -- <stdout> )
: getInput { [] getNumber #[ getLn + ] times } // ( <stdin> -- [string] )
List method: split { self first self second }       // ( pair -- fst snd )
: parse { words map(#asFloat) }                   // ( string -- [kg,m] )
: bmi { split sq / }                                // ( [kg, m] -- bmi )
: obese { "obese" }
: ?over { 30 < ifTrue: [ "over" ] else: [ obese ] }
: ?normal { dup 25 < ifTrue: [ drop "normal" ] else: [ ?over ] }
: ?under { dup 18.5 < ifTrue: [ drop "under" ] else: [ ?normal ] }
: getBmi { ?under }

getInput printcr map( #[ parse bmi getBmi ] ) pprint


I'm quite sure there is a more elegant way to do the if chain, but it's what I found for now.
sotolf
 
Posts: 55
Joined: 30 Jul 2015 15:53

Re: Codeabbey -- bmi

Postby Franck » 20 Aug 2015 12:03

Hi,

Some comments, more about factoring than code :

1) #obese function just returns a constant, so, imo, it is better to create a constant, like :

Code: Select all
"obese" Constant new: Obese


or even use a symbol. Symbols are like strings, but there a identity, which means that only one instance of a particular symbol is created into the system. Symbols are created (or not if they alreday exist) using $

2) ?over, ?normal and ?under seem strange to me.
When I write a function ?under, I except it to return if bmi is under or not. I would not except that this function could call ?normal (and that this one could call ?over )

So, imo, i would write (yes I know ... local variables :) ) :

Code: Select all
: bmi(l) { l first l second sq / }         // ( aPair -- bmi )

: getBmi(b)                                                // ( aNumber -- aSymbol )
{
   b 18.5 < ifTrue: [ $under  return ]
   b 25   < ifTrue: [ $normal return ]
   b 30   < ifTrue: [ $over return ]
   $obese
}


Well, this is my personal coding style... Don't stick to it if you are not comfortable with it.

Franck
Franck
 
Posts: 155
Joined: 29 Oct 2014 19:01

Re: Codeabbey -- bmi

Postby sotolf » 21 Aug 2015 07:52

1) #obese function just returns a constant, so, imo, it is better to create a constant


100% yes, I don't know why I didn't think of that. A constant would be good.

or even use a symbol. Symbols are like strings, but there a identity, which means that only one instance of a particular symbol is created into the system. Symbols are created (or not if they alreday exist) using $


So that means something like $test , would it be close to what :test is in ruby or clojure? or "test" $ ?

Code: Select all
2) ?over, ?normal and ?under seem strange to me.
When I write a function ?under, I except it to return if bmi is under or not. I would not except that this function could call ?normal (and that this one could call ?over )


Yeah, I was unsure about the naming, and how those functions where structured, ?under should be a function that returns something only if the condition of under is fulfilled, which I had them as first, so that ?under would write "under" to the stack only if the value was under 18, and so on. Then I was thinking it was a bit stupid to check all of the conditions every time, even though I knew that if it was one of them, it couldn't be the other, so I combined them, but didn't change the names.

So, imo, i would write (yes I know ... local variables


Hehe, bmi I would write without, since it's used so that much stack shuffeling isn't needed, but the second one is one where I feel local variables should be used, yes, that's a lot nicer. And #return it is that I was looking for but not finding.
sotolf
 
Posts: 55
Joined: 30 Jul 2015 15:53


Return to Oforth examples

Who is online

Users browsing this forum: No registered users and 1 guest

cron