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)
CodePudding user response:
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()
CodePudding user response:
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
CodePudding user response:
- 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
CodePudding user response:
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?
CodePudding user response:
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.")