Python refresher: Part I#

Hello everyone!

The first two labs are going to be just an introduction to python. It’s not feasible to become familiar with programming in just two weeks, so this is meant more for people who have had previous experience with programming but might need a refresher. These are just the minimal requirements to follow the rest of the course, and it would be great if you could try to really internalize it and become familiar with it. You do this by going through the lab multiple times, or by looking at other introductions ot python on the internet. The latter might make more sense because the particular way I have to explain this stuff might not click with you; seeing different approaches is always useful.

NOTE Much of what I will say here is not strictly true from a programming point of view, but it is true enough for our purposes. If you want to know more I can give you pointers for more in-depth treatments.

Unfortunately, familiarity with programming takes time - no way around that!

Colab#

If you want to run this code on the server (not in your laptop), you should be seeing this document on colab. Colab. Colab is a product from Google that allows anyone to write and run python code through the browser. This way, you don’t need to set up and keep track of a python environment, which can be painful, and also we can make sure that we are all working on the same system, which helps with managing packages and avoiding surprises.

While colab works pretty well for our purposes, it has some disadvantages. First, it limits the amount of computation you can do. Second, it makes it more complicated to manage files if you make changes to the notebooks I’ll provide. If you do, you’ll have to save your version of the notebook on your laptop and then re-upload it on colab to keep working on it.

Jupyter notebooks#

The labs (including the one you are working on right now!) will be written in Jupyter notebooks. Jupyter notebooks are files that contain a combination of text and code. Each notebook consists of a series of cells, and each cell is either a text cell or a code cell.

Various things to keep in mind:

  • You can select a cell by clicking on it.

  • You can edit both code and text cells. To edit a code text, press twice on it. To edit a code cell, just click on it.

  • You can run a cell by selecting it and then pressing ctrl+enter. If the cell is a text cell, it will render. If the cell is a code cell, it will run the code.

  • To add new code cells, select a cell, press Esc, and then click a to create a new cell above and b to create a new cell below the selected one.

  • You can move between cells also by pressing k to move to the cell above and j to move to the cell below.

Exercises

  • Add a new cell below this one.

Some programming concepts in python#

Spaces and indentation#

Spaces in python are part of the code, so adding or removing spaces can change the meaning of the code or break it. For instance, this should run fine:

for i in range(3):
    print(i, end='')
012

while this, which is only different in the spaces, should throw an error:

for i in range(3):
print(i, end='')
  Input In [3]
    print(i, end='')
    ^
IndentationError: expected an indented block after 'for' statement on line 1

Printing and commands#

As is traditional when learning a programming language, let’s start with how you print the string ‘Hello world’. Strings in python are written with single or double quotation marks (they aren’t quite the same, but that doesn’t matter here). For instance, the string containing the sentence ‘Hello world’ can be written as "Hello world" or as 'Hello world'.

The way we print a string is by passing the string as an argument to the print function. Here’s the code:

print('Hello world')
Hello world

Exercises

  • Create a new cell and print your name!

Comments#

Comments are parts of the code that are not ran when you run the code. You can add them to your code to add explanations about what your code is doing. In python, if we want to only comment one line, we use the symbol #: everything after # will be a comment. If we want the comment to span over multiple lines, we use three quotation marks to mark the beginning of the comment and then three more to mark its end (possibly on a different line).

For instance, suppose we wanted to comment the code above to explain what we are doing. We could do it so:

# We are printing the sentence 'Hello world'
print('Hello world')
Hello world

And suppose we wanted a longer comment over multiple lines:

"""
Here comes the first line of comment
and here comes the second
"""
print('Hello world')
Hello world

Python doesn’t see the comments!

Variables in python#

The topic of variables is huge and we can’t do it justice in the little space we have available here. But just to give you an idea, you can think of a variable as a letter or word that has some content.

In python, variables are defined with the symbol =. On the left of the symbol you specify the name of your variable, and on the right the (initial) value, which you can generally change later. For instance, suppose we want to create a variable called name that has as value the string John. We could do it as follows:

name = 'John'

NOTE Once you have defined a variable by running a cell in the notebook, the variable is accessible in other cells too!

Let’s verify this by printing the value of name in a different cell:

print(name)
John

Exercises

  • Define a new variable called myname that has your name as its value.

  • Print myname.

We can also print more than one variable in one go by passing multiple arguments to print, separated by commas:

second_name = 'Rawls'

print(name, second_name)
John Rawls

Note that not all sequence of symbols can be used for variable names in python. Here’s some criteria for a variable name:

  • It must start with a letter or the underscore character, but not a number or other symbols.

  • It can only contain letters, numbers, and underscores (A-z, 0-9, and _ )

  • It is case-sensitive (name and Name are two different variables)

We will follow the convention that when a variable name contains more than one word we want to separate, we use an underscore. For instance, we will write first_name rather than for instance firstName.

NOTE Always give your variables meaningful names or your code will be very confusing!

Operators#

We have seen how to define string and variables containing string. But what if you wanted to combine two or more strings into a longer string? This is an example of what an operator can do. You can think of an operator as a python keyword to do something to an object, for example a string.

