Basics

This chapter introduces the basic and most common elements of a structured programming language and also introduces the less intuitive programming paradigm of object-oriented programming. The structure of the chapter is

  • Data Types introduces the basics data types common to most programming languages and a few types that are special to python

  • Program Flow introduces constructs typical for structured programming languages such as branching and loops

  • Functions introduces the concept of functions for code re-usability and how in Python functions are defined

  • Object-oriented Programming gives a glimpse on the idea of bundling data structures and functions into objects.

Although we are using Python as an example language throughout this book, the general ideas are not specific or limited to Python.

But before we dive in, let’s start with some fundamentals

Comments

Comments are lines in the source code that are not interpreted by the Python interpreter. Their purpose is solely to make the source code more readable and understandable for other programmer, but also for yourself. Typically, after a week or two, a programmer is not able to remember the details of an implementation he has coded himself. So comments help you to remember why you have chosen a particular solution to a problem. However, to many comments make the code less readable. So a good balance is needed. A general rule is to add comments where you made a non-trivial decision on a particular choice of implementation.

In Python a comment starts with #:

# This is a comment
spam = 1  # second comment...
          # ... and the third!
text = "# this is NOT a comment!"

Note that the last line does not contain a comment. Double or single quotes (", ') enclose a text sequence, typically called string, which we will learn more about in the next section.

Expressions

Expressions are instructions that take input data, do some operation on it and possibly return some output data. Arithmetic expressions are an example of an expression. But also comparisons or the call to some function are expressions.

In Python, expressions can be grouped using brackets and arithmetic expressions follow the same rules as one would expect such as the associative law and commutative law.

Here are some examples:

(50 - 5 * 6) / 7
17 // 3
17 % 3.0
16. ** 0.5
(5+1j) * 1j
5. == 5
(5 > 3) and (8 < 10)

Logical expression, that are expression which are either True or False, can be combined using logical operators such as and or or.

Operators

Here is a list of common operators available on numeric data, for a complete list of operator symbols have a look at the Python documentation.

Operator

Description

+

Summation

-

Subtraction

*

Multiplication

/

Division

//

Explicit floor division

%

Modulo for division of integer operands

**

Exponentiation

==

Equal

!=

Unequal

+=, -=, *=, /=, //=, …

Summation, subtraction etc. with simultaneous assignment

Some of the operators such as + and * are also available for sequence data, but we will cover this later. As we will see in the section object-oriented programming, it is also possible to define a custom meaning of an operator symbol when defining your own data types by implementing special methods.

Assigning variables

Variables are symbols, which represent data in the memory. Data can be assigned to symbols with the assignment operator =.

width = 20
height = 5 * 9
n = 4.

Assignments can be used straightforward for further calculations. The names, or symbols, defined in the assignment statements above, are used as placeholders for the data they are assigned to.

width * height
width * n

Variables can also be assigned expressions that may contain variables too.

area = width * height

Multiple assignments in one line are also possible

a = b = 3.
a, b, c = 1, 2, 3

To inspect the content of an assigned variable, we can use the print() function, to output the content of the variable.

print(area)
print(a, b)
900
1 2

In an interactive session, such as Jupyter Lab, simply putting the variable name on the last line will also output the content of the variable

c
3

Getting Help

Reading the documentation of the programming language and software packages frequent task of a programmer. Nobody is expected to memorize all the details on how some function is exactly invoked and the names of all of its arguments. Therefore, it is important to quickly find the information you need to continue to be productive. The IPython interpreter that is running under the hood of Python Jupyter kernels offers a very convenient way of accessing documentation to functions, modules, packages or simply assigned variables. Put a question mark ? right after the name you want to know something about. To learn something about the print function, use

print?
Docstring:
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file:  a file-like object (stream); defaults to the current sys.stdout.
sep:   string inserted between values, default a space.
end:   string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
Type:      builtin_function_or_method

or

help(print)
Help on built-in function print in module builtins:

print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.

To get some information about the variable area, do

area?
Type:        int
String form: 900
Docstring:  
int([x]) -> integer
int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is a number, return x.__int__().  For floating point
numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base.  The literal can be preceded by '+' or '-' and be surrounded
by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4

The information you are getting on the variable is actually the documentation of the data type of that variable.

When you start to feel comfortable using Python, it is also very beneficial to take a look at the Python documentation to get a broader and deeper understanding about the language itself.

Errors

Errors and mistakes are an essential part of the programming process. However, one has to distinguish between errors you as a programmer are doing and errors the users of your software might do. Let us concentrate on the first type of errors: coding errors (or bugs).

Do not be disappointed if you code does not work at the first time. It almost never does, either because your syntax is not correct (a syntax error) or your code tries to do something that is not well-defined (an exception) Most languages, and also Python, do have some mechanism to deal with errors that occur during the runtime of the program. If the Python interpreter encounters some error it raises an exception. An exception raised due to a syntax error may look like this

a = 5 when 3 < 9
  File "<ipython-input-1-933321c6757f>", line 1
    a = 5 when 3 < 9
          ^
SyntaxError: invalid syntax

This code raises a SyntaxError exception, since Python does not know a when key word. The ^ symbol in the output points to the exact location where the syntax is wrong. This greatly helps to find typos in your code.

But there are a lot more exceptions, such as arithmetic exceptions, raised if an invalid operation occurs:

a = 1
b = 0
c = a / b
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-2-51f8442ebea1> in <module>
      1 a = 1
      2 b = 0
----> 3 c = a / b

ZeroDivisionError: division by zero

Here we try to divide by zero which is a not well-defined mathematical operation. Hence, the interpreter complains and in the output the ----> marks the line in the code where the interpreter raised the exception. Note that in many cases, unlike in this simple example, the occurrence of an exception depends on the conditions at runtime, i.e. when the program is executed. Such conditions could be the data that are fed into the program, which may be different for each execution.

Often, when we use functions or packages, the exception is raised inside some function that may not even be part of our own code. To still be able to identify the origin of the issue, the Python interpreter provides a traceback, that is a list of all lines that are executed until the program went wrong.

def outer(a, b):
    c = function2(a, b)
    return c

def inner(a, b):
    return a / b

result = outer(1, 0)
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-22-bfb4d7ae17ad> in <module>
      6     return a / b
      7 
----> 8 result = outer(1, 0)

<ipython-input-22-bfb4d7ae17ad> in outer(a, b)
      1 def outer(a, b):
----> 2     c = function2(a, b)
      3     return c
      4 
      5 def inner(a, b):

<ipython-input-21-9e9aa47843e7> in function2(a, b)
      4 
      5 def function2(a, b):
----> 6     return a / b
      7 
      8 result = function1(1, 0)

ZeroDivisionError: division by zero

In this example, two functions, outer and inner are defined where outer is simply calling inner with it’s own parameters. In the last line, we call outer with the parameters 1 and 0. In the last block of the traceback, we can see that the exception has been raised within the function inner. The second last block tells us, that the function inner has been called within the function outer. And finally, in the first block we see that the function outer has been called in the eighth line of the cell with the arguments 1 and 0. Hence, a traceback is best read backwards, allowing to trace the occurrence of an error back to it’s origin.

Note that for the syntax error, the output looks different. The reason is that the syntax error is raised while the interpreter reads the source code and before the code is executed. All other exceptions are raised during the execution of the program. See the Pyhon documentation to learn more about errors and exceptions and how to deal with them.