1 | Getting Started: Your First Programming Project


Programming is a means of communication between us and the computer. It is primarily one-way communication: we tell the computer what to do. The computer only responds when it doesn’t understand something.

Unlike when communicating with other humans, when communicating with a computer, we always need to remember that we are talking to a non-intelligent entity that needs to be told everything step-by-step in a clear and unambiguous way. We cannot take anything for granted.

Programming is a mindset, a way of thinking that is different from our natural human thought process. Often you hear beginners say that they are learning a programming language. However, the first thing to learn is programming. The language is needed, but it is not the most important thing we need to know.

What is Programming and Why Do We Need It?

You’re at home one late afternoon and your spouse calls out to you:

Dinner will be ready in 20 minutes. Can you get the tomatoes ready, please?

What you’ll do next depends on the recipe. It may involve rinsing the tomatoes underneath the tap in the kitchen sink, chop them finely and season them with salt, pepper and some olive oil, perhaps.

Now imagine your spouse called out with the following very similar phrase:

Dinner will be ready in 20 minutes. Can you get the children ready, please?

It would be best if you did not rinse the children under the sink or sprinkle them with salt and pepper. Probably you’ll make sure they clear up and wash their hands, say.

Grammatically, the sentences above are identical. All we’ve done is to replace the plural noun tomatoes with another plural noun, children. Humans rely on context when communicating with other humans. Our experiences tell us that getting the tomatoes ready is a very different task from getting the children ready.

Computers cannot do this.

When we communicate with a computer, we need to be very clear, specific and unambiguous. Understanding this critical point is the first and essential step towards understanding computer programming.

Let’s look at another example. Read the following phrase:

say Happy Birthday

And now consider the following:

my name is Stephen

say my name

These simple phrases are easy for us humans to understand and respond to. Two important aspects make this possible.

Firstly, we recognise the word say as the command we are asked to do. Secondly, as you’ve seen above, we understand the context of the phrase, which is why we would react differently to the two phrases.

In the first one, we separate the three words into the action say and the information we are being asked to say: Happy Birthday.

A computer needs to know what the command is. In Python, we would use the built-in function print() for the example above. This is one of the basic Python words, and it is followed by parentheses (). The parentheses, or brackets, and the fact that print is written in lowercase indicate that this is a function.

Think of a function as the equivalent of a verb. It represents an action that needs to be done. The context is not enough, as it is for us humans reading say Happy Birthday.

Now let us look at the difference between say Happy Birthday and say my name. The structure of these phrases is very similar but, unless someone is being deliberately funny, the answer to the second instruction will be Stephen, and not the words my name. Again, we humans understand the context easily, but a computer needs help to distinguish between the two.

In Python, you can represent the first phrase above with the line of code:

print("Happy Birthday")

You can write the second pair of phrases as:

my_name = "Stephen"
print(my_name)

The speech marks tell the computer that whatever is inside them is just a string of characters that has no meaning for the computer but that a human will be able to understand. We call this type of information a string in programming, short for a string of characters.

In the second example, you’re first asking Python to create something you called my_name and to store the string "Stephen" within it. Next, you ask the computer to print out whatever is stored in my_name. This storage box you called my_name is what’s referred to as a variable in Python. You’ll find out more about assigning data to variable names in the following sections.

Python will respond in a different way to print(my_name) compared to print("my_name").

To write programs that a computer can understand, you need to think in a similar way to how the computer operates. It’s helpful to think of the computer as a stupid device that requires you to be very clear in what you say, without taking anything for granted.

Running Your First Python Program

There are many ways to run a Python program. If you already have run Python programs before, you can move straight on to the next section.

In the Preface, you downloaded and installed PyCharm Community Edition, the IDE I recommend, unless you already have a favourite.

Once you’ve opened a project, you can open a new Python File, and you’re ready to start writing code. Make sure you choose the Python File option and not just the first option in the list that says File. You should see the extension .py added to the filename you choose. This is displayed in the name of the tab at the top of the editor window.

When you want to run your program, you can choose Run… from the Run menu and then select the name of your file from the list that comes up. When you’ve run the program once, you can simply click the play button (green arrow) whenever you need to run the program. You may also want to learn the keyboard shortcut to run your program, as you’ll need to run your programs often while coding.

The output of your code will show in the bottom window on your PyCharm screen. If there’s an error in your code, then instead of the output, you’ll see error messages in red. You’ll read more about how to deal with errors later on in this book.

Your First Project: The Angry Goblin Hunt

The fundamentals of programming are pretty much the same whether you are writing a game or analysing scientific data. In this book, you’ll find a diverse set of projects and applications which will give you a broad understanding of the tools and concepts in programming and how to use them effectively.

It’s time to start working on your first proper Python program: The Angry Goblin Hunt game. In this project, you’ll learn about some of the fundamental concepts and tools in programming and how to put things together to make up a fully functioning program. This first project aims to introduce several key topics, and we’ll take a few detours along the way to discuss these new topics as we write this program together.

The game is simple. However, the programming needed to write the game will set the scene for every program you will write in the future.