In the case of combining string, we can use the operator +. We can do it as follows:

full_name = 'John' + ' ' + 'Rawls'
print(full_name)
John Rawls

Note that we can use the operator on the variables as well, and not just on the string themselves. The operator then will be applied to the content of the variables. For instance:

full_name = name + ' ' + second_name
print(full_name)
John Rawls

Equality sign#

The equality sign in programming in a sense is close to what in English is expressed by the word ‘is’. However, note that there is a fundamental difference between two sense of ‘a is 3’:

  1. We are giving a the value 3

  2. We are claiming that the (previously defined) variable a has value 3 The former expression is not making a claim, it’s changing something, and therefore is neither true nor false. The latter expression is true or false depending on whether we gave a the value 3.

In python, these two senses are written differently. We saw above that we use a single equality sign to attribute a value to a variable, which is the first sense defined above. For the second sense, we use two equality signs. For example:

# here we are giving a value to a with a single equality sign
a = 3
# here we are checking the value of a with two equality signs
print(a == 3)

# Now let's try with a false one!
a = 4
print(a == 3)
True
False

Data types and their operators#

Things in python can be of different types, and depending on what type they are you can do different things with them and use different operators. To check the type of any object, use the keyword type. For instance, the following tells us that a is a string ('str') and that b is an integer ('int'):

a = 'Hello Mr. Fodor!'
print('a is of type: ', type(a))

b = 12
print('b is of type: ', type(b))
a is of type:  <class 'str'>
b is of type:  <class 'int'>

Let’s consider some important types one by one (not exhaustive!).

Strings: str#

We have already briefly seen strings above. Basically, you can use them to encode text. You can join multiple strings with +, as we saw above. You can also do loads of other stuff with strings!

a = 'this is a good string'

print(a.capitalize())
print(a.swapcase())
This is a good string
THIS IS A GOOD STRING

Etcetera. If you want to know more about what you can do with strings, have a look here.

Integers: int#

Integers are just numbers without a fractional part. They can be positive or negative. Note that there are limits to the size of integers in python (and to the size of variables of every other type, too).

You can do with ints everything you’d expect to be able to do:

# add them
print(3 + 5)

# subtract them
print(4 - 10)

# check for equality
print(3 == 5)

# multiply them
print(3 * 5)

# divide them 
# NOTE: result is a float rather than an int
print(6 / 2)

# raise them to a power
print(3 ** 2)
8
-6
False
15
3.0
9

Floats: float#

Intuitively, these are numbers with a comma. You can do with them everything you can do with integers, and it behaves as you’d expect. Moreover, note that equality doesn’t care about the type:

a = 3
print(type(a))

b = 3.0
print(type(b))

print(a == b)
<class 'int'>
<class 'float'>
True

Lists: list#

You can think of lists as ordered sets of values of any type.

You can define them as follows:

# create a list 
# whose first value is 1,
# whose second value is 2,
# and whose third value is 3
a = [1, 2, 3]

print(type(a))
<class 'list'>

You can add a value to the end of a list with the keyword append, as follows:

# first define a list with two strings
a = ['first', 'second']
# add a new string to the end of the list
a.append('third')
print(a)
['first', 'second', 'third']

You can also access elements of a list as follows:

a = ['first', 'second', 'third']

# get the first element of the list
# NOTE: the index of the first element is 0!
print(a[0])

# get the second element
print(a[1])

# try to get the fourth element
# (note that the list only has three elements!)
print(a[3])
first
second
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Input In [56], in <cell line: 12>()
      8 print(a[1])
     10 # try to get the fourth element
     11 # (note that the list only has three elements!)
---> 12 print(a[3])

IndexError: list index out of range

Boolean: bool#

Boolean values are truth values, and there’s two of them: True and False. We can manipulate Booleans as you learned in logic 1. For instance, we can use the Boolean operators to calculate a function of multiple Boolean values:

print(not True)
print(not False)
print(True and True)
print(True and False)
print(True or False)
print(False or False)
False
True
True
False
True
False

Some expressions in python (e.g., ones containing equality) are Boolean values. For instance, the whole expression 3==(1+2) is just the Boolean value True:

a = 3 == (1+2)
print(a)
print(a is True)
True
True

Conditionals#

Suppose you want one thing to happen if a condition obtains and another thing to happen if it doesn’t. We can use the ‘if-else’ construction to achieve this. The way it works is:

  • The first line of the if-else construct is like:

if <condition>:

where <condition> is some expression with a Boolean value.

  • Then there is one or more lines of indented code with the stuff you want to happen if the condition obtains.

  • Then optionally there is a line that says:

else:

followed by one or more lines of indented code with the code you want to run if the condition does not hold.

For instance, suppose you want to print The variable is true if a variable has Boolean value True and print The variable is false otherwise. You can do it as follows:

a_boolean_variable = True

if a_boolean_variable:
    print('The variable is true')
else:
    print('The variable is false')
The variable is true

for loops#

