Skip to main content
Notice removed Content dispute by CommunityBot
Post Unlocked by CommunityBot
Post Locked by Mast
Notice added Content dispute by Mast
Rollback to Revision 4
Source Link
Mast
  • 13.8k
  • 12
  • 57
  • 127

[EDITS]

The changes done are non-significant, and the answer remains correct. This is just because some descriptions were irrelevant and made the post more difficult to read.


I tried to implement what I understood from previous advices here.

Additions

  • commentsuse more functions
  • some typesimprove the logic of "play"
  • allowed aallow wrong user input
  • indent to keep playing4 spaces and accumulate the result.remove ()

Mind that I only have access to google colab so I cant benefit from formatting tools or tests.

I also added comments and types to the extent I could do it, and allowed a user to keep playing and accumulate the result.

import random
import sys
from typing import TypedDict

welcome='''
    
    Possible values: r, p, s, q.
    Enter r for ROCK, p for PAPER, s for SCISSORS, q to quit the game.

    '''

def request_valid_input(msg:str, allowed_values:list[str], max_tries:int):
    '''
    Gives the user a certain number of tries in case it types the wrong letter.
    returns: valid user input
    '''
    user_input = input(msg).strip()
    if max_tries <=0:
        raise Exception(f"Max tries reached. Input must be one of {allowed_values.join(',')}")
    while user_input not in allowed_values:
        max_tries-=1
        request_valid_input(max_tries=max_tries)
    return user_input

        
class Score(TypedDict):
    user:int
    py:int

class LastRound(TypedDict):
    user_score:int
    py_score:int
    user_letter:str
    py_letter:str

class RPS():
    '''
    Represents a simple Rock Paper Scissors game
    '''
    def __init__(self):
        self.total_score:Score = {"user":0, "py":0}
        self.last_round:LastRound|None = None 
        self.welcome = welcome
        self.max_tries=3 # when user tries an invalid letter or input.
        self.letter_mapping = {"r":"ROCK", "s":"SCISSORS", "p":"PAPER"} # for informing user
        self.allowed_values=['r', 's', 'p', 'q']

    def random_letter(self):
        '''
        Generates r, s or p used as the computer's input value / choice.
        '''
        letters=['r', 's', 'p']
        our_val = random.randint(0,2)
        return letters[our_val]

    def report_result(self)->None:
        '''
        Print a formatted string telling who wins.
        Returns: None
        '''
        user_selection  = self.letter_mapping[self.last_round["user_letter"]]
        py_selection  = self.letter_mapping[self.last_round["py_letter"]]

        print(f"You chose {user_selection}, Python chose {py_selection}")
        if self.last_round["user_score"] > self.last_round["py_score"]:
            print("User wins.")
        elif self.last_round["py_score"] > self.last_round["user_score"]:
            print("Python wins.")
        else:
            print("Ties.")


    def play(self, user_input):
        user_score=0
        py_score=0
        if user_input == "q":
            sys.exit("Exiting game.")
        user_val = user_input
        our_val = self.random_letter()

        # test tie separately.
        if user_val==our_val:
            pass

        # case 1: user chooses ROCK
        elif user_val=="r":
            if our_val=="s":
                user_score+=1

            else:
                py_score+=1
        # case 2 user chooses PAPER
        elif user_val=="p":
            if our_val=="r":
                user_score+=1
            else:
                py_score+=1
        # case 3 user chooses SCISSORS
        else:
            if our_val=="r":
                py_score+=1
            else :
                user_score+=1

        # put the results in the state of the class
        self.last_round:LastRound = {"user_score":user_score, "py_score":py_score, "user_letter":user_val, "py_letter":our_val}
        self.total_score["user"]+=user_score
        self.total_score["py"]+=py_score

    
def run_game(subsequent_message="remember: r for ROCK, s for SCISSORS, p for PAPER"):
    game = RPS()
    keep_going='y'
    first_try=True
    while(keep_going=='y'):
        msg = game.welcome if first_try else "Type your new choice (r, p, s or q): "
        input = request_valid_input(msg=msg, max_tries=game.max_tries, allowed_values=game.allowed_values)
        game.play(input)
        game.report_result()
        keep_going = request_valid_input(msg="Would you like to play again? Type y for yes, n for no.", allowed_values=['n', 'y'], max_tries=2)
        first_try=False
    print(f"user score: {game.total_score['user']}, python score: {game.total_score['py']}")

run_game()

For other users

Black formatter can be run in Colab though using (actually it fixes some things only.):

# run once
!pip install black[jupyter] --quiet
from google.colab import drive
drive.mount("/content/drive")

# run many times
!black /content/drive/MyDrive/'Colab Notebooks'/'file_name_here.ipynb'

[EDITS]

