I'm practicing conditionals and logical operators.
How do I make the following rock, paper, scissors game print "This is not a valid object selection." immediately after Player 1's input, if Player 1 enters an invalid object? Right now the string is not printed until both players have entered an object.
Also, any suggestions for making the following code more elegant?
player1 = input('Player 1? ')
player2 = input('Player 2? ')
if (player1.lower() == 'rock' and
player2.lower() == 'rock'):
print('Tie.')
elif (player1.lower() == 'rock' and
player2.lower() == 'paper'):
print('Player 2 wins.')
elif (player1.lower() == 'rock' and
player2.lower() == 'scissors'):
print('Player 1 wins.')
elif (player1.lower() == 'paper' and
player2.lower() == 'paper'):
print('Tie.')
elif (player1.lower() == 'paper' and
player2.lower() == 'scissors'):
print('Player 2 wins.')
elif (player1.lower() == 'paper' and
player2.lower() == 'rock'):
print('Player 1 wins.')
elif (player1.lower() == 'scissors' and
player2.lower() == 'scissors'):
print('Tie.')
elif (player1.lower() == 'scissors' and
player2.lower() == 'rock'):
print('Player 2 wins.')
elif (player1.lower() == 'scissors' and
player2.lower() == 'paper'):
print('Player 1 wins.')
else:
print('This is not a valid object selection.')
How about a function to ask each player their choice? Only if the player enters a valid selection will they be allowed to proceed through the code to your logic statements.
def get_choice(Player_number):
print('Player', Player_number, 'please enter your choice: ', end='')
while True:
choice = input().lower() #lower converts input to all lowercase
if choice in ('rock', 'paper', 'scissors'): # check if valid choice
return choice # if valid return choice
else:
print('Incorrect choice, try again: ', end='') # else print this and start loop agan
player1 = get_choice('1')
player2 = get_choice('2')
For the logic part, note that if player1 choice == player 2 choice, this will substitute 3 elif blocks in your code, ie.
if player1 == player2:
print('tie')
Now replaces pl==rock and p2 == rock, p1 == scissors and p2 == scissors, ect.
edit:
1) The problem if you move the print statement in 2 to inside the input in 4 is you can no longer specify the ,end='' parameter, as it does not work with input. As you said it will generate SyntaxError. The code looks much cleaner when run this way in terminal as it all lines up, but do test it for yourself.
2) end='' prints an empty string at the end of the print statement. you are confusing this with end='\n' which prints a new line after print. As my way keeps the cursor on the same line after the print, it lines up with the input to make it look nice, see above question. Note the print statement in python by default passes , end='\n'. This is why
print('hello') #same as print('hello', end='\n')
print('world)
hello
world
print('hello', end='')
print('world', end='')
helloworld
3) The while True loop will alway evaluate to true. So the body of the while loop will constantly cycle - However, it can return out of the entire function with the 'return choice' function. The only way to leave this function if to get down the logical steps required to reach the return statement. In this case unless the choice is in that tuple('rock', 'paper', 'scisors') it will just print invalid entry try again, finishing the block. However, As while is still true the loop will begin again and ask the user to input again. This will repeat until a valid choice is selected.
4) You could concatenate it onto the player_number eg..
print('Player', Player_number + ',' , 'please enter your choice: ', end='')
Related
when input is asked, I type Rock it loops back as though i did not type the right input.
I've tried retyping the error checking but nothing is working. The only input it will accept is 'q'. Here is the code:
import random
user_wins = 0 #setting default score
computer_wins = 0
options = ["rock", "paper", "scissors"]
while True:
user_input = input('Type Rock/Paper/Scissors or Q to quit: ').lower()
if user_input == "q":
break
if user_input not in options:
continue
random_number = random.randint(0, 2) #rock: 0 , paper: 1, scissors: 2
computer_pick = options[random_number] #using computer's pick from a random from the list to be stored.
print('Computer picked:', computer_pick + ".") #printing the result of computer's pick
if user_input == "rock" and computer_pick == "scissors": #setting win or lose conditions
print('Rock Crushes Scissors...You Win!')
user_wins += 1
elif user_input == "paper" and computer_pick == "rock":
print('Paper Covers Rock...You Win!')
user_wins += 1
elif user_input == "scissors" and computer_pick == "paper":
print('Scissors Cuts Paper...You Win!')
user_wins += 1
else:
print("You Lose")
computer_wins += 1
print("You won ", user_wins, "times.")
print("Computer won ", computer_wins, "times.")
print('Goodbye')
It's because you need to break the loop when input is in options, so the loop could be
while True:
user_input = input('Type Rock/Paper/Scissors or Q to quit: ').lower()
if user_input == "q":
break
if user_input not in options:
continue
else:
break
Anyways, a better implementation could be creating the empty option and assign it if matches, so
answer = ''
while not answer:
user_input = input('Type Rock/Paper/Scissors or Q to quit: ').lower()
if user_input == "q":
break
elif user_input in options:
answer = user_input
In you case try this code. You will need to have two while loops: one is for checking the input, the other is for continuing the game.
exit = False #this helps you to exit from the main while loop.
while not exit:
options = ['rock', 'scissors', 'paper']
user_input = ""
while True:
user_input = input('pls write paper, rock, scissors, or
q(quit) ').lower()
if user_input in options:
break
elif user_input == 'q':
exit = True
break
#do some calculations
# do some summary calculations and print them
I hope you will find it helpful)
If we are doing a menu on python and the user selects option for finish the interaction. Is preferable to use exit(), conditionals, return or break?
Example with break, where we stop the infinite loop with the break:
def show_menu():
print('1. Pet kitten\n'
'0. Exit')
def start_app():
while True:
show_menu()
user_choice = input('Select an option: ')
if user_choice == '1':
pet()
elif user_choice == '0':
print('\nBye!')
break
else:
print('\nPlease select a number from the menu.')
start_app()
Example with exit(), where we use built-in function exit() for stop the execution of the script:
def show_menu():
print('1. Pet kitten\n'
'0. Exit')
def start_app():
while True:
show_menu()
user_choice = input('Select an option: ')
if user_choice == '1':
pet()
elif user_choice == '0':
print('\nBye!')
exit()
else:
print('\nPlease select a number from the menu.')
start_app()
Example with conditionals, where the while stops when the condition change:
def show_menu():
print('1. Pet kitten\n'
'0. Exit')
def start_app():
continue_ = True
while continue_:
show_menu()
user_choice = input('Select an option: ')
if user_choice == '1':
pet()
elif user_choice == '0':
print('\nBye!')
continue_ = False
else:
print('\nPlease select a number from the menu.')
start_app()
Example with return, where we finish the interaction returning a random value:
def show_menu():
print('1. Pet kitten\n'
'0. Exit')
def start_app():
continue_ = True
while continue_:
show_menu()
user_choice = input('Select an option: ')
if user_choice == '1':
pet()
elif user_choice == '0':
print('\nBye!')
return None
else:
print('\nPlease select a number from the menu.')
start_app()
It is worth noticing that your options fall into two categories, with one important difference between them.
On one hand, you can use break, return or a condition variable to break out of the loop and, eventually, return to the caller. Among these options, I'd say just pick whichever gives the cleanest code.
On the other hand, you can use exit() which ends the program there and then.
If you ever wish to use this as something other than a top-level menu, for example wrapped in a library to be used as a sub-menu of something else, you do not want the program to suddenly exit.
Generally, exit() is a rather big chunk of explosives, that should be treated with a bit of respect.
For example 1:
First give 4 space in line 2 so that the print function can stay into the show_menu() function and second define the #pet() function in line 11, otherwise you will get name error. Then put a break statement after line 11.
For example 3:
The while loop stop in line 15 when you define continue as False.
#HappyCoding
Here is my code (for hangman game):
import random, os
def main():
print("******THIS IS HANGMAN******")
print("1. Play Game ")
print("2. Quit Game ")
choice = input("Please enter option 1 or 2")
if choice == "1":
words = ["school", "holiday", "computer", "books"]
word = random.choice(words)
guess = ['_'] * len(word)
guesses = 7
while '_' in guess and guesses > 0:
print(' '.join(guess))
character = input('Enter character: ')
if len(character) > 1:
print('Only enter one character.')
continue
if character not in word:
guesses -= 1
for i, x in enumerate(word):
if x == character:
guess[i] = character
if guesses == 0:
print('You LOST!')
break
else:
print('You have only', guesses, 'chances left to win.')
else:
print('You won')
elif choice == "2":
os.system("cls")
main()
else:
print("that is not a valid option")
main()
I have tried os.system("clear") but it doesn't clear the screen, I want it to clear the entire screen but instead (cls) makes it print my menu again and (clear) does nothing except clear the 2. If I'm missing something obvious it's probably because I'm new to python.
It prints the menu again because you call main() again instead of just stopping there. :-)
elif choice == "2":
os.system("cls")
main() # <--- this is the line that causes issues
Now for the clearing itself, os.system("cls") works on Windows and os.system("clear") works on Linux / OS X as answered here.
Also, your program currently tells the user if their choice is not supported but does not offer a second chance. You could have something like this:
def main():
...
while True:
choice = input("Please enter option 1 or 2")
if choice not in ("1", "2"):
print("that is not a valid option")
else:
break
if choice == "1":
...
elif choice == "2":
...
main()
First of im sorry about bombarding my post with a bunch of code, but im putting it here hoping that it will help you guys understanding my question better.
I am trying to figure out why my IDE is unwilling to execute the first function of my code. Obviously im doing something wrong, but im to unexperienced to see it for myself. All help would be greatly appriciated.
If you have any further comments or tips on my code feel free contribute.
import random
print("Press '1' for New Single Player Game - Play against computer component: ")
print("Press '2' for New Two Player Game - Play against another person, using same computer: ")
print("Press '3' for Bonus Feature - A bonus feature of choice: ")
print("Press '4' for User Guide - Display full instructions for using your application: ")
print("Press '5' for Quit - Exit the program: ")
def choose_program():
what_program = int(input("What program would you like to initiate?? Type in the 'number-value' from the chart above: "))
if what_program == 1 or 2 or 3 or 4 or 5:
program_choice = int(input("Make a choice: "))
if (program_choice > 5) or (program_choice < 1):
print("Please choose a number between 1 through 5 ")
choose_program()
elif program_choice == 1:
print("You picked a New Single Player Game - Play against computer component")
def single_player():
start_game = input("Would you like to play 'ROCK PAPER SCISSORS LIZARD SPOCK'?? Type 'y' for YES, and 'n' for NO): ").lower()
if start_game == "y":
print("Press '1' for Rock: ")
print("Press '2' for Paper: ")
print("Press '3' for Scissors: ")
print("Press '4' for Lizard: ")
print("Press '5' for Spock: ")
elif start_game != "n":
print("Please type either 'y' for YES or 'n' for NO: ")
single_player()
def player_one():
human_one = int(input("Make a choice: "))
if (human_one > 5) or (human_one < 1):
print("Please choose a number between 1 through 5 ")
player_one()
elif human_one == 1:
print("You picked ROCK!")
elif human_one == 2:
print("You picked PAPER!")
elif human_one == 3:
print("You picked SCISSORS!")
elif human_one == 4:
print("You picked LIZARD!")
elif human_one == 5:
print("You picked SPOCK!")
return human_one
def computers_brain():
cpu_one = random.randint(1, 5)
if cpu_one == 1:
print("Computers choice iiiiiis ROCK!")
elif cpu_one == 2:
print("Computers choice iiiiiis PAPER!")
elif cpu_one == 3:
print("Computers choice iiiiiis SCISSORS!")
elif cpu_one == 4:
print("Computers choice iiiiiis LIZARD!")
elif cpu_one == 5:
print("Computers choice iiiiiis SPOCK!")
return cpu_one
def who_won(human, cpu, human_wins, cpu_wins, draw):
if human == 1 and cpu == 3 or cpu == 4:
print("Human is invincible!!")
human_wins = human_wins.append(1)
elif human == 2 and cpu == 1 or cpu == 5:
print("Human is invincible!!")
human_wins = human_wins.append(1)
elif human == 3 and cpu == 2 or cpu == 4:
print("Human is invincible!!")
human_wins = human_wins.append(1)
elif human == 4 and cpu == 2 or cpu == 5:
print("Human is invincible!!")
human_wins = human_wins.append(1)
elif human == 5 and cpu == 1 or cpu == 3:
print("Human is invincible!!")
human_wins = human_wins.append(1)
elif human == cpu:
print("Human & computer think alike, such technology")
draw = draw.append(1)
else:
print("Computer have beaten it's master, incredible..")
cpu_wins = cpu_wins.append(1)
return
def end_score(human_wins, cpu_wins, draw):
human_wins = sum(human_wins)
cpu_wins = sum(cpu_wins)
draw = sum(draw)
print("Humans final score is: ", human_wins)
print("Computers final score is: ", cpu_wins)
print("Total draws: ", draw)
def main():
human = 0
human_wins = []
cpu = 0
cpu_wins = []
draw = []
finalhuman_wins = 0
finalcpu_wins = 0
finaldraw = 0
Continue = 'y'
single_player()
while Continue == 'y':
human = player_one()
cpu = computers_brain()
who_won(human, cpu, human_wins, cpu_wins, draw)
Continue = input("Would you like to play again (y/n):").lower()
if Continue == 'n':
print("Printing final scores.")
break
end_score(human_wins, cpu_wins, draw)
main()
elif program_choice == 2:
print("You picked a New Two Player Game - Play against another person, using same computer")
elif program_choice == 3:
print("You picked the Bonus Feature - A bonus feature of choice")
elif program_choice == 4:
print("You picked the User Guide - Display full instructions for using your application")
elif program_choice == 5:
print("You picked to Quit - Exit the program")
return program_choice
elif what_program != 1 or 2 or 3 or 4 or 5:
print("To initiate a program you need to type in the appropriate number to initiate this program, either 1, 2, 3, 4 & 5 ")
choose_program()
Outout in IDE:
Press '1' for New Single Player Game - Play against computer component:
Press '2' for New Two Player Game - Play against another person, using same computer:
Press '3' for Bonus Feature - A bonus feature of choice:
Press '4' for User Guide - Display full instructions for using your application:
Press '5' for Quit - Exit the program:
Process finished with exit code 0
Thank you in advance for your help :)
I am using Python and I am trying to write a simple program that simulates a rock, paper, scissors game. Everything works except for when I enter an invalid response (something other than rock, paper, or scissors) when I get this error.
Traceback (most recent call last):
File "C:/Users/home/Desktop/BAGARDNER/Python/rock_pape_scissors.py", line 88, in <module>
main()
File "C:/Users/home/Desktop/BAGARDNER/Python/rock_pape_scissors.py", line 14, in main
number = user_guess()
File "C:/Users/home/Desktop/BAGARDNER/Python/rock_pape_scissors.py", line 48, in user_guess
return number
UnboundLocalError: local variable 'number' referenced before assignment
I understand that this is telling me that number isn't referenced, but from what I understand of the code, it shouldn't need a number when the qualifier is false.
#import random module
import random
#main function
def main():
#intro message
print("Let's play 'Rock, Paper, Scissors'!")
#call the user's guess function
number = user_guess()
#call the computer's number function
num = computer_number()
#call the results function
results(num, number)
#computer_number function
def computer_number():
#get a random number in the range of 1 through 3
num = random.randrange(1,4)
#if/elif statement
if num == 1:
print("Computer chooses rock")
elif num == 2:
print("Computer chooses paper")
elif num == 3:
print("Computer chooses scissors")
#return the number
return num
#user_guess function
def user_guess():
#get the user's guess
guess = input("Choose 'rock', 'paper', or 'scissors' by typing that word. ")
#while guess == 'paper' or guess == 'rock' or guess == 'scissors':
if is_valid_guess(guess):
#if/elif statement
#assign 1 to rock
if guess == 'rock':
number = 1
#assign 2 to paper
elif guess == 'paper':
number = 2
#assign 3 to scissors
elif guess == 'scissors':
number = 3
return number
else:
print('That response is invalid.')
user_guess()
def is_valid_guess(guess):
if guess == 'rock' or 'paper' or 'scissors':
status = True
else:
status = False
return status
def restart():
answer = input("Would you like to play again? Enter 'y' for yes or \
'n' for no: ")
#if/elif statement
if answer == 'y':
main()
elif answer == 'n':
print("Goodbye!")
else:
print("Please enter only 'y' or 'n'!")
#call restart
restart()
#results function
def results(num, number):
#find the difference in the two numbers
difference = num - number
#if/elif statement
if difference == 0:
print("TIE!")
#call restart
restart()
elif difference % 3 == 1:
print("I'm sorry! You lost :(")
#call restart
restart()
elif difference % 3 == 2:
print("Congratulations! You won :)")
#call restart
restart()
main()
Thank you for your help!
Here's your problem:
if guess == 'rock' or 'paper' or 'scissors':
This line in is_valid_guess doesn't do what you think it does. Instead, it always returns True. What you're looking for is something like this:
if guess == 'rock' or guess == 'paper' or guess == 'scissors':
or more concisely:
if guess in ('rock', 'paper', 'scissors'):
The problem is that what you have always returns True because of how Python evaluates strings in a boolean context. The line if guess == 'rock' or 'paper' or 'scissors': evaluates as:
if (guess == 'rock') or ('paper') or ('scissors'):
What this means is that Python checks to see if guess == 'rock'. If that's true, the conditional evaluates to True. If it's false, the interpreter tries to evaluate bool('paper'). This always evaluates to True because all non-empty strings are "truthy". Therefore, your whole conditional is always True, and every string is "valid".
As a result, your code considers all strings "valid" and then blows up when it fails to assign a number to a guess that is not actually supported.
As a final note, your is_valid_guess method could be trimmed a bit, since you're just returning the result of your boolean expression. Rather than using the status variable as an intermediate, you can just compute the expression and return it right away. I also use the lower() method of string objects to allow for case-insensitive guessing, in case that's something you want to allow.
def is_valid_guess(guess):
return guess.lower() in ('rock', 'paper', 'scissors')
You've got another issue, which you mentioned in the comments: you've implemented user_guess in a recursive fashion, so that it calls itself if the user enters an invalid guess. However, in this case, it does not return the result of the recursive call. You need to either return the recursive result by changing the last line of user_guess to:
return user_guess()
Or else you should make that function use a loop instead of recursion, which is what I would do, since the function is not inherently recursive. You can do something like this:
def user_guess():
# get first guess
guess = input("Choose 'rock', 'paper', or 'scissors' by typing that word. ")
# If that guess is invalid, loop until we get a valid guess.
while not is_valid_guess(guess):
print('That response is invalid.')
guess = input("Choose 'rock', 'paper', or 'scissors' by typing that word. ")
# Now assign the (valid!) guess a number
# This dictionary is just shorthand for your if/elif chain.
guess_table = {
'rock' : 1,
'paper' : 2,
'scissors' : 3
}
# Return the number associated with the guess.
return guess_table[guess.lower()]
Change
if guess == 'rock' or 'paper' or 'scissors':
to
if guess == 'rock' or guess == 'paper' or guess == 'scissors':
In fact, to make the function as streamlined as possible, just do this:
def is_valid_guess(guess):
return guess == 'rock' or guess == 'paper' or guess == 'scissors'
As other users have pointed out, you need to change your validation in is_valid_guess to:
if guess == 'rock' or guess == 'paper' or guess == 'scissors':
While this won't solve your immediate problem, it is good (upvote-worthy) advice, and will let you avoid some errors you would have run into.
Additionally, no matter what the user inputs, you always return what they type in. To prevent this, you must return user_guess() in your else block:
if is_valid_guess(guess):
#if/elif statement
#assign 1 to rock
if guess == 'rock':
number = 1
#assign 2 to paper
elif guess == 'paper':
number = 2
#assign 3 to scissors
elif guess == 'scissors':
number = 3
return number
else:
print('That response is invalid.')
return user_guess() # <-- right here
Just change input to raw_input