Which of "and" or "or" should I use to join non-equality checks, and why?
Asked Answered
T

4

13

This is a very simple dice roll program that keeps rolling two dice until it gets double sixes. So my while statement is structured as:

while DieOne != 6 and DieTwo != 6:

For some reason, the program ends as soon as DieOne gets a six. DieTwo is not considered at all.

But if I change the and to an or in the while statement, the program functions perfectly. This doesn't make sense to me.

import random
print('How many times before double 6s?')
num=0
DieOne = 0
DieTwo = 0

while DieOne != 6 or DieTwo != 6:
    num = num + 1
    DieOne = random.randint(1,6)
    DieTwo = random.randint(1,6)
    print(DieOne)
    print(DieTwo)
    print()
    if (DieOne == 6) and (DieTwo == 6):
        num = str(num)
        print('You got double 6s in ' + num + ' tries!')
        print()
        break
Thingumabob answered 12/1, 2019 at 19:31 Comment(13)
If DieOne is 6 then the statement DieOne != 6 and DieTwo != 6 is false because it's not true the both die are not equal to six.Conurbation
That makes sense to me, so it's unclear what you're asking. You want the loop to end when both checks are false, so or is the correct combination.Clinic
the problem is this. you want NOT(die 1 is 6 AND die 2 is 6). The equivalent condition becomes die 1 is NOT 6 OR die 2 is NOT 6. This is a logic problem that you'd need to work out. when you say "die 1 is not 6 AND die 2 is not 6", the condition will immediately fail the moment one of them become a 6, because AND needs to ensure BOTH conditions stay satisfied.Oliy
en.wikipedia.org/wiki/De_Morgan%27s_lawsCascara
ps. the way you have the code written though, you have a break statement to leave the loop. so to be honest a while true works just fine, you have a condition in place to leave the loop already.Oliy
I guess my brain is thinking in terms of an IF statement rather than WHILE. If condition A is false AND condition B is false then . . . But WHILE is structured differently. WHILE condition A is false OR condition B is false. This is not intuitive for me.Thingumabob
no, dont mix your while or code syntax at all.youre getting the math behind it wrong because of the way "not" works. the bottom line is this: both if and while work when the condition in front of them is TRUE. not false. you should move the "negation" logic into the way conditional is being structured.Oliy
simplify: while DieOne+DieTwo != 12: ... or simply while True: together with your breakAdorable
hey thats cheating. :P @PatrickArtnerOliy
@ParitoshSingh How is that "cheating," its coding, if it works it works.Figurehead
@ParitoshSingh DeMorgan is the way to go and you explained it well ... but simpler is often ...simpler ;o) - the less I have to think about it the easer the next reviewer will have it - see python.org/dev/peps/pep-0020 number 3Adorable
haha yes indeed, agreed. cant resist the opportunity for a tongue in cheek remark though if it presents itself like that :POliy
I much appreciate the comments here. I can see my confusion now. I like the while DieOne + Die2 != 12 much better.Thingumabob
F
19

TLDR at bottom.

First off, while loops run if the following condition is true, so

DieOne != 6 or DieTwo != 6:

must return true when simplified, for the while funtion to run

The and operator returns true if both conditions are true, so the while loop will only run when it is True and True.

So the following won't run if either of the dice rolled a 6 for example:

while DieOne != 6 and DieTwo != 6:

If DieOne rolled a 4 and DieTwo rolled a 6, the while loop won't run because DieOne != 6 is true, and DieTwo != 6 is false. I put this train of thought into code below.

while DieOne != 6 and DieTwo != 6:
while True and False:
while False: #So it won't run because it is false

The or operator works differently, the or operator returns true when one of the conditions is true, so the while loop will run when it is True or True, True or False, or _False or True. So

while DieOne != 6 or DieTwo != 6:

will run if only either dice rolled a six. For example:

If DieOne rolled a 4 and DieTwo rolled a 6, the while loop will run because DieOne != 6 is true, and DieTwo != 6 is false. I put this train of thought into code below.

while DieOne != 6 or DieTwo != 6:
while True or False:
while True: #So it will run because it is true

TLDR/Review:

while True: #Will run
while False: #Won't run

And:

while True and True: #Will run
while True and False: #Won't run
while False and True: #Won't run
while False and False: #Won't run

Or:

while True or True: #Will run
while True or False: #Will run
while False or True: #Will run
while False or False: #Won't run
Figurehead answered 12/1, 2019 at 21:24 Comment(0)
M
3

What you need is Not instead of !=.

try this:

while not (DieOne == 6 or DieTwo == 6):
Mcdougal answered 10/9, 2020 at 7:17 Comment(1)
Good try, but this runs into the same problem as my original code. It works if you change the Or operator to And.Thingumabob
O
1
while DieOne != 6:
   if DieTwo != 6:
      break
   num = num + 1
   DieOne = random.randint(1, 6)
   DieTwo = random.randint(1, 6)
   print(DieOne)
   print(DieTwo)
   print()
   if (DieOne == 6) and (DieTwo == 6):
      num = str(num)
      print('You got double 6s in ' + num + ' tries!')
      print()
      break
Ong answered 8/10, 2021 at 21:9 Comment(1)
While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. You can find more information on how to write good answers in the help center: stackoverflow.com/help/how-to-answer . Good luck 🙂Proudfoot
G
1

Hmm. Boil it down to a single condition, both_6:bool, based on multiple conditions:

import random

num = 0
both_6 = False

​
while not both_6:
    num += 1

    DieOne = random.randint(1,6)
    DieTwo = random.randint(1,6)

    if (DieOne==6) and (DieTwo==6):
        both_6 = True
        print(f"\nIt took you {num} attempts to get double sixes!\n")


"""
It took you 25 attempts to get double sixes!
"""

It feels like multiple conditions is broken

Gimpel answered 27/9, 2022 at 20:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.