Understanding loops in-conjunction with if/elif/else statements (Python) [duplicate] - python

This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 2 years ago.
Evening all,
I'm new to programming and I am attempting to understanding while loops that are used with if/elif/else statements.
My Thought Process
The function that I have created is a part of the game Tic Tac Toe (or Noughts and Crosses). The idea behind the function is to prompt Player 1 for their symbol choice (O or X).
My logic behind the function is such that, the player will continue to be prompted (the loop) for a valid choice. Once the player has made a valid choice, the loop should end and print the player's choice.
My Question
What I don't understand is that the function only works if I include break at the end of both the IF and ELIF blocks of code. Why won't the loop break upon the user entering a valid choice?
Please see the code, written in Python, below.
Regards,
def player_input():
player1_input = str
player1_symbol = str
while player1_symbol != "X" or "O": #loop until user supplies an valid (X or O) input
player1_input = str(input("\nPlayer 1, would you like to be X or O?: ")) #prompt user for their choice
player1_symbol = player1_input #link player1_input to player1_symbol
if player1_symbol == "X": #follow this block if Player 1 selected X
print("\nPlayer 1: You are now X") #states that Player 1 is X
print("Player 2: You are now O") #states that Player 2 is now O as a result of Player 1's choice
print("IF Statement Executed") #lets me know that this block was executed
break #WHY DO I NEED THIS TO BREAK THE LOOP IF A VALID SELECTION WAS MADE?
elif player1_symbol == "O": #follow this block if Player 1 selected O
print("\nPlayer 1: You are now O") #states that Player 1 is O
print("Player 2: You are now X") #states that Player 2 is now O as a result of Player 1's choice
print("ELIF Statement Executed") #lets me know that this block was executed
break #AGAIN, WHY DO I NEED THIS TO BREAK THE LOOP IF A VALID SELECTION WAS MADE
else:
print("\nInvalid choice. Please choose X or O.") #lets Player 1 know that he needs to make a valid (X or O) input
print("ELSE Statement Executed") #lets me know that this block was executed

The comment gives the appropriate fix. To understand why this is happening, note that the or operator combines two separate logic statements. In your case, these two logic statements are player1_symbol != "X" as well as "O". Because the latter statement is nonzero, python always evaluates it as True so that the entire statement player1_symbol != "X" or "O" is always true, no matter the value of player1_symbol.
Edit: To be clear what I mean by "the latter statement is nonzero", I mean the ASCII value for the character "O" is nonzero, so python evaluates it as true.

Related

Python conditional triggering twice

I am practicing functions. I made a short game to practice functions. I use the input() to interact.
When I enter "End" is where the confusion begins.
def endgame():
if input("Are you sure you want to exit?") == "yes" or input("Are you sure you want to exit?") == "y":
return 1
else:
return 0
The input() is triggered on both sides of the OR condition if I select anything that is not "yes".
This is not what I expected. Here is the entire code.
#function calls
def picker(v):
if v == "Game":
somegame()
elif v == "judo":
judo()
elif v == "End":
#x = endgame()
if endgame():
print("Closing")
else:
print("Restarting")
picker(input("Try to pick the secret again: "))
else:
picker(input("You must pick the secret: "))
def somegame():
print("Some game")
if input("Another game?") == "y":
picker(input("Pick another game: "))
else:
print("Game ending")
def judo():
print("Judo chop")
if input("Another game?") == "y":
picker(input("Pick another game: "))
else:
print("Game ending")
def endgame():
if input("Are you sure you want to exit?") == "yes" or input("Are you sure you want to exit?") == "y":
return 1
else:
return 0
#Start the game here
picker(input("Pick the game: "))
I can see that if it doesn't match the first OR condition, it asks for input again. I believe it should ask once and compare the input to both variables. I assume this means I would have double calls if I used other functions within a IF/OR structure in the same way?
Storing the input() in a separate variable for comparison works, but I imagine other functions that I might make that return a value having this behavior.
def endgame():
x = input("Are you sure you want to exit?")
if x == "yes" or x == "y":
return 1
else:
return 0
I know I am answering the question here, but the W3schools lesson doesnt describe this unexpected behavior.
Conditions like this in Python are evaluated from left to right, until the required condition is met or the end of the statement has been reached. Calling the same method in an or statement will result in the method being called multiple times until the condition is met, or not.
Example,
if 1 == 1 or 2 == 2 or 3 == 3 results in the rest of the condition past 1 == 1 to be totally ignored, since the whole condition has already been met. Somewhat similarly, if 1 == 2 or 2 == 3 or 3 == 3 results in the first two conditions to be evaluated. If you were to put a condition after 3 == 3, that would also be ignored assuming the previous condition (3 == 3) was True.
This sort of logic applies in conditions that incorporate and statements, though not exactly the same way depending on the circumstances of the if statement & its conditions.

