Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
User input with while loops
#1
Hi , Thanks for viewing, hope all is good.
I'm trying to put together a rock paper scissors code and what i was trying to do as an improvement, was to to the user from inputting a non good input and only allowing the 3 inputs to play.
On first wrong input it does ask to input again but if i put in another wrong answer it takes the wrong answer and uses it, could someone please have a look and tell me what i'm doing wrong, or if there is a preferred robust method that programmers use that would be greatly appreciated.

i also seem to have an issue with trailing white space for some reason.

import random
while True:
      
   
        mylist =  ["rock","paper","scissors"]
        user_choice = input("Enter your choice(rock,paper or scissors):")
        while user_choice not in mylist:
           try: 
            user_choice = input("Enter your choice(rock,paper or scissors):")
           except ValueError:
              
               continue
           else:
               break
   
    
        computer_choice = random.choice(["rock","paper","scissors"])
        
        
        print("You chose: ",user_choice)
        print("Computer chose:",computer_choice)

        if user_choice == computer_choice:
            print("it's a tie!")
        elif(user_choice == "rock" and computer_choice == "scissors") or \
            (user_choice == "paper" and computer_choice == "rock") or \
            (user_choice == "scissors" and computer_choice == "paper"):
            print("you win!")
        else:
            print("Computer wins!")
            
        play_again = input("Do you want to play again?(yes/no):")
        if play_again != 'yes':
            break
Reply
#2
You cannot use try/except when nobody raises an exception. You could raise an exception yourself:
while True:
    while True:
        try:
            user_choice = input("Enter your choice (rock, paper or scissors): ")
            if user_choice not in choices:
                raise ValueError("That is not a valid choice.")
            break
        except ValueError as ex:
            print(ex)
But I think this is easier to understand:
while True:
    while True:
        user_choice = input("Enter your choice (rock, paper or scissors): ")
        if user_choice in choices:
            break
        print("That is not a valid choice.")
Python coding conventions are described in a document named PEP8. You can find it here:

https://peps.python.org/pep-0008/

Your editor might be complaining that you don't have blank space following a comma, like here:
computer_choice = random.choice(["rock","paper","scissors"])
Or it might be complaining about your inconsistent indentation. Always indent 4 spaces.

Avoid repeating code. Your code has ["rock","paper","scissors"] appearing in two places. Assign the list to a variable and use the variable to refer to the list. You also repeated code here:
        user_choice = input("Enter your choice(rock,paper or scissors):")
        while user_choice not in mylist:
           try: 
            user_choice = input("Enter your choice(rock,paper or scissors):")
That is fixed be reworking the logic as mentioned above.

The line continuation character has fallen out of favor. Instead of this:
        if user_choice == computer_choice:
            print("it's a tie!")
        elif(user_choice == "rock" and computer_choice == "scissors") or \  # should have space between elif and (
            (user_choice == "paper" and computer_choice == "rock") or \
            (user_choice == "scissors" and computer_choice == "paper"):
            print("you win!")
You would probably see this:
        if user_choice == computer_choice:
            print("it's a tie!")
        elif ((user_choice == "rock" and computer_choice == "scissors")
                or (user_choice == "paper" and computer_choice == "rock")
                or (user_choice == "scissors" and computer_choice == "paper")):
            print("you win!")
Instead of an if statement you could take advantage of the order of the choices. You win if the computer choice immediately precedes your choice in (rock, paper, scissors) which can be written in python as:
import random

choices = ("rock", "paper", "scissors")

while True:
    while True:
        user_choice = input(f"Enter your choice {choices}: ")
        if user_choice in choices:
            break
        print("That is not a valid choice.")

    computer_choice = random.choice(choices)
    print("Computer chose:", computer_choice)
 
    if user_choice == computer_choice:
        print("it's a tie!")
    elif choices[choices.index(user_choice) - 1] == computer_choice:
        print("you win!")
    else:
        print("Computer wins!")

    play_again = input("Do you want to play again?(yes/no):")
    if play_again != 'yes':
        break