The best way to introduce the game is to show you the output from the program:

Welcome to the Angry Goblin Hunt
An award-winning game full of adventure and excitement (!)

Type in your name: Stephen

Stephen, do you think you can find the goblin hiding in the kitchen cupboards?
|_||_||_||_||_|

Which cupboard do you think the goblin is in [type in number]: 2
Sorry! The goblin is still lurking somewhere else.

Which cupboard do you think the goblin is in [type in number]: 4
Sorry! The goblin is still lurking somewhere else.

Which cupboard do you think the goblin is in [type in number]: 3
Sorry! The goblin is still lurking somewhere else.

Which cupboard do you think the goblin is in [type in number]: 1
Well done!! You have found the goblin. He was so scared he ran away.

Here’s a summary:

  • Show a welcome message.
  • Ask the player for their name, and once they type in their name present the next part of the welcome message.
  • Show a "graphical" representation of the kitchen cupboards (yes, we’re keeping it very, very simple here!)
  • Ask the player to guess where the goblin is hiding by typing in the number of the cupboard.
  • If the guess is incorrect, display a message and ask again.
  • If the guess is correct, display a winning message and end the game.

Breaking down your project into steps such as the ones above is an essential first step when writing any computer program. You’ll look at this in more detail later on.

Basic Input and Output in Programming

Two of the most basic functions in Python are print() and input(). They’re not the most exciting of functions, but they’re very useful.

The print() function is relatively straightforward to use. You have already seen it used earlier on. It allows the programmer, or more specifically the computer program, to communicate with the user by displaying some information on the screen. This is the information the programmer puts within the parentheses ().

The input() function requires a slightly more extended discussion. Let’s look at functions in more detail to explain what’s happening with input().

Functions

You can think of functions as the verbs of a programming language. They perform an action. Sometimes we can input data required by the function by putting the information within the parentheses (), as with print(). Not all functions need additional information to be placed within the parentheses, but even in these cases, you still need the empty pair of brackets for a function to run. The () tell Python to do the command now.

Functions can also return some data back to the program. The input() function does just this. It asks the user of the program to type something and returns that information as a string. For this reason, if we want to use the information that has been typed in by the user later on in the program, we need to store it using a name:

name_of_pet = input("What is the name of your pet? ")

You have created a variable that you called name_of_pet and stored whatever comes back from the input() function using that name. A useful analogy you can think of to understand what the = sign is doing is the following:

  • Ask the computer program to bring an empty storage box.
  • Stick a label with the name name_of_pet on the outside of the box.
  • Put whatever string comes back from input() into the box so that you can retrieve it later.

This is called assignment of data to a variable name. From this point onwards, whenever you need to access the name of the user’s pet, you can refer to it by the label name_of_pet.

Note that input() also performs the same operation as print() and displays whatever is in the parentheses to the user, in addition to returning the input typed in by the user. You can think of print() as a one-way form of communication, from program to user. You can achieve two-way communication using input() in which the program communicates to the user, and the user can also communicate back to the program by typing and then pressing the Enter/Return key.

What would happen if you had only written the following line of code?

input("What is the name of your pet? ")

The function input() would still have run since it’s followed by (). However, the data returned by the function has nowhere to go. You haven’t asked the computer program to bring a storage box, label the box, and store the information that’s returned by input() in the box. In this case, the information the user types will be lost, as there is no way of retrieving it and using it later on in the program.

Notation: Functions need to be followed by parentheses () for the program to execute them. The computer needs to know whether we are just referring to the function’s name or whether we want it to be executed.

The equivalent distinction in human to human communication is inferred from the context. If I ask someone: "Do you know how to run?" they are likely to answer yes, but will not start running when they hear the word run in that sentence. On the other hand, if we’re late to catch a train and I say "Run", the implication is that we actually need to run. The latter would need () in Python. The former does not.

You may be wondering why we would ever need to use the name of a function without putting brackets after it, as the program will not execute this function. For the time being, it is unlikely you’ll ever need to use a function without the brackets immediately after. But as you learn more about functions later on, you’ll see how there are times when we only want to refer to a function without running it.

Function names are usually always written in lowercase, and if the name of the function consists of more than one word, these are usually linked using the underscore _ character, as in do_something_now().

Angry Goblin: Getting Started

You can now start working on the Angry Goblin game. If you haven’t done so already, you can open a new Python file and try the code yourself as you go along over the following sections. Feel free to experiment.

The first step is to show a welcome message, then ask the user to type in their name, and then to display the second part of the welcome message:

print("Welcome to the Angry Goblin Hunt")
print("An award-winning game full of adventure and excitement (!)")
 
player_name = input("What is your name? ")
print(player_name + ", can you find the goblin?")

print("|_||_||_||_||_|")

There aren’t too many surprises in the first two lines. You’re asking the computer to display the strings of characters within the speech marks "". You can write anything you like within the speech marks. The terminology often used is that you’re passing a string as an argument to the function print().

