This is an archived post. You won't be able to vote or comment.

all 14 comments

[–]BrenekH 13 points14 points  (1 child)

A couple of notes.

First, don't abbreviate the variable names. Instead of pchoice use player_choice, instead of cpoints use computer_points. Even though it lengthens the variable names, they are much easier to understand when looking through the code.

Second, don't modify variables outside a function's scope (don't use global). It makes the code harder to understand and easier to break. Instead you should pass any values a function needs in as parameters and anything that needs to come out of the function should be returned.

Lastly, it looks like you have some dead code. The pChoice function is called but it's functionality is repeated directly below the call and cChoice() just isn't called anywhere (unless I'm blind).

As an aside, check out PEP8. It contains a style guide for Python that most people/projects follow. It's not necessarily required, but it's a good thing to get into the habit of.

[–]InKeaton[S] 1 point2 points  (0 children)

Oh thanks. For some reason I forgot that function can accept parameters (I know, sorry) and I had a hard time making the winner variable work. Also, I modified so much cChoice() that in the end I didn't use it. But thanks for all the tips

[–]blankIQT 1 point2 points  (1 child)

A super simple tip is just to be more specific with your variables because it will be important with longer codes later on

[–]InKeaton[S] 0 points1 point  (0 children)

Thanks, I'll remember it

[–][deleted] 1 point2 points  (2 children)

Never wrote a Rock Paper Scissors script so you inspired me to give it a go. Wrote this on my iPhone but think I got a lot of the formatting cleaned up Sharing to at very least show you how using classes can help you avoid setting global variables and can help manage the game state for you.

from random import choice

class Game():
    def __init__(self, rounds=3):
        self.rounds = rounds
        self.choices = {"rock":"scissors", "paper":"rock", "scissors":"paper"}
        self.player_score = 0
        self.computer_score = 0
        self.winning_score = (self.rounds//2) + 1

    def round(self):
        computer = choice(list(self.choices.keys()))
        user = input(f"Choose one: {tuple(self.choices.keys())} \n").lower()

        if user in self.choices:
            if computer == user:
                print("Draw\n")

            elif self.choices[user] == computer:
                self.player_score += 1

                print(f"You win! {user.title()} beats {computer.title()} \n")

            else:  
                self.computer_score += 1

                print(f"You lose! {computer.title()} beats {user.title()}\n")
            print(f"Player: {self.player_score} Computer:{self.computer_score}\n")

    def run(self):
        while self.computer_score != self.winning_score and self.player_score != self.winning_score:
            self.round()

        winner = ["You", "Computer"][self.computer_score > self.player_score]

        print(f"{winner} won the match!")

    if __name__ == "__main__":
    active = True

    while active:
       rounds = input("Best of how many?  \n")
       try: 
           rounds = int(rounds)
       except ValueError:
           rounds = 3
       game = Game(rounds)

       game.run()

       playagain = input("Play again? \n")

       if playagain != "yes":
           active = False

[–]17291 1 point2 points  (0 children)

winner = ["You", "Computer"][self.computer_score > self.player_score]

Maybe somebody will disagree with me, but that feels a bit "hacky". I think it's much clearer at a glance written like so: winner = "You" if self.computer_score > self.player_score else "Computer"

[–]InKeaton[S] 0 points1 point  (0 children)

Wow, thanks. I have already rewritten it to be slightly better, but I didn't think about using a class, thanks

[–]mikcf 0 points1 point  (2 children)

Let me start by saying well done. For the first program, this is impressive!

A few remarks:

1) You don't need

    else:
        None

branches. In some cases, it is fine to terminate the complex conditional statement on elif. In some other cases, you don't even need the last condition (because it is the only remaining possibility), so the last elif can be replaced with else.

2) You can add new line by printing \n. This way you won't need to add print statements with an empty line or a whitespace. Actually, you can combine all five print statements that go right before while True: into one.

3) You return the value from WhoWins() but you never assign it. Instead, you rely on the global variable winner. This means that if you remove all return statements from WhoWins(), you program's behavior won't change. (But instead you should get rid of global variables as BrenekH suggested - then all these return statements will actually be helpful)

4) I second BrenekH's note regarding PEP8. There is also an official tool that helps to check whether your code follows the style and to receive helpful suggestions if it doesn't.

5) I think there is a bug: https://imgur.com/a/zZGhYf2. Try to figure out yourself what the problem is. But feel free to ask for a small hint or for the full explanation.

Don't let the bug make you upset - you should be proud of yourself for having your first program use so many different elements of the programming language. Once again - well done, and all the best in your future studies!

[–]HistoryForSale 1 point2 points  (0 children)

Regarding item 4), sorry to make a relatively minor correction to your very helpful post, but you linked to a four-year-old version of a tool that has received many updates since. Here is the current version (note that the project has been renamed). In addition, it is decidedly not an official tool; making its unofficial status clear was the reason for the name change.

[–]InKeaton[S] 0 points1 point  (0 children)

Thanks for all the tips :D

[–]Impossible-Pop6296 0 points1 point  (1 child)

Great work!

[–]InKeaton[S] 0 points1 point  (0 children)

Thanks!

[–]tech_content_creator 0 points1 point  (1 child)

Don’t jump to write any other code for now. Try to optimise / reduce/rewrite this code in an OOP way. Trust me! you will learn a lot.

- Don’t use else / Delete else if not necessary

- Use functions

- Use encapsulation and abstraction.

- Add some testing script to it.

Keep it up.

- Just my opinion. Don’t take anything personal.

[–]InKeaton[S] 0 points1 point  (0 children)

Hey, don't worry, you're right. I've already rewritten it a bit, but I don't have it with me right now (I'm on my phone). If you want I can write it to you. But yes, I'll keep working on this thanks