When you stop looking at a the most literal implementation of an algorithm and begin to think more abstractly, possibilities appear. A game like rock, paper scissors has a very simple set of rules: Rock breaks scissors, Paper covers rock, Scissors cuts paper. The rules can be abstracted to WINNER does something to LOSER. We can write a program that parses rules of this format into determine all possible outcomes, and write logic to search those outcomes to determine the result for any pair of inputs. Instead of a rock, paper, scissor game, you have a generic game that plays any game that follows a similar structure.
import random
from collections import defaultdict


def game(rules=None):
    """Play rock, paper, scissors type game.
    
    Define rules as a list of WINNER something LOSER outcomes.
    Defaults to play rock, paper, scissors
    """
    if rules is None:
        rules = ("Rock breaks scissors", "Paper covers rock", "Scissors cuts paper")
    outcome = defaultdict(dict)
    for rule in rules:
        winner, *_, loser = rule.lower().split()
        outcome[winner][loser] = rule
    choices = list(outcome)

    while True:
        user_choice = input(f"Enter your choice ({', '.join(choices)}): ")
        if user_choice in choices:
            break
        print("That is not a valid choice.")

    computer_choice = random.choice(choices)
    print(f"Computer chose", computer_choice)
 
    if user_choice == computer_choice:
        print("it's a tie!")
    elif computer_choice in outcome[user_choice]:
        print(outcome[user_choice][computer_choice])
        print("you win!")
    else:
        print(outcome[computer_choice][user_choice])
        print("Computer wins!")


while True:
    game()
    play_again = input("Do you want to play again?(yes/no):")
    if play_again != 'yes':
        break

# And a bonus game of rock/paper/scissors/lizard/spock
rock_paper_scissors_lizard_spock = (
    "Rock crushes scissors",
    "Rock crushes lizard",
    "Paper covers rock",
    "Paper disproves Spock",
    "Scissors cuts paper",
    "Scissors decapitates lizard",
    "Lizard eats paper",
    "Lizard poisons Spock",
    "Spock smashes scissors",
    "Spock vaporizes Rock",
)
game(rock_paper_scissors_lizard_spock)
chizzy101010 likes this post
Reply
#3
Thanks deanhystad for that reply i wasn't expecting anyone to go into that detail and give so many pointers, i get the try except concept more now thanks to the explanation.

the spock version was to be the project.....

much appreciated
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to revert back to a previous line from user input Sharkenn64u 2 916 Dec-28-2024, 08:02 AM
Last Post: Pedroski55
  WHILE LOOP NOT RETURNING USER INPUT AFTER ZerroDivisionError! HELP! ayodele_martins1 7 2,484 Oct-01-2023, 07:36 PM
Last Post: ayodele_martins1
  restrict user input to numerical values MCL169 2 1,847 Apr-08-2023, 05:40 PM
Last Post: MCL169
  user input values into list of lists tauros73 3 1,969 Dec-29-2022, 05:54 PM
Last Post: deanhystad
Information How to take url in telegram bot user input and put it as an argument in a function? askfriends 0 2,345 Dec-25-2022, 03:00 PM
Last Post: askfriends
Question Take user input and split files using 7z in python askfriends 2 2,310 Dec-11-2022, 07:39 PM
Last Post: snippsat
Sad how to validate user input from database johnconar 3 4,038 Sep-11-2022, 12:36 PM
Last Post: ndc85430
  How to split the input taken from user into a single character? mHosseinDS86 3 2,134 Aug-17-2022, 12:43 PM
Last Post: Pedroski55
  Use pexpect to send user input alisha17 0 3,209 May-10-2022, 02:44 AM
Last Post: alisha17
  WHILE Loop - constant variables NOT working with user input boundaries C0D3R 4 2,513 Apr-05-2022, 06:18 AM
Last Post: C0D3R

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020