Suppose you want to go through the elements of a list one by one. One way to do it would be to just do it by hand. But for long lists that would become impractical, and the point of programming is automation. A better way is to use a for loop. The idea is that you run some piece of code repeatedly, and a variables you specify takes on each value in the list in turn.

The syntax to do this is:

  1. The first line of the loop says for <varname> in <list>, where <varname> is the name of a (new) variable and <list> is a list.

  2. Then there is one or more lines of indented code, a so-called block of code. The code in the block is called one for every element of the list, and the variable <varname> takes on each value of the list in turn.

To see how this works, suppose we have a list of words and we want to print each word along with its index in the list. We could do it as follows:

useful_list = ['first', 'second', 'third']
for i in [0,1,2]:
    print(i, useful_list[i])
0 first
1 second
2 third

Some other important keywords#

range: Often, we want to loop over successive integers. range allows us to do this easily. Specifically, suppose we want to loop from number 0 to number 9. Then we could write for i in range(10). Let’s test it:

for i in range(10):
    print(i)
0
1
2
3
4
5
6
7
8
9

Note how range(n) loop from 0 to \(n-1\) rather than from 0 to \(n\)!

However, suppose we want to start from number \(m\) rather than starting from 0. range can do this too. We just need to write range(m, n) and we can loop from \(m\) to \(n-1\). Let’s try it:

for i in range(10, 16):
    print(i)
10
11
12
13
14
15

Finally, suppose we don’t want all the integers, but only every three integers. Then we can write range(m, n, 3). Let’s test this:

for i in range(10, 30, 3):
    print(i)
10
13
16
19
22
25
28

enumerate: Recall the code above where we printed each word in a list of words along with its index. Wouldn’t it be cool if there was a way of getting the word along with the index, without having to take the word from the index? There is! That’s what enumerate is for. We use it as follows:

for i, word in enumerate(['first', 'second', 'third']):
    print(i, word)
0 first
1 second
2 third

import: While ‘base’ python defines some useful by default (e.g., all the stuff we’ve seen above), often you’ll need to use functions and other things that are not defined in python by default. One option is to write them yourself, but often someone else has done that already, and if that someone else was organized enough, they put it in a library and now we can use it too! The way we do it is by first installing the library (there’s various ways of doing this, but I’ll mostly do it for you in this course) and then calling import <libraryname>, where <libraryname> stands for the name of the library you want to import.

The meaning of the dot ‘.’#

You’ll see that in python you often write things like foo.bar, where foo and bar are some words. The meaning of the dot is that you are accessing an attribute (e.g., bar) from an object (e.g., foo). E.g., it could be something like person.age or person.calculate_age(), where you are accessing the attribute age from the object person.

Objects can be all sorts of things in python (and you use the dot for things that aren’t objects, too), and this is a huge topic. But I hope that this gives you a first intuition.

In practice, you’ll soon encounter this when using a library. After we import a library, e.g., we import numpy with import numpy as np, we can access the things defined within the library with the dot notation. For instance, if we want to get the function sum from numpy, we could write np.sum

On googling problems#

Finally, a short comment on googling stuff. Finding stuff on google is an absolutely social skill for programming, whether you get an error and you have no idea what it means or you need to finds a way of doing something complicated. An important part of this skill is to learn how to phrase your problem in a way that relevant results come up. This skill is hard to teach, and often you need several tries before something relevant comes up, but some words of advice:

  • Python is incredibly popular and the community is huge. If you have a problem, it’s most likely that someone else already had it and there’s a discussion / solution out there on the internet.

  • Don’t try to google your whole problem. Think whether you can break it down in smaller problems and google the smaller ones. While it’s possible that nobody was in the exact same situation as you, the features of your situation probably are pretty common. To give an extreme example, if you encounter a programming problem in this course you wouldn’t google ‘Fausto probabilistic LoT why is sum not working’, but rather just something about the sum. Think what’s essential to your problem.

  • Googling technical questions is not necessarily ‘cheating’, and normal programming involves constant googling. You need to ask yourself if the googling you are doing is a normal part of the programming. A possible rule of thumb in the context of this course is: Think about how much time you can spend on the exercise, if you have a problem stop and think before you google, but if you feel you’re stuck and can’t finish within the self-allotted time or if you don’t see a way to proceed after a good think, google it.

Some exercises#

Please make sure you can do these exercises:

  1. Write a loop that prints the characters in the string ‘Fodor was a great writer’. The output should be:

F
o
d
o
r
 
w
a
s

etc.

  1. Write a conditional that prints ‘Odd’ if a variable’s value is odd and ‘Even’ otherwise.

  2. Write a loop that prints the first 50 even numbers.

  3. Write a loop that given a string prints each character in the string twice.

  4. Print the first 20 even numbers without calling range with three arguments.

One more word on programming#

This was a super super condensed introduction / refresher on python, but of course it could only scratch the surface of the tip of the iceberg (metaphor parkour!).

If this stuff was all familiar and easy peasy, steady on. However, if you found it new / difficult / confusing, I recommend that you try to familiarize yourself with these concepts as soon as possible. Also, let me know and if there is enough interest I can arrange a separate class for a more thorough introduction to programming.

Don’t lose the thread of the course!