The changes done are non-significant, and the answer remains correct. This is just because some descriptions were irrelevant and made the post more difficult to read.


I tried to implement what I understood from previous advices here.

Additions

  • comments
  • some types
  • allowed a user to keep playing and accumulate the result.
import random
import sys
from typing import TypedDict

welcome='''
    
    Possible values: r, p, s, q.
    Enter r for ROCK, p for PAPER, s for SCISSORS, q to quit the game.

    '''

def request_valid_input(msg:str, allowed_values:list[str], max_tries:int):
    '''
    Gives the user a certain number of tries in case it types the wrong letter.
    returns: valid user input
    '''
    user_input = input(msg).strip()
    if max_tries <=0:
        raise Exception(f"Max tries reached. Input must be one of {allowed_values.join(',')}")
    while user_input not in allowed_values:
        max_tries-=1
        request_valid_input(max_tries=max_tries)
    return user_input

        
class Score(TypedDict):
    user:int
    py:int

class LastRound(TypedDict):
    user_score:int
    py_score:int
    user_letter:str
    py_letter:str

class RPS():
    '''
    Represents a simple Rock Paper Scissors game
    '''
    def __init__(self):
        self.total_score:Score = {"user":0, "py":0}
        self.last_round:LastRound|None = None 
        self.welcome = welcome
        self.max_tries=3 # when user tries an invalid letter or input.
        self.letter_mapping = {"r":"ROCK", "s":"SCISSORS", "p":"PAPER"} # for informing user
        self.allowed_values=['r', 's', 'p', 'q']

    def random_letter(self):
        '''
        Generates r, s or p used as the computer's input value / choice.
        '''
        letters=['r', 's', 'p']
        our_val = random.randint(0,2)
        return letters[our_val]

    def report_result(self)->None:
        '''
        Print a formatted string telling who wins.
        Returns: None
        '''
        user_selection  = self.letter_mapping[self.last_round["user_letter"]]
        py_selection  = self.letter_mapping[self.last_round["py_letter"]]

        print(f"You chose {user_selection}, Python chose {py_selection}")
        if self.last_round["user_score"] > self.last_round["py_score"]:
            print("User wins.")
        elif self.last_round["py_score"] > self.last_round["user_score"]:
            print("Python wins.")
        else:
            print("Ties.")


    def play(self, user_input):
        user_score=0
        py_score=0
        if user_input == "q":
            sys.exit("Exiting game.")
        user_val = user_input
        our_val = self.random_letter()

        # test tie separately.
        if user_val==our_val:
            pass

        # case 1: user chooses ROCK
        elif user_val=="r":
            if our_val=="s":
                user_score+=1

            else:
                py_score+=1
        # case 2 user chooses PAPER
        elif user_val=="p":
            if our_val=="r":
                user_score+=1
            else:
                py_score+=1
        # case 3 user chooses SCISSORS
        else:
            if our_val=="r":
                py_score+=1
            else :
                user_score+=1

        # put the results in the state of the class
        self.last_round:LastRound = {"user_score":user_score, "py_score":py_score, "user_letter":user_val, "py_letter":our_val}
        self.total_score["user"]+=user_score
        self.total_score["py"]+=py_score

    
def run_game(subsequent_message="remember: r for ROCK, s for SCISSORS, p for PAPER"):
    game = RPS()
    keep_going='y'
    first_try=True
    while(keep_going=='y'):
        msg = game.welcome if first_try else "Type your new choice (r, p, s or q): "
        input = request_valid_input(msg=msg, max_tries=game.max_tries, allowed_values=game.allowed_values)
        game.play(input)
        game.report_result()
        keep_going = request_valid_input(msg="Would you like to play again? Type y for yes, n for no.", allowed_values=['n', 'y'], max_tries=2)
        first_try=False
    print(f"user score: {game.total_score['user']}, python score: {game.total_score['py']}")

run_game()

For other users

Black formatter can be run in Colab though using (actually it fixes some things only.):

# run once
!pip install black[jupyter] --quiet
from google.colab import drive
drive.mount("/content/drive")

# run many times
!black /content/drive/MyDrive/'Colab Notebooks'/'file_name_here.ipynb'

I tried to implement what I understood from previous advices here.

  • use more functions
  • improve the logic of "play"
  • allow wrong user input
  • indent to 4 spaces and remove ()

Mind that I only have access to google colab so I cant benefit from formatting tools or tests.

I also added comments and types to the extent I could do it, and allowed a user to keep playing and accumulate the result.

import random
import sys
from typing import TypedDict

welcome='''
    
    Possible values: r, p, s, q.
    Enter r for ROCK, p for PAPER, s for SCISSORS, q to quit the game.

    '''

