Exit a program conditional on input (Python 2) - python

This is for a game. The game asks the user if s/he would like to play again. If not, the program should just exit. If yes, the entire game is repeated and asks to play again, and so on.
while True:
print "*game being played*"
# prompt to play again:
while True:
replay = raw_input("Play again? ")
print replay
if replay.lower == "yes" or "y":
break
elif replay.lower == "no" or "n":
sys.exit()
else:
print "Sorry, I didn't understand that."
However, when I actually execute this code it acts as if every answer input is a yes (even "aksj;fakdsf"), so it replays the game again.
.
When I changed the code to first consider no instead of yes:
if replay.lower == "no" or "n":
sys.exit()
I get the error
Traceback (most recent call last):
File "C:/Python27/Programs/replay game.py", line 18, in <module>
sys.exit()
NameError: name 'sys' is not defined
This might have something to do with the fact I don't actually know what sys.exit() does but just found it while googling "how to exit program python".

lower is a function in python.
Be sure to include the elipses (). It should look like string.lower()
Also, try putting it at the end of your input so you don't have to type it every time
replay = raw_input('Play again? ').lower()
As Jon Clements pointed out, something that I looked over and missed in your code, consider the following statement:
if replay.lower() == "yes" or "y":
#execute
To the human eye, this looks correct, but to the computer it sees:
if replay.lower() is equal to "yes" or if 'y' is True...execute
Your game will always replay because "y" is a string and always true. You must replace the code with something like this (my above advice included):
if replay == 'yes' or replay == 'y':
#execute
finally, import sys at the top of your program. This is where the error is occurring, because sys is a module that must be imported to the program.
Here is an article on operators that you might benefit reading from

You first need to import sys. Place this:
import sys
at the top of your code to import the sys module.
However, a much easier way to exit a script is to just do this:
raise SystemExit
The above code does the exact same thing as sys.exit.
Also, for your code to work properly, you will need to do two more things:
Reconstruct your if-statements to use the in keyword.
Invoke the .lower method by placing () after it.
Below is a fixed version of your script:
while True:
print "*game being played*"
# prompt to play again:
while True:
# I put .lower() up here so I didn't have to call it multiple times
replay = raw_input("Play again? ").lower()
print replay
if replay in ("yes", "y"):
break
elif replay in ("no", "n"):
raise SystemExit
else:
print "Sorry, I didn't understand that."
Now let me explain why you needed to remake your if-statements. As it currently stands, Python is reading your code like this:
if (replay.lower == "yes") or "y":
Furthermore, since "y" is a non-empty string (which always evaluate to True in Python), this if-statement, left as it is, will always pass as True. Using in however like I did above tests whether replay can be found in the tuple ("yes", "y").

At the beginning of the code you have to add:
import sys
then other code can follow

Firstly, sys is a standard lib package that needs to be imported to reference it. I recommend reading up a bit on importing in python.
put this at the top of your code:
import sys
That should take care of the sys namespace error
Secondly you need to understand how python evaluates if statements
if replay.lower == "no" or "n":
which can be broken up into two statements:
if ( (replay.lower == "no") or ("n") ):
the left side will evaluate to False, and the right side will evaluate to True. this is because "n" (or any non 0/non False object) evaluates to True.

Related

Python input() not being called during function call [duplicate]