The next line is one you’ve seen already and uses the input() function. You’re passing a string with the prompt you want the user to read. The program will then wait for the user to type in something and press the Enter/Return key. Whatever the user has typed will be stored as a string in the variable player_name.

You can choose any name you want for variables. However, it is always best to choose something that describes the information that the variable is storing. This makes it easier to read and understand the code. Making code readable for humans is an important aspect of writing good code.

When choosing variable names, you should always use lowercase letters and separate words using the underscore _ symbol. Python will not force you to do this, but it’s the convention when naming variables in Python, so better stick with the norm. The underscore is the only symbol you can use when naming things in Python. This includes spaces that cannot be used as part of a name. In addition to letters, you can also use numbers as part of a name, but the name cannot start with a number.

The last two lines in the code above are two more uses of the print() function. The last one is similar to how we have used print() earlier. This line displays the kitchen cupboards in a very simplified way: |_||_||_||_||_|.

This leaves the line that says:

print(player_name + ", can you find the goblin?")

The argument you are passing to the print() function has two parts, connected with a + sign. The variable player_name refers to a string with the name of the player. This string is added to the string that shows the rest of the sentence. We call this string concatenation. There are other ways we can connect and format strings which you’ll learn about in later chapters. This is the simplest one to use in this case.

In the game, the next step is to ask the player to guess where the goblin is. But there is another important step that’s hidden from the user. How does your computer program know where the goblin is?

You need to tell the program where the goblin is hiding. This information needs to be stored within the program to be retrieved later on when it’s needed. You’ve already seen how to store information in a computer program by creating a ‘storage box’ and putting a label on the box:

goblin_position = 3

Later, you’ll make this a bit more interesting by placing the goblin in a different position each time the program runs to make the game less predictable. But for now, the goblin will always be in the third cupboard.

Next, the computer program needs to ask the player to guess where the goblin is. You need two-way communication to do this in which the program displays a prompt to the user, and the user can type in their guess. Try the following:

input("Can you guess where the goblin is hiding? ")

Can you spot a problem with this line of code?

The code is perfectly valid Python. However, the information returned by the input() function is not being stored anywhere. The data returned is short-lived. The moment the program moves on to the next line, it will discard the information that came back from input().

You can fix this by creating and labelling a storage box. The technical jargon for this is to assign the data to a variable:

guessed_position = input("Can you guess where the goblin is hiding? ")

You can now retrieve the user input at any time in the program by using the variable name guessed_position.

Angry Goblin: Deciding What To Do Next

What’s next? Well, it depends? What happens next depends on whether the player has guessed the location of the goblin correctly or not.

There’s a decision to be made, but this is not a decision that you, the programmer, can make. You need the computer program to decide. Getting a computer program to make decisions while it is running is one of the key tasks you’ll need your programs to do very often. The program needs to decide what actions to take depending on other things happening in the program.

Let’s look at the if statement in Python before you can go ahead with the Angry Goblin game.

if Statement

Read the following sentence:

If it’s raining, take an umbrella, and don’t forget your wallet.

What would you do if it’s a sunny day? Would you leave your wallet at home? Probably not. The context in the sentence above is clear enough for most humans to understand. The situation would be different if the sentence were:

If it’s raining, take an umbrella, and don’t forget your raincoat.

In this case, it seems to make sense that taking an umbrella and a raincoat are both conditional to whether it’s raining or not. And here’s one last sentence:

If it’s raining, take an umbrella and a raincoat, and don’t forget your wallet.

However, when communicating with a computer, we need to be very clear as computers don’t understand the context in the same way humans do. There’s no place for ambiguity when writing a computer program.

In Python, as in English, we can use the word if when we need to decide how to proceed. To be more specific, we use if when we need the computer program to decide for us. This is called a conditional statement.

You can start a new Python file if you want to explore the code in this section before returning to the Angry Goblin game. In PyCharm, remember to choose New… from the File menu and then choose Python file (not the option that just says File). When you open a new file, you’ll need to select the new file from the Run… menu the first time you want to run it. After the first run, you can use the green play button or use the keyboard shortcut.

is_monday = True

if is_monday:
  print("Have a great week")

True and False are important keywords in Python. An if needs to be followed by something which is either True or False (or more precisely, something that Python can interpret as either True or False, but don’t worry about this subtle distinction for now.) This is how the computer program decides whether to print out the text ‘Have a great week’. We’ll discuss why the last line starts with a tab shortly.

Let’s rewrite the code above in a slightly different format:

day = "Monday"

if day == "Monday":
  print("Have a great week")

You have created a variable named day, and you assigned the string "Monday" to it. On the line that starts with the if keyword, there is a statement that you may think has a typo in it. However, the double equals == is a valid Python operator which has a very different role to the single equals = operator.

You’ve seen that the = sign is used to assign data to a variable. You’re asking the computer program to bring an empty storage box, put a label on it and store whatever information follows the = sign in the storage box.

The == sign, however, asks your computer program a question: are the two bits of information on either side of the == sign the same? In this case, you’re asking the computer to tell you whether the data stored in the variable day is the same as the string "Monday". The answer to this question will be either True or False, as required by the if statement. The program can therefore make a decision based on the answer to the == question.