def request_valid_input(msg:str, allowed_values:list[str], max_tries:int):
    '''
    Gives the user a certain number of tries in case it types the wrong letter.
    returns: valid user input
    '''
    user_input = input(msg).strip()
    if max_tries <=0:
        raise Exception(f"Max tries reached. Input must be one of {allowed_values.join(',')}")
    while user_input not in allowed_values:
        max_tries-=1
        request_valid_input(max_tries=max_tries)
    return user_input

        
class Score(TypedDict):
    user:int
    py:int

class LastRound(TypedDict):
    user_score:int
    py_score:int
    user_letter:str
    py_letter:str

class RPS():
    '''
    Represents a simple Rock Paper Scissors game
    '''
    def __init__(self):
        self.total_score:Score = {"user":0, "py":0}
        self.last_round:LastRound|None = None 
        self.welcome = welcome
        self.max_tries=3 # when user tries an invalid letter or input.
        self.letter_mapping = {"r":"ROCK", "s":"SCISSORS", "p":"PAPER"} # for informing user
        self.allowed_values=['r', 's', 'p', 'q']

    def random_letter(self):
        '''
        Generates r, s or p used as the computer's input value / choice.
        '''
        letters=['r', 's', 'p']
        our_val = random.randint(0,2)
        return letters[our_val]

    def report_result(self)->None:
        '''
        Print a formatted string telling who wins.
        Returns: None
        '''
        user_selection  = self.letter_mapping[self.last_round["user_letter"]]
        py_selection  = self.letter_mapping[self.last_round["py_letter"]]

        print(f"You chose {user_selection}, Python chose {py_selection}")
        if self.last_round["user_score"] > self.last_round["py_score"]:
            print("User wins.")
        elif self.last_round["py_score"] > self.last_round["user_score"]:
            print("Python wins.")
        else:
            print("Ties.")


    def play(self, user_input):
        user_score=0
        py_score=0
        if user_input == "q":
            sys.exit("Exiting game.")
        user_val = user_input
        our_val = self.random_letter()

        # test tie separately.
        if user_val==our_val:
            pass

        # case 1: user chooses ROCK
        elif user_val=="r":
            if our_val=="s":
                user_score+=1

            else:
                py_score+=1
        # case 2 user chooses PAPER
        elif user_val=="p":
            if our_val=="r":
                user_score+=1
            else:
                py_score+=1
        # case 3 user chooses SCISSORS
        else:
            if our_val=="r":
                py_score+=1
            else :
                user_score+=1

        # put the results in the state of the class
        self.last_round:LastRound = {"user_score":user_score, "py_score":py_score, "user_letter":user_val, "py_letter":our_val}
        self.total_score["user"]+=user_score
        self.total_score["py"]+=py_score

    
def run_game(subsequent_message="remember: r for ROCK, s for SCISSORS, p for PAPER"):
    game = RPS()
    keep_going='y'
    first_try=True
    while(keep_going=='y'):
        msg = game.welcome if first_try else "Type your new choice (r, p, s or q): "
        input = request_valid_input(msg=msg, max_tries=game.max_tries, allowed_values=game.allowed_values)
        game.play(input)
        game.report_result()
        keep_going = request_valid_input(msg="Would you like to play again? Type y for yes, n for no.", allowed_values=['n', 'y'], max_tries=2)
        first_try=False
    print(f"user score: {game.total_score['user']}, python score: {game.total_score['py']}")

run_game()
The changes done are non-significant, and the answer remains correct. This is just because some descriptions were irrelevant and made the post more difficult to read.
Source Link

[EDITS]

The changes done are non-significant, and the answer remains correct. This is just because some descriptions were irrelevant and made the post more difficult to read.


I tried to implement what I understood from previous advices here.

Additions

  • use more functionscomments
  • improve the logic of "play"some types
  • allow wrongallowed a user input
  • indent to 4 spaceskeep playing and remove ()accumulate the result.

Mind that I only have access to google colab so I cant benefit from formatting tools or tests.

I also added comments and types to the extent I could do it, and allowed a user to keep playing and accumulate the result.

import random
import sys
from typing import TypedDict

welcome='''
    
    Possible values: r, p, s, q.
    Enter r for ROCK, p for PAPER, s for SCISSORS, q to quit the game.

    '''

def request_valid_input(msg:str, allowed_values:list[str], max_tries:int):
    '''
    Gives the user a certain number of tries in case it types the wrong letter.
    returns: valid user input
    '''
    user_input = input(msg).strip()
    if max_tries <=0:
        raise Exception(f"Max tries reached. Input must be one of {allowed_values.join(',')}")
    while user_input not in allowed_values:
        max_tries-=1
        request_valid_input(max_tries=max_tries)
    return user_input

        
class Score(TypedDict):
    user:int
    py:int