This question already has answers here:
Why does "a == x or y or z" always evaluate to True? How can I compare "a" to all of those?
(8 answers)
Closed 6 months ago.
This is a code snippet from a simple text based game I'm writing to improve my Python skills.
I plan on using input_check() to simplify a lot of code that I'll write later on in the project, but I can't get it to work at the moment. I'm running this on the latest master of VS Code with the Pylance extension, which doesn't flag any errors in my code. I've run multiple tests to make sure input_check() is the issue, and removing it and simply running the code multiple times works just fine.
import time
def rules():
print("The rules of this game are:")
time.sleep(0.5)
print("rules")
time.sleep(0.5)
print("rules")
time.sleep(0.5)
print("rules")
time.sleep(0.5)
print("rules")
time.sleep(0.5)
print("rules")
time.sleep(0.5)
input_check("Do you understand?\n", rules(), "Ok. Starting game...")
def input_check(question: str, function, confirmation: str):
yes_no = input(question)
if yes_no.lower() == "n" or "no":
function
elif yes_no.lower() == "y" or "yes":
print(confirmation)
time.sleep(1)
else:
print("Invalid input.")
input_check(question, function, confirmation)
input_check("Do you know the rules?\n", rules(), "Ok. Starting game...")
I'm almost a complete newbie to Python so I have no idea if taking the function argument and then running it as a function later in input_check() would work or not, but that's not the issue.
There should be a prompt run to define yes_no with input() but it never reaches this. Instead, it seems like it skips ahead to running rules() (which should only happen if the user inputs 'no' or 'n'), and rules() runs continuously until stopped, completely skipping input_check() .
My questions are:
Why is input_check() being completely ignored?
Can you run code taken as a parameter as-is (the function parameter) or is there an extra step I need to make it run?
Is there a better/more efficient way to do this? (e.g. a package that parses input that avoids having to make your own function)
Look at this statement:
input_check("Do you know the rules?\n", rules(), "Ok. Starting game...")
When you do that, Python is going to CALL the rules function immediately, so it can pass it's result to input_check. Your rules function prints out a bunch of stuff, then has the exact same line, which is going to call rules() again, and again, and again, and again... It never gets a chance to call input_check. It's still processing the parameters.
If you want to PASS the function object but not call it, don't use the parens:
input_check("Do you know the rules?\n", rules, "Ok. Starting game...")
Note that the input_check function will keep calling the passed in function. You DON'T need to call it again inside rules.
Followup
This does not do what you think:
if yes_no.lower() == "n" or "no":
That's parsed as:
if (yes_no.lower() == "n") or "no":
and since "no" is true, that if will always be taken. You should use one of these:
if yes_no.lower() in ("n" or "no"):
if yes_no.lower()[0] == "n":
Next, you have this:
if yes_no.lower() == "n" or "no":
function
Here, you DO want to call the function, so you need to add the parens:
if yes_no.lower()[0] == "n":
function()
inputCheck("Do you know the rules?\n", rules(), "Ok. Starting game...")
You don't need any parantheses() after rules, instead of passing function as an argument you're running it. Write it like this:-
inputCheck("Do you know the rules?\n", rules, "Ok. Starting game...")
Also here:-
if yes_no.lower() == "n" or "no":
function
You need to add () after function, write:-
if yes_no.lower() == "n" or "no":
function()
Let me know if it does solve problem
The problem is you used rules() like a parameter to pass a function. You need to change to: inputCheck("Do you know the rules?\n", rules, "Ok. Starting game...").
rules(): will calling function rules()
rules: functions can be passed as a parameter to another function.
You can come here to get more information:
What is the difference between calling function with parentheses and without in python?.
Note: I saw your sample code has many errors (when using def rules() like an object or function). You should to learn how to debug, it will help you fix errors effective
along with the other answers, I found another semantic error: your first if statement will always evaluate to true, as it will be evaluating the boolean value of 'no' as follows
if yes_no.lower() == 'n' or 'no' == True:
since a non empty string evaluates to true, this statement will always execute. instead of what you have, you can add
yes_no.lower() == 'no'
giving you
if yes_no.lower() == "n" or yes_no.lower() == "no":
making it so that statement evaluates as true only if yes_no.lower is 'n' or 'no'
for further clarification, see
Why is my python if statement not working?
You're getting a lot of explanation for the code's current behavior but not
much practical advice on how to do what I think you're trying to do. You don't
need to pass the rules function back and forth. You need the most important
tool for getting user input: a while-true loop.
def game():
if not yesno('Do you know the rules'):
rules()
print("Ok. Starting game ...")
def rules():
while True:
print("The rules of this game are ... BLAH BLAH")
if yesno('Do you understand'):
break
def yesno(question):
while True:
yn = input(f'{question}? [yes/no]: ').lower()
if yn in ('y', 'yes'):
return True
elif yn in ('n', 'no'):
return False
else:
print("Invalid input.")

