Basic Python in a nutshell#

There are many excellent introductions to python programming on the web. This document is not supposed to replace them, but only to introduce some basic concepts to get you started. To get more in-depth knowledge on python, just google for it.

How to use the Jupyter notebook#

In this course, we will make use of Jupyter notebooks, because they are user friendly and interactive. Essentially, an Jupyter notebook is just a browser-based environment for executing python code. It additionally allows to add some structure to the notebook, i.e. add nice text with formulas, figures, etc., all rendered by the browser.

Code is executed in Code cells, which are grey boxes with In [ ]: in front. To execute a cell, click in it and type Shift + ENTER. Try this in the following two boxes:

x = 1
print(x)

The Jupyter notebook has a quite intuitive interface. Don’t forget to save from time to time (although there is also an autosave) by clicking on the save button (with the floppy disk symbol). You can also insert cells, delete cells, and write text in Markdown cells (like this one), etc. If you wish to learn more about the Jupyter notebook, click on Help above for a tour or keyboard short-cuts.

Basics about the Python language#

Variables#

In python, we can create a variable and assign a value to it (as we just saw above):

x = 1

From now on, x is set to 1:

print(x)

We can also assign a new value to x:

x = 2
print(x)

In assigning a value to a variable, we give this variable a “type”. Here, this is an integer number:

print(type(x))

But we can just assign later a different value to that variable, and the type will change (it is not fixed as in a compiled language as C):

x = 1.0
print(type(x))
x = "A string"
print(type(x))
x = True
print(type(x))
x = 1 + 1j
print(type(x))

Note that above we already introduced a complex number.

Some further remarks on Jupyter notebooks#

One thing to note about Jupyter notebooks is that code in cells are executed in the order you execute cells. This is in fact the same behavior that Mathematica has (for those who know Mathematica). What this means you can see by evaluating the next three cells, and then evaluating the second cell with print(x) again.

x = 1
print(x)
x = 2

You see that now the print function writes 2 to the screen. The code is really as if you executed

x = 1
print(x)
x = 2
print(x)

You will also note that the number in the preceding In [ ] has changed: This number gives the order in which the cells were evaluated. Again, for those who know Mathematica this will feel familiar.

Math#

Operations on variables are quite intuitive, and also work for complex numbers. Note that you can also mix variables of different ype.

a = 1.1
b = 2.0 + 1j
c = 3.1 - 1.3j

print(a * 2)
print(a + b)
print(c / b)

Taking the power of a number is denoted by ** (and not ^ as in other languages), and works for any power:

print(a ** 2)
print(a ** 0.5)
print(c ** -0.7)

Note that the imaginary unit is written as 1j (those engineers having their influence …)

1j**2

If you want to use elementary functions such as sqrt or sin, you first have to import them:

from math import sin, sqrt

print(sqrt(a))
print(sin(a))

To act on complex numbers, you need to import from cmath:

from cmath import sin, exp

print(sin(b))
print(exp(1j * a))

Mini-exercises variables and math#

  • Execute the cells above, if you haven’t done so yet.

  • Set the value of variable z to 4, and print it. Then set it to "Hello!", and print it again. Bonus: print also the type of the variable z

  • Define two variables x and y with some arbitrary numbers. Then compute the distance of the point (x,y) from the origin by computing \(\sqrt{x^2+y^2}\)

  • Add 1 to the value of x and store it in x. (That is, after the operation x stores a value that is larger by 1)


Lists, tuples and dictionaries#

Python lists can hold a number of different values. They are a bit like arrays in other languges, but the entries in the list can be of different type.

some_list = [1, "test", 1+1j]

An entry in a list is accessed by its index. The first element starts at 0.

print(some_list[0])
print(some_list[2])

The last entry in a list can also be indexed by -1.

print(some_list[-1])

One can add and delete elements in the list, and ask for its length:

del some_list[2]
print(some_list)
some_list.append(1.0)
print(some_list)
print("List has", len(some_list), "elements")

A neat feature is that you can also address several elements at a time using the start:stop or start:stop:step syntax:

some_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(some_list[2:5])
print(some_list[3:8:2])

If start, stop are omitted, it assumes you want to go from the beginning to the end:

print(some_list[::2])

Tuples are similar to lists, but are defined with round brackets:

t = (1, 2, 3, 4, 5)
print(t)
print(t[1:4:2])

However, in contrast with lists, tuples cannot be modified after they have been created – they are so-called immutable objects.

# Will throw an error
t[0] = 3

If you see an error, read it carefully and google it, so that you can fix it.

Note that to initialize a tuple with a single element you need to add a comma:

not_a_tuple = ('car')
is_a_tuple = ('car',)
print(type(not_a_tuple))
print(type(is_a_tuple))

Lists and tuples are indexed by consecutive integers. Another useful container in python is a dictionary which can use many (immutable) objects as an “index”:

some_dict = {1: "some entry", "key": 1.0}

print(some_dict["key"])
some_dict[8] = "something"
del some_dict[1]
print(some_dict)

We can separately access the keys and values in a dictionary:

print(some_dict.keys())
print(some_dict.values())

We can also extract keys and values simultaneously:

print(some_dict.items())

