Rob Cook


Home | Donate

Rock, paper, scissors, code! - part one


2020-04-04

For Hugo. Choose your own doors to open.

What is this book?

Think of this book as a taster session. By the end of it you will have:

Hopefully you will enjoy it. If you do there a number of suggestions for further learning at the end. If you don't you will at least understand what it is a programmer does, and the effort it takes to make a computer do what you want it to. Above all the aim is to help you realise that you can learn to program a computer, if you want to.

A joke

Did you hear the one about the programmer's wife? She asked her husband to go to the supermarket and buy a loaf of bread. As he headed out the door, she said "if they have eggs, get a dozen". The programmer dutifully came home with twelve loaves of bread.

Confused? Don't worry, it's most likely because you don't know how to think like a computer programmer (yet).

Hello, world!

We learn best by doing. Let's write some code. We will use the Python programming language as it is simple to read and write. To keep setup to a minimum, we will use the free online Python programming environment at trinket.io. You can use any device with an internet connection and you don't need to install anything.

Task

Go to the trinket.io website. Click the Sign Up link at the top. Fill out the form to create a free account.

Once you have completed the sign up process, you need to login to the website.

Task

Click the Log In link at the top. Enter your username and password on the form.

Trinket refers to each program you write as a trinket. To create a new program click the blue New Trinket and select Python from the list.

Task

Create a new trinket, select Python from the available options.

You should now see the program editor page. The left hand side of the screen is where you will type in Python code. It has a tab named main.py. We will call this the code pane. The right hand side of the screen is where you will see the output from running your code. We will call this the output pane. At the moment this is blank. Up top there should be space for giving this trinket a name. It currently has the text untitled.

Task

Give your trinket the name hello world by clicking on the untitled text and typing it in. Click the `save` button to save your changes.

You are now ready to write a Python program.

Task

In the code pane carefully enter the following two lines of text, including all the punctuation marks.


#!/bin/python3

print("Hello world!")

Save your changes by clicking the Save button again. Get in to the habit of saving your work regularly. The internet is mostly reliable but sometimes things go wrong. We don't want to lose our work.

We've typed in a program! But nothing happened. We need to tell Python to run our program. Running a program makes Python read each line of our code, and turn it into instructions the computer can understand.

Task

Click the large triangle button at the top of the code pane. This is the `Run` button. See what happens.

Did it work?

If all went well you should have seen the text Hello world! in the output pane. Don't worry if you didn't. I'll help you to diagnose and fix the problem.

Fixing problems in your code is called debugging and programmers do it a lot. Even if your code worked it is still worth reading through the steps below. Sooner or later you'll need to use them.

  1. Python should give you an error message when something goes wrong. This is shown in a pale red box at the bottom of the screen.
  2. The error message will often include the number of the line in your code Python had a problem with. This is the best place to start looking for a bug.
  3. Double check that what you typed in on that line matches the code given in the example. Punctuation is important, as are letters being upper case or lower case. In some cases spacing is also important (we will cover these later).
  4. Correct the line so it matches the code in the example. Save your changes and run your program again.
It's common to have to go through these steps several times before you get a working program, especially when learning. As you get familiar with Python code this will happen less often, so don't worry.

Task

If your program didn't work, go through the process outlined above until you see the message `Hello world!` in the output pane.

What's with the funny looking first line?

Our program actually only has one line of code that does something, the one with the print() command on it. The first line is a special one that tells the computer to use version 3 of Python. This is the most up to date version of Python and is the one we will be using.

Printing other things

The print statement we saw in the previous program can be used to say any number of things on the screen. The message we want to display appears between the beginning and end quote marks ".

Task

Change the print() command in your program to say different things. Run your program after each change to see if Python will print out your new message.

Are there any things it can't print out? Do some messages cause an error?

This sort of trial and error approach to writing code is a useful way of learning a new feature of a language. Hopefully you got Python to successfully print out another message.