In this case, day and "Monday" are identical. Therefore the program will execute the print() function. You’ll find out about the other punctuation mark in this code and the extra tab very soon.

You can now extend the code above as follows:

day = "Monday"

if day == "Monday":
  print("Have a great week")
else:
  print("It's almost the weekend")

Only one of the two print() functions can run. You’re asking the computer program to make a decision and then to go along one of two possible paths, depending on what it has decided. In this case, since day is "Monday", the printout will be ‘Have a great week’ and the line following else will not run. Try and change the value of day to make sure the program makes the right decision every time.

You can go a step further:

day = "Monday"

if day == "Monday":
  print("Have a great week")
elif day == "Tuesday":
  print("Hang on in there!")
elif day == "Wednesday":
  print("You're half way through the week")
else:
  print("It's almost the weekend!")

The keyword elif stands for else if, and it allows you to create additional conditions that will be considered if the previous ones were False. There are now four possible outcomes to this block of code. The code can split into four paths, and the computer program will decide which path to take depending on the conditions. The conditions are evaluated in the order they were written, starting with the one following if and then those following the elif keywords. When the first True condition is met, that path is executed and the rest of the elif and else blocks are ignored.

Syntax: By now, you would have noticed that programming requires you to be precise with the syntax—the grammar and punctuation. Each of the lines that start with if, elif, or else have a colon : at the end of the line. The lines that follow have an indent. If a condition is met (which means a True statement follows the if or elif keywords), the lines immediately after the condition that are indented will be executed.

In the English statements about rain, umbrellas, coats, and wallets at the start of this section, the context was sufficient for humans to understand what is conditional to whether it’s raining and what isn’t. In Python, the indent is what determines what should happen if a condition is met. The indentation removes any ambiguity. Try to run the following two code snippets, one at a time:

day = "Tuesday"

if day == "Monday":
  print("Have a great week")
  print("Get back to work now")

The second variant is the following:

day = "Tuesday"

if day == "Monday":
  print("Have a great week")
print("Get back to work now")

Did you spot the difference? In the first version, both print() functions are part of the conditional block. The program will execute both of them if the condition is True, and neither will run if the condition is False.

In the second version, there is only a small difference compared to the first. The last line doesn’t have an indent. This means it’s not part of the conditional block. Only the line that prints ‘Have a great week’ is conditional on whether the day is "Monday". ‘Get back to work now’ will always be displayed in this case, whatever day of the week it is.

If you wanted to replicate the statements at the beginning of this section in Python code, you could write:

is_raining = True

if is_raining:
  print("Don't forget the umbrella")
  print("And don't forget the raincoat")
print("Don't forget your wallet")

You’re now ready to return to the Angry Goblin game.

Angry Goblin: Did I Win?

Now you know how to get your computer program to make a decision while it’s running. So far, you’ve asked the player to guess the goblin’s position, and you’ve placed the goblin in one of the kitchen cupboards—it’s cupboard number 3, but shhh, don’t tell anyone!

You can now ask the computer program to decide whether the player has guessed correctly. Here’s the code so far, with a few additional lines:

print("Welcome to the Angry Goblin Hunt")
print("An award-winning game full of adventure and excitement (!)")
 
player_name = input("What is your name? ")
print(player_name + ", can you find the goblin?")

print("|_||_||_||_||_|")

goblin_position = 3

guessed_position = input("Can you guess where the goblin is hiding? ")

if guessed_position == goblin_position:
  print("Well done. You've found the goblin.")
else:
  print("No, sorry. The goblin is still hiding somewhere.")

An important part of programming is to make sure you test your program at each stage and test all possible outcomes of your code whenever possible. By checking your code often, you’ll be able to spot if things go wrong early on.

Try running this code. When you run the program, you should make sure you test both paths. So try getting the answer right—for now, you know that the goblin is in cupboard 3—but also try to see what happens when you get the answer wrong.

Try it out before reading on.

Did it work?

No? Don’t worry, you haven’t done anything wrong. We have a bug in our program. A bug is an unexpected outcome. The computer program gives an output, but it’s not the output you expected.

You’ll read a lot more about errors and bugs in a later chapter. In this introductory project, we’ll use this bug to discuss another important topic in programming: data types.

Programming in the Python Console

We’ll take a short diversion from our game to introduce a tool we’ll need as we code. You’ll often write your Python code in a file that you can run. You’ve been doing this so far when you’ve opened a Python file and ran the file. This file is often referred to as a script.

However, there are times when you’ll want to run lines of code one line at a time and see the output of that line straight away, rather than having to run all the code.

In these instances, you can use the Python Console. Sometimes the Console can also be referred to as a shell. If you’re using PyCharm as your IDE, you’ll see a tab at the bottom of the screen that says Python Console, or you can browse through the View / Tool Windows menu. This will open up a window at the bottom of your screen. You know you’re in the Python Console as each line starts with the triple chevron prompt >>> (unless you’ve enabled IPython in preferences, but I’ll assume you haven’t changed any of the settings in PyCharm!)