Issue when trying to add user validation [duplicate]

This question already has answers here:
not equals operator(!=) not working in python string comparison
(2 answers)
Closed 1 year ago.
Trying to add validation to user input.
So the code is:
print ('Does this service require an SFP Module? (y/n): ')
while True:
sfpreq = input()
if sfpreq != 'y' or 'n':
print("You must enter either y or n")
continue
else:
break
So even when the user enters 'n' it returns the "print("You must enter either y or n")" and continues the loop.
I have tried setting the variabl manually to and also tried another convention I found on realpython and also removed the if statement from the while loop:
sfpreq = "n"
if sfpreq != 'y' or sfpreq != 'n':
print("You must enter either y or n")
else:
print("Test")
Again it just returns:
admin#MacBook-Pro Learning Folder % python3 test22.py
You must enter either y or n
Am I just missing something very fundamental here?
Problem with the logic
sfpreq = "n"
if sfpreq != 'y' or sfpreq != 'n':
print("You must enter either y or n")
else:
print("Test")
Here, when you enter the if loop,
sfpreq != 'y' is validated as True and sfpreq != 'n' is validated as False.
Now True OR False statement in boolean algebra equates to True.
So, the if loop gets executed and You must enter either y or n is printed.
See, more about boolean algebra here
A better solution
sfpreq = "n"
if sfpreq not in {"y","n"}:
print("You must enter either y or n")
else:
print("Test")
So, here we are checking if y or n is not there in the set {"y","n"}. As in this case, sfpreq is there in that set so,the else statement gets executed.

How Can I Give the User 5 Lives for my script?