class LastRound(TypedDict):
    user_score:int
    py_score:int
    user_letter:str
    py_letter:str

class RPS():
    '''
    Represents a simple Rock Paper Scissors game
    '''
    def __init__(self):
        self.total_score:Score = {"user":0, "py":0}
        self.last_round:LastRound|None = None 
        self.welcome = welcome
        self.max_tries=3 # when user tries an invalid letter or input.
        self.letter_mapping = {"r":"ROCK", "s":"SCISSORS", "p":"PAPER"} # for informing user
        self.allowed_values=['r', 's', 'p', 'q']

    def random_letter(self):
        '''
        Generates r, s or p used as the computer's input value / choice.
        '''
        letters=['r', 's', 'p']
        our_val = random.randint(0,2)
        return letters[our_val]

    def report_result(self)->None:
        '''
        Print a formatted string telling who wins.
        Returns: None
        '''
        user_selection  = self.letter_mapping[self.last_round["user_letter"]]
        py_selection  = self.letter_mapping[self.last_round["py_letter"]]

        print(f"You chose {user_selection}, Python chose {py_selection}")
        if self.last_round["user_score"] > self.last_round["py_score"]:
            print("User wins.")
        elif self.last_round["py_score"] > self.last_round["user_score"]:
            print("Python wins.")
        else:
            print("Ties.")


    def play(self, user_input):
        user_score=0
        py_score=0
        if user_input == "q":
            sys.exit("Exiting game.")
        user_val = user_input
        our_val = self.random_letter()

        # test tie separately.
        if user_val==our_val:
            pass

        # case 1: user chooses ROCK
        elif user_val=="r":
            if our_val=="s":
                user_score+=1

            else:
                py_score+=1
        # case 2 user chooses PAPER
        elif user_val=="p":
            if our_val=="r":
                user_score+=1
            else:
                py_score+=1
        # case 3 user chooses SCISSORS
        else:
            if our_val=="r":
                py_score+=1
            else :
                user_score+=1

        # put the results in the state of the class
        self.last_round:LastRound = {"user_score":user_score, "py_score":py_score, "user_letter":user_val, "py_letter":our_val}
        self.total_score["user"]+=user_score
        self.total_score["py"]+=py_score

    
def run_game(subsequent_message="remember: r for ROCK, s for SCISSORS, p for PAPER"):
    game = RPS()
    keep_going='y'
    first_try=True
    while(keep_going=='y'):
        msg = game.welcome if first_try else "Type your new choice (r, p, s or q): "
        input = request_valid_input(msg=msg, max_tries=game.max_tries, allowed_values=game.allowed_values)
        game.play(input)
        game.report_result()
        keep_going = request_valid_input(msg="Would you like to play again? Type y for yes, n for no.", allowed_values=['n', 'y'], max_tries=2)
        first_try=False
    print(f"user score: {game.total_score['user']}, python score: {game.total_score['py']}")

run_game()

For other users

Black formatter can be run in Colab though using (actually it fixes some things only.):

# run once
!pip install black[jupyter] --quiet
from google.colab import drive
drive.mount("/content/drive")

# run many times
!black /content/drive/MyDrive/'Colab Notebooks'/'file_name_here.ipynb'

I tried to implement what I understood from previous advices here.

  • use more functions
  • improve the logic of "play"
  • allow wrong user input
  • indent to 4 spaces and remove ()

Mind that I only have access to google colab so I cant benefit from formatting tools or tests.

I also added comments and types to the extent I could do it, and allowed a user to keep playing and accumulate the result.

import random
import sys
from typing import TypedDict

welcome='''
    
    Possible values: r, p, s, q.
    Enter r for ROCK, p for PAPER, s for SCISSORS, q to quit the game.

    '''

def request_valid_input(msg:str, allowed_values:list[str], max_tries:int):
    '''
    Gives the user a certain number of tries in case it types the wrong letter.
    returns: valid user input
    '''
    user_input = input(msg).strip()
    if max_tries <=0:
        raise Exception(f"Max tries reached. Input must be one of {allowed_values.join(',')}")
    while user_input not in allowed_values:
        max_tries-=1
        request_valid_input(max_tries=max_tries)
    return user_input

        
class Score(TypedDict):
    user:int
    py:int

class LastRound(TypedDict):
    user_score:int
    py_score:int
    user_letter:str
    py_letter:str