how to ask the user if they want the code to start again

I am just starting out on a python Nat5 course so I'm sorry if the answer is glaringly obvious but what I'm trying to do is ask the user if they want the code to restart or not and ask again if the user inputs an incorrect answer
print("would you like to ask again?")
go = input("enter yes/y or no/n")
if(go == 'y') or (go == 'yes'):
#replay here
elif(go == 'n') or (go == 'no'):
exit()
else:
print("It's a yes or no question")
#ask to replay again
I do not know if this is the best practice, but it works for me and I have had no issues.
Put the code in a function
def code():
#insert the code here
and then call the function
if (go=='y'):
code()
It is also worth noting that you will need to also call the function at the end of the code so that it actually runs the first time round.

Why is this script repeating itself?

I'm trying to teach myself python, I recently learned how to use raw input in an if statement (yes or no). However, when I answer yes, the program asks me the same if question.
Can anyone help? I'm not really good at programming but love doing it.
import time
name = raw_input("what is your name? ")
print "Hello " + name
#yes no statement with raw input
while True:
yesno = raw_input("would you like to play hangman?")
if yesno.lower().startswith("n"):
print("ok bye")
exit()
elif yesno.lower().startswith("y"):
print("cool, let me prep for e second")
time.sleep(5)
# this is where it goes wrong
# below is what is supposed to follow
word = "kaasblok"
guesses = ''
turns = 6
while turns > 0:
If you use a while true loop, your program will keep on running.
In Python, the tabs or whitespace tell the interpreter when a loop ends.
So what happens in your code is this:
While True is running,
It asks if you want to play
If you write no it works as intended
If you write yes, it sees that the loop is over so it restarts.
Also your code has several errors, like syntax from both Python 3 and Python 2 and a while loop that doesn't terminate.
I wrote some updates to make the code sort of work but it is not "good" code because I tried to keep it as similar as possible. Also I chose a syntax (python 3) so make sure to change that if you're using Python 2.
I recommend you modularize your code and look at other people's code, it'll make your code better. Avoid using a while True loop, at least at the beginning. The code I wrote sort of tries to address it, but it probably doesn't do such a great job.
Maybe try editing the code a bit and updating with an answer later? I think you meant to write input, not raw_input but it could be that's the way you do it in Python 2. You should really learn Python 3 if you're trying to pick up Python btw as Python 2 is at its end of life cycle.
Place your game in the loop and it'll run. Try something like this:
import time
name = input("what is your name? ")
word = "kaasblok"
turns = 6
print("Hello " + name)
#yes no statement with raw input
trueorfalse = True
while trueorfalse:
yesno = input("would you like to play hangman?")
if yesno.lower().startswith("n"):
print("ok bye")
#trueorfalse = False
break
elif yesno.lower().startswith("y"):
print("cool, let me prep...")
time.sleep(1)
# Place your code in the elif block
while turns > 0:
guess = input("what is the word")
if guess == word:
print('win')
#trueorfalse = False
break
else:
turns -=1
print("you have these many turns left", turns)
print("you lost")
break
All that's missing is a way to break out of the while loop. So, use the break command.
import time
name = raw_input("what is your name? ")
print "Hello " + name
#yes no statement with raw input
while True:
yesno = raw_input("would you like to play hangman?")
if yesno.lower().startswith("n"):
print("ok bye")
exit()
elif yesno.lower().startswith("y"):
print("cool, let me prep for e second")
time.sleep(5)
break # <-- break out of of the current loop
print "made it!"

Inputting a function into an imported module