The main difference between the Console and running a script is that each time you hit the Enter/Return key in the Console, the code in that line will be executed. Another difference is that if that line of code has some output to display, this will be displayed automatically. You don’t need to use the print() function to show the output.

For example:

>>> a_number = 12
>>> a_number
12

You assigned the number 12 to the variable a_number. When you wrote a_number on a separate line, the Console displayed the contents of the storage box a_number. If you were using a script, you would need to explicitly print the variable’s value using print(a_number).

In the rest of this book, whenever you see the triple chevron prompt >>> in a code block, you can assume that this is running in the Python Console. Otherwise, you can assume all code is in a script.

Data Types

Let me start by demonstrating why data types are important before discussing what they are.

Try running the following code in the Python Console. The asterisk * stands for multiplication in Python:

>>> a_number = input("What's your favourite number: ")
What's your favourite number?  >?  12
>>> a_number * 2
'1212'

Not quite what you expected? Who would have thought Python can’t even multiply a number by 2?

Before digging a bit deeper and restoring Python’s reputation to show it knows its times tables, let’s look at the following two variables and the data they contain.

>>> my_name = "Stephen"
>>> some_number = 12

Python recognises that the information stored in these two variables is different. However, it also recognises that it’s of a different type. The first is a string of characters, or simply a string. The second variable contains a number, and more specifically, a whole number, or integer. You can ask Python to confirm what type of data is stored in a variable:

>>> type(my_name)
<class 'str'>

>>> type(some_number)
<class 'int'>

Python refers to strings as str, and integers are represented by the term int. These are data types.

Try multiplying the data in both of these variables by 2 and see what happens:

>>> some_number * 2
24

Your faith in Python has been restored. It can multiply!

>>> my_name * 2
'StephenStephen'

The same multiplication operator * was used, but it behaves differently in the two examples shown above. Python recognises my_name as a str, so it uses a different rule to multiply.

A program may need to ask the user for a word or a sentence. On other occasions, the user will need to input a number. The input() function you’ve used earlier has no way of knowing what the programmer is asking the user for. For this reason, input() always returns a str. When you typed in the number 12 when prompted by the input() function, this information was not stored as the number 12 but as the characters '1' and '2' next to each other. This is why when we multiplied by 2, Python returned the string '1212'.

In these instances, you can use Python’s built-in functions to convert between data types:

>>> a_number = input("What's your favourite number? ")
What's your favourite number?  >?  12
>>> a_number = int(a_number)
>>> a_number * 2
24

Let’s have a look at a few other basic data types in Python:

>>> another_number = 2.5
>>> type(another_number)
<class 'float'>

>>> is_sunny = False
>>> type(is_sunny)
<class 'bool'>

A float is a non-integer number. Python needs more memory to store a float than an int. Therefore, when only an integer is needed, storing it as an int saves memory. Note that Python will store 3.0 as a float and 3 as an int. You don’t need to worry about the difference between int and float for the time being. You can simply think of both data types as a type of number for now.

A bool is a Boolean data type. Booleans can take only one of two values, either True or False. You’ll often need to store this type of information in a program.

You may hear Python described as a dynamically typed language. This means that when you assign data to a variable using the = sign, Python will look at the information on the right-hand side of the = and it will decide what data type this looks like. If it’s a number without a decimal point, Python will store the number as an int. If the number has a decimal point, then it’s stored as float. Text that’s in quotation marks is interpreted as a str. In Python, you can use either single or double quotation marks to represent strings:

>>> word_1 = "hello"
>>> word_2 = 'hello'

There is no difference between the data stored in the two variables. Both variables store a str. You can even use triple quotes if you want! Although best stick to single or double quotes.

Binary Operators Which Return Boolean Data

A number of operators in Python ask a question that has a True or False answer. You’ve already encountered one of these:

>>> a_number = 5
>>> another_number = 10

>>> a_number == another_number
False

>>> a_number == 5
True

The line a_number = 5 is an assignment. You’re asking Python to assign the int 5 to the variable a_number. The line a_number == 5 is a comparison statement. It’s asking whether the data in a_number is the same as the number 5.

Here are some other operators:

>>> 2 > 20
False

Is 2 greater than 20? Python responds with False.

>>> another_number != 10
False

Is another_number not equal to 10? Response is False.

>>> 5 >= 5
True

Is 5 greater than or equal to 5? Yes.

>>> "e" in "Stephen"
True

>>> "x" in "Stephen"
False

Is the str "e" to be found in the str "Stephen"? How about "x"?

Angry Goblin: Let’s Make The Game A Bit Harder

You can now fix the bug in the Angry Goblin game. Here’s the code so far with a small addition just before the if statement to change the data in guessed_position from a str to an int. New and modified lines will be shown as highlighted in code blocks, when required:

print("Welcome to the Angry Goblin Hunt")
print("An award-winning game full of adventure and excitement (!)")

player_name = input("What is your name? ")
print(player_name + ", can you find the goblin?")

print("|_||_||_||_||_|")

goblin_position = 3

