Introduction
Contents
Introduction1#
The content of these notes is organized to accompany the books Python for Everybody by Charles Severance[Sev16] and Think Python (2nd edition) by Allen Downey[Dow15].
The code fragments have mostly been taken from the books and adapted in some cases.
You are encouraged to play along in this file as you read the book.
The more you practice programming the better your programming skills will become! You do not learn programming by just reading code, you have to write the code yourself. However, before writing the first line of code, you have to solve the problem in your head, on a blackboard or on paper. If you start solving the problem at hand by immediately writing code, you will spend a lot of time because it is a very inefficient way of working. It is too much trial-and-error. You first need to understand the problem, mentally create a solution, figure out whether you have dealt with all (corner) cases, and then start writing the code.
To evaluate a cell, select it by clicking on it, and then click the Run
cell button in the toolbar at the top, or press Shift + Enter
.
If this is your first use of Jupyter, then take the User Interface Tour (see Help > User Interface Tour
). See Help > Notebook Help
for more details, such as how to format Markdown cells.
To find out about keyboard shortcuts for Jupyter commands,
see Help > Keyboard Shortcuts
.
Pressing Cmd + Shift + P
(MacOS) / Ctrl + Shift + P
(Windows, Linux)
shows an overview of all commands.
Occasionally, we have added a bit of extra information. This is marked as [EXTRA].
Algorithms #
We can use logic to solve everyday life problems. To do so, we rely on the so-called algorithms. Logic and algorithms are not equivalent. On the contrary, an algorithm uses logic to make decisions for it to solve a well-defined problem. In short, an algorithm is a finite sequence of well-defined instructions that are used to provide a solution to a problem. According to this definition, it seems that algorithms are what we create, refine, and execute every single day of our lives, isn’t it? Think for instance about the algorithm to dress up in the morning or the algorithm (or sequence of steps) that you follow to bake a cake or cook a specific recipe. Those are also algorithms that we have internalized and follow unconsciously.
To design an algorithm, we usually first need to specify the following set of elements:
the problem to be solved or question to be answered. If you do not have a well-defined problem you might end up designing a very efficient but useless algorithm that does not solve the problem at hand. Thus, ensure you understand the problem before thinking about a solution;
the inputs of the algorithm–that is, the data you require to compute the solution;
the output of the algorithm–that is, the expected data that you want to get out of your solution, and;
the algorithm or sequence of steps that you will follow to come up with an answer.
Without having a clear picture of your problem, and the expected inputs and output to solve that problem, it will be unlikely that you will be able to come up with a proper algorithm. Furthermore, beware that for algorithms to be useful, they should terminate at some point (they cannot just run forever without providing a solution!) and output a correct result. An algorithm is correct if it outputs the right solution to every possible input. Proving this might be unfeasible, which is why testing your algorithm (maybe after implementing a program) is crucial.
3. Languages #
“The limits of my language mean the limits of my world.” - Ludwig Wittgenstein
Writing down an algorithm is of great importance given that you do not only guarantee that you can execute the algorithm in future opportunities, but you also provide a means to share the algorithm, so other people can benefit from what you designed. But to be able to write down the algorithm, we require an additional tool–that is, a language. However, the algorithms we want to write down must be written in a language that can be understood by a computer. But beware! The computer is not the only other entity that needs to understand your algorithm: what you write down should be understood by both the machine and other people that might read it afterward (including the you from the future).
A language is a system of communication. It has a syntax and semantics:
The syntax of a language describes the form or structure of the language constructs. The syntax can be defined with a grammar, which is a set of rules that specify how to build a correct sentence in the language.
The semantics describes the meaning of language constructs.
Languages can also be classified as natural or formal:
Natural languages are languages used by people to communicate with each other (e.g. English, Spanish, Dutch, Arabic). They were not designed from the very beginning; on the contrary, they evolved naturally over time.
Formal languages are languages designed by humans for specific domains or purposes. They usually are simplified models of natural language. Examples of formal languages are the mathematical, chemical, or staff (standard music notation) notations. There is also a very important example that interests us the most: programming languages.
Programming Languages#
Programming languages are formal languages with very strict syntax and semantics. These languages are used to write down algorithms. A program is, then, an algorithm implemented using a programming language. To this point, we can make some connections with previous concepts: CT is a method of problem-solving where problems are solved by reusing or designing a new algorithm. This algorithm might later be written down as a program to compute a solution to the original problem.
Python #
Python is an example of a programming language. It was conceptualized in 1989 by Guido van Rossum when working at the Centrum Wiskunde & Informatica (CWI), in Amsterdam. Python saw its beginnings in the ABC language. Its name–referring to this monumental sort of snake–actually comes from an old BBC series called Monty Python’s Flying Circus. Guido was reading the scripts of the series and he found out that Python sounded “short, unique, and slightly mysterious”, which is why he decided to adopt the name.
The Zen of Python#
In 1999, Tim Peters–one of Python’s main contributors– wrote a collection of 19 principles that influence the design of the Python programming language. This collection is now known as the Zen of Python. Peters mentioned that the 20\(^{th}\) principle is meant to be filled in by Guido in the years to come. Have a look at the principles. You can consider them as guidelines for the construction of your own programs.
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one -- and preferably only one -- obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Programs #
A program is a set of algorithms written in a given programming language, used to solve a specific problem. Programming is part of software engineering. Software engineering is the discipline of solving problems in a structured way by developing high-quality software in efficiently.
It is also important to realise that software may have a very long timespan and a lot of modifications may be performed on the software over this timespan. If you walk, for instance, into the software development department of an arbitrary bank in the Netherlands, you will find operational COBOL code written somewhere between 1960 and 1970! So this code is already 50 to 60 years old. In this timespan, we had the Y2K challenge, the introduction of the Euro, merging of banks, and changes in legislations. All these changes had to be implemented in the COBOL code that keeps the bank operational 24/7.
Keep this in mind when you are writing code, by creating a clear structure, choosing the right names for variables, functions, classes, and methods, and finally to add useful documentation to the code.
There is a lot more to tell about software engineering but for the moment this is suffient. Actually, software engineering is an entire research field.
Interpreters and Compilers #
Computers only understand machine language. This language is written exclusively in zeros and ones, so it looks somehow like this:
0011101000111010 1011010100001010
It is cumbersome for programmers to write programs in such language. That is why we need translators that map high-level laguages like Python to machine language. A high-level language is a programming language designed to be used by humans in an intuitive way. These translators can be either interpreters or compilers.
Interpreter: it reads the source code of a program written by a human, parses it and translates it on the fly. Python is an example of an interpreted programming language.
Compiler: it takes the whole program written in a high-level language and translates it into machine language. This translation is saved in an independent file that can be later used for execution. An executable file is usually labelled with the .exe or .dll extensions in Windows. There is no unique suffix for Mac or Linux. If you open a file like this in a text editor it will look somehow like this:
äE�Lâ˜ËÙìJ�Hã{(HÖˇtæË*íJ�Î∑LâΩ˚ˇˇHãΩ˚ˇˇËíJ�ÉΩà˝ˇˇÖ0��HãΩ®˝ˇˇË,íJ�H«Ö˚ˇˇ����H∏����ˇˇˇˇHâÖ˚ˇˇ1ˆ1“LâÔË‘∂ˇˇHãÖ†˝ˇˇLãpXMÖˆttAˇunIã~@HÖˇt Iâ~HË≤ëJ�Mã~ MÖˇt9IãF(L9¯t$HçX–HãxËHÖˇt HâxËäëJ�HâÿI9flu‚Iã~ ÎLâˇMâ~(ËpëJ�Iã~HÖˇt Iâ~Ë^ëJ�Lâ˜ËVëJ�foÖ˚ˇˇHãÖ†˝ˇˇÛ@XfÔ…ÛHhHâ«HÉ«xfI~∆1ˆ1“ËûπˇˇMÖˆttAˇunIã~@HÖˇt Iâ~HËëJ�Mã~ MÖˇt9IãF(L9¯t$HçX–HãxËHÖˇt HâxËflêJ�HâÿI9flu‚Iã~ ÎLâˇMâ~(Ë≈êJ�Iã~HÖˇt Iâ~Ë≥êJ�Lâ˜Ë´êJ�Ë÷êJ�Lã≠x˝ˇˇHãù0˝ˇˇLãΩÄ˝ˇˇÈÅflˇˇHãµx˝ˇˇË ≈ˇˇH9¬LãΩ–¸ˇˇLã≠p˝ˇˇÜô���Hâ”Lçµ˚ˇˇfÑ�����HâÖ˚ˇˇHâù˚ˇˇIãEHâÖ ˚ˇˇH«Ö(˚ˇˇ����IãGI;Gt2Hãç(˚ˇˇHâHHãç ˚ˇˇHâHHãç˚ˇˇHãï˚ˇˇHâPHâIÉG Î
Our First Program #
The first program any developer writes is the “Hello World!” printing program. However, we took the liberty to change this boring first program a bit.
# Our first program
print('Hello Data Scientists!')
Hello Data Scientists!
'Hello Data Scientists!'
'Hello Data Scientists!'
Do It Yourself!
Can you print the text “Hello Software Developers!”?
# Remove this line and add your code here
Arithmetic Operators #
The fact that Python interprets its programs allows us to immediately execute Python statements/expressions, such as the print statement for “Hello Data Scientists!”.
The arithmetic operators +
, -
, *
perform addition, subtraction, and multiplication, as demonstrated in the following cells.
40 + 2
42
43 - 1
42
6 * 7
42
100 * (100 + 1)
10100
Do It Yourself!
Can you add 40 to 25, then multiply it by 2, and finally substracting 5?
# Remove this line and add your code here
More arithmetic operators
The operator /
performs a division and the operator **
is the “to the power” operator.
84 / 2
42.0
100 * (100 + 1) / 2
5050.0
6**2 + 6
42
Beware of the priorities, use brackets when in doubt!
100 * 100 + 1 / 2
10000.5
Do It Yourself!
Let’s compute the area of a circle of radius \(r = 10\). Remember that the area of a circle is computed as \(a = \pi r^2\).
# Remove this line and add your code here
What Can Go Wrong? #
While writing your program you will introduce errors, and it is completely normal! However, it will be easier to fix them if you know the four types of errors that you will find.
Syntax errors: “Syntax” refers to the structure of a program and the rules about that structure. For example, in English the construct “She all night” has a syntax error because there is no verb that completes the sentence. To fix this issue you should add a verb like “She studies all night”. Now, if you run the following cell you will get a syntax error in Python. This happens because we forgot to end the line with the closing parenthesis ‘)’.
print('Hello Data Scientists!'
Cell In[15], line 1
print('Hello Data Scientists!'
^
SyntaxError: unexpected EOF while parsing
Runtime errors: these errors do not appear until the program has started running. Can you think of a runtime error?
What happens if I execute the following instructions?
value = 66
result = value / 0
print(result)
Logic errors: they appear when there is an invalid order in your program. For instance, in English the construct “She sleeps, goes to bed, and takes a shower” has logic errors. It would make more sense if we say “She takes a shower, goes to bed, and sleeps”.
Semantic errors: “Semantic” refers to meaning. These errors appear when the program does not do what it is supposed to do. If there is a semantic error in your program, it will run without generating error messages, but it will not do the right thing. It will do something else. Specifically, it will do what you told it to do. For example, you compute the addition between two numbers but the program was supposed to compute the difference.
Comments #
A program is more than just a list of instructions to be executed. It is also a means of documenting your ideas and a means of communication to fellow software developers. So, it is very important to add comments if needed to your programs, so you explain in natural language what the program is doing.
One challenge is not to write trivial comments, such as “the value 1 is assigned to the variable x”. Such a comment is useless.
Another challenge is to keep comments up to date, so if you change a program make sure the comments are still valid. It is a nightmare to maintain software with outdated comments.
A Python comment starts with
#
, and extends to the end of the line. It is ignored during execution.