At the time of writing, the latest stable release of Python is version 3.10.5. If you already have Python installed, please ensure that you have at least version 3.6 or newer.
To install or upgrade Python, you can either:
You can verify whether Python was successfully installed on your
system by opening your Terminal or PowerShell and entering the command
python --version
or python3 --version
.
In addition to installing Python, you will also need a text editor. Here is a non-exhaustive list of suggestions:
A traditional first program to run is “Hello World!”. We will use this to ensure that everyone has Python properly installed and can execute Python scripts.
print("Hello World!")
## Hello World!
We can directly launch Python from our command line (Terminal or
PowerShell) and execute the program interactively from there, or save
the program to a file (e.g. called hello.py
) and execute
the program stored within the file by running Python on it:
python3 hello.py
. For the latter option, we need our
Terminal to have the folder in which we saved the script file as its
working directory. We can set the working with the cd
command followed by a space and the file path. (NB: You may also be able
to drag the folder to the Terminal after having typed cd
followed by a space.) You can verify the path with the command
pwd
(“print working directory”) and/or list the content of
the directory with ls
(macOS/Linux) or dir
(Windows) to see whether your script file appears in the list of
contents.
A further option is to make our Python script executable. For this, we place a line that will tell our system how our script should be executed. NB: The path provided explicitly applies to Unix-like systems (Linux and macOS among others) but should be also interpretable (or even unnecessary) on Windows.
#!/usr/bin/env python3
print("Hello World!")
On Unix-like systems, we should then give executable permissions to
the file with chmod +x hello.py
. Once this is done, we can
run the script as ./hello.py
.
Let us start with a “cultural studies flavoured” approach: We will generate the American song 99 bottles of beer of the wall in Python to see some of the basic concepts of the language. We will be aiming for the following lyrics:
99 bottles of beer on the wall, 99 bottles of beer. Take one down and pass it around, 98 bottles of beer on the wall.
[…]
1 bottle of beer on the wall, 1 bottle of beer. Take one down and pass it around, no more bottles of beer on the wall.
No more bottles of beer on the wall, no more bottles of beer. Go to the store and buy some more, 99 bottles of beer on the wall.
We can repeat operations for a certain number of times using a
for loop. At each repetition, a specified variable
(often called i
for iterative) is assigned a
different value. To print numbers from 1 to 10, we can do the
following:
for i in range(1, 11):
print(i)
## 1
## 2
## 3
## 4
## 5
## 6
## 7
## 8
## 9
## 10
Notice how the count is one number short of the endpoint of the range.
The range()
function may take a further argument
specifying the interval to be used. We could skip even numbers by
specifying 2 as an interval.
for i in range(1, 11, 2):
print(i)
## 1
## 3
## 5
## 7
## 9
To count down, we can specify the interval negatively. We also don’t
have to stick with i
for the name of the iterating
variable, but can choose something more expressive.
for bottle_count in range(99, -1, -1):
print(bottle_count)
Our condition is that we only need the singular form when the number of bottles is 1. We can achieve this with a conditional if statement.
if bottle_count == 1:
print(str(bottle_count) + " bottle")
else:
print(str(bottle_count) + " bottles")
There are more elegant ways to insert variables into strings:
print("%s bottles" % bottle_count) # "old school" way
print(f"{bottle_count} bottles") # new f-string introduced in Python 3.6
We can now combine our for-loop and our if-statement:
for bottle_count in range(99, -1, -1):
if bottle_count == 1:
print(f"{bottle_count} bottle")
else:
print(f"{bottle_count} bottles")
for bottle_count in range(99, -1, -1):
if bottle_count == 1:
print(f"{bottle_count} bottle of beer on the wall, {bottle_count} bottle of beer.\n\tTake one down and pass it around, no more bottles of beer on the wall.\n")
else:
print(f"{bottle_count} bottles of beer on the wall, {bottle_count} bottles of beer.\n\tTake one down and pass it around, {bottle_count - 1} bottles of beer on the wall.\n")
It is generally advised to keep lines of code under 80 characters for better readability. But how can we keep the line short when our text is long? While this length limit is more a suggestion than a requirement, we can still comply with it by splitting parts of the string as long as they are within brackets. NB: Do not place any commas between the strings as Python would interpret this as a tuple, i.e. a data type akin to a list that cannot be edited.
for bottle_count in range(99, -1, -1):
if bottle_count == 1:
print(
f"{bottle_count} bottle of beer on the wall, "
f"{bottle_count} bottle of beer.\n\t"
"Take one down and pass it around, "
"no more bottles of beer on the wall.\n"
)
else:
print(
f"{bottle_count} bottles of beer on the wall, "
f"{bottle_count} bottles of beer.\n\t"
"Take one down and pass it around, "
f"{bottle_count - 1} bottles of beer on the wall.\n"
)
There are multiple ways to achieve this. We could handle this with an
if-statement, but it would quickly become convoluted due to the existing
if-statement for handling the singular, and the fact that 0 occurs both
when the bottle count is 1 due to the subtraction, and in the final
line. A more elegant solution is to substitute the character 0 with the
character string “no more”. For this, we use regular expressions, for
which we need to import the module re
. The imported modules
are typically listed at the very top of a Python script. We can even use
regular expressions to get rid of the if-statement to handle the
plural-singular distinction and reserve the conditional to handle the
last line. To substitute the text we want, we first store a default
version of the line and then perform the substitutions we want on
it.
Some things to note:
\b
. In Python,
this particular wild card is somewhat confusing because the sequence
\b
is an escape sequence for bytes literals, so we either
need to escape the \
escape character itself, hence
\\b
, or use a raw string notation
r"\b"
. In a nutshell, raw strings ignore any
Python-specific uses of the backslash character and pass everything as
is to the regular expression parser. If you are confused, you can place
double backslashes for any wild card, whether they are necessary
(e.g. \\b
, \\1
) or not (e.g. \w
or \\w
). You can also play around with the raw string
notation to see whether you prefer it (e.g. r"\b"
,
r"\1"
, r"\w"
).^
to specify
the beginning of the string.import re
for bottle_count in range(99, -1, -1):
default_line = (
f"{bottle_count} bottles of beer on the wall, "
f"{bottle_count} bottles of beer.\n\t"
"Take one down and pass it around, "
f"{bottle_count - 1} bottles of beer on the wall.\n"
)
updated_line = re.sub("\\b0", "no more", default_line)
updated_line = re.sub("^n", "N", updated_line)
updated_line = re.sub("\\b1 bottles", "1 bottle", updated_line)
print(updated_line)
Our song looks fine except for the ending. We can use an if-statement to treat the ending differently. We can now also skip the capitalization of “no” at line beginnings.
import re
for bottle_count in range(99, -1, -1):
if bottle_count > 0:
default_line = (
f"{bottle_count} bottles of beer on the wall, "
f"{bottle_count} bottles of beer.\n\t"
"Take one down and pass it around, "
f"{bottle_count - 1} bottles of beer on the wall.\n"
)
updated_line = re.sub("\\b0", "no more", default_line)
updated_line = re.sub("\\b1 bottles", "1 bottle", updated_line)
else:
updated_line = (
"No more bottles of beer on the wall, "
"no more bottles of beer.\n\t"
"Go to the store and buy some more, "
"99 bottles of beer on the wall.\n"
)
print(updated_line)
Alternatively, we can also let the for-loop stop at 1 and just write the ending after the loop.
import re
for bottle_count in range(99, 0, -1):
default_line = (
f"{bottle_count} bottles of beer on the wall, "
f"{bottle_count} bottles of beer.\n\t"
"Take one down and pass it around, "
f"{bottle_count - 1} bottles of beer on the wall.\n"
)
updated_line = re.sub("\\b0", "no more", default_line)
updated_line = re.sub("\\b1 bottles", "1 bottle", updated_line)
print(updated_line)
print(
"No more bottles of beer on the wall, "
"no more bottles of beer.\n\t"
"Go to the store and buy some more, "
"99 bottles of beer on the wall.\n"
)
In addition to a for-loop, we could also use a while-loop. Unlike in for-loops, there is no automatic iteration of the looping variable, so we have to be extra careful to specify how the loop should end or we may be stuck in an infinite loop. In general, prefer for-loops over while-loops unless there is a good reason to use a while-loop.
import re
bottle_count = 99
while bottle_count > 0:
default_line = (
f"{bottle_count} bottles of beer on the wall, "
f"{bottle_count} bottles of beer.\n\t"
"Take one down and pass it around, "
f"{bottle_count - 1} bottles of beer on the wall.\n"
)
updated_line = re.sub("\\b0", "no more", default_line)
updated_line = re.sub("\\b1 bottles", "1 bottle", updated_line)
print(updated_line)
bottle_count = bottle_count - 1 # infinite loop without this line ! ! !
print(
"No more bottles of beer on the wall, "
"no more bottles of beer.\n\t"
"Go to the store and buy some more, "
"99 bottles of beer on the wall.\n"
)
There are different ways we can write the output to a file:
import re
for bottle_count in range(99, 0, -1):
default_line = (
f"{bottle_count} bottles of beer on the wall, "
f"{bottle_count} bottles of beer.\n\t"
"Take one down and pass it around, "
f"{bottle_count - 1} bottles of beer on the wall.\n\n"
)
updated_line = re.sub("\\b0", "no more", default_line)
updated_line = re.sub("\\b1 bottles", "1 bottle", updated_line)
with open("99bottles.txt", "a") as outp:
outp.write(updated_line)
with open("99bottles.txt", "a") as outp:
outp.write(
"No more bottles of beer on the wall, "
"no more bottles of beer.\n\t"
"Go to the store and buy some more, "
"99 bottles of beer on the wall.\n\n"
)
import re
song_lyrics = ""
for bottle_count in range(99, 0, -1):
default_line = (