1

I am working on "Learn Python the hard way" and have a little understanding question regarding while loops and boolean operators.

def bear_room():
    print "There is a bear here."
    print "The bear has a bunch of honey."
    print "The fat bear is in front of another door."
    print "How are you going to move the bear?"
    bear_moved = False

    while True:
        choice = raw_input("> ")

        if choice == "take honey":
            dead("The bear looks at you then slaps your face off.")
        elif choice == "taunt bear" and not bear_moved:
            print "The bear has moved from the door. You can go through it now."
            bear_moved = True
        elif choice == "taunt bear" and bear_moved:
            dead("The bear gets pissed off and chews your leg off.")
        elif choice == "open door" and bear_moved:
            gold_room()
        else:
            print "I got no idea what that means." 

The script moves to next "step" as soon as I type in "taunt bear". Then I can type in "open door" and I go on to the next function.

But, should a while loop not run endless until something is false? What happens after the "taunt bear" is that bear_moved is set to True. How can it go on the next step then. Furthermore, I do not understand the and not bear_moved statement. Shouldnt that set bear_moved to false? But it is already set to false. It confuses me.

Thanks for any explanation.

four-eyes
  • 10,740
  • 29
  • 111
  • 220
  • Is this your code or some code provided via book/teacher/etc? – But I'm Not A Wrapper Class Jul 31 '14 at 17:58
  • That is the code provded via book http://learnpythonthehardway.org/book/ex35.html – four-eyes Jul 31 '14 at 17:59
  • `if choice == 'taunt bear' and not bear_moved` means exactly what it says: "in case if the choice is `taunt bear` and bear is not moved". – bereal Jul 31 '14 at 18:01
  • @jonrsharpe: This isn't a dup. He doesn't have that problem; in fact, he has working code, but just doesn't understand it. – abarnert Jul 31 '14 at 18:03
  • looking at the code, the `dead` function takes an argument and calls `sys.exit`, which would break the loop and end the game which makes sense considering you are dead ;) – Padraic Cunningham Jul 31 '14 at 18:07
  • I don't get why this book gets so much praise. The design of this code is absolutely terrible; it's trying to tail-call the next room whenever you move—and in the case of `cthulhu_room`, recursively calls itself instead of using a loop. Unless you're trying to use Python to teach people Scheme, or trying to set them up for a subtle lesson about the pitfalls of recursion and deep stack frames, why would you put such a thing in an example meant to teach people? – abarnert Jul 31 '14 at 18:12
  • @abarnert I think what he is trying to show in this example everything the reader learnt so far. Looking at the gold_room i.e. does not make much sense either. I think its just like "Hey, look. you can do this, and that, and this and that". does not need to make much sense, but rather showing how different statements, functions, etc. can be combined. I guess thats the point. – four-eyes Jul 31 '14 at 18:15

3 Answers3

4

But, should a while loop not run endless until something is false?

There are at least two ways to stop an infinite loop (while True:). One way is to use a break statement. It will break out the loop. The other is to use the exit function. That will end the program. Look at the definition of the dead function:

def dead(why):
    print why, "Good job!"
    exit(0) #this ends the program (therefor ends loop)

What happens after the "taunt bear" is that bear_moved is set to True.

Whenever bear_moved is set to True, there are more possibilities available based on your input:

elif choice == "taunt bear" and bear_moved:
    dead("The bear gets pissed off and chews your leg off.")
elif choice == "open door" and bear_moved:
    gold_room()

How can it go on the next step then.

It's an infinite loop. It'll cycle through these options again and again until it breaks or exits.

Furthermore, I do not understand the and not bear_moved statement. Shouldnt that set bear_moved to false? But it is already set to false

not bear_moved is just negating the Boolean. If you do not True, you get False. If you do not False, you get True. That's negation. This will not change the value of bear_moved. It only calculates the if/elif statement.

Sidenote: You seem very new to Python. I'd recommend taking it slower and learning more of the basics of the language before jumping to larger strands of code.

  • Hey, thanks a lot. That was very detailed! Yes, I am new to Python. I worked myself all the way through the book and that is the first part I got stuck on and could not figure it out myself. – four-eyes Jul 31 '14 at 18:11