I am attempting to create a game menu that I can then use in games to skip having to make a new menu each time. However, currently it just preforms the gameMain() function instead of doing the gameMenu() first, and then trying to select the game with "g" or "G" does nothing but end the program.
What I'm asking is if it's possible to have a variable in a module that's a function in the code that's importing it.
Here is the code for the menu, which is called textbasedadventures.py:
def gameMenu(game,your_choice="Please Enter how you'd like the game described"):
menu_options = ""
while not(menu_options == "G" or menu_options == "g":
title()
print()
print("\t\t",your_choice,"\n\n")
print('G start game')
menu_options = input("\t\tChoice: ")
if menu_options == "G" or menu_options == "g":
game
input(pause)
and this is the code for the game:
import sys
sys.path.append("\MyOwnProjects")
import textbasedadventures as t
def veryStart():
answer = ""
while not(answer == "1" or answer == "2" or answer == "3"):
print("\tYou are awoken by the blaring of your alarm clock.How did you sleep last night?")
print("\n\t1 Very well\n\n\t2 Well\n\n\t3 Not good\n\n\t4 atrociously")
answer = input("You slept ")
if answer == "1":
print("one option")
elif answer == "2":
print("\t")
elif answer == "3":
pass
elif answer == "4":
print("another option")
else:
print("\t",answer,"is not a valid entry, please try again")
def gameMain():
veryStart()
t.gameMenu(gameMain(),"please work")
If anyone can tell me how to do this, or if this is even possible, I'd be very grateful.
Your remaining problem is getting used to when you're calling a function, and when you're referring to the function as an object.
Since you didn't get any errors when you imported your textbasedadventures (which I shortened to tba to avoid typos), I assume that you've handled that properly: the file is named textbasedadventures.py and is in the local directory.
I had to remove the input(pause) line, since you didn't define pause, and it's there for a different shell from the one I'm using. I also had to remove title(), since that's no longer in your code.
When you pass the main program's main-game function, you have to pass it as a function object. You did this:
t.gameMenu(gameMain(),"please work")
This calls gameMain (because of the parentheses), grabs the return value, and passes that to t.gameMenu. Since there isn't any such return value, your remote menu routien receives only the value None.
Simply remove the parentheses:
t.gameMenu(gameMain,"please work")
This takes the entire gameMain function (well, a reference to it) and passes that to your remote function, where ...
Instead of calling the passed-in game module, you simply listed its value. Python thinks, "okay, cool, I have to evaluate this expression. Gee, a reference to an object -- that's easy. The value is simply the reference itself. I'm not even supposed to do anything with it. Done."
Simply putting a value on a line is legal Python, but boring: the value is displayed if you're in an interactive shell, but is otherwise ignored. Therefore, you never got any response from that line.
Instead, now you call it: this is where you put the parentheses you took off the other end of the call:
game()
I made those changes, and here's the result:
enter G to start game
Choice: g
You are awoken by the blaring of your alarm clock.How did you sleep last night?
1 Very well
2 Well
3 Not good
4 atrociously
You slept

Python Else won't work with Modules imported?

I've been testing stuff with modules specifically time module,
and I tried doing "Else", but I just get a syntax error over the "Else", I've looked over the internet a lot, and on here, and I can't find anything, so I decided to ask Myself, I'm probably going to sound like the stupidest person on earth because of this.
Here's my code,
import time
input ("Hello, would you like to sleep?")
if input == "Yes":
time.sleep(0.5)
print("Sleeping.")
print("Sleeping..")
print("Sleeping...")
print("You have awoken!")
else:
print("Alright.")
Your program should be like,
import time
inputString = input("Hello, would you like to sleep?")
if inputString.lower() == "yes":
time.sleep(0.5)
print("Sleeping.")
print("Sleeping..")
print("Sleeping...")
print("You have awoken!")
else:
print("Alright.")
input is a keyword in python, you can use that to refer something else, but it is highly discouraged. Also, input() returns string in python 3.x and eval(input()) in python 2.x
You know, indentation is very important in Python.
You may need to review your indentation for this. Remember, Python uses whitespace to denote code blocks. It may be that the editor has mangled your code, but it should look like:
import time
inputString = input("Hello, would you like to sleep?")
if input == "Yes":
print("Sleeping.")
print("Sleeping..")
print("Sleeping...")
time.sleep(0.5)
print("You have awoken!")
else:
print("Alright.")
Note that the if and the else are at the same level of indentation, and everything inside of there block is indented one level.

Categories