Python Fundamentals

This material is mostly adapted from the official python tutorial, Copyright 2001-2021, Python Software Foundation. It is used here under the terms of the Python License.

Invoking Python

There are three main ways to use Python.

  1. By running a Python file, e.g. python myscript.py

  2. Through an interactive console (Python interpreter or iPython shell)

  3. In an interactive notebook (e.g. Jupyter)

As previously mentioned, we will mostly be interacting with Python via Jupyter notebooks in this course.

Python Versions

There are two versions of the Python language out there: Python 2 and Python 3. In 2021, the vast majority of the scientific community now uses Python 3. As new Python learners, you should definitely learn Python 3. But it is important to be aware that Python 2 exists, since you might encounter it in the wild.

Some of the main changes introduced in Python 3 are:

  • print is a function

  • Integer division returns a float

Basic Variables: Numbers and String

# Comments are anything that comes after the "#" symbol
a = 1       # assign 1 to variable a
b = "hello" # assign "hello" to variable b
# how to we see our variables?
print(a)
print(b)
print(a,b)
1
hello
1 hello

All variables are objects. Every object has a type (class). To find out what type your variables are

print(type(a))
print(type(b))
<class 'int'>
<class 'str'>
# as a shortcut, iPython notebooks will automatically print whatever is on the last line
type(b)
str
# we can check for the type of an object
print(type(a) is int)
print(type(a) is str)
True
False

Different objects attributes and methods, which can be accessed via the syntax variable.method

IPython will autocomplete if you press <tab> to show you the methods available.

# this returns the method itself
b.capitalize
<function str.capitalize()>
# this calls the method
b.capitalize()
# there are lots of other methods
'Hello'
# binary operations act differently on different types of objects
c = 'World'
print(b + c)
print(a + 2)
print(a + b)
helloWorld
3
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-8-958e0fcf701c> in <module>
      3 print(b + c)
      4 print(a + 2)
----> 5 print(a + b)

TypeError: unsupported operand type(s) for +: 'int' and 'str'

Math

Basic arithmetic and boolean logic is part of the core Python library.

# addition / subtraction
1+1-5
-3
# multiplication
5 * 10
50
# division
1/2
0.5
# that was automatically converted to a float
type(1/2)
float
# exponentiation
2**4
16
# rounding
round(9/10)
1
# built in complex number support
(1+2j) / (3-4j)
(-0.2+0.4j)
# logic
True and True
True
True and False
False
True or True
True
(not True) or (not False)
True

Conditionals

The first step to programming. Plus an intro to Python syntax.

x = 100
if x > 0:
    print('Positive Number')
elif x < 0:
    print('Negative Number')
else:
    print ('Zero!')
Positive Number
# indentation is MANDATORY
# blocks are closed by indentation level
if x > 0:
    print('Positive Number')
    if x >= 100:
        print('Huge number!')
Positive Number
Huge number!

More Flow Control

# make a loop 
count = 0
while count < 10:
    # bad way
    # count = count + 1
    # better way
    count += 1
print(count)
10
# use range
for i in range(5):
    print(i)
0
1
2
3
4

Important point: in Python, we always count from 0!

# what is range?
type(range)
type
range?
# iterate over a list we make up
for pet in ['dog', 'cat', 'fish']:
    print(pet, len(pet))
dog 3
cat 3
fish 4

What is the thing in brackets? A list! Lists are one of the core Python data structures.

Lists

l = ['dog', 'cat', 'fish']
type(l)
list
# list have lots of methods
l.sort()
l
['cat', 'dog', 'fish']
# we can convert a range to a list
r = list(range(5))
r
[0, 1, 2, 3, 4]
while r:
    p = r.pop()
    print('p:', p)
    print('r:', r)
p: 4
r: [0, 1, 2, 3]
p: 3
r: [0, 1, 2]
p: 2
r: [0, 1]
p: 1
r: [0]
p: 0
r: []
# "add" two lists
x = list(range(5))
y = list(range(10,15))
z = x + y
z
[0, 1, 2, 3, 4, 10, 11, 12, 13, 14]
# access items from a list
print('first', z[0])
print('last', z[-1])
print('first 3', z[:3])
print('last 3', z[-3:])
print('middle, skipping every other item', z[5:10:2])
first 0
last 14
first 3 [0, 1, 2]
last 3 [12, 13, 14]
middle, skipping every other item [10, 12, 14]

Memorize this syntax!

It is central to so much of Python and often proves confusing for users coming from other languages.

In terms of set notation, Python indexing is left inclusive, right exclusive. If you remember this, you will never go wrong.

# that means we get an error from the following
N = len(z)
z[N]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-33-74032376c16b> in <module>
      1 # that means we get an error from the following
      2 N = len(z)
----> 3 z[N]

IndexError: list index out of range
# this index notation also applies to strings
name = 'Mickey Mouse'
print(name[:6])
Mickey
# you can also test for the presence of items in a list
5 in z
False

Lists are not meant for math! They don’t have a datatype.

z[4] = 'fish'
z
[0, 1, 2, 3, 'fish', 10, 11, 12, 13, 14]

Python is full of tricks for iterating and working with lists

# a cool Python trick: list comprehension
squares = [n**2 for n in range(5)]
squares
[0, 1, 4, 9, 16]
# iterate over two lists together uzing zip
for item1, item2 in zip(x,y):
    print('first:', item1, 'second:', item2)
first: 0 second: 10
first: 1 second: 11
first: 2 second: 12
first: 3 second: 13
first: 4 second: 14

Other Data Structures

We are almost there. We have the building blocks we need to do basic programming. But Python has some other data structures we need to learn about.

Tuples

Tuples are similar to lists, but they are immutable—they can’t be extended or modified. What is the point of this? Generally speaking: to pack together inhomogeneous data. Tuples can then be unpacked and distributed by other parts of your code.

# tuples are created with parentheses, or just commas
a = ('Mickey', 33, True)
b = 'Mouse', 25, False
type(b)
tuple
# can be indexed like arrays
print(a[1]) # not the first element!
33
# and they can be unpacked
name, age, status = a

Dictionaries

This is an extremely useful data structure. It maps keys to values.

Dictionaries are unordered!

# different ways to create dictionaries
d = {'name': 'Mickey', 'age': 33}
e = dict(name='Mouse', age=25)
e
{'name': 'Mouse', 'age': 25}
# access a value
d['name']
'Mickey'

Square brackets [...] are Python for “get item” in many different contexts.

# test for the presence of a key
print('age' in d)
print('height' in e)
True
False
# try to access a non-existant key
d['height']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-45-76eb79130058> in <module>
      1 # try to access a non-existant key
----> 2 d['height']

KeyError: 'height'
# add a new key
d['height'] = (5,11) # a tuple
d
{'name': 'Mickey', 'age': 33, 'height': (5, 11)}
# keys don't have to be strings
d[99] = 'ninety nine'
d
{'name': 'Mickey', 'age': 33, 'height': (5, 11), 99: 'ninety nine'}
# iterate over keys
for k in d:
    print(k, d[k])
name Mickey
age 33
height (5, 11)
99 ninety nine
# better way
### Python 2
### for key, val in d.iteritems()
for key, val in d.items():
    print(key, val)
name Mickey
age 33
height (5, 11)
99 ninety nine