2

The while loop does run endlessly, because True is never false.

The if … elif … chain checks the first condition, then the next, then the next, etc., only running one of those blocks of code. But, since it's inside a while True loop, you'll immediately read another line of input and do the whole if chain again.

So, the first time through, when you type "taunt bear", that doesn't match the first condition, but it does match the second. Let's break down why:

Breaking it down further:

  • bear_moved is False.
  • So not bear_moved is True. That's what not means: not foo is true iff foo is not true.
  • choice == "taunt bear" is True.
  • So choice == "taunt bear" and not bear_moved is True. That's what and means: foo and bar is true iff both foo and bar are true.

Then you start the loop again, and type "taunt bear" again. This time, that doesn't match the first condition, or the second one—because now bear_moved is True, or the next, so you finally get to the else.

It may help you to see this visually. Try a debugger, or a visualizer like this one online, and it'll show you the flow of control.

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • 1
    Ah, thanks. So the statement `and not` changes from `false` to `true`? Like here explained in the tables: http://learnpythonthehardway.org/book/ex27.html – four-eyes Jul 31 '14 at 18:08
  • @Christoph: Exactly. The textbook hopefully explains it better than I did. :) – abarnert Jul 31 '14 at 18:08
  • 1
    He is getting a bit lazy on the explanation to the end of the book. But I guess that is on purpose that the reader gets used to figure it out him- or herself! – four-eyes Jul 31 '14 at 18:11
1

and not bear_moved isn't an assignment statement, it's a Boolean test. That whole line is saying "if you taunt the bear and he hasn't moved, then the bear will move". Then the while loop continues to the next step, at which point bear_moved is true.

The while loop doesn't continue until anything is false; it will continue until the specific condition you gave it is False. In this case, we have while True, so the loop will continue forever until True == False, which happens to be never. In a loop like this, you would get out of it by using the break statement at some point, which automatically short-circuits the loop.

On a side note, this particular while loop doesn't have a break in it anywhere, which makes me nervous for the overall structure of the program. There are probably better ways of programming this game.

TheSoundDefense
  • 6,753
  • 1
  • 30
  • 42
  • you can still exit the game from another function with sys.exit, the break would not have to be in the loop, looking at the code that is exactly what dead does. – Padraic Cunningham Jul 31 '14 at 18:05
  • @PadraicCunningham: True, or an exception… But it's still very bad design for an IF game in Python (or any language without TCO); you're building up a stack chain consisting of every room the user has visited, and I doubt a player will be happy if he's gone through 999 rooms and the game suddenly bails on him… – abarnert Jul 31 '14 at 18:09
  • Ah, I guess I start to understand. Thanks! – four-eyes Jul 31 '14 at 18:09
  • @abarnert this is meant for learning purpos only, not to become a proper game. there are more chapters to go! I really would recommend that book to everyone. Its in a good pace, well written and understandable. This is the first chapter (and I am nearly done, another ten to go) where I got stuck and could not figure it out myself – four-eyes Jul 31 '14 at 18:13
  • @Christoph: But the point is, he's teaching you something that is a very bad idea. In a few cases, he does this and then explains that it's a bad idea, and why, or asks you to figure it out, but often he just writes really bad code as if it were the right thing to do, which means everyone who learns from this book comes to SO with the same completely avoidable problems… – abarnert Jul 31 '14 at 18:16
  • @abarnert if you say so. I am far away from judging someone elses code and cant tell at all if that is good code or bad code. I just started to learn and tried to lay out his intention why he is doing it the way he does. What I can say is that I learned something doing his course. I got a better understand for the way the language works and how it is structured and for that I am very thankful. But weather the code he writes is good nor bad - no idea. But, the way the book is written is understandable and I like that. It starts from 0 and works its way "up". – four-eyes Jul 31 '14 at 18:25
  • @Christoph I wouldn't stress about it that much at the moment. The book sounds like it's very good for syntax, but not great for practices. You'll want to learn practices not long after syntax, but there are other resources for that. – TheSoundDefense Jul 31 '14 at 19:03