# "or" and "and"

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. OpenStax)

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?

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.

elsif te == te_last and on > st and on < st + st

try this:

elsif (te == te_last) && (on > st) && (on < (st + st))

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 G.

Department of Biochemistry
University of Cambridge

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 W. 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:

=> 2
=> 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

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

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

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

On Mon, Jul 28, 2008 at 7:04 AM, Alex G.
[email protected]wrote:

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