A. Python Mini Tutorial

This mini tutorial explains in more detail the Python specifications discussed in Chapters 3 and 4 of the main text, assuming that you understand Chapter 2. This does not cover all the features of Python.

A.1. Execution of Statement

A.1.1. Line-by-line execution

Python programs are basically executed line by line, in the order in which they are written. There is no need to indicate the end of a sentence with a semicolon ; as in the C language. Conversely, line breaks cannot be inserted arbitrarily.

As we saw in Chapter 2, indentation also has a meaning, so you should not insert arbitrary whitespaces at the beginning of a line.

A.1.2. Comment

A portion of a line from # to the end is a comment. It will not be executed. If you want to write a multi-line comment, you may enclose it in """ and """:

# This line is a comment
x = 12
y = 456  # You can start a comment from the middle of a line

# For multi-line comments, all lines should be marked with #,
# or enclosed in "" and "".

"""This also can be
treated as a comment.
"""

Strictly speaking, the part enclosed in """’s is not a comment, but a long string including newlines. A statement that only evaluates a string is equivalent to “doing nothing”, so it can be treated like a comment. Therefore, unlike #, it must be written with the correct indentation level:

# This is a comment.
    ## Arbitrary indentation is possible.

"""Strictly speaking, this is not a comment,
but a string.
"""
    """So an error will be raised
    if you write in this way.
    """

Comments are often used not only to annotate code, but also to temporarily prevent some code from being executed. This is called commenting out.

However, since Git keeps track of your history and you can retrieve past code at any time, you should not be careless about deleting code that has been commented out for a long time.

Reactivating the code that has been commented out is often referred to as uncommenting, although this may not not a standard term.

A.1.3. Continuation of a Line

If a line becomes too long and you want to break the line in the middle, you need to put \ at the end of the line to continue to the next line. However, you don’t need a \ to break lines within parentheses () [] {}, since it is clear that the statement is not yet finished:

# This requires "\":
variable_with_very_very_long_name = \
    function_with_very_very_long_name(123, 456, 789)

# This does not require "\":
another_variable = function_with_very_very_long_name(123,
                                                     456,
                                                     789)

A.2. Variable and Operation

A.2.1. Arithmetic Expression

The way to write expressions is similar to that of many other programming languages, so you should not have much trouble:

>>> 3 + 2
5
>>> 4 - 8
-4
>>> (2 + 3) * 4
20
>>> 10 / 4
2.5
>>> 10 // 4
2
>>> 10 % 3
1
>>> 10 ** 3
1000
>>> 3.14 * 2 * 2
12.56

Note that / is real number division and // is integer division. % is a remainder and ** is a power.

The order of precedence of operations and the direction of concatenation are the same as in many other languages:

>>> 6 - 3 - 2
1
>>> 6 + 3 * 2
12
>>> 6 / 3 / 2
1.0

A.2.2. Variable and Assignment

An assignment statement can be used to assign a right hand side value to a left hand side variable:

>>> pi = 3.14
>>> radius = 5
>>> pi * radius ** 2
78.5

There is no need to declare the use of a variable in advance. The variable is defined at the time it is first assigned.

C-like cumulative assignment operators can also be used:

>>> x = 10
>>> x += 2
>>> x
12
>>> x -= 5
>>> x
7
>>> x *= 10
>>> x
70

However, there is no ++ (add 1) or – (subtract 1) operators, which are often used in C. Instead, they are written as x += 1 or x -= 1.

We used in Chapter 2 that the left hand side can be separated by commas to assign the contents of a tuple separately. The right hand side is not limited to tuples, but can also be given comma-separated values:

>>> x, y = (100, 200)
>>> x, y = y, x
>>> (x, y)
(200, 100)

Swapping the values of two variables in this way is not possible in a single line in C.

A.2.3. Type and Type Conversion

Each value has a type to which it belongs. The primitive types defined in Python include integers (int), real numbers (float), and boolean values (bool). The types can be checked with the type function:

>>> type(5)
int
>>> type(5.0)
float
>>> type(2e-3)
float
>>> type(True)
bool
>>> type(False)
bool

Note that 2e-3 means \(2^{-3}\).

If you use a type name as a function, that is, if you prefix some value with a type name in round brackets, type conversion is performed. Of course, the conversion can only be done between the types for which the conversion is defined:

>>> float(5)
5.0
>>> int(2.5)
2
>>> bool(1)
True

Conversion from real number to integer results in rounding. For integer-to-bool and real-to-bool conversions, 0 means false and non-zero means true.

A.3. Function

A.3.1. Function Definition

It is useful to be able to call a sequence of processings with a name. Examples from Chapter 2 include print and pygame.init. You can define something similar yourself:

def function_name(argument1, argument2, argument3):
    Function body here
    ...

    return return_value

The typical definition of a function is as above. A colon : is required at the end of the def line. From the next line, write the body of the function, but note that indentation is required.

There can be any number of arguments. To take no arguments, leave the parenthesis empty, as in def function_name():.

When the return statement is executed, the execution returns to the caller. If the caller is part of an expression, the “return_value” is used as the value. If the last line of the function body is just return, you may omit it (it will return to the caller by itself without a return value).

A.3.2. Funcation Call

A function that has been defined can be called by appending a round-bracketed argument after the function name:

function_name(argument1, argument2, argument3)

A.3.3. Default Argument and Keyword Argument

When defining a function, it is possible to specify a default value to be used if the argument is omitted:

def func_abc(a, b=20, c=10):
    return (a + b) * c

The function func_abc, defined as above, can be called as follows:

>>> func_abc(2, 3, 5)
25
>>> func_abc(2, 3)   # c is omitted
50
>>> func_abc(2)      # b and c are omitted
220

When defining a function, the order of arguments must be such that the ones without default values come first and the ones with default values come later.

The way of calling a function with named arguments instead of in the positional order is called keyword arguments. The previous function func_abc can also be called as follows:

>>> func_abc(2, b=3, c=10)  # a is given by position; b and c are given by keywords
50
>>> func_abc(2, c=10, b=3)  # Keyword arguments can be in any order.
50
>>> func_abc(2, c=3)        # Only b is omitted
66
>>> func_abc(c=3, a=2)
66
>>> func_abc(c=3, 2)        # Positional arguments cannot follow keyword ones
  File "<stdin>", line 1
    func_abc(c=3, 2)
                   ^
SyntaxError: positional argument follows keyword argument

It is also possible to force some arguments to be positional or keyword specific when defining a function.

A.4. Control Statements

As we have seen in Chapter 2, we can control the execution order of statements in a program by using if and while statements. Let’s look at some similar and frequently used ones.

A.5. If Statement and Friends

You can change what is executed when a condition is met or not met:

if condition:
    block of lines executed when the condition is met
else:
    block of lines executed when the condition is not met

“block of lines executed when…” can include multiple statements. The else clause can be omitted, and actually was omitted in the if statement used in Chapter 2.

If you are familiar with C or other languages, note that indentation is always required, and that a colon : is required after conditions and else.

You can also add more conditions in place of else statement to chain them together.

if condition1:
    block executed when condition1 is met
elif condition2:
    block executed when condition1 is not met and condition2 is met
elif condition3:
    block executed when neither condition1 or 2 is not met and condition3 is met
else:
    block executed when none of condition1, 2, or 3 is met

Elif is short for “else if”. The last “else” clause can be omitted.

A.5.1. Conditions

The conditional part of “if” and “elif” is a boolean value; True means the condition is met, False means it is not met.

As in C, relational operators such as == and != for equality and its negation, and >, >=, <, and <= for inequality are used. In particular, note that the assignment operator = is different from the equality operator ==.

Boolean values can be combined with logical operators such as “and”, “or”, and “not”. If you are familiar with the C language, note that &&, ||, and ! are not used in Python:

>>> a = 10                        # assignment (not an equality operator)
>>> a == 10                       # Is a equal to 10?
True
>>> 2 <= a and a < 8              # Is a greater than or equal to 2 and smaller than 8?
False
>>> not (2 <= a and a < 8)        # Negation of the above condition
True
>>> (not 2 > a) or (not a >= 8)   # Equivalent to the above condition by de Morgan rule
True

A.5.2. while and for statements

We used the while statement in Chapter 2 to perform repetition (looping):

while condition:
    The Loop Body

The for statement also performs repetition. For example, it can be written as follows:

for x in (0, 1, 2, 3, 4):
    print(x + 3)

If you run this example, you will see the following output:

3
4
5
6
7

In this case, the elements of the tuple after the keyword``in`` are assigned to x one by one, and print(x + 3) is executed for each x.

Not only a tuple but also other kind of data in series (called a Sequence in Python) can be placed after the keyword in. List, which we will discuss in the next section, is also a kind of sequence.

There are many ways to create a sequence other than writing it directly, such as (0, 1, 2, 3, 4) in the above example. Here we just mention the most common way using the function range:

for x in range(5):
    print(x + 3)

where range(5) returns a sequence of integers starting from 0 and less than 5, which is equivalent to specifying (0, 1, 2, 3, 4). If you are familiar with C, you can remember it as equivalence to for (x = 0; x < 5; x++) ....

A.5.3. break and continue statements

To break out of a loop in the middle of a repeating statement such as a while or for statement, use the break statement as we saw in Chapter 2. The continue statement is similar to this, but instead of exiting the loop, it skips the current iteration and proceeds to the next one:

for x in (1, 2, 3, 4):
    if x == 3:
        continue
    print(x)

When you run this, you should see the following output:

1
2
4

A.5.4. Global and Local Variables

When a variable is defined in a function, it becomes a local variable that can only be seen from within that function. In contrast, variables that are visible to the entire file are called global variables.

If you are familiar with the C language, please note that Python does not have “block local variables” that are only visible within a while or for statement:

def func():
    for item in (10, 20, 30):
        print(item)
    for item in (99, 98, 97):
        print(item)

where the item in lines 1-2 and the item in lines 3-4 are the same thing. So, if you accidentally misspell like:

def func():
    for item in (10, 20, 30):
        print(item)
    for irem in (99, 98, 97):
        print(item)

and so on, you are likely to be troubled by the mysterious behavior without getting an error:

>>> func()
10
20
30
30
30
30

A.6. List (list type)

We talked about the fact that you can take a sequence of data to be processed by a for statement. In Python, there are many data structures that can be treated as sequences, the most important of which is the List:

>>> x = [0, 1, 2, 3, 4]

In this way, a five-element list of integers from 0 to 4 is assigned to the variable x. It is similar to a tuple, but uses square brackets instead of round brackets.

Lists are characterized by the ability to change their length and to rewrite their elements. In fact, tuples are not allowed to do so. Once a tuple is created, it is immutable, while a list is mutable.

This section describes only the basic methods for manipulating lists. There are many more, so please refer to the official manual.

A.6.1. Operation of Sequence

First, we list the operations common to sequences such as list and tuple.

A.6.1.1. Index

The elements of a list can be accessed by putting an index in square bracket after the list. The index starts from 0:

>>> x = [10, 20, 30, 40, 50]
>>> x[0]
10
>>> x[2]
20

If you specify a negative number as the index, you can specify the position counting from the end of the list:

>>> x[-1]
50
>>> x[-2]
40

A.6.1.2. Slice

Instead of specifying an element by a single index, you can use the form x[begin:end] to access a partial list whose index is from begin till end. Note that the element with index end is not included. A sub-list specified in this way is called a slice:

>>> x[2:4]
[30, 40]
>>> x[1:5]
[20, 30, 40, 50]

If you omit “begin” or “end”, you get “from beginning to less than index end” or “from index begin to the end of the list”, respectively:

>>> x[2:]
[30, 40, 50]
>>> x[:2]
[10, 20]

A.6.1.3. Basic Operations

The + operator can be used to represent a concatenation of sequences, and the * operator can be used to represent a sequence repeated multiple times:

>>> x = [10, 20, 30]
>>> y = x + [40, 50]
>>> y
[10, 20, 30, 40, 50]
>>> z = x * 3
>>> z
[10, 20, 30, 10, 20, 30, 10, 20, 30]

Note that in this example, x itself has not changed. The result of the operation is just returned as a new list. (Otherwise it could not be applied to an immutable object like a tuple).

The sequence length can be obtained with the function len:

>>> len([10, 20, 30])
3

The operators in and not in can be used to check whether a value is included in a sequence or not. However, since the sequence is checked one by one from the beginning, it is slow if the desired element is in the latter part of a long sequence:

>>> x = [10, 20, 30, 40, 50]
>>> 30 in x
True
>>> 30 not in x
False
>>> 35 in x
False

A.6.2. Creating a List

A.6.2.1. range

Let’s take a closer look at the range function used to create the sequential numbers used in the for statement.

First of all, note that range is not a function that returns a list or tuple. What it is, then, is a range object, but that’s a bit difficult to explain, so I’ll pass. For now, just understand that it is not a list, but can be converted to a list.

Therefore, you can put it directly after in in a for statement, but to assign it to a variable as a list, you need to do a type conversion:

>>> x = range(5)
>>> x
range(0, 5)
>>> x = list(range(5))
>>> x
[0, 1, 2, 3, 4]

If you pass one argument to range, as in the example above, you can create a sequential number starting from 0. If you want to change the first value, pass two arguments:

>>> list(range(2, 6))
[2, 3, 4, 5]

The first argument is the first value, the second argument is the “last” value, but the last value is not included in the result, since the same rule applies as for slices.

The third argument can be used to specify the increment step. If you write the following, you will get a sequence of numbers starting from 2, increasing by 3, and ending before reaching 10:

>>> list(range(2, 10, 3))
[2, 5, 8]

By using this, you can write most of the for statements that are commonly used in other languages.

C Example
for (x = 2; x < 10; x += 3) {
    printf("%d\n", x); /* print the value of integer x and a newline */
}
for (x = 10; x > 0; x -= 1) {
    printf("%d\n", x);
}
Python Example
for x in range(2, 10, 3):
    print(x)
for x in range(10, 0, -1):
    print(x)

A.6.2.2. List Comprehension

Here is another useful notation for making lists. It is called by a bit confusing name, list comprehension:

>>> x = [1, 2, 15, 30]
>>> x_doubled = [2 * a for a in x]
>>> x_doubled
[2, 4, 30, 60]
>>> even_values_doubled = [2 * a for a in x if a % 2 == 0]
>>> even_values_doubled
[4, 60]
>>> powers_of_two = [2 ** n for n in range(5)]
>>> powers_of_two
[1, 2, 4, 8, 16]

It’s easier to understand if you compare it to the mathematical notation for sets. You read \(\mid\) as for, and \(\in\) as in.

\[\begin{split}X_\text{doubled} &= \{ 2a \mid a \in X \}\\ X_\text{even,doubled} &= \{ 2a \mid a \in X, a \equiv 0 \,(\text{mod}\, 2) \}\\ T &= \{ 2^n \mid n \in \{0, 1, 2, 3, 4\} \}\end{split}\]

Note that the elements of a mathematical set are not ordered, but a list is. If used effectively, complex lists can be expressed concisely.

A.6.3. Mutation of List Elements

By placing a sub-list specified by an index or a slice on the left hand side of an assignment statement, you can change the specified elements of the list:

>>> x = [10, 20, 30, 40, 50]
>>> x[2] = 12345
>>> x
[10, 20, 12345, 40, 50]
>>> x[2:4] = [-20, -30]
>>> x
[10, 20, -20, -30, 50]

A.6.4. Stretching and Shrinking a List

A.6.4.1. Appending and Inserting an Element

Because the list is mutable, its length can be manipulated; the method append can be used to add an element to the end, and the method insert can be used to insert an element at the specified index:

>>> x = []
>>> x.append(0)
>>> x.append(10)
>>> x.append(20)
>>> x.append(30)
>>> x
[0, 10, 20, 30]
>>> x.insert(2, 12345)
>>> x
[0, 10, 12345, 20, 30]

A.6.4.2. Deletion of an Element

The method pop removes the trailing element from the list and returns its value:

>>> x = [0, 10, 20, 30, 40, 50]
>>> item = x.pop()
>>> item
50
>>> x
[0, 10, 20, 30, 40]
>>> item = x.pop()
>>> item
40
>>> x
[0, 10, 20, 30]

If an index is passed as an argument to the pop method, it will remove the specified element and return its value:

>>> item = x.pop(2)
>>> item
20
>>> x
[0, 10, 30]

If you do not need to return the deleted value, you can use the del statement. The element(s) can be specified not only by a single index but also by a slice:

>>> x = [0, 10, 20, 30, 40, 50]
>>> del x[3]
>>> x
[0, 10, 20, 40, 50]
>>> del x[1:4]
>>> x
[0, 50]
>>> del x[:]
>>> x
[]

You can delete all elements by del x[:] as in the example above, but it is a bit faster to use the clear method:

>>> x = [10, 20, 30]
>>> x.clear()
>>> x
[]

The method remove is also provided to remove an element by specifying its value. It searches the list from the beginning for an element with a value equal to the argument, and removes the first one found:

>>> x = [0, 10, 20, 30, 40, 50]
>>> x.remove(30)
>>> x
[0, 10, 20, 40, 50]

A.6.4.3. Elements Should be Added or Removed at the End Whenever Possible

A list is a data structure in which elements are arranged in series. It is inefficient to add or remove elements other than at the end.

For example, suppose you have a list like this:

>>> x = [10, 20, 30, 40]
_images/list_append_insert_trim_1.png

Adding an element at the end does not require the computer to move the existing elements:

>>> x.append(50)
_images/list_append_insert_trim_2.png

However, if you insert an element at a position other than the end, your computer needs to move everything after that element:

>>> x.insert(0, 99)
_images/list_append_insert_trim_3.png

Therefore, when expanding or contracting a list, it is advisable to consider the structure and calculation procedure so that append or no-argument pop can be used as much as possible.

A.7. List-like Data Structures

A.7.1. Tuple (tuple type)

A tuple is also a kind of sequence, and like a list, it can be accessed by index or slice, it can be concatenated or repeated by + or *, and its length can be obtained by the len function.

However, unlike lists, tuples are not mutable: you cannot use methods like append or pop to change their length, nor can you use index or slice to mutate their elements:

>>> tup = (10, 20, 30)
>>> tup[0]
10
>>> tup[1] = 123
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

A.7.2. string (str type)

Strings have been expressed by enclosing them in double quotes, such as “hello, world” or “red” since Chapter 1. You can also use single quotes, such as ‘hello, world’ or ‘red’.

In this textbook, we mainly use double quotes, but what Python returns as a result of a calculation is mainly written in single quotes:

>>> "hello"
'hello'

Either is fine, but if you want to include " or ' itself in the string, it is useful to use them properly:

>>> print("what's new")
what's new
>>> print('1" is equal to 25.4 mm')
1" is equal to 25.4 mm

If you really want to include the same quoting character that you used to enclose the string, prefix it with \. In a way like this, \ is generally used to indicate something that you want to include in the string but cannot write directly. This usage is called escaping. Other uses include \n for a newline character, \t for a tab character, and \\ for \ itself:

>>> print('1h 23\' 45"')
1h 23' 45"
>>> print("hello\nworld")
hello
world
>>> print("C:\\Windows\\System32")
C:\Windows\System32

The type name of the string is str. For example, type conversion from an integer or real number will yield a string in the standard format. If you want to adjust the format, you need to use the format method described below:

>>> str(123)
'123'
>>> str(2 * 4 * 3.14)
'25.12'
>>> str(1e3)
'1000.0'

A.7.2.1. String as a Sequence

A string is also a kind of immutable sequence. They can be accessed by indexes and slices, applied with len, +, and *, used with for statements and list comprehensions, and so on, in the same way as lists and tuples:

>>> s = "auto" + "maton"
>>> s
'automaton'
>>> len(s)
9
>>> s[2]
't'
>>> s[2:8]
'tomato'
>>>  [c * 2 for c in "hello"]
['hh', 'ee', 'll', 'll', 'oo']

A.7.2.2. Methods of String

There are many methods specific to the string type.

Of course, all of them cannot be mentioned here, so I’ll pick a few to show you:

>>> "Computer Seminar I".split()
['Computer', 'Seminar', 'I']
>>> ", ".join(["abc", "def", "ghi"])
'abc, def, ghi'
>>> "2021-10-01".replace("-", "/")
'2021/10/01'
>>> "{} errors found in {}".format(10, "hello_pygame.py")
'10 errors found in hello_pygame.py'

Note that the original string is never changed by any of the methods, since strings are immutable. For example, let’s take the replace method as an example:

>>> old_string = "2021-10-01"
>>> new_string = old_string.replace("-", "/")
>>> new_string
'2021/10/01'
>>> old_string
'2021-10-01'

As you see, it does not change the original string. It only returns the result of the replacement as a new string.

A.7.2.3. format method

The format method needs some explanation. In the example above, it returns a string in which the integer 10 and the string “hello_pygame.py” are embedded at the places of {}’s in the format string in the order of the arguments.

In the {} part, you can specify the index of the argument to be embedded by writing a number such as {0} or {1}. If you need to specify the format of the embedded argument, write the formatting specification in {} followed by :. There are many ways to specify the formatting, so we will only give a few examples:

>>> "{1} {2}, {0}".format(2021, "October", 1)
'October 1, 2021'
>>> "{:5}".format(123)   # Space-padded if less than 5 characters
'  123'
>>> "{:05}".format(123)  # Zero-padded if less than 5 characters
'00123'
>>> "{:.4f}".format(3.141592) # Rounded to 4 decimal places
'3.1416'
>>> "{:10.4f}".format(3.141592) # Rounded and space-padded
'    3.1416'
>>> "{0} {0:5} {0:05}".format(123)  # argument specifier and format specifier
'123   123 00123'

A.7.3. Dictionary (dict type)

Lists, tuples, and strings are sequences, so the elements are ordered and can be specified by an integer index.

Sometimes it is useful to use a string instead of an integer as an “index”. In Python, this is called a dictionary:

>>> score = {"Alice": 80, "Bob": 80, "Charlie": 80}
>>> score["Alice"] = 90
>>> score["Bob"] -= 10
>>> score["Alice"]
90
>>> score["Bob"]
70
>>> score["Charlie"]
80

Anything used in place of an index (in this case “Alice” etc.) is called a key. A dictionary is a data structure that holds key-value pairs and can be searched by key. Similar structures are called associative arrays, hashes, or maps in other programming languages.

Not only strings can be used as keys, but note that keys must be immutable. Thus, a list cannot be a key, but a tuple can be.

Lists are defined with square brackets and tuples with round brackets, but dictionaries are defined with curly brackets, as shown in the first line. Keys and values are paired with a colon and separated by commas. When accessing dictionary values, square brackets are used as in lists and tuples (not curly brackets).

A.7.3.1. Addition and Deletion

As you can see from the example above, dictionaries mutable. New keys can be added, and existing keys can be removed:

>>> score["Dave"] = 95
>>> del score["Charlie"]
>>> score
{'Alice': 90, 'Bob': 70, 'Dave': 95}

It is possible to create a new key that does not exist, just like score["Dave"] = 95, but you will get an error if you try to read the value of a key that does not exist:

>>> score["Charlie"]
KeyError: 'Charlie'

A.7.3.2. Existence of a Key

Therefore, we often want to check whether a key exists or not. The operators in and not in can be used to check this:

>>> "Alice" in score
True
>>> "Alice" not in score
False
>>> "Charlie" in score
False

For example, the following is a typical usage:

def increment_value(dic, key, delta):
    if key not in dic:
        dic[key] = 0
    dic[key] += delta

increment_value(score, "Charlie", 10)

The time taken to look up a dictionary by key or to determine the existence of a key by in or not in is independent of the number of elements in the dictionary. This is in contrast to in and not in operations for lists.

A.7.3.3. Conversion to List

It is a common situation that we want to apply some operations to everything in the dictionary. A type conversion of a dictionary to a list gives a list of keys, which can be processed by a for statement:

>>> list(score)
['Alice', 'Bob', 'Charlie']

A.7.3.4. Example in pygame internals

Let’s take a look at an example of how a dictionary is used in pygame: In Chapter 2, we asked you to look at the following page to see the color names that can be passed as an argument to pygame.Color.

If you look at this page now, you can see what’s going on: a dictionary called THECOLORS is defined, which returns (240, 248, 255, 255) for the key “aliceblue”, for example. These four numbers represent red, green, blue, and opacity, respectively, as integers between 0 and 255, and are used to show colors on the display. Such a dictionary is used internally in pygame.

A.8. Complex Data Structures

In this Appendix, we have only dealt with sequences that have integers as elements, but it is also possible to create lists of real numbers, strings, or a mixture of them. Further, they can even have lists and tuples as elements:

>>> x = [10, 20, 3.14, "abc"]
>>> y = [10, 20, [99, 88, ["a", "b", "c"]], 40, 50]

For more information on these, see Chapter 4, Section 4.4 onwards.