class RPS():
    '''
    Represents a simple Rock Paper Scissors game
    '''
    def __init__(self):
        self.total_score:Score = {"user":0, "py":0}
        self.last_round:LastRound|None = None 
        self.welcome = welcome
        self.max_tries=3 # when user tries an invalid letter or input.
        self.letter_mapping = {"r":"ROCK", "s":"SCISSORS", "p":"PAPER"} # for informing user
        self.allowed_values=['r', 's', 'p', 'q']

    def random_letter(self):
        '''
        Generates r, s or p used as the computer's input value / choice.
        '''
        letters=['r', 's', 'p']
        our_val = random.randint(0,2)
        return letters[our_val]

    def report_result(self)->None:
        '''
        Print a formatted string telling who wins.
        Returns: None
        '''
        user_selection  = self.letter_mapping[self.last_round["user_letter"]]
        py_selection  = self.letter_mapping[self.last_round["py_letter"]]

        print(f"You chose {user_selection}, Python chose {py_selection}")
        if self.last_round["user_score"] > self.last_round["py_score"]:
            print("User wins.")
        elif self.last_round["py_score"] > self.last_round["user_score"]:
            print("Python wins.")
        else:
            print("Ties.")


    def play(self, user_input):
        user_score=0
        py_score=0
        if user_input == "q":
            sys.exit("Exiting game.")
        user_val = user_input
        our_val = self.random_letter()

        # test tie separately.
        if user_val==our_val:
            pass

        # case 1: user chooses ROCK
        elif user_val=="r":
            if our_val=="s":
                user_score+=1

            else:
                py_score+=1
        # case 2 user chooses PAPER
        elif user_val=="p":
            if our_val=="r":
                user_score+=1
            else:
                py_score+=1
        # case 3 user chooses SCISSORS
        else:
            if our_val=="r":
                py_score+=1
            else :
                user_score+=1

        # put the results in the state of the class
        self.last_round:LastRound = {"user_score":user_score, "py_score":py_score, "user_letter":user_val, "py_letter":our_val}
        self.total_score["user"]+=user_score
        self.total_score["py"]+=py_score

    
def run_game(subsequent_message="remember: r for ROCK, s for SCISSORS, p for PAPER"):
    game = RPS()
    keep_going='y'
    first_try=True
    while(keep_going=='y'):
        msg = game.welcome if first_try else "Type your new choice (r, p, s or q): "
        input = request_valid_input(msg=msg, max_tries=game.max_tries, allowed_values=game.allowed_values)
        game.play(input)
        game.report_result()
        keep_going = request_valid_input(msg="Would you like to play again? Type y for yes, n for no.", allowed_values=['n', 'y'], max_tries=2)
        first_try=False
    print(f"user score: {game.total_score['user']}, python score: {game.total_score['py']}")

run_game()

[EDITS]

The changes done are non-significant, and the answer remains correct. This is just because some descriptions were irrelevant and made the post more difficult to read.


I tried to implement what I understood from previous advices here.

Additions

  • comments
  • some types
  • allowed a user to keep playing and accumulate the result.
import random
import sys
from typing import TypedDict

welcome='''
    
    Possible values: r, p, s, q.
    Enter r for ROCK, p for PAPER, s for SCISSORS, q to quit the game.

    '''

def request_valid_input(msg:str, allowed_values:list[str], max_tries:int):
    '''
    Gives the user a certain number of tries in case it types the wrong letter.
    returns: valid user input
    '''
    user_input = input(msg).strip()
    if max_tries <=0:
        raise Exception(f"Max tries reached. Input must be one of {allowed_values.join(',')}")
    while user_input not in allowed_values:
        max_tries-=1
        request_valid_input(max_tries=max_tries)
    return user_input

        
class Score(TypedDict):
    user:int
    py:int

class LastRound(TypedDict):
    user_score:int
    py_score:int
    user_letter:str
    py_letter:str

class RPS():
    '''
    Represents a simple Rock Paper Scissors game
    '''
    def __init__(self):
        self.total_score:Score = {"user":0, "py":0}
        self.last_round:LastRound|None = None 
        self.welcome = welcome
        self.max_tries=3 # when user tries an invalid letter or input.
        self.letter_mapping = {"r":"ROCK", "s":"SCISSORS", "p":"PAPER"} # for informing user
        self.allowed_values=['r', 's', 'p', 'q']

    def random_letter(self):
        '''
        Generates r, s or p used as the computer's input value / choice.
        '''
        letters=['r', 's', 'p']
        our_val = random.randint(0,2)
        return letters[our_val]

    def report_result(self)->None:
        '''
        Print a formatted string telling who wins.
        Returns: None
        '''
        user_selection  = self.letter_mapping[self.last_round["user_letter"]]
        py_selection  = self.letter_mapping[self.last_round["py_letter"]]

        print(f"You chose {user_selection}, Python chose {py_selection}")
        if self.last_round["user_score"] > self.last_round["py_score"]:
            print("User wins.")
        elif self.last_round["py_score"] > self.last_round["user_score"]:
            print("Python wins.")
        else:
            print("Ties.")


    def play(self, user_input):
        user_score=0
        py_score=0
        if user_input == "q":
            sys.exit("Exiting game.")
        user_val = user_input
        our_val = self.random_letter()

        # test tie separately.
        if user_val==our_val:
            pass

        # case 1: user chooses ROCK
        elif user_val=="r":
            if our_val=="s":
                user_score+=1

            else:
                py_score+=1
        # case 2 user chooses PAPER
        elif user_val=="p":
            if our_val=="r":
                user_score+=1
            else:
                py_score+=1
        # case 3 user chooses SCISSORS
        else:
            if our_val=="r":
                py_score+=1
            else :
                user_score+=1

        # put the results in the state of the class
        self.last_round:LastRound = {"user_score":user_score, "py_score":py_score, "user_letter":user_val, "py_letter":our_val}
        self.total_score["user"]+=user_score
        self.total_score["py"]+=py_score

    