Mini-exercises lists and dictionaries#

  • Execute the cells above, if you haven’t done so yet.

  • Make a list that contains the letters a - d (each letter as a separate string, i.e. "a", etc.).

  • print the first, second and third entry of the list

  • add the letter "e" at the end of the list, and delete the letter "a". Print the length of the list.


Conditional statements#

Often in a program one needs to do different things depending on what happened previously. For this we have the if-statement:

i = 10

if i < 5:
    print("i is smaller than 5")
elif 5 <= i < 10:
    print("i is bigger than 4 but smaller than 10")
else:
    print("i is larger than 9")

If you need to fulfil more than one condition, then one can just concatenate several conditions using and or or:

i = 1

if i == 1 or i == 2:
    print("i is 1 or 2")
elif i > 3 and i < 5:
    print("i is 4")

Mini-exercises conditional statements#

  • Execute the cells above, if you haven’t done so yet.

  • Write an if-statement that prints “even” if the variable i is even, and “odd” if it’s odd. Check your if-statement for a few different values.
    Hint: the operator % computes the remainder after division, e.g. 3 % 2 == 1

  • Write an if statement that prints “inside” if the point described by the variables x and y is inside the unit circle, and “outside” if it is not.


Loops#

A loop in python is written as:

for i in range(10):
    print(i)

Note that in python indenting (whitespace) is essential: Everything that is indented to the same level belongs to the same block – in the above example to the for loop. So the following two examples are different:

a = 0
for i in range(10):
    a += i
    print(a)
a = 0
for i in range(10):
    a += i
print(a)

In the latter case it is actually advisable to add an empty line to visually separate the print statement from the loop.

In fact, the for loop can run over any list (more precisely, any iterable, but google this yourself):

some_list = [1, "text", 5, 1.0]

for entry in some_list:
    print(entry)

Loops can of course also be nested:

N = 2
for i in range(N):
    for j in range(N):
        print(i, j)

If you want to start the loop not from zero, type help(range) to get more information about the syntax. You can get help on any python statement in that way. Within Jupyter, you can also use range? or press Shift+TAB (twice) within the brackets ( ).

There is also a second type of loop in python, the while-loop:

i = 1
while i < 50:
    print(i)
    i = i * 2

while-loops are more general than for-loops, as we can put any condition there. The while-loop will run as long as the condition remains True. Still, in most cases for is enough.

Mini-exercises loops#

  • Execute the cells above, if you haven’t done so yet.

  • Write a loop that prints the numbers 3, 4, 5, 6, 7

  • Write a loop that prints the letters a-e

  • Write a loop that computes the factorial \(N\), where \(N\) is some integer \(\geq 1\)


Functions#

When writing more complex code, we group code into functions, such that we can reuse it. A function is defined with a name and arguments, as:

def some_function(x, y):
    c = x + y
    return c

Note that we write the function’s name in lower-case letters and glue different words using an underscore _. This is a good coding practice, and you can read more about it in PEP8.

print(some_function(1, 3))
print(some_function(1, 1.4))

Again, the indenting tells what belongs to the function and what not.

Python also allows for default values for functions, and using the variable name to pass a value to the function

def another_function(x, y=10):
    print("x =", x)
    print("y =", y)
    print()

another_function(1)
another_function(y=1, x=10)

A function is not just a function, it is also a object (more about this in a minute). In particular, this means a function can also be assigned to a variable:

def print_function(x):
    print("The value x =", x)

pfun = print_function
pfun(1)
print(type(pfun))

Just like any variable, a function can also be passed to another function:

def some_function(x, p_fun):
    p_fun(x)

some_function(1, print_function)

Mini-exercised functions#

  • Execute the cells above, if you haven’t done so yet.

  • Write a function called multiply that takes two numbers a and b and returns the product. Apply it to several examples

  • Write a function add_multiply that takes two numbers a and b and returns the sum and the product. You can return two (or more) values by separating them with a ,, e.g. return x, y. To store the returned values, you then also give two variables separated with a ,, e.g. v,  w = add_multiply(a, b)


Comments#

The Jupyter notebook does allow to write explanatory text like this. But it is also possible to add comments directly in the python code. A comment starts with #:

i = 5  # some value 

Documenting your code#

Python allows to easily add help strings to functions. Just write a string directly after a function definition:

def function():
    "This function does not do anything"

Or, if the string should span several lines:

def function(x):
    """This function takes `x` and adds 2 to it, but does not return it.

    Input
    -----
    x: some value
    """
    x += 2

This information can be retrieved in the usual ways:

help(function)
function?

Or using Shift + TAB within the function’s (...)

function()

Python objects#

Often the value of a variable in python is actually a python object. This means that this value has additional functionality in the form of functions attached to it. Consider the example of a string:

x = "A sentence with words."
print(type(x))

words = x.split()
print(words)

Again, help(str) (or the python website) would give you more information.

A typical aspect of python objects is that they often can behave like another well-known object. For example, a string has many of the properties of a list:

x = "ABC"
print(x[0])

for letter in x:
    print(letter)

Another example would be files:

file = open("filename")

for line in file:
    do_something

file.close()

Mini-exercises Python objects#

  • Execute the cells above, if you haven’t done so yet.


Summary and outlook on exercises#

Now you learned about the basics of python! With these, you can already go quite some way. Apply what you learned to the bonus short exercises for our List of possible short projects!