guessed_position = input("Can you guess where the goblin is hiding? ")
guessed_position = int(guessed_position)

if guessed_position == goblin_position:
  print("Well done. You've found the goblin.")
else:
  print("No, sorry. The goblin is still hiding somewhere.")

Try running the program now to make sure that you do get a different outcome if you input 3 or any other number when running the game.

There is a problem with this game. The player will soon figure out that the goblin is always hiding in the third cupboard. Let’s work on making this game a bit more challenging to play. You can ask the computer program to choose a random number to assign to the variable goblin_position.

Python, like many other languages, has plenty of built-in functionality. However, not all of these functions are immediately available when writing a computer program. You’ll need to first bring them into the program before you can use them.

Importing Modules

Picture a library. Think of one of those large libraries with high ceilings and books covering every bit of the walls, from floor to ceiling. Each book in this library has a theme, and the books are full of commands. If you want to use any of the commands within a book in your program, you will first need to check out the book you need from the library and bring it to your program.

You can do this in Python using the import keyword. In the Angry Goblin game, you’ll need a book called random. This book contains functions dealing with, you guessed it, randomness. The books I’m referring to in this library analogy are called modules.

Let’s briefly experiment with how to use this module in a Console session before you can make changes to the Angry Goblin game:

>>> import random
>>> random.randint(1, 10)
7

The import statement brings the random book from the library into your program. In this case, you’re importing the module into a Console session. Whenever you need to use any of the functions within this module, you’ll need to refer to the name of the module followed by a full stop (or period) and then the name of the function you need. This dot notation is one you’ll see a lot of in Python.

You’re using a function called randint(), which stands for random integer, or random whole number. As you’ve seen with functions earlier, the function name is followed by parentheses. However, this function needs two bits of information in the parentheses. The randint() function needs the start and end of the range from which it will pick a random number. In the above instance, the function returned the number 7. Every time the function runs, it will return a random number from within the range 1-10.

You can now use this function in the Angry Goblin game. There are two changes to make. The first is to import the random module. By convention, import statements are always placed at the top of a program. You’ll then need to change the assignment to goblin_position so that a random integer is assigned to this variable:

import random

print("Welcome to the Angry Goblin Hunt")
print("An award-winning game full of adventure and excitement (!)")

player_name = input("What is your name? ")
print(player_name + ", can you find the goblin?")

print("|_||_||_||_||_|")

goblin_position = random.randint(1, 5)

guessed_position = input("Can you guess where the goblin is hiding? ")
guessed_position = int(guessed_position)

if guessed_position == goblin_position:
  print("Well done. You've found the goblin.")
else:
  print("No, sorry. The goblin is still hiding somewhere.")

When you run the program now, you don’t know where the goblin is hiding anymore as it’s the computer program that has chosen where to hide the goblin.

Angry Goblin: Going On Until The Game Ends

When you run the program to play the game, you’ll only get one try at guessing where the goblin is hiding. You’ll now need to change the program so that the player is given more attempts to guess, and the game will end when the player guesses the position of the goblin.

The first decision you’ll need to make is which lines need to be repeated:

  • The game’s welcome messages and asking the player to input their name does not need repeating.
  • Asking the computer to choose a random position for the goblin also only needs to happen once.
  • However, the program needs to ask the player to guess where the goblin is more than once and convert this input from str to int.
  • The code that decides whether the guess is correct or not and prints the appropriate message must also happen several times.

Once you’ve identified the lines that need repeating, you’ll need to ask your computer program to repeat these lines. When a block of code is repeated several times, we call this a loop.

Repeating Code: while Loop

There’s more than one way of creating loops in Python, but for this task, you’ll look at the while loop.

Let’s start by making changes to the code:

import random

print("Welcome to the Angry Goblin Hunt")
print("An award-winning game full of adventure and excitement (!)")

player_name = input("What is your name? ")
print(player_name + ", can you find the goblin?")

print("|_||_||_||_||_|")

goblin_position = random.randint(1, 5)

while True:
  guessed_position = input("Can you guess where the goblin is hiding? ")
  guessed_position = int(guessed_position)

  if guessed_position == goblin_position:
    print("Well done. You've found the goblin.")
  else:
    print("No, sorry. The goblin is still hiding somewhere.")

There are two changes you’ve made to this code:

  • You’ve added the while True: line just before the block of code that needs to be repeated.
  • You’ve added an indent at the start of each line in the block of code that needs repeating. Note that this means that some lines now have a double indent, one showing they’re a part of the while loop and another showing they’re part of the conditional block following the if or the else.

Top tip: In most programming environments such as PyCharm, if you select a block of code and press the Tab key, an indent will be added to each line in the block of code, thus indenting the whole block at once. Shift-Tab will remove the indentation.

The while keyword needs to be followed by a statement the program can interpret as either True or False. When a True statement follows while, the indented block of code following the while will be executed. At the end of this block of code, the program goes back up to the while statement and checks whether this is still followed by a True statement.