def run_game(subsequent_message="remember: r for ROCK, s for SCISSORS, p for PAPER"):
    game = RPS()
    keep_going='y'
    first_try=True
    while(keep_going=='y'):
        msg = game.welcome if first_try else "Type your new choice (r, p, s or q): "
        input = request_valid_input(msg=msg, max_tries=game.max_tries, allowed_values=game.allowed_values)
        game.play(input)
        game.report_result()
        keep_going = request_valid_input(msg="Would you like to play again? Type y for yes, n for no.", allowed_values=['n', 'y'], max_tries=2)
        first_try=False
    print(f"user score: {game.total_score['user']}, python score: {game.total_score['py']}")

run_game()

For other users

Black formatter can be run in Colab though using (actually it fixes some things only.):

# run once
!pip install black[jupyter] --quiet
from google.colab import drive
drive.mount("/content/drive")

# run many times
!black /content/drive/MyDrive/'Colab Notebooks'/'file_name_here.ipynb'
Removed from Network Questions by Mast
Rollback to Revision 1
Source Link
Mast
  • 13.8k
  • 12
  • 57
  • 127

Additions

  • commentsuse more functions
  • some typesimprove the logic of "play"
  • allowed aallow wrong user input
  • indent to keep playing4 spaces and accumulate the result.remove ()

Mind that I only have access to google colab so I cant benefit from formatting tools or tests.

I also added comments and types to the extent I could do it, and allowed a user to keep playing and accumulate the result.

import random
import sys
from typing import TypedDict

welcome='''
    
    Possible values: r, p, s, q.
    Enter r for ROCK, p for PAPER, s for SCISSORS, q to quit the game.

    '''

def request_valid_input(msg:str, allowed_values:list[str], max_tries:int):
    '''
    Gives the user a certain number of tries in case it types the wrong letter.
    returns: valid user input
    '''
    user_input = input(msg).strip()
    if max_tries <=0:
        raise Exception(f"Max tries reached. Input must be one of {allowed_values.join(',')}")
    while user_input not in allowed_values:
        max_tries-=1
        request_valid_input(max_tries=max_tries)
    return user_input

        
class Score(TypedDict):
    user:int
    py:int

class LastRound(TypedDict):
    user_score:int
    py_score:int
    user_letter:str
    py_letter:str

class RPS():
    '''
    Represents a simple Rock Paper Scissors game
    '''
    def __init__(self):
        self.total_score:Score = {"user":0, "py":0}
        self.last_round:LastRound|None = None 
        self.welcome = welcome
        self.max_tries=3 # when user tries an invalid letter or input.
        self.letter_mapping = {"r":"ROCK", "s":"SCISSORS", "p":"PAPER"} # for informing user
        self.allowed_values=['r', 's', 'p', 'q']

    def random_letter(self):
        '''
        Generates r, s or p used as the computer's input value / choice.
        '''
        letters=['r', 's', 'p']
        our_val = random.randint(0,2)
        return letters[our_val]

    def report_result(self)->None:
        '''
        Print a formatted string telling who wins.
        Returns: None
        '''
        user_selection  = self.letter_mapping[self.last_round["user_letter"]]
        py_selection  = self.letter_mapping[self.last_round["py_letter"]]

        print(f"You chose {user_selection}, Python chose {py_selection}")
        if self.last_round["user_score"] > self.last_round["py_score"]:
            print("User wins.")
        elif self.last_round["py_score"] > self.last_round["user_score"]:
            print("Python wins.")
        else:
            print("Ties.")


    def play(self, user_input):
        user_score=0
        py_score=0
        if user_input == "q":
            sys.exit("Exiting game.")
        user_val = user_input
        our_val = self.random_letter()

        # test tie separately.
        if user_val==our_val:
            pass

        # case 1: user chooses ROCK
        elif user_val=="r":
            if our_val=="s":
                user_score+=1

            else:
                py_score+=1
        # case 2 user chooses PAPER
        elif user_val=="p":
            if our_val=="r":
                user_score+=1
            else:
                py_score+=1
        # case 3 user chooses SCISSORS
        else:
            if our_val=="r":
                py_score+=1
            else :
                user_score+=1

        # put the results in the state of the class
        self.last_round:LastRound = {"user_score":user_score, "py_score":py_score, "user_letter":user_val, "py_letter":our_val}
        self.total_score["user"]+=user_score
        self.total_score["py"]+=py_score

    
