1

I'm new to Python. I came up with a simple program to test some of the tools I've learned. It works for the most part, except for one of my nested 'while' loops. Below is my code. The part that doesn't work is when I enter "manual" in my work function and it's "raining". I intended for it to print rainedOut then go back to the raw_input. Only once it's raining 3 times (i.e., after looping back to the raw_input 3 times and it being rainedOut) should it print "You should probably just give up now." and exit the function. However, what it does, is on the first go, it prints out rainedOut 3 times in a row and then ends the function automatically. Can anyone help me with the error in my code?

import time
import sys
done = "I'm tired of you. Goodbye."
rainedOut = "Sorry, rain foiled your plans :("
dontUnderstand = "I'm sorry, I don't understand."
def good_weather():
 """Imagine a world where every 5 seconds it rains (good_weather = False),
 then is sunny again (good_weather = True). This function should return
 whether good_weather is True or False at the time it's called.
 """
 seconds = time.time()
 seconds %= 10
 if seconds <= 5:
 good_weather = True
 return good_weather
 else:
 good_weather = False
 return good_weather
def start():
 entries = 0
 while entries < 4:
 choice = raw_input("Hello! What do you want to do right now? Options: 1) Sleep, 2) Work, 3) Enjoy the great outdoors: ")
 if choice == "1":
 print "We are such stuff as dreams are made on, and our little life is rounded with a sleep. - Shakespeare, The Tempest"
 elif choice == "2":
 work()
 elif choice == "3":
 outdoors()
 else:
 print dontUnderstand
 entries += 1
 print done
def work():
 entries = 0
 entries2 = 0
 while entries < 4:
 choice = raw_input("Would you prefer sedentary office work or manual labor in the elements?: ")
 if "office" in choice:
 print "The brain is a wonderful organ; it starts working the moment you get up in the morning and does not stop until you get into the office. -Robert Frost"
 elif "manual" in choice:
 sunny = good_weather()
 if sunny == True:
 print "A hand that's dirty with honest labor is fit to shake with any neighbor. -Proverb"
 else:
 while entries2 < 3:
 print rainedOut
 entries2 += 1
 print "You should probably just give up now."
 sys.exit()
 else:
 print dontUnderstand
 entries += 1
 print done
 sys.exit()
def outdoors():
 sunny = good_weather()
 if sunny == True:
 print "Adopt the pose of nature; her secret is patience. -Ralph Waldo Emerson"
 sys.exit()
 else:
 print rainedOut
 start() # go back to start
start()
asked Jul 25, 2015 at 21:41
7
  • Never use sys.exit() to exit a loop, or function. Just return from the function. As to why you shouldn't, see numerous questions here. If that requires you to augment your function to return True/False status, or some more complicated object/None, then augment it. Commented Jul 25, 2015 at 22:33
  • You should use break to exit from within a loop, return or return <exit-value/object> to return from a function, and you can shortcut breaking from a loop inside a function with a return (as long as you know what the return value will be). Do not use sys.exit() as some nuclear shotgun to escape all control-flow constructs! (Teardown, memory-leaks, housekeeping, message logging, GUI threads, persistent storage... just some of many reasons why it's a terrible habit. Also, it will screw up unit-tests/ Test-Driven Design) Commented Jul 25, 2015 at 22:39
  • 1
    There is also no point in assigning a value to a variable and then immediately returning it. You're doing it at least twice (in good_weather). Use return True and return False instead. Commented Jul 25, 2015 at 22:41
  • 1
    @ReutSharabani: in fact those six lines can all be replaced with return (seconds <= 5). Commented Jul 25, 2015 at 22:43
  • Or the entire function with return (time.time() % 10) <= 5 Commented Jul 25, 2015 at 22:44

1 Answer 1

2

I think you want this part:

else:
 while entries2 < 3:
 print rainedOut
 entries2 += 1
 print "You should probably just give up now."
 sys.exit()

To be more like this:

if entries2 < 3:
 print rainedOut
 entries2 += 1
 continue # restart loop (optional)
else:
 print "You should probably just give up now."
 sys.exit()

You're confusing the while (loop) and if (test) functionality.

answered Jul 25, 2015 at 21:53

6 Comments

You should point out to OP that the entire if...elif...else ladder exists inside a while-loop. The responsibility for incrementing/updating the loop-variable should be reduced to one (or very few) points in that loop. OP's undisciplined splattergun use of sys.exit() to break from loops/return from functions is a bad coding habit they need to stop immediately.
While I strongly agree, this is more for "Code Review" than "Stack Overflow". I've concentrated on his problem. There are more problems in the code. We can discuss them in the question's comments.
It works! You're right; thank you. I got confused because I tried to replicate a similar functionality earlier on in the work() function (i.e., while entries < 4...) Do I need to change that one from 'while' to 'if' as well?
If there are any comments about the code otherwise -- e.g., what to do instead of sys.extit() -- I'm all ears. I'm also new to SO, so I'm not sure if this is the proper venue?
@mmrtre18: see my comments above, also read good code examples here and at CodeReview.stackexchange.com
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.