In this case, you just put in the bool value True directly after the while keyword. This means that whenever the code returns back to the while statement, it will always find it to be True. This is an infinite loop. You’ll change this later to make sure it doesn’t go on forever.

When you learned about the if statement earlier, you found out about expressions in Python that give a True or False response. The == and > are examples of such operators. These can be used to follow the while keyword.

Your next step is to change this from an infinite loop to a loop that keeps repeating until the player guesses correctly. Try making the following changes to the code:

import random

print("Welcome to the Angry Goblin Hunt")
print("An award-winning game full of adventure and excitement (!)")

player_name = input("What is your name? ")
print(player_name + ", can you find the goblin?")

print("|_||_||_||_||_|")

goblin_position = random.randint(1, 5)

keep_trying = True

while keep_trying:
  guessed_position = input("Can you guess where the goblin is hiding? ")
  guessed_position = int(guessed_position)

  if guessed_position == goblin_position:
    print("Well done. You've found the goblin.")
    keep_trying = False
  else:
    print("No, sorry. The goblin is still hiding somewhere.")

print("Thank you for playing. Now get back to work!")

You’ve created a new variable keep_trying and assigned the bool value True to it. You then used this variable in the while statement. This seems like an unnecessary step since keep_trying is the same as the value True. However, since you’re now using a variable to determine whether the while statement is True or False, you can change what’s inside this box. The final change you’ve made to the code above is to change keep_trying to store the value False once the player guesses correctly.

Let’s walk through the logic of the code above. Just before the while loop starts, the variable keep_trying is True. This means that the first time the while statement is executed, the block of code within the loop will run. As long as the player doesn’t guess correctly, the line that changes the value of keep_trying never runs. So each time the code goes back to the while statement, keep_trying will still be True, and the block of code will keep repeating itself. When the player guesses correctly, keep_trying changes to False. When the code goes back to the while statement, this will now evaluate as False. The block of code will no longer run.

The last line is also a line you’ve just added. Note that this line has no indentation, and therefore it is not part of the while loop. This line will only run once the while loop has finished repeating. In this case, this line will be displayed just before the program ends.

Angry Goblin: Finishing Touches

You’re almost there. There’s a couple of small but important changes you need to make to your code to finish it off.

Let’s look back at the following line which you used to display the high-tech graphics (!) showing the cupboard doors:

print("|_||_||_||_||_|")

One of the things programmers don’t like is to have to repeat themselves. You had to repeat the same characters five times within the speech marks. You’ve already seen a way of repeating a string several times:

print("|_|" * 5)

What if you want to make the game harder and run the game with more doors, say? You can change the 5 to 8 in the line above, but you’ll also need to make another change in the code. The number 5 is used as one of the arguments in random.randint(). Therefore you’ll need to make the change in two places each time you wish to change the number of doors. This may not seem like too much work, but it’s a dangerous practice. What if you’re using the value many times in a longer program and forget to change one of the values?

When you write a program, it is best to avoid hard-wiring values in the code, such as the number 5 in the example above. The solution is to create a variable that stores the number 5 within it and then use the variable name wherever you need to use the value 5 in the code to represent the number of doors. Here’s the final code:

import random

number_of_doors = 5

print("Welcome to the Angry Goblin Hunt")
print("An award-winning game full of adventure and excitement (!)")

player_name = input("What is your name? ")
print(player_name + ", can you find the goblin?")

print("|_|" * number_of_doors)

goblin_position = random.randint(1, number_of_doors)

keep_trying = True

while keep_trying:
  guessed_position = input("Can you guess where the goblin is hiding? ")
  guessed_position = int(guessed_position)

  if guessed_position == goblin_position:
    print("Well done. You've found the goblin.")
    keep_trying = False
  else:
    print("No, sorry. The goblin is still hiding somewhere.")

print("Thank you for playing. Now get back to work!")

And you’ve completed the game. You can customise the game further and make some additions if you wish.

Comments and Writing Readable Code

While writing this code, you may have wondered why there are some blank lines in the code from time to time. These blank lines are not part of Python’s syntax. You can leave out all the blank lines, and the code will run just fine.

However, you’ll want to make your code as neat and readable as possible. Writing code that’s neat and readable benefits you and others who may read your code. While writing a program, your thought processes will be fresh in your mind. You’ll remember the reason why you wrote a particular line of code when you revisit that line a few hours later.

However, if you return to your code several weeks later, it is likely that your own code will not look as familiar to you as you when you wrote it. When writing code, there are several practices you can adopt to make your code more readable.

Separating your code into blocks makes the code easier to read and follow. This action is similar to starting a new paragraph when writing. You can go a step further by adding comments to your code. A comment is a short phrase or sentence that the computer program ignores. A comment is meant only for the humans reading the code. In Python, you can use the hash symbol # to create a comment. The # symbol is also referred to as the pound symbol or octothorpe, although the latter name is rarely used.

Anything that follows the # on a specific line is ignored when the program runs. You’ll often see the # symbol at the start of a line to show that the entire line is a comment. But you can also add a comment at the end of a valid line of code:

# This is a comment. When you run the program,
# these lines will be ignored.
# You can write anything you want in a comment.