def run_game(subsequent_message="remember: r for ROCK, s for SCISSORS, p for PAPER"):
    game = RPS()
    keep_going='y'
    first_try=True
    while(keep_going=='y'):
        msg = game.welcome if first_try else "Type your new choice (r, p, s or q): "
        input = request_valid_input(msg=msg, max_tries=game.max_tries, allowed_values=game.allowed_values)
        game.play(input)
        game.report_result()
        keep_going = request_valid_input(msg="Would you like to play again? Type y for yes, n for no.", allowed_values=['n', 'y'], max_tries=2)
        first_try=False
    print(f"user score: {game.total_score['user']}, python score: {game.total_score['py']}")

run_game()

For other users

Black formatter can be run in Colab though using (actually it fixes some things only.):

# run once
!pip install black[jupyter] --quiet
from google.colab import drive
drive.mount("/content/drive")

# run many times
!black /content/drive/MyDrive/'Colab Notebooks'/'file_name_here.ipynb'

Additions

  • comments
  • some types
  • allowed a user to keep playing and accumulate the result.
import random
import sys
from typing import TypedDict

welcome='''
    
    Possible values: r, p, s, q.
    Enter r for ROCK, p for PAPER, s for SCISSORS, q to quit the game.

    '''

def request_valid_input(msg:str, allowed_values:list[str], max_tries:int):
    '''
    Gives the user a certain number of tries in case it types the wrong letter.
    returns: valid user input
    '''
    user_input = input(msg).strip()
    if max_tries <=0:
        raise Exception(f"Max tries reached. Input must be one of {allowed_values.join(',')}")
    while user_input not in allowed_values:
        max_tries-=1
        request_valid_input(max_tries=max_tries)
    return user_input

        
class Score(TypedDict):
    user:int
    py:int

class LastRound(TypedDict):
    user_score:int
    py_score:int
    user_letter:str
    py_letter:str

class RPS():
    '''
    Represents a simple Rock Paper Scissors game
    '''
    def __init__(self):
        self.total_score:Score = {"user":0, "py":0}
        self.last_round:LastRound|None = None 
        self.welcome = welcome
        self.max_tries=3 # when user tries an invalid letter or input.
        self.letter_mapping = {"r":"ROCK", "s":"SCISSORS", "p":"PAPER"} # for informing user
        self.allowed_values=['r', 's', 'p', 'q']

    def random_letter(self):
        '''
        Generates r, s or p used as the computer's input value / choice.
        '''
        letters=['r', 's', 'p']
        our_val = random.randint(0,2)
        return letters[our_val]

    def report_result(self)->None:
        '''
        Print a formatted string telling who wins.
        Returns: None
        '''
        user_selection  = self.letter_mapping[self.last_round["user_letter"]]
        py_selection  = self.letter_mapping[self.last_round["py_letter"]]

        print(f"You chose {user_selection}, Python chose {py_selection}")
        if self.last_round["user_score"] > self.last_round["py_score"]:
            print("User wins.")
        elif self.last_round["py_score"] > self.last_round["user_score"]:
            print("Python wins.")
        else:
            print("Ties.")


    def play(self, user_input):
        user_score=0
        py_score=0
        if user_input == "q":
            sys.exit("Exiting game.")
        user_val = user_input
        our_val = self.random_letter()

        # test tie separately.
        if user_val==our_val:
            pass

        # case 1: user chooses ROCK
        elif user_val=="r":
            if our_val=="s":
                user_score+=1

            else:
                py_score+=1
        # case 2 user chooses PAPER
        elif user_val=="p":
            if our_val=="r":
                user_score+=1
            else:
                py_score+=1
        # case 3 user chooses SCISSORS
        else:
            if our_val=="r":
                py_score+=1
            else :
                user_score+=1

        # put the results in the state of the class
        self.last_round:LastRound = {"user_score":user_score, "py_score":py_score, "user_letter":user_val, "py_letter":our_val}
        self.total_score["user"]+=user_score
        self.total_score["py"]+=py_score

    