You might also have discovered that trying to print out a message that included the double quote " symbol caused an error. This is because we use " to mark the beginning and end of the message. If we want to print out a message that includes a " we have two options:

  1. Use a single quote ' to mark the beginning and end of the message instead of a double quote. For example print('A "word" in double quote marks.').
  2. Precede the double quotes in the message with a backslash \ character. For example print("Another \"word\" in double quote marks.").

Task

Type in both of the examples for printing a message with double quote marks in it. Add these lines to the end of your program. Run your program and check the messages shown on screen include the quote marks.

Using a backslash to print a quote mark is known as escaping. It tells Python to ignore the special meaning of the quote mark that follows. The print() command supports a number of different escape sequences for printing out difficult characters. The following ones often come in handy.


Escape sequence     Output
----------------------------------------
\\                  A backslash.
\'                  A single quote mark.
\"                  A double quote mark.
\n                  A newline.
\t                  A tab.

Task

Write a print() command for each of the following messages. Add the necessary escape sequences to each one. For example, the first one needs a newline added to it.

  1. This is on one line. This is on another.
  2. This "message" has double and 'single' quotes in it.
  3. These words each have a tab between them.
  4. There's a \ in this message.

Sometimes we want to write a lot of text spanning several lines. When this is the case Python lets us begin and end the block of text with three of the same quote marks - either """ or '''. Messages written in this way will be printed out as is.


print("""This is a very long
message that will be 
printed
out across several lines!""")

Task

Write a print() command that uses the triple quotes for its message. Make the message span several lines. Run your program and see how Python outputs it on screen.

Can you use any of the escape sequences in your triple quoted message?

Asking questions

So far our program can output messages to the screen. It would be useful if we could also receive input from somewhere too.

The input() command lets us do just this. We can use it to prompt for input from the keyboard.

Task

Add the following lines of code to the end of your program. Save your changes.


name = input("What is your name?")
print("Hello", name)

Task

Run your program. In the output pane type in your name when prompted and press enter. Your program should say hello to you.

What just happened?

Despite only being two lines of code, quite a lot just happened. Let's break it down.

  1. We created a _variable_ called name. A variable is a label we use to remember things in a program.
  2. We got some input from the keyboard using the input() command, and _assigned_ it to name using the equals = sign. Assignment is like putting a sticky label on something. In this case we put the label name on to some input from the keyboard.
  3. We passed two _arguments_ to the print() command. One was the message Hello, the other was the name variable.
Note how Python didn't print out the word name, but instead printed out whatever we typed in at the keyboard and had assigned to name.

Task

Try running your program several times typing in something different each time. We called our variable name but Python lets us type in any text we like.

Anything we want to remember in a program must be assigned to a variable. You can have as many variables as you like in a program, the only limit is the amount of memory present on the computer.

Making decisions

Alongside input and output another basic ability our programs need is to make decisions. Programs typically look at the content of one or more variables and then decide what to do. Python uses the if statement for this purpose.


#!/bin/python3

birthplace = input("Where were you born?")

if birthplace == "England":
    print("So was I!")

In the code above Python will print out the message So was I! only if you enter a birthplace of England (with a capital letter E).

The statement birthplace == "England" is known as a condition. Conditions can be true or false. When the condition is true the code associated with the if runs.

How does Python know what lines to run when the if statement is true? First we end the line with a colon :. Then we indent the lines it should run with a single tab. Any lines that are indented Python considers to be part of the if statement.

We use a double equals == to see if one thing is the same as another in Python. It's a common mistake to get this mixed up with the single equals = which is used for assignment to a variable (as we saw with the input() command earlier).

Task

Create a new trinket and give it the name Questions. Type in the lines from the example above and save your changes.

Task

Run your program twice - once with England as the input and once with somewhere else. See that the message is only printed out for England.

Making more than one decision

We can add additional statements to the basic if to check for other conditions. The simplest of these is else. Lines associated with an else only run when the if condition isn't true. Let's expand our example.


#!/bin/python3

birthplace = input("Where were you born?")

if birthplace == "England":
    print("So was I!")
else:
    print(birthplace, "is a nice place.")

Task

Change your birthplace program to look like the one above. Note the use of else: and the indentation of the second print() command with a tab.

If we run this new version of our program we should see that it prints out one message or the other depending on if we input England or something else.

Task

Run your program several times with different place names. See which message gets printed out for each place.

We can also add conditions with elif, which is short for else if. The program below shows how to do this.


#!/bin/python3

birthplace = input("Where were you born?")

if birthplace == "England":
    print("So was I!")
elif birthplace == "Ireland":
    print ("Next door to me.")
else:
    print(birthplace, "is a nice place.")

Task

Modify your program again, this time adding in the elif statement and associated print() command.

Running this new program we should see one of three messages in the output pane, depending on if we enter England, Ireland, or somewhere else when prompted.

Task

Run your program several times with different place names. See which message gets printed out for each place.

Making a game

Believe it or not we now know (almost) enough Python to write a game. With input, output, and decisions we can play Rock, Paper, Scissors!

For those unfamiliar with the game, a quick summary. A game for two players, on the count of three both pick one of rock, paper, or scissors by making an appropriate shape with their hand. The winner is determined as follows:

If both players make the same choice the game is a draw.

In our version of the game you will be one player and the computer the other. We'll need a way for the computer to make a choice. Also we can't use hand shapes (at the time of writing computers don't come with hands), so we'll have to find some other way to represent the choices you and the computer make.

Task

Create a new trinket and call it Rock, Paper, Scissors. Write the funny first line that tells the computer to use Python version 3. Save your changes.

An algorithm

Before starting to write code we should get a clear idea of what we want our program to do. Let's write out the steps needed to play the game in plain English.

  1. Make the computer pick a random choice between rock, paper, or scissors.
  2. Remember the choice in a variable.
  3. Ask the player to choose either rock, paper, or scissors.
  4. Remember the choice in a variable.
  5. Print both choices on screen - for example rock vs scissors.
  6. Compare the two variables to see who has won, or if the game is a draw.
  7. Print out a message to say if the player won, drew, or lost the game.

The description we just wrote is our algorithm for playing Rock, Paper, Scissors. An algorithm helps us get a clear understanding of what our program is trying to do before we sit down to write code. If ever we get stuck coding, we can refer to our algorithm to remind us what to do next.

Task

Write out each line of the algorithm in the code pane, putting a hash # symbol at the start of each line. This symbol tells Python the line is a comment. Comments are there to help the programmer with useful information and are ignored by Python.


#!/bin/python3

# 1. Make the computer pick a random choice between rock, paper, or scissors.
# 2. Remember the choice in a variable.
# 3. Ask the player to choose either rock, paper, or scissors.
# 4. Remember the choice in a variable.
# 5. Print both choices on screen - for example "rock vs scissors".
# 6. Compare the two variables to see who has won, or if the game is a draw.
# 7. Print out a message to say if the player won, drew, or lost the game.

The computer's choice

Python is often described as coming with batteries included. This is because there is a large library of pre-written code that you can use in your programs. Such code can do useful things for us without having to work out how to do it for ourselves. Generating random things is one of those useful functions we can find in the Python library.

To use a part of the Python library we must first import it into our program by name. Parts of the library are known as modules and they all have a unique name to identify them. To make the computer pick something at random we will import the `random` module.

Task

Add the line below to your program, after the comments describing the algorithm, to import the random module.


import random

The first port of call when using a new module is to take a look at the documentation for it. This gives details on all the functions contained in the module. Functions are pieces of named code that do specific things. The print() and input() commands we have been using so far are actually functions. From now on we will use the term function instead of command.

Task

Trinket has built in documentation for some Python modules. To access it click on the hamburger menu (the three horizontal lines) above your code pane. Click the Modules link to open the documentation. Scroll down the list and click on the random entry.

Have a look at the information but don't worry if it doesn't make sense just yet! To get back to your code, click the hamburger menu again and click on Modules to close the documentation.

It may look quite intimidating but after some practice coding, the documentation will become easier to understand. For now, know that we are interested in the function random.randint(). This function is used to make the computer generate a random number between a minimum and maximum that we decide.

How does this help us with our game? Well we can't get the computer to pick the words rock, paper, or scissors, but we can use the numbers 1, 2, and 3 to represent the choices.


1 rock
2 paper
3 scissors

Let's do this in our program now.

Task

Add the following lines to the end of your program.


# Get computer choice.
comp_choice = random.randint(1,3)

Here we ask the randint() function for a random number between 1 and 3, and assign it to a variable named comp_choice (short for computer choice).

The player's choice

One choice down one to go. We can prompt the player for their choice using the input() function, like we did in previous exercises. As with the computer we want the player to choose a number between 1 and 3.


player_choice = input ("1 rock, 2 paper, 3 scissors?")

This will capture the keyboard input and assign it to the player_choice variable. There is however a problem. To understand it we need to expand our knowledge of variables a little.

Types of things

All variables in Python have a type associated with them. The type describes what sort of data the variable refers to. Our comp_choice variable is of type int which is short for integer. An integer is a whole number (one without a decimal point in it). 1, 23, and 2006 are all examples of integers.

On the other hand our player_choice variable is of type str which is short for string. A string is any piece of text. "Hello", "nice to meet you", and "tasty bacon" are all examples of strings.

When we come to work out who has won the game we are going to need to compare both choices. It is here that the problem arises. The integer 1 is not the same as the string "1". So how do we solve this problem?

Python provides functions for converting one type of data to another. We can use the int() function on a string to to turn it into an integer, and assign this to a new variable.

Confused? Let's see an example.


# Get player choice.
input_str = input ("1 rock, 2 paper, 3 scissors? ")
player_choice = int(input_str)

This revised code for getting the players choice first assigns the keyboard input (which is a string) to the variable input_str. It then uses the int() function to turn the string in to an integer, and assigns it to the variable player_choice.

Task

Add the code for getting the player's choice given in the sample above to the end of your program. Run your program and enter a number between 1 and 3. There wont be any output yet, but neither should there be any errors.

Showing both choices

Now that we have both choices we can print out a message along the lines of "rock vs paper" on screen. Alas we now have another issue relating to how choices are represented in our program. Both choices are numbers, and printing out "1 vs 2" isn't what we want to see. What we want to see is "rock vs paper".

Using if, elif, and else we can write code to print out the correct word for each choice.


# Show player choice.
if player_choice == 1:
    print("rock", end=" ")
elif player_choice == 2:
    print("paper", end=" ")
else:
    print("scissors", end=" ")

What's with the extra end=" " argument in the call to print()? Normally the print function will automatically add a newline to the end of the text we give it. For us that is a problem as we want "rock vs paper" to appear all on one line, and we haven't finished writing it all out to the screen yet. We can change this behaviour by giving the print function an end argument that has a different character to use at the end of a line. We will use a single space instead of the default newline.

Task

Add the code above for showing the players choice to the end of your program. Run your program and see that it successfully prints out your choice as a word.

Our message is halfway there. Let's print out the computer's choice to finish the job.


# Show computer choice.
if comp_choice == 1:
    print("vs rock")
elif comp_choice == 2:
    print("vs paper")
else:
    print("vs scissors")

In this case we can let the print function add a newline to the end, as we have now written out the full message.

Task

Add the code to print out the computer's choice to the end of your program. Run your program and see that it successfully prints out both choices on one line.

Winners and losers

The only thing left to do is determine the outcome of the game. Before writing any code for this we need to work out how many possible outcomes there are. Both players can make one of three choices, so there are nine possible outcomes for our game.


player      computer    winner
--------------------------------
rock        rock        draw
rock        paper       computer
rock        scissors    player
paper       rock        player
paper       paper       draw
paper       scissors    computer
scissors    rock        computer
scissors    paper       player
scissors    scissors    draw

Once again we can use if statements to work out the correct message to display.

Task

Given the list above, work out how many if statements we will need to check all possible outcomes of the game. Don't write any code just yet, instead see if you can work it out on paper or in your head.

Can we use less than 9 if statements (one for each outcome of the game)?

The first thing to notice is the three draw outcomes can be handled with one condition player_choice == comp_choice. It doesn't matter if the game is "rock vs rock", "paper vs paper", or "scissors vs scissors". What matters is if the choices are the same as each other.

Our first if statement looks like this.


# Determine who won.
if player_choice == comp_choice:
    print("A draw.")

Let's look at winning next. From the table of outcomes we can see three ways the player can win. We will need to check for each of these outcomes separately.

So far our if statements have only checked if one thing equals another, as in some_variable == "this value". However to work out if a player has won the game, we will need to check both the player_choice and comp_choice in one if statement. Its no good just checking the player's choice.

We can check both choice variables in one if statement by using the and operator. and joins two conditions together returning true only when both conditions are true. For example player_choice == 1 and comp_choice == 3 checks if the player chose 1 (rock) and the computer chose 3 (paper). Remember, our choice variables contain the numbers of each choice not the word.

Lets add the three winning conditions to our code for determining the outcome of the game.


# Determine who won.
if player_choice == comp_choice:
    print("A draw.")
elif player_choice == 1 and comp_choice == 3:
    print("Rock blunts scissors. You win!")
elif player_choice == 2 and comp_choice == 1:
    print("Paper wraps rock. You win!")
elif player_choice == 3 and comp_choice == 2:
    print("Scissors cut paper. You win!")

That just leaves the three outcomes where the player loses. However in this case we don't need to check all three possibilities. We have already checked for a draw and winning. This means if none of those conditions have matched, whatever combination of choices is left must be a loss for the player.

In other words, if you didn't draw and you didn't win, you must have lost.

This can be written using the else statement. Our final code for determining the outcome of the game is as follows.


# Determine who won.
if player_choice == comp_choice:
    print("A draw.")
elif player_choice == 1 and comp_choice == 3:
    print("Rock blunts scissors. You win!")
elif player_choice == 2 and comp_choice == 1:
    print("Paper wraps rock. You win!")
elif player_choice == 3 and comp_choice == 2:
    print("Scissors cut paper. You win!")
else:
    print("You lose :(")

It turns out we only needed 5 statements to cover all possible outcomes of the game. Is this how many you thought would be needed? If not, can you see where the code is different to your approach?

Task

Add the final version of the code given above for checking the outcome of the game to the end of your program.

That's it, we have a complete game of Rock, Paper, Scissors written in Python!

Try running your program several times to make sure it works correctly. In particular see if:

Go through the debugging steps outlined earlier if you have any errors. Keep testing and debugging your code until it plays the game correctly.

Well done for making it this far! Our game works, but our job as a programmer is far from complete. Next time we will look at what happens when we provide invalid input to our program, and what we can do to handle it. We will also make the game play more than once, until the player decides to quit. Finally we will look at how we can reduce some of the repetitive code we have, by writing our own function to help display the player and computer choices.

Complete code listing


#!/bin/python3

# 1. Make the computer pick a random choice between rock, paper, or scissors.
# 2. Remember the choice in a variable.
# 3. Ask the player to choose either rock, paper, or scissors.
# 4. Remember the choice in a variable.
# 5. Print both choices on screen - for example `rock vs scissors`.
# 6. Compare the two variables to see who has won, or if the game is a draw.
# 7. Print out a message to say if the player won, drew, or lost the game.

import random
# Get computer choice.
comp_choice = random.randint(1,3)
# Get player choice.
input_str = input ("1 rock, 2 paper, 3 scissors? ")
player_choice = int(input_str)
# Show player choice.
if player_choice == 1:
    print("rock", end=" ")
elif player_choice == 2:
    print("paper", end=" ")
else:
    print("scissors", end=" ")
# Show computer choice.
if comp_choice == 1:
    print("vs rock")
elif comp_choice == 2:
    print("vs paper")
else:
    print("vs scissors")
# Determine who won.
if player_choice == comp_choice:
    print("A draw.")
elif player_choice == 1 and comp_choice == 3:
    print("Rock blunts scissors. You win!")
elif player_choice == 2 and comp_choice == 1:
    print("Paper wraps rock. You win!")
elif player_choice == 3 and comp_choice == 2:
    print("Scissors cut paper. You win!")
else:
    print("You lose :(")

end