Hi, I'm just getting to discover ruby, but I find it very nice programming language. I just still don't understand how the "or" and "and" in ruby... I was playing with ruby and for example made a def to print Stem and Leaf plot (for those who didn't have a statistics course or slept on it, e.g. http://cnx.org/content/m10157/latest/) Here is the Beta version of it: class Array def n ; self.size ; end def stem_and_leaf(st = 1) # if st != (2 or 5 or 10) then ; st = 1 ; end k = Hash.new(0) self.each {|x| k[x.to_f] += 1 } k = k.sort{|a, b| a[0].to_f <=> b[0].to_f } te_last = 999999999999999999999999999999999 # impossible number puts " Stem and Leaf plot" + " N = " + self.n.to_s + " Steps / " + st.to_s st = 10 / st k.each do |key, val| te = (key / 10).to_i on = (Math.sqrt((key - te * 10).to_i**2)).to_i if te == te_last and on < st val.times { print on.to_s } te_last = te elsif te == te_last and on > st and on < st + st val.times { print on.to_s } te_last = te st += st else print "\n" + "%+6s" % te.to_s + " : " val.times { print on.to_s } te_last = te end end end end It prints: Stem and Leaf plot N = 15 Steps / 2 1 : 234 1 : 56789 2 : 019 # it shouldn't be like this 3 : 08 # it shouldn't be like this 4 : 07 # it shouldn't be like this Or with different "steps" value: Stem and Leaf plot N = 15 Steps / 5 1 : 23 1 : 4567 1 : 89 2 : 019 # it shouldn't be like this 3 : 08 # it shouldn't be like this 4 : 07 # it shouldn't be like this (data: 12 13 14 15 16 17 18 19 20 21 29 30 38 40 47) My questions: /1 If I just wanted it to work with "st" values: 1, 2, 5, how should the "or" statement look like? Ruby don't understand multiple or's (I tried using different brackets is several places but it still doesn't work). /2 It feels like Ruby didn't understand 3 and's in the elsif part of script. It don't understand the 3rd "and". Why? How to write those "and" statements? Thanks in advance : ) If anyone'd like to use the script feel free, I'd be just grateful to if you cite this message as a source ; ) Greetz, Timo
As far as i know ruby deals with multiple ors and ands perfectly well. It may be a precedence mixup though: "or" has lower precedence than "||", and similarly, "and" has lower precedence than "&&". 'and' and 'or' actually have the SAME precedence, which has even more potential for error, i think. Using the symbols, && has higher precedence than ||. Try it with the symbol versions, ie || and &&, and see if it's still broken, maybe? Also, i've found that bracketing up multiple logical tests helps a lot: the optional omission of the brackets seems to lead to interpreter to do something different to what you'd expect, sometimes. So, instead of this elsif te == te_last and on > st and on < st + st try this: elsif (te == te_last) && (on > st) && (on < (st + st)) -- Posted via http://www.ruby-forum.com/.
On 28 Jul 2008, at 11:39, es_ wrote: > class Array > > def n ; self.size ; end > > def stem_and_leaf(st = 1) > # if st != (2 or 5 or 10) then ; st = 1 ; end This won't fly (as you've noticed). you'll need to do either if st != 2 or st != 5 or st != 10 then st = 1 end or more consisely if not [2,5,10].include? st then st = 1 end or even [2,5,10].include? st or st = 1 Alex Gutteridge Department of Biochemistry University of Cambridge
Note to self - read question properly before answering :) -- Posted via http://www.ruby-forum.com/.
Thanks for help! The problem is that 3 or's don't work: ?> st = 1 => 1 >> if st != 2 or st != 5 or st != 10 then ; st = 1 ; end => 1 >> ?> st = 2 => 2 >> if st != 2 or st != 5 or st != 10 then ; st = 1 ; end => 1 >> ?> st = 2 => 2 >> if st != 2 or st != 5 or st != 10 then ; st = 1 ; end => 1 >> st = 5 => 5 >> if st != 2 or st != 5 or st != 10 then ; st = 1 ; end => 1 >> st = 10 => 10 >> if st != 2 or st != 5 or st != 10 then ; st = 1 ; end => 1 Or with extra brackets: >> if (st != 2) or (st != 5) or (st != 10) then ; st = 1 ; end => 1 Hopefully the "include' option works fine and is beautiful, that's a great example of simplicity of Ruby I'm getting to appreciate. And about the brackets, Max Williams wrote, it doesn't work either. I tried if before. I also know the difference on "and" and "&&", I revived some articles on that while looking for some info. Greetz, Timo
Hi -- On Mon, 28 Jul 2008, es_ wrote: > Thanks for help! > > The problem is that 3 or's don't work: > > ?> st = 1 > => 1 >>> if st != 2 or st != 5 or st != 10 then ; st = 1 ; end > => 1 >>> > ?> st = 2 > => 2 >>> if st != 2 or st != 5 or st != 10 then ; st = 1 ; end > => 1 >>> > ?> st = 2 > => 2 >>> if st != 2 or st != 5 or st != 10 then ; st = 1 ; end > => 1 >>> st = 5 > => 5 >>> if st != 2 or st != 5 or st != 10 then ; st = 1 ; end > => 1 >>> st = 10 > => 10 >>> if st != 2 or st != 5 or st != 10 then ; st = 1 ; end > => 1 It looks OK to me. What isn't working here? David -- Rails training from David A. Black and Ruby Power and Light: * Advancing With Rails August 18-21 Edison, NJ * Co-taught by D.A. Black and Erik Kastner See http://www.rubypal.com for details and updates!
> It looks OK to me. What isn't working here? It checks if st is 2, 5 or 10. I set st to 5 and it says, "wrong" while it should say "correct". Greetz, Timo
es_ wrote: > It checks if st is 2, 5 or 10. I set st to 5 and it says, "wrong" > while it should say "correct". No, it checks whether st is not 2, st is not 5 or st is not 10. When st is 5 it is still not 10 and not 2. So two out of three conditions are true. And with or it suffices if one of the conditions is true. HTH, Sebastian -- Jabber: sepp2k@jabber.org ICQ: 205544826
Hi, I've spotted the err in and's by printing the st values: Stem and Leaf plot N = 15 Steps / 5 (st =2) 1 : 2(st =2)3(st =4) 1 : 4(st =4)5(st =8)6(st =8)7(st =8) 1 : 8(st =8)9(st =16) 2 : 0(st =16)1(st =16)9(st =16) 3 : 0(st =16)8(st =16) 4 : 0(st =16)7 ....stupid mistake, I forgot that it sums it into infinity. In the "or" example it was just my logical mistake. I mistaken "or" with "neither"... Greetz and thanks for help! Timo
[Note: parts of this message were removed to make it a legal post.] On Mon, Jul 28, 2008 at 7:04 AM, Alex Gutteridge <alexg@ruggedtextile.com>wrote: > On 28 Jul 2008, at 11:39, es_ wrote: > > class Array >> >> def n ; self.size ; end >> >> def stem_and_leaf(st = 1) >> # if st != (2 or 5 or 10) then ; st = 1 ; end >> > > > This won't fly (as you've noticed). And as for WHY it doesn't fly. The expression 2 or 5 or 10 evaluates to 2 since anything but nil or false is 'truthy' in ruby and or returns its left hand operand it it's truthy otherwise it returns the evaluation of its right hand operand. So if st !=(2 or 5 or 10) then; st = 1;end might as well be if st != 2 then; st = 1;end -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/