Title.
I'm currently writing a choose your own adventure python script for my computer science class and need to give the player 5 lives and when they run out have a line of text appear. Any ideas?
(I'm not sure if I need to post the script or not but I can later today if needed.)
script:
# Name: Drew Dilley
**# Date: 12/7/20
# 1 REMOVED IMPORT MATH BECAUSE IT IS NOT NEEDED FOR THIS SCRIPT.
# 2
import random
answer: str = input("Do you want to go on an adventure? (Yes/No)")
# hint: the program should convert player's input to lowercase and get rid of any space player enters
# hint: check out what .upper(), .lower(), .strip() do on a string, reference: https://www.w3schools.com/python/python_ref_string.asp
# 3
if answer.upper().strip() == "yes":
# hint: pay attention to the variable name
# 4
ANSWER= input("You are lost in the forest and the path splits. Do you go left or right? (Left/Right) ").lower().strip()
if answer == "left":
# 5 UNNECESSARY INDENT
answer = input("An evil witch tries to cast a spell on you, do you run or attack? (Run/Attack) ").lower().strip()
if answer == "attack": #(HAD TO FIX UNEXPECTED INDENT)
print("She turned you into a green one-legged chicken, you lost!")
# 6 HAD TO ADD PARENTHESES AND FIX THE SEMICOLON AFTER "ANSWER"
elif answer := "run":
print("Wise choice, you made it away safely.")
answer = input("You see a car and a plane. Which would you like to take? (Car/Plane) ").lower().strip()
if answer == "plane":
print("Unfortunately, there is no pilot. You are stuck!")
elif answer == "car":
print("You found your way home. Congrats, you won!")
# 7 SEMICOLON NEEDED AFTER "ELSE" PLANE/ANSWER + CAR/ANSWER NEEDED TO BE FLIPPED. NO INDENTATION NEEDED FOR "ELSE". == INSTEAD OF !=
elif answer != "plane" or answer != "car":
print("You spent too much time deciding...")
elif "right" != answer:
else:
print("You are frozen and can't talk for 100 years...")
# hint: the program should randomly generate a number in between 1 and 3 (including 1 and 3)
# hint: remember random module? reference: https://www.w3schools.com/python/module_random.asp
# 8 HAD TO IMPORT "RANDOM"
num: int = random.randint(0,3)
# 9
answer = input("Pick a number from 1 to 3: ")
# hint: will the following if statement ever be executed even when the values of answer and num are the same? If not, can you fix the problem?
# hint: the error is not necessarily in the line below.
if answer == num:
print("I'm also thinking about {}".format(num))
print("You woke up from this dream.")
else:
print("You fall into deep sand and get swallowed up. You lost!")
else:
print('You can\'t run away...')
# 10 NEEDED A SEMICOLON FOLLOWING THE ELSE STATEMENT, SO THAT IT KNOWS WHAT TO READ AND PERFORM NEXT IN THE SCRIPT.
else:
print ("That's too bad!")** ```
you can use a for loop with a counter variable which you can decriment at every time player looses and when it goes from 5 to zero you can use break to exit the loop or a print before break to display a message.

Python multiple nested while True continue/end looping error [duplicate]

This question already has answers here:
How can I break out of multiple loops?
(39 answers)
Closed 5 years ago.
Here's a piece of code from my project software:
def fun_1(self, i):
print("")
print("Welcome to Option 1: View Passwords")
while True:
print("")
which_o1 = input("1: Input a New Account details \n2: Exit \nPlease Input the option number: ")
if which_o1 == str(1):
with open(str(i)+'.txt', 'a+') as file:
while True:
print("")
web_n = input("Please Input Website name: ")
print("")
e_u = input("Please input email/username: ")
print("")
pass_w = input("Please input password: ")
while True:
print("")
sure = input("Website- " +web_n+"\nEmail/Username- "+e_u+"\nPassword- "+pass_w+"\nAre You sure about these details? Yes/No: ")
if (sure.lower()[0]) != 'y' and (sure.lower()[0]) != 'n':
print("")
print("Please input a valid response Yes/No!")
continue
elif (sure.lower()[0]) == 'y' and (sure.lower()[0]) != 'n':
list_log = [web_n, e_u, pass_w]
file.write(str(list_log) + '\n')
break
break
continue
elif (sure.lower()[0]) == 'n' and (sure.lower()[0]) != 'y':
break
continue
elif which_o1 == str(2):
return (i)
else:
print("")
print("Please Enter a Valid Response!")
continue
So has you can see that it has 3 while True loop. The problem is occurring while breaking and looping the loop. If you see the latest While True under "pass_w" in the middle elif, where it says elif (sure.lower()[0]) == 'y' and (sure.lower()[0]) != 'n':, in it I have 2 break and 1 continue because what I wanted to do is that when that elif executes it just break middle 3rd while true, 2nd while true and continue means loop the first while true at the start of the code, but it just keep looping 3rd While True in the middle of the code instead of breaking it.
Is there a way I can make it possible?
Firstly, understand that no lines can be executed after a break statement inside of a while loop. So putting multiple breaks and a continue won't work. You need to restructure your code. Personally, I would recommend either implementing try except statements, or putting some of the code inside of functions so that you can return when you want to stop looping and pass variables as indications to the outer loops where the function was called.
Another option could be instead of using breaks and continues, use a variable or set of variables that your while loops check for to decide if they should continue. So inside your ifs and elifs you could set exitfirstloop = True, etc. and in the while loops you check while not exitfirstloop

I need to figure out how to make my program repeat. (Python coding class)

I am a beginner student in a python coding class. I have the majority of the done and the program itself works, however I need to figure out a way to make the program ask if wants a subtraction or an adding problem, and if the user would like another question. I asked my teacher for assistance and he hasn't gotten back to me, so I'm simply trying to figure out and understand what exactly I need to do.
import random
x = int(input("Please enter an integer: "))
if x < 0:
x = 0
print('Negative changed to zero')
elif x == 0:
print('Zero')
elif x == 1:
print('Single')
else:
print('More')
maximum = 10 ** x;
maximum += 1
firstnum = random.randrange(1,maximum) # return an int from 1 to 100
secondnum = random.randrange(1, maximum)
compsum = firstnum + secondnum # adds the 2 random numbers together
# print (compsum) # print for troubleshooting
print("What is the sum of", firstnum, " +", secondnum, "?") # presents problem to user
added = int(input("Your answer is: ")) # gets user input
if added == compsum: # compares user input to real answer
print("You are correct!!!")
else:
print ("Sorry, you are incorrect")
You'll want to do something like this:
def foo():
print("Doing good work...")
while True:
foo()
if input("Want to do more good work? [y/n] ").strip().lower() == 'n':
break
I've seen this construct (i.e., using a break) used more often than using a sentinel in Python, but either will work. The sentinel version looks like this:
do_good_work = True
while do_good_work:
foo()
do_good_work = input("Want to do more good work? [y/n] ").strip().lower() != 'n'
You'll want to do more error checking than me in your code, too.
Asking users for input is straightforward, you just need to use the python built-in input() function. You then compare the stored answer to some possible outcomes. In your case this would work fine:
print('Would you like to test your adding or subtracting skills?')
user_choice = input('Answer A for adding or S for subtracting: ')
if user_choice.upper() == 'A':
# ask adding question
elif user_choice.upper() == 'S':
# ask substracting question
else:
print('Sorry I did not understand your choice')
For repeating the code While loops are your choice, they will repeatedly execute a statement in them while the starting condition is true.
while True: # Condition is always satisfied code will run forever
# put your program logic here
if input('Would you like another test? [Y/N]').upper() == 'N':
break # Break statement exits the loop
The result of using input() function is always a string. We use a .upper() method on it which converts it to UPPERCASE. If you write it like this, it doesn't matter whether someone will answer N or n the loop will still terminate.
If you want the possibility to have another question asked use a while loop and ask the user for an input. If you want the user to input whether (s)he want an addition or substraction you already used the tools to ask for such an input. Just ask the user for a string.

Categories