import random

number = random.randint(1, 5)  # Chooses a random number between 1 and 5
# number = random.randint(-5, 5)

You can use comments to:

  • Write a description of your program or a section of your program
  • Label sections of your code
  • Add an explanation for a tricky line of code
  • Temporarily remove one or more lines of code from the program but without deleting the code

Writing comments in your code is a habit you’ll get into with practice, especially when your code becomes longer and more complex. How much commenting you should do is a question that doesn’t have an easy answer. In part, it depends on a programmer’s coding style. Some programmers comment more than others, and you’ll settle into your own style with time. You can add a few comments to your Angry Goblin game to make it easier for another person to read and understand the code:

import random

number_of_doors = 5

# Display welcome messages
print("Welcome to the Angry Goblin Hunt")
print("An award-winning game full of adventure and excitement (!)")

# Get player name
player_name = input("What is your name? ")
print(player_name + ", can you find the goblin?")

print("|_|" * number_of_doors)

goblin_position = random.randint(1, number_of_doors)

keep_trying = True

# Main game loop
while keep_trying:
  guessed_position = input("Can you guess where the goblin is hiding? ")
  guessed_position = int(guessed_position)

  if guessed_position == goblin_position:  # If player guesses correctly
    print("Well done. You've found the goblin.")
    keep_trying = False
  else:  # If player's guess is incorrect
    print("No, sorry. The goblin is still hiding somewhere.")
    
print("Thank you for playing. Now get back to work!")

However, there are other practices you can and should use to make your code readable. It’s preferable to make your actual Python code more readable instead of requiring a comment whenever possible. Let’s look at an example from the program you’ve just completed:

gp = random.randint(1, 5)  # This variable represents the goblin's position

The variable name chosen in this line is gp. When writing the code, you would have been aware that you chose those letters to stand for goblin’s position. However, it’s not obvious that this is what these letters stand for. So you wrote an in-line comment to explain to anyone reading the code what this variable is.

However, if you re-write the line in a different way, the comment won’t be needed:

goblin_position = random.randint(1, 5)

By choosing a longer name that fully describes the information stored in the variable, you’ve made the comment unnecessary. The variable name is self-explanatory. Decades ago, it was common for variable names to be short to speed up typing. In modern programming, IDEs such as PyCharm have auto-completion functionality, so there is no penalty for writing longer names. It’s considered a best practice in modern programming to choose descriptive names.

Conclusion

Congratulations! You’ve completed your first project. In this Chapter, you’ve covered:

  • How to run a Python program
  • How to store data in variables
  • How to use functions, including print() and input()
  • How to recognise different data types, including int, float, str and bool
  • How to use the if statement to get the program to make a decision on how to proceed
  • How to import modules such as random, and use functions within those modules, such as randint()
  • How to repeat a block of code using the while loop

In the next Chapter, you’ll go a bit deeper into many of the concepts you’ve learned about. You’ll also look at new data types and new programming tools and methods, including defining your own functions.


Glossary

Function A function is a self-contained unit that carries out a certain function, hence the name. Functions are equivalent to verbs in human languages. Functions in Python are written in lowercase letters and they are followed by parentheses.
Calling a function A function is called when the function name is written followed by parentheses. These brackets may be empty or may have information within them. When a function is called, the computer program jumps to where the function is defined and executes the code within the function.
String A string (str) is a type of data that contains characters. These characters could be letters, numbers, punctuation marks, or whitespace. Strings are enclosed in single, double, or even triple quotes.
Variable A variable is a storage box that stores some information that will be needed in the program. The variable name is the label of the box which you can use to refer to this storage box in your code. One way of creating a variable is through assignment, using the = operator.
Assignment of data Data is assigned to a variable using the equals operator. The data is stored in a variable and the variable is given a name.
Conditional statement A conditional statement checks if a certain condition is true and it will only execute some code if the condition is true.
Indent The tab at the start of some lines of code that are needed to group certain lines of code together into a block.
Data types Information is stored in different forms depending on the type of data. Common data types include integers, floats, Booleans, and strings.
Integer An integer (int) is a type of data that stores whole numbers.
Float A float (float) is a type of data that stores numbers which do not need to be whole numbers.
Boolean A Boolean (bool) is a type of data that stores one of two values, True or False.
Module A module is a file that contains Python code that has the extension .py. The term is usually used when importing existing code from another file or module, but technically every Python file is a module.
Loop A loop is a block of code that will repeat several times. The number of times the block of code will repeat will depend on the type of loop that you use.
Comment A comment is text written within a Python file that is not part of the program and that will be ignored by the computer program. It’s usually text that follows the # symbol.


Sign-Up For Updates

This site was launched in May 2021. I’ll be adding chapters regularly over the coming weeks and months.

Sign-up for updates and you’ll also join the Codetoday Forum where you can ask me questions as you go through this journey to learn Python coding.


© Codetoday Limited. Codetoday Limited is a company registered in England (company number 9789836). Registered office: 13 Hawley Crescent, London, NW1 8NP, United Kingdom