def run_game(subsequent_message="remember: r for ROCK, s for SCISSORS, p for PAPER"):
    game = RPS()
    keep_going='y'
    first_try=True
    while(keep_going=='y'):
        msg = game.welcome if first_try else "Type your new choice (r, p, s or q): "
        input = request_valid_input(msg=msg, max_tries=game.max_tries, allowed_values=game.allowed_values)
        game.play(input)
        game.report_result()
        keep_going = request_valid_input(msg="Would you like to play again? Type y for yes, n for no.", allowed_values=['n', 'y'], max_tries=2)
        first_try=False
    print(f"user score: {game.total_score['user']}, python score: {game.total_score['py']}")

run_game()

For other users

Black formatter can be run in Colab though using (actually it fixes some things only.):

# run once
!pip install black[jupyter] --quiet
from google.colab import drive
drive.mount("/content/drive")

# run many times
!black /content/drive/MyDrive/'Colab Notebooks'/'file_name_here.ipynb'
  • use more functions
  • improve the logic of "play"
  • allow wrong user input
  • indent to 4 spaces and remove ()

Mind that I only have access to google colab so I cant benefit from formatting tools or tests.

I also added comments and types to the extent I could do it, and allowed a user to keep playing and accumulate the result.

import random
import sys
from typing import TypedDict

welcome='''
    
    Possible values: r, p, s, q.
    Enter r for ROCK, p for PAPER, s for SCISSORS, q to quit the game.

    '''

def request_valid_input(msg:str, allowed_values:list[str], max_tries:int):
    '''
    Gives the user a certain number of tries in case it types the wrong letter.
    returns: valid user input
    '''
    user_input = input(msg).strip()
    if max_tries <=0:
        raise Exception(f"Max tries reached. Input must be one of {allowed_values.join(',')}")
    while user_input not in allowed_values:
        max_tries-=1
        request_valid_input(max_tries=max_tries)
    return user_input

        
class Score(TypedDict):
    user:int
    py:int

class LastRound(TypedDict):
    user_score:int
    py_score:int
    user_letter:str
    py_letter:str

class RPS():
    '''
    Represents a simple Rock Paper Scissors game
    '''
    def __init__(self):
        self.total_score:Score = {"user":0, "py":0}
        self.last_round:LastRound|None = None 
        self.welcome = welcome
        self.max_tries=3 # when user tries an invalid letter or input.
        self.letter_mapping = {"r":"ROCK", "s":"SCISSORS", "p":"PAPER"} # for informing user
        self.allowed_values=['r', 's', 'p', 'q']

    def random_letter(self):
        '''
        Generates r, s or p used as the computer's input value / choice.
        '''
        letters=['r', 's', 'p']
        our_val = random.randint(0,2)
        return letters[our_val]

    def report_result(self)->None:
        '''
        Print a formatted string telling who wins.
        Returns: None
        '''
        user_selection  = self.letter_mapping[self.last_round["user_letter"]]
        py_selection  = self.letter_mapping[self.last_round["py_letter"]]

        print(f"You chose {user_selection}, Python chose {py_selection}")
        if self.last_round["user_score"] > self.last_round["py_score"]:
            print("User wins.")
        elif self.last_round["py_score"] > self.last_round["user_score"]:
            print("Python wins.")
        else:
            print("Ties.")


    def play(self, user_input):
        user_score=0
        py_score=0
        if user_input == "q":
            sys.exit("Exiting game.")
        user_val = user_input
        our_val = self.random_letter()

        # test tie separately.
        if user_val==our_val:
            pass

        # case 1: user chooses ROCK
        elif user_val=="r":
            if our_val=="s":
                user_score+=1

            else:
                py_score+=1
        # case 2 user chooses PAPER
        elif user_val=="p":
            if our_val=="r":
                user_score+=1
            else:
                py_score+=1
        # case 3 user chooses SCISSORS
        else:
            if our_val=="r":
                py_score+=1
            else :
                user_score+=1

        # put the results in the state of the class
        self.last_round:LastRound = {"user_score":user_score, "py_score":py_score, "user_letter":user_val, "py_letter":our_val}
        self.total_score["user"]+=user_score
        self.total_score["py"]+=py_score

    
def run_game(subsequent_message="remember: r for ROCK, s for SCISSORS, p for PAPER"):
    game = RPS()
    keep_going='y'
    first_try=True
    while(keep_going=='y'):
        msg = game.welcome if first_try else "Type your new choice (r, p, s or q): "
        input = request_valid_input(msg=msg, max_tries=game.max_tries, allowed_values=game.allowed_values)
        game.play(input)
        game.report_result()
        keep_going = request_valid_input(msg="Would you like to play again? Type y for yes, n for no.", allowed_values=['n', 'y'], max_tries=2)
        first_try=False
    print(f"user score: {game.total_score['user']}, python score: {game.total_score['py']}")

run_game()
added 38 characters in body
Source Link
Loading
added 63 characters in body
Source Link
Loading
Became Hot Network Question
Source Link
Loading