Ae1205 Python Tutorial v5
Ae1205 Python Tutorial v5
Programming and Scientific Computing in Python for AE1 (Technische Universiteit Delft)
3
for Aerospace Engineers
print("Hello world.")
if language==python:
programming = fun
Table of Contents
1. Getting started ......................................................................................................................... 9
1.1 What is programming? .......................................................................................................... 9
1.2 What is Python? .................................................................................................................. 10
1.3 Installing Python ................................................................................................................. 12
1.3.1 Windows ...................................................................................................................... 12
1.3.2 Linux ............................................................................................................................ 14
1.3.3 Apple ............................................................................................................................ 14
1.3.4 Explanation of the installed modules ........................................................................... 16
1.3.5 Configuring Python IDLE............................................................................................ 16
1.3.5 Working environments: IDLE, PyCharm and Spyder ................................................. 18
1.3.6 Documentation ............................................................................................................. 20
1.4 Sneak preview: Try the Python language yourself ............................................................. 21
1.4.1 Temperature conversion: (PRINT, INPUT statement, variables) ................................ 21
1.5 Variables and assignment statement ................................................................................... 22
1.6 Finding your way around: many ways in which you can get help ................................. 25
2. Variable assignment and types.............................................................................................. 29
2.1 Example: a,b,c formula solver (IF statement, Math functions) ...................................... 29
2.1 Assignment and implicit type declaration........................................................................... 30
2.2 Short-hand when using original value with an operator ..................................................... 31
2.3 Number operations in Python ............................................................................................. 32
2.4 Floats: variable type for floating point values .................................................................... 32
2.5 Integers: variable type for round numbers like counter or index) ...................................... 33
2.6 Complex numbers ............................................................................................................... 35
2.7 String operations ................................................................................................................. 35
2.8 Booleans and logical expressions ....................................................................................... 38
2.9 List type: collection of items ordered in a table .................................................................. 39
2.9.1 What are lists? .............................................................................................................. 39
2.9.2 Indexing and slicing, list functions and delete ............................................................. 40
2.9.3*** Lists are Mutable: risks with multiple dimensions list creation ............................ 41
2.9.4 List methods ................................................................................................................. 44
2.10 Some useful standard, built-in functions .......................................................................... 45
3. Python syntax: Statements .................................................................................................... 46
3.1 Assignment ......................................................................................................................... 46
3.2 Print statement ................................................................................................................ 49
15.2 Making a setup program with e.g. Inno Setup ................................................................ 143
16. Version Control ..................................................................................................................... 144
16.1 Managing development of larger projects ...................................................................... 144
16.2 Basic concepts of version control ................................................................................... 144
Repository, working copy ................................................................................................... 144
Revision, commit, check-out .............................................................................................. 144
Comparing source code....................................................................................................... 145
Distributed and centralized ................................................................................................. 146
Branches, and merging........................................................................................................ 147
16.3 Subversion....................................................................................................................... 148
16.4 Git ................................................................................................................................... 149
17. Go exploring: Some pointers for applications of Python beyond this course.................. 151
17.1 Alternatives to pygame for 2D graphics ......................................................................... 151
17.1.1 Tkinter canvas (included in Python) ........................................................................ 151
17.1.2 Tkinter canvas (included in Python) ........................................................................ 151
17.1.3 Arcade ( http://arcade.academy/ ) ............................................................................ 151
17.1.4 Miscellaneous .......................................................................................................... 154
17.1.5 Using Python Console in GIMP .............................................................................. 154
17.2 Animated 3D graphics .................................................................................................... 155
17.2.1 VPython or Visual Python: easy 3D graphics.......................................................... 155
17.2.2 Panda3D ................................................................................................................... 156
17.2.3 Open GL programming ............................................................................................ 156
17.2.3 Blender (www.blender.org) ..................................................................................... 157
17.2.4 Physics Engine: PyODE (http://pyode.sourceforge.net/)......................................... 157
17.3 User interfaces: windows dialog boxes, pull-down menus, etc. ..................................... 158
17.3.1 Tkinter ...................................................................................................................... 158
17.3.2 PyQt ......................................................................................................................... 161
17.3.4 wxPython ................................................................................................................. 163
17.3.5 GLUT ....................................................................................................................... 163
17.3.6 Glade Designer for Gnome ...................................................................................... 163
17.4 Reading from and writing to Excel sheets ...................................................................... 165
17.5 Interfacing with hardware ......................................................................................... 167
17.5.1 Raspberry Pi ............................................................................................................. 167
17.5.2 MicroPython ............................................................................................................ 168
Appendix A Overview of basic Python statements .................................................................... 171
Appendix B Overview of functions and special operators ......................................................... 172
Appendix C Example piece of code............................................................................................ 173
Appendix D Solutions to exercises ............................................................................................. 174
Preface
This first version of this reader was developed for, and during the pilot of, the Programming
course in the first year of the BSc program Aerospace Engineering at the Delft University of
Technology in 2012. Originally it was written for Python 2 and then converted to Python 3.
The goal of the Python programming course is to enable the student to:
- write a program for scientific computing
- develop models
- analyze behavior of the models using e.g. plots
- visualize models by animating graphics
The course assumes some mathematical skills, but no programming experience whatsoever.
This document is provided as a reference for the elaboration of the assignments. The reader is
encouraged to read through the relevant chapters applicable to a particular problem. For later
reference, many tables, as well as some appendices with quick reference guides, have been
included. These encompass the most often used functions and methods. For a complete overview,
there is the excellent documentation as provided with Python in the IDLE Help menu, as well as
the downloadable and on-line documentation for the Python modules Numpy, Scipy, Matplotlib
and Pygame.
Also, the set-up of the present course is to show the appeal of programming. Having this
powerful tool at hand allows the reader to use the computer as a ‘mathematical slave’. And by
making models, one basically has the universe in a sandbox at one’s disposal: Any complex
problem can be programmed and displayed, from molecular behavior to the motion in a complex
gravity field in space.
An important ingredient at the beginning of the course is the ability to solve mathematical
puzzles and numerical problems. Also the very easy to use graphics module Pygame module has
been included in this reader. This allows, next to the simulation of a physical problem, a real-
time visualization and some control (mouse and keyboard) for the user, which also adds some
fun for the beginning and struggling programmer in the form of visual feedback.
Next to the mathematical puzzles, challenges (like Project Euler and the Python challenge) and
simulations and games, there is a programming contest included in the last module of the course
for which there is a prize for the winners. Often students surprise me with their skills and
creativity in such a contest by submitting impressive simulations and games.
Also check out the accompanying videos: Search for “AE1205” on Youtube.
Many thanks to the students and teaching assistants, whose questions, input and feedback formed
the foundation for this reader.
Prof.dr.ir. Jacco M. Hoekstra
Faculty of Aerospace Engineering
Delft University of Technology
1. Getting started
This also means that learning to program is very different from the learning you do in most other
courses. In the beginning, there is a very steep learning curve, but once you have taken the first
big step, it will become much easier and a lot of fun. But how and when you take that first hurdle
is very personal. Of course, you first need to achieve the right rate of success over failure,
something you can achieve by testing small parts during the development. For me, there aren’t
many things that give me more pleasure than to see my program (finally) work. The instant,
often visual, feedback makes it a very rewarding activity.
And even though at some stage you will also see the right solution method in a flash, at the same
time your program will almost certainly not work the first time you run it. A lot of time is spent
understanding why it will not work and fixing this. Therefore some people call the art of
programming: “solving puzzles created by your own stupidity”!
Another way to design and represent algorithms is using simplified natural language. Let’s take
as an example the algorithm to “find the maximum value of four numbers”. We can detail this
algorithm as a number of steps:
Going through these steps, the result will always be that the maximum value of the four numbers
is shown on the screen. This kind of description in natural language is called “pseudo-code”.
This pseudo-code is already very close to how Python looks, as this was one the goals of Python:
it should read just as clear as pseudo-code. But before we can look at some real Python code, we
need to know what Python is and how you can install it. After that, we will have a look at some
simple programs in Python, which you can try out in your freshly installed Python environment.
Guido van Rossum was employed by Google for many years, as this is one of the many
companies that use Python. He is currently working for another user of Python: Dropbox. He still
is the moderator of the language, or as he is called by the Python community: the “benevolent
dictator for life”.
A practical advantage of Python is that it supports many platforms (Windows, Apples, Linux)
and that it is free, and so are all add-ons. Many add-ons have been developed by the large
(academic) Python community. Some have become standards of their own, such as the scientific
package Numpy/Scipy/Matplotlib. These scientific libraries (or modules as they are called in
Python), in syntax(grammar) heavily inspired by the software package MATLAB, are now the
10
standard libraries for scientific computing in Python. IEEE has named Python as the de facto
standard programming language for data analysis.
Up to Python 3 all versions were downwards compatible. So all past programs and libraries will
still work in a newer Python 2.x versions. However, at some point, Guido van Rossum, being the
BDFL (Benevolent Dictator For Life) of Python, wanted to correct some fundamental issues,
which could only be done by breaking the downward compatibility. This started the development
of Python 3.0. For a long time Python 2.x was also still maintained and updated. This has
stopped around 2018.
An example of a difference between the two versions is the syntax of the PRINT-function, which
shows a text or a number on the screen during runtime of the program:
(Another major difference applies to integer division and the input( ) function, but we need to
know more about data types to understand that.)
Python is called a scripting language. This means that the Python source is interpreted when you
run the program as opposed to needing to compile all program files first, then link them together
with the correct libraries to make an executable and then run this. This is very user-friendly:
there is no need to compile or link files before you can run the same program on any operating
system: Windows, Apple’s Mac OS or Linux. Many Python libraries are platform dependent, but
most are available on all three supported platforms.
The penalty for this is, depending on your program structure, sometimes some execution speed.
Some runtime, often seconds or milliseconds, are traded for shorter development times, which
saves time in the order of days or weeks. Note that Python libraries like Numpy and Scipy use
very fast low-level modules, resulting in extremely fast execution times for scientific computing.
By using a similar syntax, this is replacing MATLAB (which also uses a small scripting
language) worldwide. Using vectorized programming and the numpy librarie make runtimes
comparable with optimized C++ and Fortran for the scientific computing. The same mechanism
allows fast graphics. For example for 2D graphics the Pygame graphics library, which is a layer
over the very fast and famous SDL library, is also extremely fast.
Using an interpreter instead of a compiler, means you need to have Python, with its interpreter,
installed on the computer where you run the Python program. Would you ever want to make an
executable to avoid this requirement, there are modules, like distutils, or add-ons, like called
Py2exe creating self-contained application which does not need Python installed. Such an
executable will only run on the OS under which it was compiled. How this should be done, is
covered by a separate chapter of the reader, called ‘Distributing your Python program’. Using the
Inno Setup tool, you can make a installer for your application on Windows for example. This
tool converts the complete folder with data and the program into one setup executable file, which
is also covered in this chapter.
11
1.3.1 Windows
Go to Python.org and download the latest version of Python 3 64-bits.
(You can also check it out at Youtube: https://youtu.be/-P7dVLJPows )
If you’re installing it a second time, then make sure you have uninstalled/removed any other
versions of Python, using the Add/Remove Apps/Programs from the Settings/Configuration
panel of Windows.
Then select Install to do a full install, so select all options in the installer see figures below.
12
Now you have pip installed, which makes it relatively simple to install the other packages. Pip
makes sure to download the exactly right version for your installation of Python and OS and will
install it.
Now we install the additional modules which we will use in this course. In the Windows Start
Menu, Search for ‘Command prompt’ and if the window below does not appear, right click it.
13
Python includes the editor IDLE, which we will use mostly in the course. But for larger projects
you can use more advanced editors like PyCharm, Visual Code with Python extension, Sublime,
etc.
1.3.2 Linux
Open a terminal, then type follow two lines (replace 'apt' with 'zypper' on for RPM based Linux):
1.3.3 Apple
Installing python3 and all the required packages on macOS takes a little more effort. Since
python2 is part of the operating system on your Mac, the installation of both python2 and
python3 can cause conflicts on your laptop.
Make sure that you follow this manual explicitly when installing python3. If you have installed
python2 previously, make sure you completely remove any python2 installation before you
proceed.
1. Download Anaconda for Mac from the following link. Make sure you select the Python
3.* version. https://www.anaconda.com/download/#macos
2. Open de .pkg file you just downloaded and follow the installation instructions. Anaconda
will install most packages that are required for this course for you, but Pygame is one of
the packages that have to be installed at a later stage.
3. After the installation you can find the ‘Anaconda-Navigator’ in your Applications folder.
Open the Anaconda-Navigator
4. On the left of the screen that appears you can see a menu with “Home” and
“Environment” being the most important. If you go to “Environment” you can see which
packages are installed in this conda installation. Next to this, you can also install new
packages that are in the conda library. In the “Home” screen you can launch different
apps that come preinstalled with Anaconda, the one you will be using is Spyder. Launch
Spyder now.
5. Once you have launched Spyder, you have one setting that you have to change. Go to
‘python’ in the top left corner of your Mac and select ‘preferences’. Select the ‘iPython
console’ menu, go to ‘graphics’ and make sure you change the Graphics Backend from
‘inline’ to ‘Qt5’. This ensures that your plots show up nicely when using plotting tools
later on in this course.
14
6. Now you only have to install pygame. Go to your Applications folder and open
‘Terminal’. Type pip install pygame. This will ensure the correct version of pygame is
installed and linked to your Anaconda installation. To check if everything is functioning
properly, please go to the iPython console in spyder and type ‘import pygame’. If you do
not get an error and see the ‘Hello from the community’ message, your installation is
completed!
15
If you ever want to install a package which is not found by pip, it might be useful to download
the .whl (wheel file) which is used by pip, yourself from this site:
https://www.lfd.uci.edu/~gohlke/pythonlibs/
Download the correct wheel file yourself, open a Command prompt, go to the downloads folder
(with cd command) and type “pip install” in the folder with this file followed by the filename,
for example:
16
menu. It contains “Run”, indicating this is a Program window, still called Untitled at first. Enter
the following lines in this window:
print(“Hello World!”)
print(“This is my first Python program.”)
Note: Python is case sensitive, so it matters that you use lower case for the print command.
Now select Run > Run Module. You will get a dialog box telling you that you have to Save it
and then asking whether it is Ok to Save this, so you click Ok. Then you enter a name for your
program like hello.py and save the file. The extension .py is important for Python, the name is
only important for you. Then you will see the text being printed by the program which runs in
the Python Shell window.
After File>New Window, IDLE shows an editor window (right) next to the Shell window(left)
Note: Be careful not to use program names which are identical to modules that you import. So
avoid calling your program “python.py” or “numpy.py” or”math.py” etc. Also for every new
assignment or set of exercises make a new folder to keep your files well organized.
17
For more larger projects, there are many other IDEs, for example PyCharm. You try any of these.
At the exam IDLE will be sufficient and Spyder is also available. So it is advised to learn how to
use IDLE for the exam.
Though IDLE is a very useful IDE (Interactive Development Environment), there are some
limitations:
- With large projects and many files it can become cumbersome to switch between
different files
- Debugging facilities are limited
For this reason often other IDEs are used for larger projects. There are many on the web.
The screenshot on the next page shows PyCharm, a very popular versatile IDE. The community
version, which we use, is freely available from Jetbrains:
https://www.jetbrains.com/pycharm/download/
PyCharm IDE
For scientific purposes a very popular one is Spyder, as it reminds many older users of the
Matlab tool for scientific computing which they used before. An example of a screenshot of
Spyder with some explanation is given below:
18
Spyder screenshot
Other features include inspecting data arrays, plotting them and many other advanced debugging
tools.
Make sure to change the settings of file in the dialog box which will pop up the first time you run
the file to allow interaction with the Shell. Then you have similar features to which IDLE allows:
checking your variables in the shell after running your program or simply to testing a few lines
of code.
Spyder has chosen to stop offering a standard Python console, so they only have an iPython
console. By tweaking the run setting per file, it is still possible to run your script in an external
Python console. But this would still be a reason to prefer PyCharm as it is more versatile and
focused on Standard Python applications not just the interactive iPython.
My advice would be to first keep it simple and use IDLE for the basics. Use the print( ) function
and the shell (to inspect variables) as debugger and occasionally www.pythontutor.com. Then
later, and only for larger or more complex problems switch to PyCharm or Sublime (or
optionally Spyder).
There are many IDEs, here are some you could try out:
- PyCharm
- Sublime
- VSCode
- Atom (open source shareware, multi-platform)
- Eclipse
- Wing
- PyDev
A different environment especially for Scientific Computing, using iPython is Jupyter, which
creates Python Notebooks, a beautiful blend between a document, spreadsheet and Python.
19
1.3.6 Documentation
IDLE, our default editor supplied with Python, has an option to Configure IDLE and add items to
the Help menu. Here a link to a file or a URL can be added as an item in the Help pull down
menu.
The Python language documentation is already included,select them with F1, on-line they can be
found at:
https://docs.python.org/3/
For Scipy and Numpy, downloading the .HTML files of the reference guides onto your hard disk
and linking to these files is recommended. They are available for download at:
http://docs.scipy.org/doc/
http://matplotlib.sourceforge.net/contents.html
Also check out the Gallery for examples but most important: with the accompanying source code
for plotting with Matplotlib:
http://matplotlib.sourceforge.net/gallery.html
http://www.pygame.org/docs/
Another useful help option is entering ‘python’ in the Google search window followed by what
you want to do. Since there is a large Python user community, you will easily find answers to
your questions as well as example source codes.
Search on Youtube for the course code AE1205 for some videos or the Python 3 playlist:
https://www.youtube.com/results?search_query=ae1205
Stackoverflow contains many answers and will often show up in your Google results:
https://stackoverflow.com/questions/tagged/python-3.x
20
In the IDLE window, named Python Shell, select File > New Window to create a window in
which you can edit your program. You will see that this window has a different pull-down menu.
It contains “Run”, indicating this is a Program window, still called Untitled at first.
Enter the following lines in this window and follow the example literally.
Exercise 1: If you want to make it a bit more interesting, and harder for yourself, you could make
a variation on this program. In much the same fashion, you could try to make a saving/debt
interest calculator where you enter start amount, interest rate in percentage and number of years.
To raise x to the power y, you use x**y)
Exercise 2: Make a program that computes the overall resistance for the
circuit shown at the right, where your inputs are the three resistances (RA,
RB, RC).
Now select Run > Run Module. Depending on your settings, you might get a dialog box telling
you that you have to Save it and then asking whether it is Ok to Save this, so you click Ok. Then
you enter a name for your program like temperature.py and save the file. The extension .py is
important for Python, the name is only important for you. Then you will see the text being
printed by the program, which runs in the window named “Python Shell”:
21
Now let us have a closer look at this program. It is important to remember that the computer will
step through the program line by line. So the first line says:
The computer sees a print( ) function, which means it will have to output anything that is entered
between the brackets, separated by commas,) to the screen. In this case it is a string of characters,
marked by a “ at the beginning and the end. Such a string of characters is called a text string or
just string. So it put this on the screen. The computer will also automatically add a newline
character to jump to the next line for any next print statement (unless you specify otherwise,
which will be explained later).
Then this line is done, so we can go to the next one, which is slightly more complicated:
Then this line is done, so we can go to the next one, which is slightly more complicated:
This first part of this line, until the “=”,should be read as: “let tempf be”. This is a so called
assignment statement, indicated by the “=” symbol. In general, it has the following structure:
variablename = expression
In our example it tells the computer that in the computer’s memory a variable has to be created
with the name tempf. (If the variable name is already in use, it will be overwritten by this result
at the end.)
22
To be able to do this, the computer first evaluates the expression on the other side of the “=” sign
to see what the type of this variable has to be. It could for example be a floating point value
(float type) or a round number (integer type), a series of characters (string) or a switch (boolean
or logical). It then reserves the required amount of bytes, stores the type and the name. If the
name already exists, then this old value and type are first to avoid problems later on.
The computer evaluates the expression. The outcome is stored in memory and can be used later
in other expressions by using the variable name on the left side of the equal sign. To do this, the
computer saves the name in a table associated with this module. This table contains information
on the type of variable and points to a computer memory address where the value is stored.
name ‘a’
type Integer 4 bytes
memory address 1625981072
… ….
a = 2
Address Byte value
1625981072 2
1625981073 0
1625981074 0
1625981075 0
For numbers, three basic types of variables exist, each stored binary in a different way:
- Integers: 2
- Floats: 2.0
- Complex: 2.0+0j
Integers are whole numbers, used to count something or as an index in a table or grid. Floats are
numbers with a floating point and can have any real value. Complex numbers refer to the
mathematical definition of ‘complex’, which have a real part and an imaginary part. They are
like floats but can have an imaginary part next to the real part. Each type is stored in a different
way.
23
In chapter 2 the assignment statement, as well as the different types ofvariables are discussed in
detail.
Now let us have a look at the expression in our example program. This is not a simple one. The
expression in our example has a combination of twice the following structure :
functionname ( argument )
Python knows this is a function because of the brackets. In our example case, there are two
functions float( ) and input(). As the result of the input-function is needed as input of the
float-function, the input function is called first. Both are standard functions included in the
Python language. (Later we will also use functions which we have defined ourselves!)
Most functions do some calculations and yield a value. Example of these functions are abs(x)
for the absolute value (modulus) of x or int(x) which will truncates the float x to returns an
integer type. The int( ) function is one of the type conversion functions:
But some functions are complete little programs in itself. The input-functions for example does
more: it can be called with one argument, which will be printed on the screen, before the user is
prompted to enter a value. When the user presses enter, the value is read, the type is determined
and this is returned as the result by the input function. So in our case, the text Enter
temperature in degrees Fahrenheit: is printed and the user enters something
(hopefully a number) and this is then stored as an integer or floating point number in a memory
location. We call this variable tempf.
The next line is again an assignment statement as the computer sees from the equal sign “=”:
tempc = (tempf-32.0)*5.0/9.0
Here a variable with the name tempc is created. The value is deduced from the result of the
expression. Because the numbers in the expression on the left side of the equal sign are spelled
like “5.0” and “32.0”, the computer sees we have to use floating point calculations. We could
also have left out the zero as long as we use the decimal point, so 5./9. would have been
sufficient to indicate that we want to use floating point values.
If we would leave them out, so using 5/9 would strictly speaking refer to dividing two integers.
In Python 2 the result will hence be zero. However, in Python 3, this is converted to a float, as it
often led to errors. Integer division is still available, but requires two slashes: 5//9 will yield
24
zero as result in integer arithmetic. (See sections 2.4 and 2.5 for a detailed discussion of the
difference between integers and floats).
When this expression has been evaluated, a variable of the right type (float) has been created and
named tempc, the computer can continue with the next line:
This line prints four things: a variable value, a text string, an expression which needs to be
evaluated and another text string, which are all printed on the same line as with each comma a
space character is automatically inserted as well. The round function means the result will be
rounded off.
Try running the program a few times. See what happens if you enter your name instead of a
value.
1.6 Finding your way around: many ways in which you can get
help
There are many ways to get help. For instance if you need help on the range function, in the
Python shell, you can type:
help(“range”)
Which calls the help-function and uses the string to find appropriate help-information. Similarly
to find methods of the list or string type, use:
help(“list”)
You can also use help interactively by typing help(), without arguments, and then type the
keywords at the “help>” prompt to get help, e.g. to see which modules are currently installed.
>>>help()
help>math
And you will see an overview of all methods in the math module. There are some limitations to
this help. When you will type append, you will not get any results because this is not a separate
function but a part of the list object, so you should have typed
>>> help("list.append")
Help on method_descriptor in list:
list.append = append(...)
L.append(object) -- append object to end
25
>>>
>>> help()
Welcome to Python 3.6’s help utility.
…..
help> list.append
Help on method_descriptor in list:
list.append = append(...)
L.append(object) -- append object to end
help>
26
27
Python has a very large user community: conservative estimates say there are 3 to 5 million
Python users and it’s growing fast as MIT, Stanford and many others use Python in their
programming courses and exercises. It is also the most popular language among PhDs. IEEE
calls it the standard language for scientific computing and data analysis.
So simply Googling a question (or error message) with the keyword Python (or later Numpy) in
front of it as an extra search term will quickly bring you to a page with an example or an answer.
For basic questions this might bring you to the same documentation as in the Help-menu which
is at http://docs.python.org . You will also see that www.stackoverflow.com is a site, which will
often pop-up, and where most questions you might have, have already been posed and answered:
(Which shows that next to append() there apparently is another method called extend() is
available, which works with a list as an argument and apparently appends each element to the
list.)
In general, thanks to the interactive Python Shell window, simply trying statements or program
lines in the Python shell is a way to try what works as you intended. Or to check the value of
variables after your still incomplete program has run.
To find bugs in your program, for small programs http://www.pythontutor.com can be helpful to
see what is going on inside the computer when your program runs. And of course using the print
statement to see what a variable is, or where the computer gets stuck in your program, is always
the first thing to try.
Be prepared that in the beginning the level of frustration might be high, but so is the reward
when your program runs. And when you get experience, you will see how fast you can make
working programs, not because you won’t create bugs, but because you will immediately
recognize what went wrong. The nice thing of software is that it can always be fixed, so “trial
and error” is an accepted way to develop programs. So do not be afraid to try things and play
around with Python to get acquainted with the way it works.
In appendix A and appendix B a short overview of the Python statements and most important
functions is given. Having a copy of these pages at hand may be handy when starting Python. It
will provide the keywords for you to look into the help-functions of Google searches. Appendix
C given some example source code.
Although we already touched upon most basic elements of the Python language, we have not
seen all statements and types yet, so first go through the next chapters (discover the very useful
while-loop, the string type and its methods and the Boolean/logical and slicing of strings and lists
etc.). Just glance over these chapters to get the essence and then start making simple programs
and study the paragraphs in more detail when you (think you) need them. Programming has a
steep learning curve at the beginning, so good luck with making it through this first phase. Once
you have passed this, things will be a lot easier and more rewarding. Good luck!
28
Below is an example program to solve a second order polynomial equation. We will use this
example to discuss the use of variables in systematic fashion.
import math
D = b**2 - 4.*a*c
print("x1 =",x1)
print("x2 =",x2)
But first some notes about this program. Run this program and you will see the effect.
- note how ** is used to indicate the power function. So 5**2 will yield 25. (Using 5*5 is
faster by the way.)
- the program uses a function called sqrt() This is the square root function. This function is
not a standard Python function. It is part of the math module, supplied with Python.
Therefore the math module needs to be imported at the beginning of the program. The
text math.sqrt() tells Python that the sqrt() function can be found in the imported math
module
- After you have run the program, you can type D in the shell to see the value of the
discriminant. All variables can be checked this way.
Also, note the difference between text input and output. There is no resulting value returned by
the print function, while the input function does return a value, which is then stored in a
variable. The argument of the input-function calls is between the brackets: it’s a prompt text,
which will be shown to the user before he enters his input.
There is one problem with our program. Many times it will stop with an error because the
discriminant D is negative, resulting in an error with the square root function.
29
To solve this, we need an extra statement, called IF. This will be discussed in the next chapter.
In this chapter we describe the building blocks which you need to write a program. First we have
a look at variables. A variable is used to store data. But there are different types of data: numbers
or bits of text for instance. There are also different data types of numbers Of course there are
more data types than just text and numbers, like switches (called “booleans” or “logicals”) and
tables (“lists”). The type of variable is defined by the assignment statement, the programming
line giving the variable its name, type and value. Therefore we first concentrate the assignment
statement and then the different data types are discussed.
variablename = expression
Example assignment statements for the four main types (which will be discussed in detail in the
following sections):
Floats, contain a decimal point or “e” to indicate the exponent of the power of 10:
in = 2.54
ft = .3048
lbs = 0.453592
spd = 4.
alt = 1e5
Logicals:
swfound = True
alive = False
forward = (v > 0.0)
onground = h <= 0.0 and abs(v) < eps
running = (forward or alive) and not onground
Python even allows multiple assignments at once when the values are separted by a comma:
a,b,c = 1. , 3. , 5
a,b = b,a # swap two variables
30
What really happens is that the expression first becomes a type of list (a tuple to be exact) which
is then unpacked. The example below shows that this principle also works with a list, which is
defined by a serie of variables within square brackets:
lst = [9 , 2 , 5]
a,b,c = lst
Mathematically speaking this statement would be nonsense if we would read the equal sign as
‘being equal to’. But as an assignment statement, this simply evaluates the expression on the
right side, which is the content of variable i to which one is added, and the result is stored in the
variable i again. The effect is thus that i is increased with 1. Here are a few other example with
the same logic:
As especially the increase or decreases with one occurs often, there is a shorthand notation for
things:
“ i = i + ” => “ i +=”
This short-hand is the same as in the programming language C (and C++), a language which is
well known for how short code can be written (often with an adverse effect on the readability).
Also in this example, the benefit is mainly for the programmer who saves a few keystrokes, there
is no execution time benefit as the operations done are the same. This short-hand hence increases
the distance from pseudo-code. Whether you use it is a matter of personal preference.
31
For the number types float, integer (and complex) the following operators can be used
+ Addition
- Subtraction
* Multiplication
/ Division
// Floored or integer division (rounded off to lower round number)
% Modulo, remainder of division
** Power operator x**y is x to power y, so x**2 is x2
-x Negated value of x
+x Value of x with sign unchanged
They are stored in a binary exponential way with base 2 (binary). This means that values which
are round values in a decimal systems sometimes need to be approximated. For insatcne if you
try typing in the shell:
>>> 0.1+0.2
0.30000000000000004
Often this is not a problem, but it should be kept in mind, that float are always approximations!
One special rule with floats in programming is that you never test for equality with floats. So
never use the condition “when x is equal to y” with floats, because a minute difference in how
the float is stored can result an inaccuracy, making this condition False when you expected
otherwise. This may not even be visible when you print it, but can still cause two variables to be
different according to the computer while you expected them to be the same. For example:
adding 0.1 several times and then checking whether it is equal to 10.0 might fail because the
actual result is approximated by the computer as 9.99999999 when it passes the 10. So always
32
test for smaller than (<) or larger than (>). You can also use “smaller or equal to” (<=) and
“larger or equal to” (<=), but do not forget that a floating point variable is always an
approximation due to the binary storage limitations (which is different from a decimal notation),
so it may be off by a small value. A way to avoid it is to test for closeness:
Floating point values can also be rounded off using the round(x) or round(x,n) function. With the
second argument n, you can specify the amount of decimals. When the second argument isnot
used, the result will be rounded off to the nearest value and converted to the type integer
automatically.
>>> round(10/3)
3
>>> round(10/3,4)
3.3333
>>> round(10./3.,0)
3.0
Try adding 0.1 to a variable for more than 1000 times (use a for-loop or while-loop) and check
the variable value to see this effect.
2.5 Integers: variable type for round numbers like counter or index)
Integers are variables used for whole numbers. They are used for example as counters, loop
variables and indices in lists and strings. They work similar to floats but division results will be
of the type float. For example:
a = 4
b = 5
c = a/b
print(c)
This will print 0.8 (in Python2 it would always floor this to an integer, but in Python 3, this has
been changed). If you want to use integer division, use a double slash:
a = 4
b = 5
c = a//b
print(c)
33
A very useful operator, especially with integers, is the ‘ %’ operator. This is called the modulo
function. You could also call it “the remainder” because it gives only remainder of a division.
For example:
27%4 = 3
4%5 = 4
32%10 = 2
128%100 = 28
You can convert integers to floats and vice versa (since they are both numbers) with the
functions int() and float():
a = float(i)
j = int(b) # Conversion cuts of behind decimal point
k = int(round(x)) # Rounded off to nearest whole number
# ..and then converted to an integer type
The int() function will cut off anything behind the decimal point, so int(b) will give the
largest integer not greater than b . These functions int() and float() can also take strings
(variables containing text) as an argument, so you can also use them to convert text to a number
like this:
txt = "100"
i = int(txt)
a = float(txt)
n = 20
i = 3
a = n/i
print(“a =”,a)
a = 6.666666666666667
j,k,m = 6 6 7
34
As we can see from the missing decimal points in the second output line, the variable j, k, m
all are integers. This can also be verified in the shell by using the type( ) function:
>>> type(m)
<class 'int'>
c = 3+4j
print (“Length of”,c,”is”,abs(c))
c = 3+0j
a = c.real
b = c.imag
print(“c has”,a,”as real part and”,b,”as imaginary part”)
>>> e = 2.718281828459045
>>> pi = 3.141592653589793
>>> e**(1j*pi)
(-1+1.2246467991473532e-16j)
Which demonstrates Euler’s equation and also shows the rounding off problems in the imaginary
part, which is practically zero. Both e and pi were binary approximations, as are all floats and
complex numbers.
35
operator on strings is the “+” which glues them together, Which can be very useful, e.g in
functions which expect one string variable (like the input function).
Example assignments:
txt = "abc"
s = ""
name = "Jacco"+" M. "+"Hoekstra" (so the + concatenates strings)
words = 'def ghi'
a = input("Give value at row"+str(i))
Using indices in square brackets [ ] allows you to take out parts of a string. This is called slicing.
You cannot change a part of string but you can concatenate substrings to form a new string
yielding the same effect:
c = "hello world"
c[0] is then "h" (indices start with zero)
c[1:4] is then "ell" (so when 4 is end, it means until and not including 4)
c[:4] is then "hell"
c[4:1:-1] is then "oll" so from index 4 until 1 with step -1
c[::2] is then "hlowrd"
c[-1] will return last character "d"
c[-2] will give one but last character "l"
c = c[:3]+c[-1] will change c into "hel"+ "d"="held"
the string variable also has many functions built-in, the so-called string methods. See some
examples below (more on this in chapter 8).
For more methods see chapter 8 or 5.6.1 of the Python supplied reference documentation in the
Help file.
36
Strings are stored as lists of characters. Characters are stored as numbers,using Unicode. This
encoding is an extension of the ASCII codes. See the table below:
ACII codes can be dereived using the ord(txt) function, similarly the character for an ASCII
code i can be retrieved hsing the chr(i) function
Special characters in a string are: \n (newline) or \t (tab)
In Windows/DOS text files the newline is indicated by characters: both a Carriage Return &
Line Feed: chr(13)+chr(10). While in Linux/Apple it is only a newline character chr(10)
37
Booleans (or logicals) are two names for the variable type in which we store conditions. You can
see them as switches inside your program. Conditions can be either True or False, so these
are the only two possible values of a logical. Mind the capitals at the beginning of True and
False when you use these words: Python is case sensitive. Examples of assignments are given
below:
found = False
prime = True
swlow = a<b
outside = a>=b
swfound = a==b
notfound = a!=b ( != means: not equal to)
notfound = a<>b ( <> also means: not equal to, but is old notation)
outside = x<xmin or x>xmax or y<ymin or y>ymax
inside = not outside
out = outside and (abs(vx)>vmax or abs(vy)>vmax)
inbetween = 6. < x <= 10.
Conditions are a special kind of expressions used in statements like if and while to control the
flow of the execution of the program. In the above statements, often brackets are used to indicate
it is a logical expression.
To test whether two variables are the same, you have to use two equal signs. Two equal signs
will check the condition and one equal sign assigns an expression to a variable name. For “is not
equal to” both != as well as <> can be used, but != is preferred. With combined conditions
with many “and”, “or” and “not” statements use brackets to avoid confusion:
if inside:
print(“(x,y) is inside rectangle”)
Note that if inside basically means: if inside==True and similarly while not
found means while found==False. This is why Boolean are never compared with ture
or false as this serves no function.
38
This would make the variable a a list of floats, b a list of integers, c a list of strings. A list of
lists as defined in d is basically a way to create a two-dimensional list. Finally e is an empty list.
Accessing elements from the list is done as indicated below. Another way to make a list of
numbers is using the so-called range function. This is an iterator function used primarily in loops,
but it can also be converted to a list. The range function can contain one two or even three
arguments:
range(stop)
range(start,stop))
range(start,stop,step))
In all these cases start is the start value (included), stop is the value for which the block is not
executed because for will stop when this value is reached. So it is an inclusive start but
excludes stop. Another option is to enter a third argument, which is then is the step. The default
start is 0, the default step is 1. Note that range( ) only works with integers as arguments:
39
lst = [1,2,3,4,5,6,7,8,9,10]
If we now print elements we can use the indices in many ways. Using one index, indicating a
single element:
Here it can be seen that indices start at 0, just as with strings. And similar to strings, the function
len( ) will give the length of a list and thus the not to reach maximum for the list. Slicing lists
with indices also works just as for strings, with three possible arguments: start, stop and step.
Only one index refers to one single element. Two arguments separated by a colon refer to start
and stop. A third can be used as step. If you look at the lists that were made in the previous
paragraph about lists you can see that:
Adding and removing elements to a list can be done in two ways the “+” operator or the
append/extend functions:
a = a+[3300.] will add 3300. at the end of the list
a = a[:-2] will remove the last two elements of the list (by first
copying the complete list without the last two elements, so
not very efficient for large lists)
a = a[:i]+a[i+1:] will remove element i from the list,
when it’s not the last one in the list
a = b + c will concatenate (glue together) two lists if b and c are lists
Another way is to use the del (delete command) and/or functions which are a part of the list
class. You call these functions by variablename.functionname( ) so a period between
variablename and functionname. Some examples:
40
a.append(x) add x as a list element at the end of the list named a, equivalent with:
a = a + [x]
a.extend(b) extend the list with another list b, equivalent with:
a=a+b
a.remove(3300.) removes the first element with value 3300.
del a[-1] removes the last element of a list named a
del a[3:5] removes the 4th till the 6th element of a list named a
a = a[:3]+a[4:] will remove the 4rd element of the list named a
Slicing
The last example line uses the slicing notation (which can also be used on strings!). Slicing, or
cutting out parts of a list is done with the colon. The notation is similar to the range arguments:
start:stop and optionally a step can be added as third: start:stop:step. If no value is enter as start,
the default value is zero. If no value is added as end the default value is the last. De default step
is 1. Negative values can be used to point to the end (-1 = last element, -2 is one but last etc.).
lst = [1,2,3,4,5,6,7,8,9,10]
2.9.3*** Lists are Mutable: risks with multiple dimensions list creation
You can quickly build a one dimensional list with 5 elements like this:
>>> a=5*[0]
>>> a
[0, 0, 0, 0, 0]
>>> a[1]=1
>>> a
[0, 1, 0, 0, 0]
>>>
Warning: This only works with one dimensional arrays, see what happens when you try it with
lists of lists, so two dimensional lists:
41
>>> a=3*[3*[0]]
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][1]=1
>>> a
[[0, 1, 0], [0, 1, 0], [0, 1, 0]]
>>>
So we only change the second element of the first row, but surprisingly all rows (all lists) have
their second element changed into 1!
In general you could say, simply avoid this. But for the people who really want to know what is
going on: In www.python.tutor.com we can see the difference. Imagine we will run the following
code:
a = 3*[0]
b = 3*[a]
c = 3*a
d = 3*[3*[0]]
When using one dimensional lists with the asterisk (star) (so for example *a or *[0]), it will
be an expression, evaluated and taken as a value and hence create a new list. Examples of this
are how the list a and d are created. But normally in Python a list is seen as an object, which
means it will just be copied by reference (a pointer to the same object, to the same memory
location) will be used. So wo variables can point to the same object, hence the same memory
location. This can cause behaviour which may seem strange at first sight.
42
To avoid this confusion (and ignore this difference), it is better to build a two dimensional array
with append and values in a for-loop:
a=[]
for i in range(3):
a.append(3*[0])
a[0][1] = 1
print(a)
a=[]
b=[0,0,0]
for i in range(3):
a.append(b)
a[0][1] = 1
print(a)
This only slightly different code will result in the problematic output again:
[[0, 1, 0], [0, 1, 0], [0, 1, 0]]
So 3*[0] is an expression, just like integer variables and float variables. But because b is a list-
object and passed on by reference to the memory location, later referencing a will affect b.
In general, using append with non-list arguments is a safe method. This is because most variable
types (floats, integers, strings) are passed on as value. They are called immutable. Expressions
are also passed on as a value. List objects (like most objects) are called mutable and will be
passed on as a reference to a memory location and hence can be changed by the function that is
called.
Here are two ways to quickly create a two-dimensional list without the risk of creating pointers
to the same list:
First create a one dimensional list, then replace each element by a list:
a=3*[0]
for i in range(3):
a[i]=3*[0]
a[0][1] = 1
print(a)
Or with nested loops, create a fresh, new list (as a row) and then append this:
a=[]
43
for i in range(3):
row = []
for j in range(3):
row.append(0)
a.append(row)
a[0][1] = 1
print(a)
Both will give this output, indicating that a indeed consists of three independent lists:
So creating the variable row, ,or the list-element a[i] every time from scratch, is the safest way
to avoid all appended lists pointing to the same memory location. If you are not sure, test a
simple example in the above way: change one element and see the effect by printing the list. Or
use www.pythontutor.com to see what is going on in the computer’s memory.
An advantage of lists are the methods that come with it. These are functions which you call with
a period after the variable name (just like append). An example is the sort function:
>>> a=[2,10,1,0,8,7]
>>> a.sort()
>>> a
[0, 1, 2, 7, 8, 10]
As we can see the function sort() (recognizable as a function because of the brackets) sorts the
list a. This is a special function in that it changes the actual source list instead of creating a sorted
copy. Most methods will give the result of the function and leave the original intact. Example are
the method index and count. Index will give the index of the first occurrence of the given value.
Count will give the total number of occurrences:
>>> a = [3,1,8,0,1,7]
>>> a.count(1)
2
>>> a.index(1)
1
>>> a.index(9)
How would you make a program which will print the index of the first occurrence but also
avoids the error message if it is not found by simply printing -1?
44
Exercise 1:
Make a program which calculates effect of a yearly the interest rate (entered by the suer) on
start sum (also entered by the user). Print the amount after each year.
Exercise 2: Make a list of e.g. airplane companies by using the append( ) function, then print
them below each other with the length of each word.
Exercise 3: You can also make a list which consist of different list, each with a different length,
as shown here:
values = [[10, 20], [30, 40, 50, 60, 70]]
Print the length of each list and all the values it contains
input(txt) prints txt, asks user for input, returns user input as a text string
help(txt) for use in shell: prints help on Python or installed function, module or
statement, e.g. help(‘math’) or help(‘input’)
45
In thischapter we discuss the basic Python statements: commands that you use in a program
which often do something with the data. A one page summary of the basic python statements can
be found in Appendix A.
We already discussed the assignment statement at the beginning of the previous chapter. The
assignment statement is one of the most simple statements in Python:
variablename = expression
In this statement the expression on the right hand side is evaluated and the stored in the variable
with the name as given left of the equal sign. The expression determines the type and value of
the variable and the left side, the variablename, the name.
It is possible to overwrite a variable, even when it is used in the expression on the right side. This
is because the computer first evaluates the expression and only then stores the result in the
variable, overwriting anything that was previously stored in that variable.
Some examples of how you can use the assignment are given below:
txt = “ea” will create a string with name txt containing “ea”
txt = txt + “sy” will change it into “easy”
Here it should be noted that a statement as i=i+1 may seem mathematically incorrect, but in
programming this simply means that the expression i+1 is evaluated with the old value of I and
the resulting value is then stored in i as this is the variable on the left side of the equal sign. So
‘=’ means ‘will become’ instead of ‘is equal to’ (for which we use ‘==’ in Python, for example
when we test a condition in an if-statement). Also note the short-hand notation “+=”, which has
been discussed extensively in section 2.1 already.
46
Adapting our example program from the previous chapter, we add some logic. Edit the program
to match this example precisely, note the margin jumps (use TAB-key) in the IF statement,
which is called indentation. Hagin the same margin, or indentation level, is what Python uses to
mark blocks of code that belong together, for example because they are part of an IF-branch or a
loop (see later sections on FOR and WHILE loops).
D = b**2 - 4.*a*c
if D<0:
print("This equation has no solutions.")
else:
x1 = (-b - sqrt(D)) / (2.*a)
x2 = (-b + sqrt(D)) / (2.*a)
print("x1 =",x1)
print("x2 =",x2)
Now the program first checks whether D is negative. If so, it will tell you that there are no
solutions.
- Note the structure and syntax(=grammar) of the if-else statement. A colon ( : ) indicates a
block of code will be given, so it acts as a ‘then’. The block is marked by the indented
part of the code,.
- When it jumps back to the margin of the beginning to indicate the end of this block of
code, an ‘else’ follows, again with a colon and an indented block of code.
- It also uses a different way to import the sqrt function from the math module. Note the
difference in syntax in both the line with the import statement as well as the line where
the sqrt function is used.
Exercise 1.1:
Adapt the program so that it calculates the hypotenuse c of a rectangular triangle for
rectangular sides a and b as entered by the user, using Pythagoras formula.
47
Exercise 1.2:
See the flow chart on the right.
48
As example, three ways, which will result in the same output, it will print Hello world on
one line:
print(“Hello world”)
print(“Hello”,”world”,sep=""))
print("Hello","world",end="\n")
print("Hello",end="")
print(”world”)
The above examples also use the use of the ‘sep’ and ‘end’ keyword, which can be used to use a
different separator character or a different end of line.
The print statement can print one or more texts, variables expressions and the outcome of
functions. Basically anything can be printed. Apart from generating output for the user, print is
also very useful when trying to find bugs in your program. Every experienced programmer puts
in a temporary print statement after each ten lines of code to check if everything works as
intended. These are then later deleted or commented out with the hash symbol.
Other examples of valid print statements with other arguments than strings:
print("Program to solve 2nd order equations. ")
print("The solutions are",x1,"and",x2)
print("Discriminant is",b*b-4.*a*c)
print("List of names",lst)
print()
print("Ready. ")
Next to ‘sep=’ and ‘end=’, there is also the keyword ‘file=’, which can be used to print to a file
instead of to the screen (see chapter 8 for more information on how to read and write text files).
This file needs to be opened first with the open function. This function returns a file-object. The
next example shows how this can be used to print to:
49
print("def",file=f)
f.close() # Close file
Note how the hash symbol ( # ), indicates the start of the comments, this symbol and everything
after it is ignored by the Python interpreter when the program is executed.
i = 5
j = 10
x = sqrt(7)
txt = "Hello"
The above syntax is actually a short-hand fversion for using the format function which you can
also use. See the example below, using the same data:
50
y = sqrt(3)
print("Result is",format(x,"5.2f"))
print("Position is ("+format(x,"5.2f")+","+format(y,"7.4f")+").")
print("Number of iterations:",format(j,"5d"))# Length 5 so 2 leading spaces
# Strings
print("Look at this: {}".format(txt))
print("Look {} times at this:{}".format(i, txt))
The input function will always return a string. When another type of variable is needed as input,
the converter functions can be used to get the right type
In some cases this might not work, for instance when we want to enter an expression (maybe
even using variable names). It will also not work when a list of values is entered by the user. In
bith cases conversion by using the alternative method for the conversion of the string: with the
evaluation function eval() is an option.This call to eval() will evaluate any expression and
determine the type in the same as the assignment function would do it:
51
The eval function could also be used in the examples above, but there is a risk of the type ending
up different from what you expected. Users will not always add a decimal point when entering a
float for instance.
Note the difference between print and input, when ouptu text. Input only takes one argument:
instead of printing with input which requires one string as output (two methods):
For the second, using f-strings, see the previous section on formatting your print output, which is
even more usefull in input as you cannot use multiple argument here.
3.4 If-statement
The if statement has the following syntax:
if condition :
statement 1
statement 2
statement 3
In this example above, only if the condition is True, the statements statement 1 and statement 2
are executed. If the condition is False it will automatically jump to statement 3 without executing
statement 1 and statement 2. The conditional lines of code are marked byincreasing the margin,
which is called indenting the lines after the colon. Lines with the same indentation level, so the
same margin, is called a block of code. In Python a code block is marked only by this same
margin. One indentation step is set to four spaces by default in IDLE but any number of spaces
will do, as long as all statements in one block have the same indentation. In many other
languages, you need extra brackets { } or being end statement to mark a block of code.
Because statement 3 starts at the beginning of the line again, so un-indented, Python knows that
this is the end of the conditional block. One of the statements inside the if-statement could be
another if-statement, which would mean that another set of conditional statement would be
indented one more time (nested if-loops).
Optionally the if-statement can be expanded with an else-branch or one or more else-ifs which
are spelled as elif in Python. As many elif-branches can be added as necessary. Only one
else can be added, always at the end of the if branche(s).
An example:
if x<xmin:
x = xmin
52
vx=-vx
print(" Ball left via left side of screen. ")
elif x>xmax:
x = xmax
vx = -vx
print(“Ball left via right side of screen.”)
else:
print(“Ball still on screen.”)
x = x + vx*dt
In this example the condition x>xmax is only checked if x<xmin is False. Which probably is
not a problem in this case. In the above example the assignment statement to update the variable
x is always executed because it is not indented.
3.5 For-loop
The for loop is a very convenient loop, especially when it is used in combination with the
range()function. For example:
for i in range(10):
print(i)
print("Ready. ")
If you try this code, you will see that it prints the numbers 0 to 9. The range(10) function results
in a list: [0,1,2,3,4,5,6,7,8,9] through which the variable i is iterated. This means: The indented
block of code (one statement in this case) is executed ten times, once for each value of i.
Another example:
total = 0
for i in range(1,11):
print(i)
total = total + i*i
print(total)
In this example, a variable total is initialized as zero just before the loop. But then in every
execution of the loop i*i is added to total. Since i runs from 1 until but, not including, 11 in
this code, the result is that total will be equal to 1*1 + 2*2 +3*3+ …+ 9*9 + 10*10 .
Instead of using range( ) to generate a range of integers, any list can be used:
fellowship = ["Frodo","Sam","Merry","Pippin","Gandalf", \
"Legolas","Gimli","Aragorn","Boromir"]
53
If you need to loop floats e.g. from 0. to 10. with step of .1, you can also use the following
construction. This example will print these values:
for i in range(101):
x= i*0.1
print(x)
When setting up loops (while or for), use print statements first (e.g. with a small number of
iterations) to see whether your loop does what you intend it to do.
For example, this bit of codeuses the permutations iterator function, which takes a list as input:
lst = [1,2,3]
for a in permutations(lst):
print (a,end=" ")
And to take all possible selection of n combinations out of a list lst, the function
combinations( lst , n) can be used:
lst = [1,2,3,4,5]
for a in combinations(lst,2):
print (a,end=" ")
There are many more useful funcitons in itertools, like cycle, product, etc. In the python shell,
type help("itertools") to see the complete overview.
54
Exercise 1: Make a program that prints all the prime numbers till a certain value,
(recall that a prime number is not divisible by any number except itself and 1).
Exercise 3: Write a Python program that accepts a string and counts the number
of digits and letters in the string.
55
3.6 WHILE-loop
A more versatile loop is the while-loop. It is a sort of a combination between an if-statement and
a for-loop. A block of statements is executed for as long as a given condition is True. The block
is repeated until the condition becomes False. The syntax is:
while condition:
statement 1
statement 2
statement 3
The while is just like the if, used to control the flow of a program based on a condition. The
difference is that in this case it is automatically repeated.
An example:
When you use this as a sort of “repeat until”, you have to prepare the condition which is tested
by while in such a way that the first time it will be true, so the loop as entered at least once. You
can see this in the second example below, where found is set to False first.
Another example:
import math
found = False
if n%i==0:
found = True
i = i+1
if found:
print(n, "is divisible by",i)
else:
print("No factors of",n, "found.")
56
While can also be used to wait for a valid answer when using input:
choice = -1
while not(0 <= choice <= 3):
choice = int(input("Enter your choice (1,2,3 or 0):"))
In this example the computer will keep asking the question until a valid choice 0, 1, 2, 3 is
entered.
The two most important things need to be addressed when using while-loops:
- Often (not always) an initialization is required to make sure that the first time the
condition in the while-loop is True, such that the while-loop starts running.
- Within the while- loop, the block of code has to assure that the condition becomes False
at some point, avoiding an endless loop.
Even though it is not considered a good programming style to use it as regular way to control the
flow of your program, it is possible to make exceptions to the normal execution of the for- or
while-loop. Two statements can do this: break and continue.
The command line break will break out of the current loop and continue with the next
statement after the loop. The command line continue will also skip the remainder of the block
of code in the loop but in contrast to the break command, it will return to the beginning of the
loop to the test in the while-line (in a for-loop it will thus return to the beginning of the loop,
taking the next value of the iterator).
while True:
…
if keypressed == ESCkey:
break
…
for i in range(100):
…
if i%4==0:
continue
57
Note that continue and break can be used in both loop-types: so both can be used in for- and
while-loops.
Using these two commands on a regular basis is considered to be a bad programming habit, as a
clever definition of the loop can avoid these unpleasant disruption of the flow of the program.
Also, take into account that an if-then statement could also do the job. The break and continue
statements however, can make the code more readable since less indentations are required
compared to the if-then statements.
continue skip the rest of the code in the block inside the loop and go to the line with the
while or for statement. So in case of a for-loop the next value of the list will be
used.
break jump out of the loop and proceed with the code after the loop
Programming language purists do not like these commands as they disrupt the flow of a program
and can be used to create real “spaghetti-code”, so only use them when there is no other neater
way to achieve the same goal, e.g. to avoid too many indentations in the margin.
Exercise 1: We can make our prime number generator faster by means of the break command,
make again a prime generator till a certain value. But now ‘break’ when a value is devisable by
another value then itself or 1.
58
- At the top of your script, write a small summary explaining the function of your code
using comment lines. Also add your name and the date of editing.
- Use empty lines to create “paragraphs” indicating which parts belong together. Also
use spaces in your line, they have no effect during runtime but can increase the
readability
- Also use a comment line just before such a piece of code indicating in plain language
what the meaning of the code is. Comments can be inserted when you start the line with
a hash-character: #. The hash-sign can also be used to add comments at the end of the
line (such as units of variables). An example:
If you have a line which becomes very long, continue on the next line. Often Python will
understand this because you are in the middle of a list or function call, but otherwise you may
end the line with a backslash as a continuation character. Then Python will know that the next
line needs to be added behind this line before it executes the command.
Tip: Since it is often not very motivating to add comments afterwards, you can also do it in the
other way around: When you have to design an algorithm, you first have to decompose the
problem into smaller steps. Use comment lines to break your problem down in smaller steps and
write in natural language what each step should do. Then all you have to do is fill in the gaps
between the comment lines with the actual code and you have developed and commented your
source code at the same time.
An example of the same code, both badly and well formatted, is given on the next page (pass is
a statement which does nothing, sometimes used temporary before filling in final code):
59
In this case the function is extremely simple, but imagine a more complex function: You would
never be able to understand it or use it again a few months or years later, when coded in the
format of the first example. When you make a habit of doing this while you code, it not an extra
effort and it even saves you the effort of memorizing which part does what and what the
variables mean during the debugging.
60
The small summary at the beginning of your code is called the header of a source file. A very
good habit is to add this header at the beginning of each Python file. In this you can quickly
describe the purpose of the program or the inputs and output of a function for potential users. For
this you often want to use multiple lines with comments. You could of course do that using the
hash sign:
#
# Main module of BlueSky Open ATM Simulator
#
# Start this module to start the program
#
# Created by : Jacco M. Hoekstra (TU Delft)
# Date : September 2013
#
# Modification :
# By :
# Date :
#
But another way to add multiple line comments is the triple quote:
"""
Main module of BlueSky Open ATM Simulator
Modification :
By :
Date :
"""
Using this format will also make sure that python recognizes this as documentation for the
function and will return it if the help function is called for your function. This is called the
docstring. See below for an example:
def complex(real=0.0, imag=0.0):
"""Form a complex number.
Keyword arguments:
real -- the real part (default 0.0)
imag -- the imaginary part (default 0.0)
"""
if imag == 0.0 and real == 0.0: return complex_zero
61
(Also note how default values are given to the arguments when this function is defined. When no
argument is give, these values will be used).
62
As we already saw in the first chapter, Python’s mathematical functions are defined in a math
module which is one of the many modules that comes with Python. The math module contains:
math functions e.g.: sqrt() (=square root) sin() (=sine of an angle in radians), asin()
(=arcsine or inverse sine, returns the angle again in radians),
angle unit conversion functions: degrees( ) and radians()
constants like pi and e.
If you use a function that has been defined in a module you first have to input that module once
at the beginning of the python script file in which you use the functions. This is done by typing:
import math
When we want to use a function from this module, we type the name of the module, math in this
case, in front of the name of the function followed by a period (.) followed by the name of the
function. For example:
The math module also contains the constants pi and e. These are used in the same way as the
functions, with the module name in front of the constant’s name:
bdeg = b/math.pi*180.0
y = math.e**x
Note that with logarithmic functions log(x) means ln(x), so base e and not base 10! To use a
logarithmic function with base 10, use the function log(x,10.) or the special function log10(x) .
As it may be cumbersome to type ‘math.’ before these very common functions there are ways to
import the names from the module into the namespace of the module. This means you don’t have
to put ‘math.’ in front of the function names every time, but you can use the function names as if
they were defined inside your module. There are two ways to do this. Look at the examples
below.
Method 1 to avoid this is directly importing selected functions from the module math:
alpha = asin(BC/AC)
bdeg = b/pi*180.0
63
or easier, just import all functions from the math module with the asterisk symbol:
alpha = asin(BC/AC)
bdeg = b/pi*180.0
In the first example the names are explicitly imported. This has two advantages: the reader of the
source can tell from which module which function was imported. This is important if you use
more than one module. Secondly, you prevent problems, which might arise if you use a variable
name which happens to be the same as some function somewhere in the imported module.
Still, if there is any module where you could use the asterisk-import method, it would be the
math module, since the names in there are well-known. In many other languages, these math
functions are also reserved names and part of the so-called ‘namespace’ of the language.
A nice feature of the “from … import” way of importing functions is the option to rename
functions:
x = wortel(9)
(This example will result in x being a float with value 3.0 as the sqrt() function converts the type
to a float. )
On the next pages an overview is given of the main functions in math. There are a few extra in
the actual module; e.g. those functions show how numbers are represented on a binary scale. If
you’re interested in these, use help (‘math’) in the shell or look up the math module in the
Python Docs via the IDLE Help menu.
64
Constants
math.pi The mathematical constant pi (= 3.1415926535897931)
math.e The mathematical constant e (= 2.7182818284590451)
Trigonometric functions
math.sin(x) Return the sine of x radians.
math.cos(x) Return the cosine of x radians.
math.tan(x) Return the tangent of x radians.
math.acos(x) Arc cosine of x (i.e. the inverse cosine), resulting angle is in radians
math.asin(x) Arc sine of x (i.e. the inverse sine), resulting angle is in radians
math.atan(x) Arc tangent of x (i.e. the inverse tangent), resulting angle is in radians.
math.atan2(y, x) Same as atan(y / x), in radians but now the result is between -pi and pi. The
vector in the plane from the origin to point (x,y) makes this angle with the positive X
axis. The point of atan2() is that the signs of both inputs are known to it, so it can
compute the correct quadrant for the angle.
math.hypot(x, y) The Euclidean norm, sqrt(x*x + y*y). This is the length of the vector from the
origin to point (x, y).
Hyperbolic functions
65
Number functions
math.ceil(x) Ceiling of x as a float, the smallest integer value greater than or equal to x.
math.copysign(x, y) Returns x with the sign of y ( so abs(x)*y/abs(y) )
math.factorial(n) n! or the factorial of n (in Dutch: faculteit n)
math.floor(x) Floor of x as a float, the largest integer value less than or equal to x.
math.fmod(x, y) Modulo fmod(x,y), returns x - n*y for some integer n such that the result has
the same sign as x and magnitude less than abs(y).This function fmod() is
generally preferred when working with floats, while Python’s x%y is preferred when
working with integers.
math.fsum(iterable) More accurate summing for floats than sum( )
math.modf(x) The fractional and integer parts of x. Both float results carry the sign of x.
math.trunc(x) Return the Real value x truncated to an Integer (usually a long integer)
Another often used module is a module which generates (seemingly) random numbers. This can
be used for random initial conditions, dice or noise etc.
To find more information on the functions in this module, go to “Python docs” in the Help pull
down menu in IDLE, we type random in the Search window.
Clicking on the first result brings us to chapter 10.6 Pseudo random generator. This section
discusses the functions inside the random module.
After a lot of complex information (which we skip) we also see some useful functions:
random.random() Return the next random floating point number in the range
[0.0, 1.0)
To see which other modules are installed, you can type help(‘modules’) in the Shell, but with
Python(x,y) installed this quickly becomes too much (and takes too long). More info on specific
modules supplied with Python can be found in the Python documentation. For instance check out
the simple modules like os, sys and time, or more advanced like urllib or Tkinter! You’ll find a
treasure box of goodies. This is what is meant with when they say Python comes “with batteries
installed”.
66
With Python you can define your own functions and in this way basically extend the language
with your own commands. The statement def is used to define a function. The syntax of this
statement is as follows:
def functionname(arg1,arg2,arg3) :
statement1
statement2
statement3
return resultvalue
Examples:
def fibo(n):
while serie[-1]<=n:
x = serie[-2]+serie[-1]
serie.append(x)
del s[-1]
return serie
Functions can be complete programs or simple one-liners. Another example with a very short
function:
def f(x):
return x*sin(x)
67
Be aware that the def statement does not yet execute the function, it merely defines it. The code
inside the function will only be executed when you call the function, after it has been defined
with def. So always call it, could be done manually from the interpreter to check the syntax and
working of your newly defined function.
As you have seen in the formatting example, you can output several different values from your
function. You can do this as a list, defined with the square brackets or as a tuple (a constant list )
with the round brackets or a tuple by leaving out the brackets.
When you call the function you can store the result in a list/tuple or in different variables. The
latter is done in the example below, which explains how to output more than one value of a
function.
68
6.4 Using one variable in definition as input and output is not possible
In some languages, a function can do something to the input variable without returning a value.
This is not the case with the standard data types in Python, except for the list type.
In Python most data types are immutable, which means they are passed on as a value of the
object, which is then used in the function. But since there is no reference to the memory location
of the original variable in the calling module will not be changed by anything the function does.
See the example below. Most types of variables (floats, integers, strings, booleans) are
immutable because they are passed on by value. Others (lists) are passed on as reference to a
memory location, then they would change as the function increases it. These are called mutable
variables.
Mind you, this use of one variable as input and output at the same time in the definition of a
function is considered very bad programming practice anyway in the procedural programming
style in the languages where this is possible. Yet at the same time, it is common practice in
object oriented programming, also in Python! It would then be called a method of the variable a
and called as: a.increaseit()
69
70
As you have already seen with the math functions in the previous chapter, they are defined in a
separate file(module) math.py and to use them, you first need to import this module.
You can also use this principle of defining functions in different files for large programs where
you want to keep an oversight by storing different sets of functions in different files, or as we say
in Python: in different modules. In this case the module file needs to be in the same folder so
Python can find it.
Suppose you have defined a function fibo in the file series.py , and you want to use it in
your own program test.py . Then you need to import your module series. We usually do
this at the beginning of the source, since you need to do this only once. Because once the
function is defined, you can use it as many times as you want. There are now many ways in
which you can import and call this function:
Method 1:
import series
s = series.fibo(10)
Method 2:
from series import fibo
s = fibo(10)
Method 3:
from series import fibo as fibonacci
s = fibonacci(10)
Method 4 which I would discourage: you do not know which other names now suddenly have a
special meaning, it also makes it harder to trace where functions are defined (I only use this with
math and sometimes with Numpy for the math functions):
On the internet you can find many 3rd party modules which extend the functionality of Python to
do a range of things. Once they are installed it is very easy to use them: just add an import call at
the beginning of your script and all functions inside that module are available to you.
71
Exercises chapter 6
Exercise 1: Make a function that counts the words in a sentence and print the last word.
Exercise 2: Make four functions which calculate respectively the surface and volume of a sphere
and the surface and volume of a cone.
Exercise 3:
Write a function:
This function repeats string ‘string’ n times, separated by the string ‘delim’.
72
Here randint, see the chapter on the random module, can be used to make an unsorted list:
for i in range(50):
numbers.append(randint(1,100))
print("Before sort:",numbers)
This prints an unsorted array of 50 random numbers under 100. Now we will sort it with the
famous Bubblesort algorithm:
If we want to add this then we have to add the code on the following page:
73
swapped = True
while swapped:
for i in range(len(numbers)-1):
if numbers[i]>numbers[i+1]:
a =numbers[i]
numbers[i] = numbers[i+1]
numbers[i+1] = a
swapped = True
# Loop end when swapped is False and no swaps were performed anymore
print()
print("After sort:")
print(numbers)
First we check whether these elements are in the wrong order. When they are the same we should
not swap them (it would keep doing this forever then). If wrong, we save the value of numbers[i]
in the variable a, then we overwrite this with the value of numbers[i+1]. And then we use our
saved value in a to put in numbers[i+1] resulting in a swap of places.
For this to work we need to let i run from 0 till the last place minus 1. Otherwise the
numbers[i+1] will result in an error. So the for-loop reads:
for i in range(len(numbers)-1):
Now all we need to do is add some logic to detect whether we are done. We can use a logical
swap to detect any swapping. For this we first set it to False outside the for-loop and as soon as
we swap two variables we set it to True.
74
Then we add a while loop around this which will keep repeating our for-loop until swap remains
False and hence no swap was performed. To make sure we enter the while loop the first time, we
have to set it to True outside the while loop.
This is the order in which this program was made: from the inside out. First putting in
elementary operations and then using a logical to add some logic.
The end result is an already complex looking construction. Look at the three indent levels: while,
for and if are inside each other or nested as we call this in programming.
75
As soon as your done with the file, you need to release it again with the close statement.:
f.close()
g.close()
h.close()
This will not only release the file for use by other programs but also empty any read/write
buffers which may be in use and whose content might get lost if the program ends abruptly
without closing (and releasing) the files.
You can use the file handle variable in a while-statement when reading files:
The easiest way is to store it in a list of lines directly and use this list in the for-loop:
# Read a file
f = open(“test.dat”,”r”) # Open file for reading
lines = f.readlines()
f.close()
for s in lines:
…. Do something with the string variable s……
The file object will return False when the end of the file is reached. This is an example of how
you can read lines from a text file using this feature:
76
# Read a file
f = open(“test.dat”,”r”) # Open file for reading
while f:
line = f.readline()
f.close()
# Read a file
f = open(“test.dat”,”r”) # Open file for reading
f.close()
for i in range(len(xtab)):
line = str(xtab[i])+”,”+str(ytab[i])+”\n”
f.write(line)
f.close()
Similarly as with readline() and readlines(), there is here also a writelines(), which will write a
complete list of strings to a file. See the following example code:
77
a = ["The Expanse\n",
"A TV-serie by SyFy set in a future in which\n",
"mankind has started exploring the solar system\n",
"beyond the planet earth.\n"]
f = open("expanse.dat","w")
f.writelines(a)
f.close()
f = open("hello.dat","w")
print(“Hello major”,file=f)
f.close()
See also the section on formatting your output in the section on how to output data in a formatted
way in the pargraph on using print.
Let’s look at an example: a data file (text format), which is named “test.dat”:
Suppose we want the program to read this file and store the result in a two-dimensional list with
strings for the label and floats for the value per variable. So in this example, the text file should
result in the following list:
[['alpha', 5.2240000000000002],
['beta', -0.0112],
['gamma', -2.7759999999999998]]
- The program should recognize comment lines because these start with a C-character.
- When no value is provided (as in the example with theta), it should also not appear in the list.
78
- Empty lines should have no effect, similarly whitespaces in the lines should not be critical
(see gamma in example)
As a first step, we read the lines into a list of strings (see previous chapter):
# Read a file
f = open(“test.dat”,”r”) # Open file for reading
lines = f.readlines()
f.close()
Now we have to process these strings. And then find the labels, strip the superfluous characters
and lines and read the values in the list. This is achieved by the following program, which we’ll
briefly discuss below.
The for-loop makes sure the indented block of code will be executed for every string in the list
variable lines.
To prevent that any further checks will not work because a lower case ‘c’ is used or somebody
starts every name with a capital character, we change the whole line to lower case with the string
method lower. Since it is not a general function but a method of the string type, we use the
variablename.methodname(arguments if any) notation. Similar to the “append” method with
lists.
79
Before we read the data two things are done: it is checked whether it is not an empty line or
comment line and then the line is split up and cut using a combination of the split-method, the
find-method and slicing.
There is a long list of string methods which can be handy. A selection is shown on the following
page.
80
A complete list, as well as more detail per function, can be found in the Python Docs in the
chapter on built-in types (6.6.1) or by typing help(‘string’) in the shell window.
These are methods, which are functions that are part of the type string. This means they are
called in a special way: by using the name of the string input variable instead of str, so followed
by a period and then the name of the function. As the string is an immutable type, so passed only
by its value, these functions return something as output: e.g. an altered copy of the string, an
integer value or a logical.
str.replace(old,new) Return copy of str with all occurrences of substring old replaced by new
str.join(lst) Return one string, with the strings from the list, separated by the character
in str
str.startswith(ch) Returns True if string str begins with the substring ch
str.endswith(ch) Returns True if string str ends with the substring ch
str.split(sep) Returns a list of strings: the words in str as separated by sep substring
str.splitlines( ) Returns a list of strings: str is split using the newline character
str.strip(ch ) Remove character ch from begin and end of str, default ch is a space. See
also rstrip( ) and lstrip( ) for stripping only one side of str
str.expandtabs(n) Replace tab-character by n spaces. If n is not provided 8 spaces are used.
str.lower( ) Returns copy of string str with all alphabetic characters in lower case
str.upper( ) Returns copy of string str with all alphabetic characters in upper case
str.title( ) Returns Copy Of String str But Then In Title Case, Like This
str.capitalize( ) Returns copy of string str with the first character capitalized
str.islower( ) Returns True if all characters in the string str are lower case
str.isupper( ) Returns True if all characters in the string str are upper case
str.istitle( ) Returns True If The String str Is In Title Case, Like This
str.isalpha( ) Returns True if all characters in the string str are alphabetic characters
str.isdigit( ) Returns True if all characters in the string str are digits
str.isalnum( ) Returns True if all characters in the string str are digits or alphabetic
str.isspace( ) Returns True if all characters in the string str are whitespace
81
8.6 Genfromtxt: a tool in Numpy to read data from text files in one line
To use genfromtxt(), the Numpy module has to be imported (by the way, it is also included in
Scipy):
import numpy as np
table = np.genfromtxt(“test.dat”,delimiter=”,”,comments=”#”)
x = table[:,0] # x in first column
y1 = table[:,1] # y1 in 2nd column
y2 = table[:,2] # y2 in third column
Here we see that the different columns of the two-dimensional array table are copied in
independent one-dimensionnal arrays x, y1 and y2.
Loads data from a text file, with missing values handled as specified. Above the default values
for the keywords are shown.
Each line past the first skiprows line is split at the delimiter character, and characters following
the comments character are discarded.
82
83
84
Try the example program below (or download plotsincos.py from blackboard). The header is the
standard way to import both matplotlib and matplotlib.pyplot. It uses import module as
newname , to create shorter names, which make it easier to use the modules.
Pyplot is a module inside a module and imported as plt in the code below. Then it uses a for-
loop to generate different values for x and with this, two y-values using sine and cosine are
calculated. Append each value to the list variables xtab, y1tab and y2tab and then plot these in
the same figure. This figure will only become visible when a call to plt.show() is made. This
starts a separate program with the plot and waits until the user has closed this window.
# Goal: Draw a sine ans a cosine for x is [0,10] with 100 steps of 0.1
step = 0.1
for i in range(101):
x = float(i)*step+0.0
y1 = sin(x)
y2 = cos(x)
xtab.append(x)
y1tab.append(y1)
y2tab.append(y2)
plt.plot(xtab,y1tab)
plt.plot(xtab,y2tab)
plt.show()
85
If you run this program, you will see the following window appear as a result of plt.show():
Now try some of the buttons below the graph. From left to right these are:
- Home button: brings you back to default figure as shown in the beginning
- Back button: return to previous plot when you’ve panned or zoomed
- Next button: opposite of back
- Pan button: move the plotting window coordinates
- Zoom: Select a zoom window
- Adjust subplot: Adjust (sub)plot parameters with sliders
- Save: Select a file format and filename to save the plot as currently set up in the window
More options are available if we define a figure and a subplot. We can then use the methods
provided in these types:
sc.plot(xtab,y1tab)
sc.plot(xtab,y2tab)
sc.set_title('Now a title can be added to a figure')
The variable fig can now also be used to add different subplots next to each other in one figure.
We define one subplot here which we call sc (sine-cosine) and then use methods provided with
the plot to both plot the sine and cosine as well as add a title. Similarly functions for legends and
labels are available.
http://matplotlib.sourceforge.net/gallery.html
In this gallery, click on a figure and then select “source code” to see how the figure is made.
Ignore all the complex stuff where they generate the data and check for useful Matplotlib
86
methods in a figure or a subplot to enhance the way your graphs look. Also the different types of
graphs like bar charts are illustrated.
Exercise 1: Make a plot of the two functions f(x) = sin x and g(x) = ex – 2 for x = [0, π]. Find the
coordinates of the point where sin x = ex – 2 using the zoom-function of the plot window.
Exercise 2: With a simple cosine function you can already make beautiful flowers in python. So
make a flower which has the function r = 4cos(2ϑ) in polar coordinates.
9.2 More plots in one window and scaling: ‘subplot’ and ‘axis’
Instead of several lines in one plot, you can also include more than one figure in one plot
window with the subplot function. In the example below, we want to show the standard
goniometric functions sine, cosine and tangent in the top row and the hyperbolic functions in the
bottom row. This is done by including the command subplot. For example the first subplot-
command:
plt.subplot(231)
The number 231 is used in an unusual way, it should be read as 2-3-1 and stands for: make 2
rows of 3 graphs and start with subplot number 1. Until the next subplot command, all function
calls will now affect this subplot. The numbering of the plots is in this case 1 to 3 for the plots in
the first row and 4 to 6 for the three plots in the bottom row.
Note that since the tangent had vertical asymptotes, it will yield a useless high range on the y-
scale. To control the range of the axes from within our program for the third subplot, we use the
command:
plt.axis([-2.*pi,2.*pi,-5.,5.])
This will set the x-axis at a range of [-2π, 2π] and the y-axis at [-5,5]. This shows the shape of the
tangent in a more sensible way.
# Generate data
x = np.linspace(-2.*pi,2.*pi,1000)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
z1 = np.sinh(x)
z2 = np.cosh(x)
z3 = np.tanh(x)
87
plt.subplot(231)
plt.plot(x,y1)
plt.title('sin')
plt.subplot(232)
plt.plot(x,y2)
plt.title('cos')
plt.subplot(233)
plt.plot(x,y3)
plt.axis([-2.*pi,2.*pi,-5.,5.]) # setting scale:xmin,xmax,ymin,ymax
plt.title('tan')
plt.subplot(234)
plt.plot(x,z1)
plt.title('sinh')
plt.subplot(235)
plt.plot(x,z2)
plt.title('cosh')
plt.subplot(236)
plt.plot(x,z3)
plt.title('tanh')
plt.show()
88
You can also see that in the plot the asymptotes are just nearly vertical jumps in the data. You
could draw the tangent graph in such a way that it will not connect these points. You can even
add drawing the asymptotes with red dashed lines when you know where they are. How would
you do this? Check out the examples and the Matplotlib reference documentation for this.
(Another way might be to draw an independent line in graph for each period!)
Exercise 1: Plot two functions y1 = cos(3x) + sin(2x) and y2 = e^(2x) - e^(-3x+1) on the interval
x = [0,10] both on a different graph and place them under each other.
Exercise 2: Plot r = ϑ and r = ϑ2 on the interval ϑ = [0,8π] in three graphs. Make sure that you
label all your axis and give titles to the plots.
Exercise 3: Sometimes it is convenient to plot straight lines in your plot. It works almost the
same as changing your axis system. You use the function plot( ):
plot([x1, x2], [y1, y2], color='k', linestyle='-', linewidth=2)
Make a plot with a vertical, horizontal and diagonal line.
Sometimes you do not want to wait till your program is ready, but you would like to see the data
already when it is being generated. For this you can use the interactive plot feature. By default
this is switched off, but you can switch it on and off using the matplotlib.pyplot.ion() and
matplotlib.pyplot.ioff() commands.
When done, close the plot with matplotlib.pyplot.close() to avoid stalling your
computer (close is especially important on Windows PCs)
for i in range(100):
x = float(i)/10.
plt.plot(x,sin(x),"ro") # plot each point as a red dot
plt.draw() # Show result
plt.close()
Which will show data as it is being generated and adjust axes on the fly when necessary:
89
Exercise 1: Plot the two functions y = (4 - x2)1/2 and y2 = -(4 - x2)1/2 on the interval x = [-2,2] as
an interactive plot and see which shape appears.
90
When you need to plot a function of two variables, for example z = f(x,y) , another type of graph
may be needed. In that case there are two common ways to do this. Using colours indicating the
z values per point x,y or using a 3D plot where the height indicates the value z. Both methods are
explained in the following example codes.
Both examples plot the function z=f(x,y) . For this they use a 2-dimensional array with a grid,
generated with a function called “meshgrid”, to generate the values at an equal distance. You
could convert these examples of source code to a function which plots your own data or your
own function. You should then only change the data X,Y and Z. To do this in a neat way, you
could convert these examples to a function where the X,Y and Z are input arguments to that
function.
The resulting figure is shown next to the source. In the 3D plot you can move around the plot to
change the viewing angle before saving it to an image file. Both plots also use a colour map cm.
91
And for the colour- and contour plot we can use the following example code:
92
#FF0000 means a RGB color code, it means 255,0,0 which indicates full signal on the red color,
and none on the green and blue. So it is light, pure red. In pygame it would be (255,0,0), in some
libraries colour codes are floats, then it would be (1.0,0.0,0.0)
93
plt.plot(x,y,”r-“) Example of line formatting: red line, try also “b+”, “go”
plt.plot(x,y1,label=”y1”)gives name a label
plt.legend() shows a legend
plt.bar(x,y) Bar plot, x = hor. place (e.g. arange(5), y , where y is alist/array with 5
values)
plt.show( ) Show graph in interactive window (put this at the end of your plot
commands or you will not see anything)
plt.axis([xmin, xmax, ymin, ymax]) Set range of axes, uses a list (or tuple) with the values
plt.legend( loc=locstr) Add legend, uses a list of strings: str1 is text for 1st line etc. Location of
box with legend can be specified with this string:
plt.subplot(231) Specify number of rows (2), number of columns(3) and finally set the
figure number for next pyplot commands (1st figure in this example)
plt.axvline(x=1) Draw a vertical line x=1. You can also limit the length with the ymin and
ymax keywords: plt.axvline(x=1,ymin=0.,ymax=2.,color=’r’)
plt.axhline(y=2) Draw a horizontal line y=2. You can also limit the length with the xmin
and xmax keywords: plt.axhline(y=2,xmin=-1.,ymax=1.,color=’r’)
94
In complex examples many forces can act on a mass, but you can often calculate these for a
given situation. And with this technique, if the forces can be calculated for a situation, we can
calculate the acceleration and then integrate this to get the time history of speed and place. In this
way we can simulate the physics and solve problems, which we cannot solve analytically.
While y remains larger than zero (until the mass hits the ground), repeat the next
iterations:
t = t + dt
F=m· g
a = - F/m
vy = vy + a·dt
y = y + vy·dt
During each step, append the value t to a table for the time and append the value of y to a
table with the value of y. After all iterations, when the mass has reached the ground, plot
the value of the height y against the time t, using these tables.
c) Compare the two different datasets in one plot to see the effect of the drag. Try
different values for starting altitude and CD.
95
x = x + vx*dt
But when drag is then added things get more complicated in two dimensions.
The drag can be calculated in the direction opposite of the speed, but then it needs to be
composed in two directions. One way to do this is by calculating the length of the force and then
decompose it into two directions.
Often it is handy to switch between polar coordinates for the positions and to orthogonal
coordinates to get the forces. We can this use for calculating acceleration, speed and
displacement in both x- and y-direction. For this there is a very convenient, special arctan-
function called atan2(y,x). Look at the example below:
V = sqrt(vx*vx+vy*vy)
D = cd*0.5*rho*V*V*S
angle = atan2(-vy,-vx)
Dx = D*cos(angle)
Dy = D*sin(angle)
Here we see that first the length of the speed vector is calculated. This is then used to calculate
the length of the drag force. Then the angle is calculated using a special arctan-function atan2. If
the normal atan function would have been used, there will be no different outcome for –vy/-vx
and vy/vx even thought the two vectors point in opposite direction. This is caused by the fact
that the tangent, being the quotient of sine and cosine, has a period of only π and not 2π.
To be able to move from Cartesian coordinates (x,y) to polar coordinates (r,θ) without an extra
if-statement for checking the sign of x and y, atan2 can be used as in the example. It will result
the correct angle for the (y,x) (vy,vx) or (dy,dx). Since the tangent is sine/cos, hence y/x the y-
coordinate is given first. So with this function θ=atan2(y,x) it works for all quadrants!
96
Use this structure as a template for all your simulations: add the descriptions in the block as
comment lines and then fill these in with real code between the comment lines.
97
Chapter 10 exercises
Exercise 1:
a) Initialize a simulation with the following variables:
While y remains larger than zero (until the mass hits the ground), repeat the next iterations:
t = t + dt
F=m·g
a = - F/m
vy = vy + a·dt
y = y + vy·dt
During each step, append the value t to a table for the time and append the value of y to a table
with the value of y. After all iterations, when the mass has reached the ground, plot the value of
the height y against the time t, using these tables.
b) Add the drag to the example. Use D = CD ½ρV2S with:
CD = 0.47 , ρ=1.225 kg/m3, S = πR2 and R = 0.15 m
c) Compare the two different datasets in one plot to see the effect of the drag. Try different
values for starting altitude and CD.
Exercise 2:
a) Make a small simulation of a cannon ball which has a mass of 10 kg, that is fired with a
starting speed of 100 m/s, but it is shot at an angle of 30⁰. Besides that, the canon is placed
one meter above the ground and you can assume that this is also the starting height of the
cannon ball. Show a plot of the vertical distance against the horizontal distance. So you can
see the trajectory of the cannon ball.
b) Now extent this program, because this model has too many simplifications. For example a
cannon ball is not frictionless, so we should include the drag. For now we assume it is
constant and N is set to for example 80. Try to find the accelerations with force equilibrium
and plot the trajectory of the ball.
c) The last step to finalize our program is that the drag is not constant. It is actually a function
of speed, in this program use the relation that Fd = 0.05V2. From Intro I you know that the
gravitational constant is changing with altitude, also include this effect in your program.
Hint: g = g0(REarth/(REarth + h)), where REarth = 6371 km.
98
Python with Numpy and Scipy is more capable than Matlab in many respects. Python is better in
handling strings, reading files, working with very large projects and with large datasets. Python
can also be used in an object oriented programming way. Both Spyder and the iPy Notebook
provide a very user-friendly environment for scientists. A more general difference are the extra
possibilities, which are provided by a full-featured general purpose programming language like
Python. And, often more importantly, MATLAB is very expensive and many applications
require extra toolboxes, which are in turn also very expensive. This also hinders sharing tools as
well as quickly using source code from the internet community: often you can only use the
downloaded bits after purchasing the required toolboxes.
With Numpy and Scipy, Python has surpassed MATLAB in terms of functionality. The modules
are available for free (as are all Python modules). They are developed, maintained, expanded and
used by a large academic community, mainly in the US and Europe.
Numpy forms the foundation for Scipy, Matplotlib and many other modules: it provides the
array- and matrix-types as well as linear algebra functions as extension to Python. Scipy adds a
whole range of sometimes very dedicated scientific computing and engineering functions.
Thanks to Numpy and Scipy, Python has become the default language of choice for scientific
computing, according to IEEE and many others. Let’s explore the capabilities of these modules,
even though we can only scratch the surface in this course.
To use these modules, they need to be imported. It has become standard practice to rename them
when importing them. Numpy becomes “np” and Scipy becomes “sp”. This means we will often
see the following header in our scientific applications. In this course, we assume you have
imported the modules as follows:
import numpy as np
import scipy as sp
import matplotlib as mplt
import matplotlib.pyplot as plt
In the Numpy and Scipy documentation it is often even assumed that you have imported
everything using from numpy import * . So do not forget to type np. before the Numpy
functions and “sp.” before the Scipy functions, even though you don’t see this in the Numpy
and Scipy documentation. Most Numpy functions can also be used as if they were a part of Scipy,
but then with the “sp.” prefix.
99
This would also be a good time to add a link to the Help chm-files containing the Numpy and
Scipy reference to your IDLE Help menu, if you have not already done so. Go to
Options>Configure IDLE, click on the “General”-sheet on the top right. Then click “Add” in the
lower part of the window to add the menu item and the link to these files.
11.2 Arrays
So far we have seen lists and even lists of lists. When we used lists as tables we often kept
separate columns in separate one-dimensional lists, so we could select them individually (like
xtab, ytab in the previous chapter). And if we used a two dimensional table, we could add small
lists of two elements to the lists like this:
for i in range(1000):
x = x + vx*dt
y = y + vy*dt
postab.append([x,y])
But how can we now select only the first column? Unfortunately, postab[:][0] does not give this
result. This indicates, as well as many other examples, that two dimensional lists are, as a
variable type, despite their versatility, not always the most suitable type for scientific computing
and working with large tables in a fast and user-friendly way.
The module Numpy has an advanced list-type which solves this: the array .This type forms the
foundations for Numpy and Scipy. With this type you can do computations with entire tables, as
easy as if they are one scalar variable.
100
The indexing also has a different syntax although both use the square brackets:
np.arange(start,stop,step) Define an array with floats evenly spaced with step (stop not
included), difference with range function: it works with floats and
the result is a numpy array, Example:
arrange(0.,0.6,0.1) will result in [0.0, 0.1, 0.2, 0.3, 0.4, 0.5]
np.linspace(start,end,nelem) Define an array ranging from start to, and including, end with
nelem elements, results in a Numpy array, example:
np.linspace(1,3,5) will result in [1.0, 1.5, 2.0, 2.5, 3.0]
Next to being able to use two indices separated by a comma instead of many pairs of square
brackets, there is another useful feature of an array: it is easy to select columns or other parts of
the array:
Numpy arrays can be multiplied by each other or a scalar and used in functions from Numpy (np)
like np.sin( ), np.exp(), np.sqrt( ) etc. All functions and operators, work on an element-by-
element basis with arrays.
A drawback of arrays is the slower append function. Note the difference in append of lists:
import numpy as np
# List append
xtab.append(x)
The effect is more than a different syntax. The numpy.append function makes a copy of the array
with the value appended to it. In this case because xtab is also before the assignment it
101
overwrites the original, so the end effect is the same. The real penalty however is the decrease in
execution speed. With large quantities of data, making a copy takes extra time which can slow
down your code immensely. There are two better alternatives, which you sometimes can use:
1. When you know the size, it is better to generate an array of the right size with
numpy.zeros(shape) e.g. numpy.zeros(10) or numpy.zeros((4,4)) or a scalar times
np.ones(shape) if you need a specific default value.
2. You can use the list-type to append first and then, when it is complete, convert the list to
an array.
Exercise 1: As you have seen in the reader, arrays can make your life a lot easier. Therefore in
this first exercise we want you to plot a somewhat harder function, but by making use of arrays,
you are much quicker. So make a plot of a hexagon in python, which fits inside a circle with
radius 2.
Exercise 2: Make a function, when you give a certain n x n array (2D) you get the main diagonal,
so e.g. if you have A = we want our function to print 2, -1. Make sure this function can
work for all n x n matrices.
Exercise 3: Make a small program that gives the first column of a 2-dimensional list and also
make a program that does this for an array. Do you see the difference and how much easier
arrays are for this use.
a = np.array([0,6,3,-1,-10,22])
b = np.array([10,20,30,40,50,60])
102
There are different ways to use logic in a program which you have vectorized with Numpy.
Imagine we want a behaviour comparable with the unvectorized code below:
import numpy as np
h = np.arange(0,20.,1.)
tropo = 288.15 - 6.5*h
strato = 216.65+0.*h
temp = []
for i in range(len(h)):
if h[i]<11:
temp.append(tropo[i])
else:
temp.append(strato[i])
Using the fact that a True-value behaves as one and a False value as zero:
temp = (h<11)*tropo+(h>=11)*strato
swtropo = h<11
temp = swtropo*tropo+(1-swtropo)*strato
Using the conditional indexing to only select the values for which the condition is True and
gluing these arrays together with append:
temp = np.append(tropo[h<11],strato[h>11])
Exercise 1: Expand the program so you can calculate the temperature till 32000 m, the
temperature gradient between 20 km and 32 km is 1.0 K/km. Make a plot of the temperature
against the height.
Exercise 2: Plot the discontinuous function f(x) =
Exercise 3: Extract from the array ([3,4,6,10,24,89,45,43,46,99,100]) with Boolean masking all
the numbers:
- which are not divisible by 3
103
The example below also times the execution time of both ways.
from math import *
import numpy as np
from random import random as rnd
from time import clock
for i in range(n):
Vtab.append(100.+250.*rnd())
hdgtab.append(360.*rnd())
vetab = []
vntab = []
t0 = clock()
for i in range(n):
vntab.append(Vtab[i]*cos(radians(hdgtab[i])))
vetab.append(Vtab[i]*sin(radians(hdgtab[i])))
dtlst = clock()-t0
print "Lists took",dtlst,"seconds"
# Convert to arrays
Vtab = np.array(Vtab)
hdgtab = np.array(hdgtab)
print("Arrays took",dtarr,"seconds")
104
The result show that with 10000 elements the numpy method is about 11 times faster than the list
method! And also the numpy code looks cleaner. If we only do it the numpy way, the program
can even cleaned up to look like this (without the timing):
n = 10000
Vtab = 100.+250.*rand(n)
hdgtab = 360.*rand(n)
vntab = Vtab*cos(radians(hdgtab))
vetab = Vtab*sin(radians(hdgtab))
The difference between the two approaches is that when you apply a function or an operator on
the complete array, or the complete vector, the looping over the elements is handled by low-level
code inside numpy. The reason this is faster is twofold:
- the loop takes place in the fast, compiled low-level code of numpy
- list elements can have different types, while all array elements always have the same type, this
saves the computer from checking the type for each element and this saves execution time
Changing the code from treating each element to a complete array (or vector) at once, is called
vectorizing your code. In general, it is a good rule of thumb that when you can vectorize your
code, you should. Sometimes lists are easier or the lists are not that large that it is needed. But for
large quantities of data with the same type, vectorizing is nearly always a good idea.
Using two-dimensional arrays and the transpose function, vectorizing can be really powerful for
geometrical calculations, see the example below:
import numpy as np
dist = np.sqrt(dx*dx+dy*dy)
del dx,dy # Free up memory
105
print("Dist = ")
print(dist)
>>> x
array([[12],
[ 2],
[35],
[11]])
x.T means x will be transposed (so rows become columns and the other way around. So in this case x.T is:
>>> x.T
array([[12, 2, 35, 11]])
Note that this is still a two dimensional array, but with one row ( double square brackets).
As you can see in the ouput x-x.T results in matrix in which dx[0,1] gives x[0]-x[1].
The downside of using vectors this way with a lot of data is that all intermediate answers also become
vectors. With large quaitites of data, you can easily consume a lot of memory this way. In that sense,
vectorizing sometimes means exchanging speed for memory usage. A good way to avoid running out of
memory is therefore delete arrays used for intermediate results. But together with some linear algebra,
you can speed things up enormously.
106
Note: the matrix type will be removed in the future. Matrix multiplication will be dealt with a a
seprate operator for arrays: @
So A@B means the matrices stored in arrays A and B will be multiplied like matrices.
For completeness the description of the matrix type is still in here. As long as it is available, you
can still use it. The linear algebra functions remain unchanged.
Another very useful type is the matrix. The matrix is a type used within linear algebra. Why don't
we use the array type for this? One important reason is that some rules are different when
working with entire tables or with matrices.
For instance: A*B will result in entirely different things depending on what type you use. If A
and B are arrays, we will get an array where each element is the product of the same elements of
A and B. This is called element-by-element multiplication and is what you would expect if you
are talking about a table with densities and temperatures for example.
With matrices in linear algebra, we don't want that kind of multiplication, we want a matrix
multiplication. This also poses different restrictions on the dimensions. The resulting matrix is a
matrix-product of the two given matrices.
There is a special function to do element-by-element multiplication with matrices and there also
is a special function to do matrix-multiplication with arrays, but the default * operator uses the
most applicable for arrays and matrices as explained above.
So in short: use arrays for tables, like time histories or other scientific computing problems with
tables. And use the matrix-type for matrices in linear algebra problems or simulation models
with matrices. An example of how to define and use matrices is given below:
import numpy as np
B = A.I
print(B)
C=A*B
print(C)
Running this example will first print the matrix A (as a matrix), then a 9, (1=second row, 2=third
column). Then it prints the inverse of A, called B here. And finally it should print the identity-
matrix to check the inverse calculation.
107
Note that we use square brackets for indices and 0 as starting index as in Python. But also note
how we use a comma instead of two separate pairs of square brackets. Slicing with matrices (and
arrays) is much more user friendly and works as you would expect. So A[:,2] will give the last
column, try for instance:
print(A[:,2])
There are many ways to define a matrix. The np.matrix() or mat function accepts lists,
arrays and strings as input as in the example above. Using a string with a space between the
numbers and a semi-colon between the rows is often the easiest way to define a matrix as in:
A = np.mat("2 -2 0;1 5 9; 4 2 -5")
For some more examples on how to use a matrix, see the following source code. Also note how
Scipy also supports all types of Numpy. (So here we use sp instead of np!)
eps = 1e-8
B = linalg.inv(A)
108
x = B*b
print("Solution 1: x =")
print(x)
print("Solution 2: x=")
print(linalg.solve(A,b))
This illustrates some of the functions Numpy provides for matrices: inverse, determinant and
solve.
np.matrix( ), np.mat( ) Creates a matrix , argument can be a string like ‘(1 2;3 4)’ or a list,
or an array (operators now work with entire matrices)
matrix.I Invert matrix
np.linalg.det(matrix) Calculates the determinant of a matrix
It is possible to use two-dimensional arrays as vectors and matrices. To use the dot product, it is
then required to use the numpy.dot() function.
import numpy as np
A = np.array([[2,-2,0],[1,5,9],[4,2,-5]])
print(A)
print(A[1,2]) # row,column as in lin algebra but index starts
# with 0!
B = np.linalg.inv(A)
print(B)
Or to solve an equation Ax = b:
import numpy as np
A = np.array([[1,0,3],[-2,-1,0],[1,1,2]])
b = np.array([[1],[-1],[2]])
AI = np.linalg.inv(A)
x = np.dot(AI,b)
print(x)
109
x = np.linalg.solve(A,b)
print(x)
Note: Unfortunately, lately the Numpy community has been very critical about this matrix type,
which is regarded as an unwanted dialect of the array type. Using two-dimensional arrays for
matrices means using np.dot(A,B) or A.dot(B) for multiplication and np.linalg.inv(A) for
inverse, you can achieve the same as with the matrix type (but less elegant). This may mean the
matrix type may be phased out of Numpy.
110
python.
Exercise 2: A motorboat makes a trip of 29.5 km upstream trip on a river against the current in
3 hours and 10 minutes. Returning the same trip with the current takes 2 hours and 6 minutes.
Find the speed of the motorboat and the current speed. Try to solve this with a system of
equation and python.
Exercise 3: Make a linear trend line from the ten points which have coordinates shown below.
Use the least squares method to calculate this coefficients for this trend line.
xi = 0.1i where i = 1,2,3,...,10
yi = c1e^(-xi) + c2xi with c1 = 5 and c2 = 2
111
Numpy forms the foundation of Scipy. It is the basis of the array types and the basic functions
such as linear algebra Building on this foundation, there are already a large number of functions
available in the modules in numpy. See the list below for an overview of what is inside numpy:
But while Numpy has some useful functions for many applications and even some advanced
functions like Fourier transforms (frequency analysis of signals), Scipy contains many more
advanced functions, like curve fitting, optimization methods, frequency analysis, statistics:
112
On the internet, many more modules, which use Scipy and Numpy can be found. For nearly all
fields of science and engineering, modules with many tools are available for free.
In comparison, for a comparable package like MATLAB, often expensive toolboxes are required
to use something, which you downloaded from the internet. These toolboxes easily cost
thousands of euros, making it a costly decision to try a toolbox. This is, next to the higher
versatility and better syntax, one of the reasons why Python+Scipy nowadays is being used
instead of MATLAB. IEEE has already called Python+Numpy+Scipy the standard for data
analysis. MATLAB will probably become obsolete in the future as it is both more limited and
more expensive.
The Python community has the highest amount of PhDs resulting in high quality toolboxes being
expanded continuously and growing very fast. For aeronautics, we could still build a better
toolbox than the sparse examples which are available.
C
C Output theta in radians to block response of elevator
C Elevator = 0.2 radians between 1 and 2 seconds
C Boeing 737
C timestamp in seconds
C
0.0 = -0.00122299949023
0.1 = -0.0148544598502
0.2 = -0.00128081998763
0.3 = -0.00912089119957
………
………
………
………
………
19.7 = 0.0375150505001
19.8 = 0.0133852241026
19.9 = 0.0195944297302
When we plot this data we get this figure, showing a very noisy signal:
113
In this plot we can see the original signal, to get this line we can try a polynomial fit, to get a
signal more close to the original signal. Note how in this program we use the function
genfromtxt() from Numpy/Scipy to read the data into a two-dimensional array with one
program line! Then we select the two columns.
To fit the data we use the function polyfit, which return the polynomial coefficients, in this case
set to a 10th order polynomial. The result is then written to a file.
import scipy as sp
import matplotlib.pyplot as plt
# Plot
plt.plot(xtab,ysmooth)
plt.plot(xtab,ytab,"r+")
plt.show()
# Write to file
g = open("filtered.log","w")
g.write("C\n")
g.write("C Data smoothed by fitting a 10th order polynomial\n")
g.write("C\n")
114
for i in range(len(xtab)):
line = str(xtab[i])+" = "+str(ysmooth[i])+"\n"
g.write(line)
print(line)
g.close()
The resulting plot shows both the power and limitation of polynomial fitting:
The curve is indeed a smooth polynomial. The disadvantage is that there are limitations to how a
polynomial can fit the data points. Even when a higher order is chosen (10th order seems to be
working for a smooth curve with 8 local minima/maxima) it does not give a useful result outside
the interval. So while it is very useful for interpolation, it should never be used for extrapolation.
More advanced methods take into account a certain assumed relation of which the parameters
will then be estimated. The least squares method, which minimizes the square of the error, can be
used for this and is made available by Scipy.
115
The iPy Notebook is very convenient user interface for Scientific Computing tasks. It allows you
to edit snippets of Python/Numpy code (“Cells”) which you run but also can still edit later. You
can access all variables between cells, as if you are in one program, but you can also see the
output (including plots) in between the code. The result is a blend of a graphical calculator,
Python and a spreadsheet program like Excel. You can run an individual cell or all cells and see
how the output changes. You can also add cells with raw text to create a living document. Each
notebook page can be saved (“downloaded” as it is called in this client-serve set-up) as either
a .py Python file or a .pyndb Python notebook file. The Notebook page is both a scratchpad as
well as a publication.
An example of how this looks is shown below. As you can see all functions from math, numpy
scipy and matplotlib.pyplot have already been imported:
116
117
# Create tables
ttab = []
ytab = []
# Initialize
y = 100.0
vy =0.0
t = 0.0
dt = 0.01
# Run simulation
while y>0.:
t = t + dt
vy = vy –g*dt
y = y + vy*dt
ytab.append(y)
ttab.append(t)
# Plot y
plt.plot(ttab,ytab)
plt.show()
Here we note two things: an empty list is created and later elements are added. These elements
could be changed later. We could set ytab[i] to a certain value. But what is also notable is the
fact that we call the append function (or method) with the variable:
variablename.append(value)
We have seen a similar syntax with strings: varname.sort() or varname.upper(). The reason
for this is that lists and strings are actually so-called classes: a sort of specific variable type with
data and functions as a part of its definition.
This syntax is often seen when using modules. Since one of the powers of Python is the number
of modules included and freely available on the internet, this deserves some extra attention in the
final paragraph on classes.
118
12.2 Tuples
Lists have been discussed in chapter 2 and in the previous chapter on Numpy we have already
seen a new type of lists called arrays, as used by Numpy. In fact, the list-type is the most simple
and versatile form of an array- or list-type of variable. It can contain different types and each
element can be treated as an independent variable. But there are many more list-like types, one is
the so-called tuple.
A tuple is a list but it is immutable (just like strings). This means it cannot be changed once it is
created. The variable can be overwritten by a new tuple, but individual element cannot be
assigned a different value, nor can elements be added or removed. This is the only difference
between lists and arrays. To distinguish between lists and tuples we use the round (normal)
brackets to define a tuple. It is also possible to omit the brackets, this also indicates you want to
create a tuple. So two valid ways to create a tuple are:
origin = (0,0)
pos = 3,4
If you call a function with a tuple, you always need the round brackets, see the line with d2
below:
d1 = dist(origin,pos)
d2 = dist((3,4),(-3,6))
If you would omit the brackets in the second line, Python would think you call the function dist
with four arguments.
Tuples can, just like lists, and unlike Numpy arrays, contain a mix of different types such as
integers and floats etc..
It seems like a tuple is a list with a limitation, so what are they used for? Tuples can be seen as
multi-dimensional values. So for instance if you want to specify an RGB-colour by its red-green-
blue components you could use the following assignment to defines these colours for later calls
to a graphical library:
black = (0,0,0)
white = (255,255,255)
brightred = (255,0,0)
red = (127,0,0)
cyan = (0,255,255)
We’ve also already seen that maptlotlib.pyplot.legend() used a tuple for the legend text,
Although this legend()-function can also be called with a list. In the next chapter about
Pygame, tuples are used for colors and positions.
There are many more list-like types. In most cases the list type will work for you. But sometimes
a special list-like type can be convenient. If you’re curious, check the Python documentation on
sets and dictionaries.
119
posa = Pos(3,4)
posb = Pos(-1,5)
distvector = posa.sub(posb)
dist = distvector.length()
To be able to do this we need to tell Python what our type of variable, our class, is and what the
functions should do. This is done by defining a new so-called class Pos:
class Pos:
def __init__(self, xcoord, ycoord):
self.x = xcoord
self.y = ycoord
return
def sub(self,pos2):
rx = self.x - pos2.x
ry = self.y - pos2.y
newp = Pos(rx,ry)
return newp
def length(self):
return sqrt(self.x*self.x+self.y*self.y)
After the header a number of methods are defined. They use the same syntax as the definition of
a function. So a method is a special type of function connected to the class Pos. It is therefore
also called by the syntax varname.methodname(arguments).
Note that a special function __init__ is defined first: the so-called “constructor”. It is called
automatically upon creation of a new instance of the class (like for posa and posb in the
example). This definition of __init__ tells Python how this type can be created and what to do
with the arguments that may also be given. In this case, they are simply stored as members x and
y. So we note there are two variables stored in a Pos-type of variable: x and y. These are called
members of the class Pos.
120
An example of how to use this class (we assume we have saved the above code in the file named
CPos.py):
a = Pos(2,3)
b = Pos(1,2)
c = a.sub(b)
print (c.x,c.y)
print (c.length())
You can build your complete program around classes. By first defining your classes including
members and methods, then building classes consisting of classes on top of each other, your final
program could be very short. This can be done by just calling the highest level of classes like:
sim = Sim()
running = sim.start(0.,0.,0.)
while running:
sim.update(running)
Overloading operators
It is also possible to define what the operator in a class. For instance the sub function in the class
could also be defined in another way, using the two underscore symbols in front of the name and
after, a key for the special functions which Python uses, just like __init___ indicates the
constructor in Python.
def __sub__(self,pos2):
rx = self.x - pos2.x
ry = self.y - pos2.y
newp = Pos(rx,ry)
return newp
The method __sub__ as defined inside this class, will automatically be called when the minus
sign operator is used. So the call to sub can then be changed in:
c = a – b # was c = a.sub(b)
121
The following is a list of operators which can be overleoaded (i.e. defined) in a class definition,
the name to be used for the method definition is given in the second column.
Object oriented programming is beyond the scope of this reader. You do not need to know how
to define your own classes. You have already been using classes when calling string methods or
list methods. For this course, it is only important that you know that the concept exists and why
you sometime call methods or access members. It also explains the syntax of variablename-
period-method(arguments) like list.append(x).
It is important for you to know how to use the classes and how to call methods inside a class.
Especially in Pygame we see two new types of variables being used a lot: a surface and a
rectangle. These are classes. One is designed to hold a bitmap, the other to hold a position and a
size of any rectangle. In the rectangle class not only methods are used but also members, (like
top, width, height) can be assigned a value. This will be shown in examples in the Pygame
chapter. Even though the concept of classes and object-oriented programming may be difficult,
using modules with classes is surprisingly easy and user-friendly, as we have already seen with
lists and strings and we will also see in the Pygame chapter.
122
Dictionaries
Two special types of lists can be handy. Dictionaries are lists where you do not use an integer
index but a key to look up a value.
An example of a dictionary:
This error can be prevented by first checking whether ‘Jet” is in the keys of this dictionary, using
the keys function:
if "Jet" in ages.keys():
print(ages["Jet"])
We can also add entries in the way as you would intuitively expect:
ages["Jet"] = 30
Even though the order is not defined you can still iterate over dictionaries. The following code
for a in ages:
print(a)
will print all keys. The again, if you wanted not the keys but the entries, simply use the key:
for a in ages:
print(ages[a])
Sets
Sets are lists used for unordered collections of unique elements. It is used to check membership
of a collection, overlaps of collections, etc.
It is defined similarly to a list (square brackets) with the function set. Example of the use of sets:
>>> a = set([3,1,34,65,2,2,1])
123
>>> a
set([1, 34, 3, 2, 65])
>>> if 2 in a:
print 'yes'
yes
>>> 2 in a
True
>>> b = set([1,6,7,10,2,3,7])
>>> a|b # which elements are in a or b?
set([1, 34, 3, 6, 65, 10, 7, 2])
>>> a&b # which elements are in a and b?
set([1, 2, 3])
>>>
The difference between a set and a list, is that in a set an element does not have specific place
and each element is only in once. It is a collection as used in the mathematical set theory: an
element is either a part of a set or not.
Imagine you have two lists with a set of numbers, and you simply want to know whether they
use the same digits, than converting them to sets and comparing it will do this for you.
a = set([1,2,5,3,6,7,0])
For a complete overview, including the operators, type “help(set)” in the Python shell.
124
In this chapter we will explore different modules inside Pygame like display, event, key, mouse,
image, transform and draw, as well as the new types (classes to be exact): surface and rect. There
are many more modules inside Pygame for you to explore like, music, joystick, etc. but these
will not be discussed here. Next to Pygame, some basics of setting up a game or simulation will
be discussed such as the ‘game-loop’ and timing issues.
Just as with Numpy and Matplotlib, Pygame is a third party add-on. So before you can use
Pygame, you need to add the import line. Also you should add two calls to Pygame at the
beginning and end of your program for initialization and cleaning up, resulting in the following
three mandatory lines:
import pygame
pygame.init()
….
….
(your program will be in between these calls)
….
….
pygame.quit()
The init-call has no immediate visible effect, but it is required to avoid having to initialize each
module of Pygame independently. So calling pygame.display.init, pygame.key.init is
not necessary when you include this one call.
pygame.quit() will have a visible effect: it will close any Pygame windows still open. If
during the development your program crashes due to an error and the Pygame window is still
open, type pygame.quit() in the shell to close it. (or pg.quit() if you used import
pygame as pg)
125
Pygame has a very good online reference manual at http://pygame.org/docs . In the top section of
this page, you see the name of each module inside Pygame. Click on these names to get a list of
functions in that module, and click on the function name in this list to get a full description.
reso = (600,500)
screen = pygame.display.set_mode(reso)
Or in a similar way (mind the double brackets, the resolution is a so-called tuple, see section
12.2):
screen = pygame.display.set_mode((600,500))
In computer graphics, a coordinate system different from mathematics is used, mainly for
historical reasons. The top left corner is the origin and the y-coordinate runs from zero in the top
to the bottom, so in our example y=500 pixels indicates the bottom line. X-coordinates are from
left to right. This stems from the text terminal which had line zero and column zero in the top left.
So the window, which we just created, has the following coordinate system:
126
In the computer graphics world things get really complicated in three dimensions. In the graphics
coordinate system, the Z-axis points positive to the viewer, in effect creating a left-handed (!)
axes reference system, where cross products and other functions work just the other way around.
So screen coordinates work in a non-standard way and are also always integers. For these two
reasons, it is standard procedure to define your own so-called world coordinates (with a right-
handed reference frame), which you use for your model. And when necessary you convert them
to screen coordinates, normally just before we need to plot, draw or blit. It also allows us to
change the window size later (e.g. to full screen), without changing our model. An example of a
simple 2D world coordinate system is:
In this case we can do calculations using any position in floats, like do numerical integration in
floats and then only when we draw convert our float world coordinates to the integer screen
coordinates just before plotting with the following lines of code. In the example below the world
coordinates are (x,y) and are converted to screen coordinates (xs,ys):
xmax = 600
ymax = 500
reso = (xmax,ymax)
screen = pygame.display.set_mode(reso)
….
…..
x = x + vx*dt
y = y + vy*dt
xs = int(x/1.67*xmax)
ys = ymax-int(y*ymax)
127
All in all, it is a very versatile type allowing you to manipulate or transform (scale move,
copy/paste, rotate) bitmaps.
When you paste one surface onto another, this is called blitting in the computer graphics world.
It stems from the “block of bits” of the video memory which is transferred with one call to a blit
function. Before we can do this we also need to specify where we want this rectangular image to
be pasted.
When we have loaded an image from the disk, we need to know how large it is and where we
should be able to position it onto another surface later. This is where the rectangle class comes in.
A rectangle is not the actual surface but it contains some parameters: the size and position of a
surface. It has several members, which we can assign values to. The neat thing is that we do not
need to worry about the bookkeeping: when you change one value, the other ones will be
changed automatically when needed. One simple example is given below. To clear the screen,
we draw a black rectangle. For this we need to specify the position and scale first. If we get the
rectangle from a surface to measure the size, the position is by default set to (0,0) for the top left
corner. To do this, we use the method get_rect in the Surface class (see the section on Surface
in the Pygame documentation for a full description of the methods of surface).
black =(0,0,0)
scrrect = screen.get_rect()
pygame.draw.rect(screen,black,scrrect)
A Rect has the following members, which you can read or assign a value to:
Center is a tuple equal to (centerx,centery). The user can choose to position the rectangle using
any combination of these members.
Another example where the Rect class is used is given below, where an image is loaded from a
file on the hard disk. Generally, we do this loading from a file only once at the beginning of our
program, because accessing the hard disk has a huge execution speed penalty. The example
shows how to use the rectangle: first we get the size from the surface object and then we position
it and use it to blit the surface on the screen surface:
128
ship = pygame.image.load(“rocket.gif”)
shiprect = ship.get_rect()
…..
…..
while running:
shipx = shipx + vx*dt
shipy = shipy + vy*dt
shiprect.centerx = shipx
shiprect.centery = shipy
screen.blit(ship,shiprect)
In the code we can see how the rectangle is used to position the bitmap, which was read from
rocket.gif, on the screen. The same call can be used with a tuple containing the coordinates of the
top-left corner of the surface. As visible in the syntax, blit is a method from the Surface class,
hence it is called as a method, so with a period behind the destination surface (=variable named
“screen” in our example).
scr = pygame.display.set_mode((500,500))
ship = pygame.image.load(‘lander.gif’)
shiprect = ship.get_rect()
………
………
shiprect.center = (xs,ys)
scr.blit(ship,shiprect)
As said before, it is important, to load the bitmaps before the actual game loop. Accessing files,
to load an image, in general takes a lot of time. This means it might cause hick-ups or delays in
your program, if you do this during the loop.
Sometimes bitmaps do need some editing before they can be used. When blitting images on a
surface a transparent background is often required. This can be edited with a painting program
such as Paint.net, Gimp, Paint Shop, Corel Draw or Photo shop and deleting the background so it
becomes the transparent colour. Save the file in the GIF format (or PNG) as these formats allow
transparent backgrounds. Also use these programs to change colors, size or perform rotations.
If you need one bitmap in a lot of different orientations, editing it with a paint program can be
cumbersome. These operations can also be done much easier with pygame in your program. This
129
can be done using the transform module which allows you to manipulate bitmaps/surfaces. Some
examples of functions available in pygame.transform:
Be aware that you do not scale or rotate inside the game loop unless it is absolutely necessary. In
most cases it pays off to generate different surfaces for all possible orientations beforehand, store
them in a list and just use the appropriate one during the game loop by setting the index with the
angle rounded off to 45, 20 or 5 degrees. The same goes for scaling. Transforming bitmaps is
rather computational intensive and in general it is the goal to do any time consuming operation as
much as possible before the actual running of the game loop.
The coordinate system used is explained in the section on setting up your screen. It runs from
(0,0) in the top left corner to the maximum x and y in the bottom right. All sizes and positions
are integers.
130
Colours are specified with a tuple (red,green,blue), three numbers each ranging from 0 – 255 to
indicate the amount of each colour channel present in the mixed color. For readability it helps to
define a few colours at the beginning of your program and use these in the calls:
black = (0,0,0)
cyan = (0,255,255)
white = (255,255,255)
background = (0,0,63)
foreground = white
Animation consists of nothing else than redrawing every frame over and over in a simulation or
game. To avoid flickering images when the screen is cleared for the next drawing, this is first
done in a part of the video memory which is not visible. There we clear the screen, and either
with drawing (rectangles, circles and lines) or blitting the next image is created. Once it is
finished, we can show it on the screen. This also means we will not see anything until we copy
this video memory to the screen. This is done with the following call, to be used at end of all
your draw and blit calls in the loop.
pygame.display.flip()
If you have used the default settings when creating the window with
pygame.display.set_mode(), a call to flip updates the window with the video memory.
When you use the option double buffering, you have two areas of video memory, so two surfaces
which will be used simultaneously: one will be shown on screen, the other you can draw on.
Once you’re done drawing the frame, you swap the function of both surfaces. The advantage is
that you do not need to start with an empty frame then, but can use the one-but-last frame as a
start. In practice, to take advantage of this you might need a lot of bookkeeping but it might
result in a higher execution speed.
131
Using the full-screen option is often only done when the game or simulation is ready, debugged
and tested, since debugging is severely hampered by a crashing full screen application!
import pygame
pygame.init()
reso = (600,500)
screen = pygame.display.set_mode(reso)
scrrect = screen.get_rect()
black =(0,0,0)
ship = pygame.image.load("rocket.jpg")
shiprect = ship.get_rect()
shiprect.centerx = 250
for y in range(500,-100,-2):
shiprect.centery = y
pygame.draw.rect(screen,black,scrrect)
screen.blit(ship,shiprect)
pygame.display.flip()
pygame.quit()
Now when we run this, it could turn out that our ship moves too fast or too slow. To fix this, we
will then adjust the third argument of the range function in the for-loop, currently set to -2.
However, on another computer the speed would again be different. Also, when another
application in the background needs the CPU for a short period, our rocket will hamper before
continuing. This is because we have no control over the real speed of the rocket. For this we
need more than controlling the position, we need to control the timing in our game as well. Or at
least measure it and calculate the elapsed time (time step) since we last drew our ship, so that we
can calculate the required new position with the speed and right time step based on the elapsed
time since the last frame.
There are two principles we can use to make sure our simulated time runs in accordance with the
real time:
132
import pygame
# initialize clock
pygame.init()
tsim = 0.0
tstart = 0.001*pygame.time.get_ticks()
dt = 0.1
……
……
running = True
while running:
trun = 0.001*pygame.time.get_ticks() – tstart
if trun+dt >= tsim:
tsim = tsim + dt
vx = vx+ax*dt
vy = vy+ay*dt
x = x + vx*dt
y = y + vy*dt
……
……
The advantage of this method is that you know what the time step is. This also allows for more
advanced numerical integration methods and guarantees the stability of your simulation. When
using a variable time step (Method II) there is a risk of getting a too large time step, which can
result in overshoots and even a runaway of your simulation. The disadvantage of this method,
that it requires a time step, which is large enough to make sure the simulation can always keep
up with the real time. If you make this time step too small, the simulation may lag behind or run
at a variable speed, resulting in quirky speeds and movements
This is how the code looks in Python when using the method of the variable time step. The
variable t0 here keeps the previous time when everything was updated:
133
import pygame
# initialize clock
pygame.init()
t0 = 0.001*pygame.time.get_ticks()
……
……
maxdt = 0.5 # time step limit to avoid jumps
running = True
while running:
t = 0.001*pygame.time.get_ticks()
dt = min(t-t0,maxdt) # set maximum limit to dt
if dt>0.:
t0 = t
vx = vx+ax*dt
vy = vy+ay*dt
x = x + vx*dt
y = y + vy*dt
……
……
One of these two mechanisms forms the basis of our loop which is executed while running. This
is generally called the game-loop. In principle, it runs indefinitely until a quit event is triggered.
This quit event can be multiple things:
In our example so far, just setting running to False will make sure the loop ends:
running = True
while running:
.....
.....
if y<0.:
running = False
.....
Another way to achieve this, is using the break command (which I personally see as less elegant):
while True:
.....
.....
if y<0.:
break
.....
134
Before the game loop our model is initialized, graphics are loaded and set-up and our simulation
is initialized. We have seen how to control time, how to numerically integrate and how to draw a
frame. But we still need to know how to process input from keyboard and/or mouse.
pygame.event.pump()
keys = pygame.key.get_pressed()
The first line is required because of the way windows handles events, like keys being pressed.
The second line collects all key states in a long list of logicals. Each key has a fixed position in
this list of logicals. When this logical is True, the key is currently held down and when the key is
not pressed, the logical is False.
So imagine we want to check for the Escape key, how do we know which logical to check?
Pygame has a list of variables (integers) with indices for every key (check
http://pygame.org/docs/ref/key.html ) that you can use. For example to check the Escape key we
use (after the storing the logical in our variable keys with the above piece of code):
if keys[pygame.K_ESCAPE]:
running = False
Some examples for other indices we can use (always with pygame. in front of this name if
you’ve use import pygame):
135
Similarly we can get the state of the mouse buttons with pygame.mouse.get_pressed(),
which returns three logicals for the three mouse buttons. The function
pygame.mouse.get_pos() returns the current position of the mouse.
Both key- and mouse-functions will return only the useful values if your pygame-window is
running in the foreground (or in windows speak: has focus).
Another more advanced way to handle the mouse is to use the windows event handler. For
instance for the quit-event (somebody tries to close the window, e.g. by clicking on the red
button). An example of how this event handling could be used is given in the following piece of
code:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
mx,my = event.pos
……
elif event.type == pygame.MOUSEBUTTONUP:
……
Many of these events contain data, e.g.on where the mouse was clicked, which button or which
key was pressed. See the example above for using the mouse position. Other names of members
of the different event type are listed below:
Most of the times the event handling is not required, but as a minimum handling the quit event is
considered good practice: it allows the user to close the window.
Note: it is important to always include the event pump. If not the Pygame window will say “Not
responding” as the windows OS events will not be processed.
pygame.display.flip() Update the screen with the video memory (so display screen surface)
surface.get_rect() get the size of a surface in a rectangle (top and left will be zero)
surface.blit(sourcesurface,rect) Pastes the source surface on the surface at the position specified
in rectangle rect
pygame.event.pump() Flush event queue (to avoid hanging app, and to poll keyboard)
var = pygame.key.get_pressed( ) Poll the keyboard: logical array for all keys, True if pressed
if var[pygame.K_ESCAPE] : How to test for Escape key: test the logical array with the
right index (see documentation for other key indices)
More information on these and many other pygame functions can be found in the on-line
reference guide: http://pygame.org/docs
137
Exercise 1: With the knowledge you achieve each section, we want you to make a relatively easy
game. So the first exercise is to make a screen with a resolution of 750x500 px, besides this it
should also have a blue background.
Exercise 2: Place an image of an airplane at the left side of this screen. Google for a nice plane
“plane no background”, flying to the right
Exercise 3: Now we want to include a time loop so that your airplane flies straight forward with
constant speed over your screen.
Exercise 4: The final step to make your game actually fun is to add key input, so make sure your
plane can move up and down when you press the arrow up and when you press the arrow key
down. Also make the escape key such that if you press it you quit the game.
138
Still, it can sometimes be a very useful feature, so we show a few examples here of how to use
try and except.
The first example of an a,b,c formula solver for second order polynomial could check for a
negative D by simply catching the error of a negative square root:
import math
D = b**2 - 4.*a*c
try:
x1 = (-b - math.sqrt(D)) / (2.*a)
x2 = (-b + math.sqrt(D)) / (2.*a)
print("x1 =",x1)
print("x2 =",x2)
except:
print("This equation has no solutions.")
To make it even more advanced: it is possible to check which error was caught:
import math
D = b**2 - 4.*a*c
try:
x1 = (-b - math.sqrt(D)) / (2.*a)
x2 = (-b + math.sqrt(D)) / (2.*a)
print("x1 =",x1)
print("x2 =",x2)
139
except ZeroDivisionError:
print("this is a first order equation: a=0")
x = -c/b
print("Solution x =",x)
except:
print("This equation has no solutions.")
Just like other flow control statements, try statements can be nested:
try:
x1 = (-b - math.sqrt(D)) / (2.*a)
x2 = (-b + math.sqrt(D)) / (2.*a)
print("x1 =",x1)
print("x2 =",x2)
except ZeroDivisionError:
print("this is a first order equation: a=0")
try:
x= -c/b
print("Solution x =",x)
except:
print("No x found.")
except:
print("This equation has no solutions.")
Examples of types of errors you can catch (the names speak for themselves):
When an error occurs, the name of the error is always given in the shell. A complete list can also be found
in the Python (the documentation provided with Python) under the header Exceptions.
140
Then click your project folder with the right mouse buton, while holding the right shift
(Windows specific) or navigate to the project folder with cd (Linux and Apple). We will then
convert the program using pyinstaller:
This will create an executable called myprogram.exe in a subfilder dist, accompanied by all the
necessary files to make it run without Python. The folder and executable will be named after the
the first script (myprogam) and this script will be started when the executable is started.
Manually you need to add any data files or data folders which you want included because the
program needs those.
The game has two python files: mazeman.py and toolsmaze.py, the latter of which all functions
are imported in mazeman.py. The are three subfolders with data files named bitmaps, sounds and
choose-your-maze. The program uses fonts to display the score text on the top line. The main
module, with which the program is started, is called mazeman.py. So we convert it using:
141
First of all we need to copy our data files to this dist folder, so our mazeman.exe will find them.
In our example, the three subfolders named: bitmaps, sounds and choose-your-maze.
To see whether our program needs any additional files, it may be useful to start our program
mazeman.exe with a batch files with a pause command, so we can read warnings and error
messages in the console. Let’s call this runme.bat for example (in the dist folder as well) .
Create it with notepad or idle):
mazeman.exe
pause
Then run it to test it and see if you need to add any other files. Sometimes you may need other
DLLs from third party module you use.
When your .exe pygame program crashes, even though it did not when executed in IDLE
Without IDLE, there is less protection against memory leakage and lost handles. When I
experienced problems with crashing Pygame executables it was always due to one thing: the font
library. When you have created a font object, you also need to delete it before you go on with the
next text. So make sure you always delete variables created with pygame.font after you’ve used
them. The font object in Pygame is very sensitive, but apparently Python handles this for you
when you run it in the shell, so you will only get into trouble when you have made your
executable.
142
There are more fancy ways to distribute your program and create an installer, which will do these
same things for you and create an executable for installation. Just download such a program e.g.
from download.com. Some are free like NSIS or Inno Setup (last one is recommended).
With Inno Setup, you need to select the ‘dist’ folder as root and add this (with all files and
subfolders). Also you need to indicate which executable is the program to start and perhaps
allows an entry in the Start menu. Inno set-up then compiles everything into one neat setup
program as a executable e.g. setupmazeman.exe. This is often quite large. Many mail programs
or mail servers will prevent sending executables, because that’s the way viruses are distributed.
So to mail it, you may need to convert this one file to a compressed folder/ archive (ZIP or ARJ
extension).
143
144
keeping the history of the repository traceable, and enabling you to go back to and compare all
the old versions of the software.
Then you are going to collaborate with Max, who also checks out a copy of the software from
the repository, and corrects to:
145
Max quickly checks this in by doing a commit, so now the repository has Max’s updated version.
In the meantime you recognize Max’s contribution, and change the line to:
# a program by Lisa and Max
Now, if you commit your version, the VCS tries to get the latest, final version of the software in
the repository by applying a patch from your old version (# a program by Lisa), to your new
version (# a program by Lisa and Max), to the version that is currently in the repository.
However, that will fail with a “conflict”, because the repository version has changed at that
specific location. You have to then manually fix the file (the VCS helps you there by marking the
conflicts), and tell the VCS that you resolved the problem. If you work together in a reasonable
fashion (typically by not all working on the same code at the same time), conflicts can be
avoided, and if they occur, it is usually easy enough to resolve them. This side effect may seem
to be a drawback of using version control systems over copying files, but there is actually a
significant advantage; it prevents you from silently overwriting previous work.
On Windows, a tools called Winmerge can be used to compare source in a GUI and merge
different versions.
146
The alternative is a distributed or de-centralised VCS, of which “git” is a prime example. When
starting to work on the code, you must “clone” from a git repository on the web. The clone
copies the entire repository, including information about its history, to the local computer. In a
second step you can check out any revision from the now local copy of this repository; by default
the VCS checks out the latest development version. Then any commit will be done to the local
clone of the repository, creating a new revision , and you will not need internet access for that. In
a second step these changes can be copied over to the remote repository, with a “push”. To get
changes that may have been added by others to the remote repository, you need a “pull”
command, which gets all the revisions added to the remote repository from the time you cloned it,
or did your last pull. The local copy you are working on is linked to one particular remote
repository, but it is also possible to link multiple remote repositories to the local development
copy, and switch between these. We will not further explore this here, interested readers are
referred to https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes. When you are
working with only one remote repository, there is conceptually not much difference between
using a centralized or a distributed version control system; the only steps you should not forget
are the pull and push steps, to synchronize the local clone with the remote repository.
147
With branching, you can split off a version of the software (i.e., as a complete set of files and
folders) that can from then on be independently developed from the main “branch”. To illustrate
this, let’s take the scenario where your teammates are already running low-speed analysis of the
flight performance using the initial version of the software you developed in your (3rd year) DSE
project, and you now want to add compressibility effects to properly calculate cruise
performance. By branching off, you will be able to simultaneously have and maintain two
versions of the program. You can work on the new version without risking breaking the version
that the others are using. When the work on the branch is complete, the two versions can be
merged again, applying all development from the development branch to the main version in one
step. For this, the VCS can apply all the commits you added to the new branch to the old branch
that people have been using. Also if the main branch has been moving on, for example when
bugs had to be fixed there, the merge will combine the changes on both branches, keeping both
the addition of new capability and the bug fixes.
16.3 Subversion
If you use subversion, branches will look like folders on a file system. The typical layout of a
subversion repository uses “trunk” as the main development version, and the “folders” branches
and tags. The folder “branches” is for branched off (development) versions, and “tags” is
typically used to remember released versions of the software. Here is an example of a repository
layout:
MyProject/trunk
MyProject/tags/v0.9
MyProject/tags/v1.0
MyProject/branches/add-mach-effects
At each branch (trunk, v0.9, etc.) the subversion repository show all the files and folders in your
project. Superficially, it looks as if everything is copied, internally, subversion maintains an
inventory of differences and changes in the files.
The following has a summary of the most-used actions in subversion. Note that the server name,
project name and branch names are fictional, adjust as needed.
148
16.4 Git
Here is a set of commands for git:
149
Note that these git and subversion command summaries are by no means complete, they
represent a minimum set of commands to handle the most common cases. There are also many
GUI tools to help you navigate the git or subversion commands, check out the pages at
https://git-scm.com/download/gui/windows or
https://en.wikipedia.org/wiki/Comparison_of_Subversion_clients
150
master = Tk()
w = Canvas(master, width=200, height=100)
w.pack()
w.create_line(0, 0, 200, 100)
w.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
w.create_rectangle(50, 25, 150, 75, fill="blue")
mainloop()
Alternatively, even LOGO like graphics have been included in Python using the turtle module.
Not te be used for serious applications but it’s really a lot of fun, like a nice, spirograph-like toy
and also a very good way to teach younger people how to program!
from turtle import *
for i in range(200):
forward(i)
right(90.5)
done()
151
# Import the Arcade library. If this fails, then try following the instructions
# for how to install arcade:
# http://arcade.academy/installation.html
import arcade
import os
# Set the working directory (where we expect to find files) to the same
# directory this .py file is in. You can leave this out of your own
# code, but it is needed to easily run the examples using "python -m"
# as mentioned at the top of this program.
file_path = os.path.dirname(os.path.abspath(__file__))
os.chdir(file_path)
# Open the window. Set the window title and dimensions (width and height)
arcade.open_window(600, 600, "Drawing Primitives Example")
# Start the render process. This must be done before any drawing commands.
arcade.start_render()
# Draw a grid
# Draw vertical lines every 120 pixels
for x in range(0, 601, 120):
arcade.draw_line(x, 0, x, 600, arcade.color.BLACK, 2)
# Draw a point
arcade.draw_text("draw_point", 3, 405, arcade.color.BLACK, 12)
arcade.draw_point(60, 495, arcade.color.RED, 10)
# Draw a line
arcade.draw_text("draw_line", 243, 405, arcade.color.BLACK, 12)
arcade.draw_line(270, 495, 300, 450, arcade.color.WOOD_BROWN, 3)
152
# Draw a polygon
arcade.draw_text("draw_polygon_outline", 3, 207, arcade.color.BLACK, 9)
point_list = ((30, 240),
(45, 240),
(60, 255),
(60, 285),
(45, 300),
(30, 300))
arcade.draw_polygon_outline(point_list, arcade.color.SPANISH_VIOLET, 3)
17.1.4 Miscellaneous
For other options to draw in 2D, see also the windows GUI section, because both PyQT and
wxPython have graphics functions included for 2D graphics. This library was discovered and
recommended by Fons de Leeuw, a student who used this to visualize acceleration data in his
paragliding footage using flight instruments. He found it to produce better images, mainly due to
the anti-aliasing which creates smoother drawing. Because of the vector format, the output
quality is also better for e.g. printing.
Not really a graphics library, but the free, open source photoshop program GIMP, has a Python
console built-in, which allows you to do batch operations in GIMP. You can find it in the pull
down menu “Filters” > “Python FU”. To get an impression of the code an example is given
below:
g = gimp.pdb
images = gimp.image_list()
my_image = images[0]
layers = my_image.layers
w = g.gimp_image_width(my_image)
h = g.gimp_image_height(my_image)
print("Image Resolution: w=%d,h=%d"%(w,h))
154
These two lines will result in the window on the right side to be shown:
Objects can be added a simple way (see the axes below to understand the positioning):
155
17.2.2 Panda3D
Panda 3D is a very complete 3D graphics and game engine developed orginally and hosted by
Carnegie Mellon. This includes very advanced graphics functions. It is compatible with the
PyODE physics engine. Check out their website for some impressive demos: www.panda3d.org
and for documentation and download. Panda3D is Open Source and free for any purpose.
PyOpenGL is very fast and interoperable with a large number of external GUI libraries for
Python including wxPython, PyGTK, and Qt. It can also use the GLUT library to provide basic
windowing and user interface mechanisms (pulldown
menus).
http://www.willmcgugan.com/blog/tech/2007/6/4/opengl
-sample-code-for-pygame/
Several students have explored this option and used it successfully to make a 3D solar system
visualization, a 3D asteroids game and even a Moonlander simulation on a hilly moon surface.
Working with OpenGL is quite complex, so it can be hard, but it is also very powerful.
156
No matter which 3D library you use, you will need to create 3D objects with complex shapes,
surfaces and textures. For this most Python programmers (and many others) use the freeware
program Blender. Blender a a very advanced, yet easy to use, 3D content creation suite. You can
import objects made in Blender in Python using OpenGL. Even without Python, Blender can
make interactive animations. Make sure to visit the website to check out the beautiful gallery.
Blender is used a lot by professionals in the Computer graphics world (for commercials, movies
and games). Also check out Youtube for some impressive Blender examples. Blender also has a
powerful game engine.
157
To add even more realism, you can also use the PyODE physics engine as your development
environment. It provides a simulation of the physics of an extremely rich physical environment.
It takes care of realistic mechanics and dynamics of your scenery including gravity, friction,
inertia, collisions, etc.. PyODE can be used for simulation, visualisation or gaming. Relatively
easy to use, but realize that the closer you get to reality with your simulation, the more complex
your model and your program will become: you’ll need to set a lot of parameters, although many
defaults are supplied. To get an impression of what it can do check put youtube videos like
‘ragdoll demo python ODE’.
17.3.1 Tkinter
Already provided with Python, builds on Tcl/Tk library. The TkInter module is an easy way to
use the standard window dialog boxes, e.g. the File Open dialog box (named:
tkFileDialog.askopenfilename ) in the example below:
import os,sys
from tkinter import *
import tkinter.filedialog as fd
Other standard dialog boxes with their tk name which you can use, like the above example, are:
158
Some documentation can be found in Python Reference, but more can be found in the pdf file at
http://www.pythonware.com/media/data/an-introduction-to-tkinter.pdf. It contains basic
functions to build dialog boxes with many controls as well as the handle to call most standard
windows dialogs. Easy to use but requires hand-coding and is rather basic in terms of graphics.
Still, the IDLE shell and editor you are using, were made in Tkinter. Tcl/Tk has a long-standing
record in the Unix world from times far before Python even existed.
An example calculator (see figure below) of which the soure code is given below the figure
(made by Eline ter Hofstede):
159
# Set up window
app = Tk()
app.title('Rekenmachine')
app.grid()
app.resizable(False,False)
# TUDelft logo
image = PhotoImage(file='tud.gif')
label2 = Label(app, image = image)
label2.grid(column=0,row=2,columnspan=8,pady=8)
app.configure(background='white')
160
17.3.2 PyQt
Qt from Riverbank Computing (: http://www.riverbankcomputing.co.uk/software/pyqt/intro)
provides an environment similar to Tkinter. It can also be installed with pip install pyqt5.
Comes with many extras, like a Qt Designer, allowing you to graphically draw the dialog boxes.
The Spyder editor and IDE were built using PyQt. It builds on Nokia's Qt application framework
and runs on all platforms supported by Qt including Windows, MacOS/X and Linux. As a result
of using QtDesigner the code is autogenerated and looks less nice. The programming effort then
comes down to connecting the right functions to hooks provided by the automatically generated
code.
An example of PyQt code is given below, as it would look when it is edited manually:
def on_equals_clicked():
''' This function will be called if the = button is pressed. '''
# Get the selected operator from the pulldown menu (+,-,/ or *)
operator = operator_menu.currentText()
else:
res = left_in.value() * right_in.value()
return
161
Or when it is dsigned in Qt Designer, the same app can be made with drag and rop as well as
setting attributes for all items:
The resulting calculator.ui file can be converted to a Python script, using the follwing command:
162
17.3.4 wxPython
Can be found at http://wxpython.org/ Also one of the classics in the Python community,
wxPython is fully Open Source, cross-platform (Windows/Linux/Mac OS). It’s something in
between Tkinter and PyQt in terms of funtionality.
To give an impression of the code, a simple Hello world example is given below. It shows a
window called “Hello world” and catches the Close event when the user closes the window to
ask for a verification with an OK/Cancel Messagebox.
import wx
class Frame(wx.Frame):
def __init__(self, title):
wx.Frame.__init__(self, None, title=title, size=(350,200))
self.Bind(wx.EVT_CLOSE, self.OnClose)
app = wx.App(redirect=True)
top = Frame("Hello World")
top.Show()
app.MainLoop()
17.3.5 GLUT
GLUT, which is a part of OpenGL, is the good old user interface system used by all Open GL
fans. Robust, does the job on all platforms, but not always very easy to use.
163
PyGTK can be downloaded from www.pygtk.org . The Glade program can be found at:
http://glade.gnome.org/
As with all of these editors, the result is a mix of generated code (XML data in this case, read by
the PyGTK module) and e.g. Python code, which you need to edit yourself. You connect buttons
or fields to functions for which you can add the source to add functionality:
The GUI of the Open Source Photoshop program GIMP has been made with the GTK-library.
164
A very straightforward way to read from and write to excel files is Openpyxl, install with pip
install in an Run as Admin console:
http://pythonhosted.org/openpyxl/
An example of the resulting source code if you use this module from the tutorial:
wb = Workbook()
ws = wb.active
wb = load_workbook(filename = r'empty_book.xlsx')
sheet_ranges = wb['range names']
print(sheet_ranges['D18'].value) # D18
165
One way is to use the xlrd and xlwt module to respectivele read and write to excel sheets. You
can find these together with xlutils at http://www.python-excel.org/. An example of the very
straightforward calls:
Pyexcelerator
Pyexcelerator is an alternative to xlrd, and xlwt. This module can also be installed with pip:
or it can be found at: http://sourceforge.net/projects/pyexcelerator/ where you can also find docs
and examples. The zip file with which you download the module contains many examples for
you to borrow.
166
The Raspberry Pi (http://www.raspberrypi.org/ ) is a very basic (but complete), low cost, very
small (credit card size) Linux computer which comes with Python installed and it also runs
pygame. For around 50 euros you have a complete computer with the basic accessories like
power supply, OS on SD-card, etc. You can connect it to any screen via HDMI. Because it is
small and comsumes not much power, it is used for many purposes like internet of things, mobile
webcam, robotics, education projects, programming/gaming console, webserver, twitter-
monitoring and other desktop applications.
Some specifications:
CPU: 1.2 GHZ quad-core ARM Cortex A53 (ARMv8 Instruction Set)
GPU: Broadcom VideoCore IV @ 400 MHz
Memory: 1 GB LPDDR2-900 SDRAM
USB ports: 4
Network: 10/100 MBPS Ethernet, 802.11n Wireless LAN, Bluetooth 4.0
167
17.5.2 MicroPython
A relatively new initiative (from MIT) is called MicroPython. This is a special version of Python
3 for a microcontroller. The Micro Python board, called pyboard, is shown below.
By simply copying the text files with your Python code from your PC onto the microboard, you
can run the programs. To get an impression of the code, some examples from the website are
given below:
Controlling LEDs:
168
169
170
del a delete variable named a (can also be an element of a list: del tab[2] )
File input/output
f = open(filename, mode) Open a file, mode can be “r” read, or “w” write.
f.readline() Read a line from a file
f.writeline(line) Write a line to a file
f.close() Close the file
171
range(stop) produces an iterable list [0,1…..stop-1] so until but not incl. stop
range(start,stop) same but now starting with start (included) i.s.o. default zero
range(start,stop,step) same but now with step step instead of default 1
random.random() returns random number (float) between 0.0 and 1.0 (from module random)
random.randint(a,b) returns random integer with minimum a and maximum b (limits included)
time.clock() returns clock time as float in seconds (starts at zero the 1st time it is called)
time.time() returns time tuple with integers: [year, month, date, hour, minute, seconds
weekday, yearday, daylightsavingtimeswitch]
172
sw = True
sw = False # if lines becomes to long and the line of code
sw = i>40 or x<10 # with a backslash “\” and continue on the next line
s = "Hello"
s = 'World'
s = '"Hello World"' #Anything after hash-sign is not read
s = "Hello " + "World" #so this is how you can add comments
a = [1,6,2,7,8,-1]
b = ["Ann","Bernie","Charlie"]
if sw or int(x)>i:
print("Check done.")
b = i*2
elif sw:
print("x is too large")
else:
print("Something else is going on")
for i in range(10):
print(i)
if i > 2:
print(i*2)
print(list(range(2,22,2)))
i=0
while n!=a[i]:
i=i+1
ans=""
while not (ans=='y' or ans=="Y"):
ans = input("Continue? (Y/N)")
for i in range(10):
print(i+1)
a = [1,6,2,7,8,-1]
for b in a:
print(a)
173
if m1>m2:
print(m1)
else:
print(m2)
Section 1.4.1
#Exercise 1
startsum = float(input("What is your starting amount to save?"))
nyears = int(input("How many years do you want to save your money?"))
interest = float(input("What is the yearly interest rate (in percent)?"))
#Exercise 2
Ra = float(input("What is the resistance of resistor A?"))
Rb = float(input("What is the resistance of resistor B?"))
Rc = float(input("What is the resistance of resistor C?"))
Rabc = Rab + Rc
print(Rabc)
174
Section 1.4.2
# Exercise 1
from math import *
c = sqrt(a*a + b*b)
Section 1.4.5
#Exercise 1:
import random
print(names[coin])
#Exercise 2:
import random
#First use random function till 4,simulating the four different playing cards
#Then use a random function till 13, to simulate all the different numbers
icol = int(random.random()*4)
number = int(random.random()*13)
colours = [“hearts”,”tiles”,”clovers”,”pikes”]
print("So your card is", colours[icol], "with ", number)
#Exercise 3:
import time
t = time.localtime()
hour = t.tm_hour
mins = t.tm_min
secs = t.tm_sec
175
debt = []
for i in range(30):
debt.append([i,round(x)])
x = x*rate
for i in range(30):
print(debt[i])
for i in range(1,int(value)):
count = 0
for j in [2]+list(range(3,i+1,2)):
if i%j == 0:
count = count+1
if count <= 2:
print(i)
#Exercise 2
for i in range(6):
string = i*"* "
print(string)
176
Section 3.6
#Exercise 3
words = input("Which string do you want to evaluate?")
d = 0
l = 0
for c in words:
if c.isdigit():
d = d + 1
elif c.isalpha():
l = l + 1
print("Number of letters is ", l,"Number of digits is ", d)
#Exercise 2
length = int(input("How long do you want your list to be?"))
lst = []
for i in range(length):
word = input("Enter the word you want in your list?")
lst.append(word)
for i in range(length):
print(lst[i], “has length”, len(lst[i]))
#Exercise 3
values = [[10, 20], [30, 40, 50, 60, 70]]
for i in range(len(values)):
print(len(values[i]), values[i])
177
#Exercise 1 with while loop and avoid break with a logical used as switch
178
Chapter 6 exercises
Exercises python section 6
#Exercise 1
def countwords(sentence):
count = 1 #the first word doesn't have a space in front, the rest does
for i in range(len(sentence)):
if sentence[i] == " ":
count = count + 1
lastspace = i
lastword = sentence[lastspace+1:]
#Exercise 2
def surfacesphere(radius):
surface = 4.*pi*radius**2
return surface
def volumesphere(radius):
volume = (4./3.)*pi*radius**3
return volume
#Exercise 3
def changestring(string, n, delim):
string = (n-1)*(string+delim)+string
return string
179
xtab = []
fxtab = []
gxtab = []
for i in range(0,314):
x = float(i)/100.
fx = math.sin(x)
gx = math.exp(x) - 2.
xtab.append(x)
fxtab.append(fx)
gxtab.append(gx)
plt.plot(xtab,fxtab)
plt.plot(xtab,gxtab)
plt.show()
#Exercise 2
xtab = []
ytab = []
for i in range(0,628):
tetha = float(i)/100.
r = 4*math.cos(2*tetha)
x = r*math.cos(tetha)
y = r*math.sin(tetha)
xtab.append(x)
ytab.append(y)
plt.plot(xtab,ytab)
plt.show()
#Exercise 3
time = range(1950,2020,10)
co2 = [250,265,272,280,300,320,389]
plt.plot(time,co2)
plt.show()
180
#Exercise 1
y1tab = []
y2tab = []
xtab = []
for x in range(0,1000):
x = x/100.
xtab.append(x)
y1 = math.cos(3.*x) + 2.*math.sin(2.*x)
y1tab.append(y1)
y2 = math.exp(-2.*x)+ math.exp(-3.*x+1.)
y2tab.append(y2)
plt.subplot(211)
plt.plot(xtab,y1tab)
plt.subplot(212)
lt.plot(xtab,y2tab)
plt.show()
#Exercise 2
x1tab = []
y1tab = []
x2tab = []
y2tab = []
tethatab = []
for i in range(0,2513):
tetha = float(i)/100.
tethatab.append(tetha)
r1 = tetha
r2 = tetha**2
x1 = r1*math.cos(tetha)
y1 = r1*math.sin(tetha)
x1tab.append(x1)
y1tab.append(y1)
x2 = r2*math.cos(tetha)
y2 = r2*math.sin(tetha)
x2tab.append(x2)
y2tab.append(y2)
181
plt.subplot(121)
plt.plot(x1tab,y1tab)
plt.title("r = tetha")
plt.xlabel("x")
plt.ylabel("y")
plt.subplot(122)
plt.plot(x2tab,y2tab)
plt.title("r = tetha**2")
plt.xlabel("x")
plt.ylabel("y")
plt.show()
#Exercise 3
plt.show()
182
plt.ion()
for x in range(-20,20):
x = float(x)/10.
y1 = (2**2 - x**2)**0.5
y2 = -(2**2 - x**2)**0.5
plt.plot(x,y1, 'ro')
plt.plot(x,y2, 'ro')
plt.draw()
plt.close()
#Exercise 1
x = arange(0,21,1)
y = linspace(0,8,21)
X, Y = meshgrid(x, y)
Z = (1./100.)*X**2
fig = plt.figure()
ax = Axes3D(fig)
183
CD = 0.47
rho = 1.225
S = math.pi*0.15**2
while y > 0:
t = t + dt
F = m * g
D = 0.5*CD*rho*vy**2*S
a = (-1.*F + D) / m
vy = vy + a*dt
y = y + vy*dt
ttab.append(t)
ytab.append(y)
plt.plot(ttab,ytab)
plt.show()
184
#Exercise 2 a)
delta = 0.01
s = 0
h = 1.
tetha = 30.*math.pi/180.
vx = 100*math.cos(tetha)
vy = 100*math.sin(tetha)
g = 9.81
stab = []
htab = []
while h >= 0:
ay = -1.*g
ax = 0
vy = vy + ay*delta
vx = vx + ax*delta
h = h + vy*delta
s = s + vx*delta
htab.append(h)
stab.append(s)
plt.plot(stab,htab)
plt.ylim(0,140)
plt.show()
#Exercise 2 b)
delta = 0.01
s = 0
h = 1.
tetha = 30.*math.pi/180.
vx = 100*math.cos(tetha)
vy = 100*math.sin(tetha)
g = 9.81
Fd = 80
m = 10
stab = []
htab = []
while h >= 0:
ay = (-1.*m*g -1.*Fd*math.sin(tetha))/m
ax = (-1*Fd*math.cos(tetha))/m
vy = vy + ay*delta
vx = vx + ax*delta
h = h + vy*delta
s = s + vx*delta
htab.append(h)
stab.append(s)
tetha = math.atan(vy/vx)
plt.plot(stab,htab)
plt.ylim(0,140)
plt.show()
185
#Exercise 2 c)
delta = 0.01
s = 0
h = 1.
tetha = 30.*math.pi/180.
vx = 100*math.cos(tetha)
vy = 100*math.sin(tetha)
m = 10
g0 = 9.80665
Re = 6371*1000 #m
stab = []
htab = []
while h >= 0:
Fd = 0.05*(vx**2+vy**2)
g = g0*(Re/(Re + h))
ay = (-1.*m*g -1.*Fd*math.sin(tetha))/m
ax = (-1*Fd*math.cos(tetha))/m
vy = vy + ay*delta
vx = vx + ax*delta
h = h + vy*delta
s = s + vx*delta
htab.append(h)
stab.append(s)
plt.plot(stab,htab)
plt.ylim(0,140)
plt.show()
186
#Exercise 1
#Make functions for the circle:
r = 2
tetha = linspace(0,pi,180)
x1 = r*cos(tetha)
y1 = r*sin(tetha)
x2 = -r*cos(tetha)
y2 = -r*sin(tetha)
#Exercise 2
def diagonal(array):
maintab = []
for i in range(len(array)):
main = array[i,i]
maintab.append(main)
return maintab
A = ones((2,2))
A[0,1] = A[0,1]*5
A[0,0] = A[0,0]*2
A[1,1] = A[1,1]*-1
A[1,0] = A[1,0]*4
print A
#Exercise 3
#list
lst = [[2,3],[5,4]]
column = []
for i in range(len(lst)):
col = lst[i][0]
column.append(col)
print(column)
arr = array(lst)
print(arr[:,0])
187
#Exercise 1
h = np.arange(0,32.,1.)
plt.plot(h, temp)
plt.show()
#Exercise 2
x = np.arange(-3,3,0.001)
fx = (x<=1.)*x**2 + (x>1)*(6.-x)
plt.plot(x,fx)
plt.show()
#Exercise 3
A = np.array([3,4,6,10,24,89,45,43,46,99,100])
div3 = A[A%3!=0]
print("Elements of A not divisible by 3:", div3)
div5 = A[A%5==0]
print("Elements of A divisible by 5:", div5)
A[A%3==0] = 42
print ("New values of A after setting the elements of A,", \
"which are divisible by 3, to 42:", A)
188
Section 11.5
from numpy import *
import matplotlib.pyplot as plt
#Exercise 1
A = matrix('2 -5 6; 4 3 8; 5 -2 9')
b = matrix('3; 5; -1')
B = A.I
x = B*b
print(x)
#Exercise 2
#Solution: u is motorboat speed and v is current speed
x = B*b
print(x)
#Exercise 3
#First we calculate all the data points
i = arange(1,11)
xi = 0.1*i
yi = 5*exp(-xi)+2*xi
Yi = ones(shape=(10,1))
Yi[:,0] = Yi[:,0]*yi
#Now we use least square problem to make a fitting. We want a lineair trend
line, so
#y = b1 + xb2 so Xb = y with
X = ones(shape=(10,2))
X[:,1] = X[:,1]*xi
X = matrix(X)
#Now we want to generate a least square solution for fitting! X.TXb = X.Ty
Xtranspose = X.T
Xfirst = Xtranspose*X
Xsecond = Xtranspose*Yi
189
Exercises chapter 13
#Exercise 1
import pygame as pg
pg.init()
reso = (750,500)
blue = (0,0,255)
screen = pg.display.set_mode(reso)
screen.fill(blue)
pg.display.flip()
pg.event.pump()
pg.quit()
#Exercise 2
import pygame as pg
pg.init()
reso = (750,500)
blue = (0,0,255)
screen = pg.display.set_mode(reso)
screen.fill(blue)
plane = pg.image.load('plane.jpg')
plane = pg.transform.scale(plane,(150,60))
planerect = plane.get_rect()
planerect.center = (75,250.)
screen.blit(plane,planerect)
pg.display.flip()
pg.event.pump()
pg.quit()
190
#Exercise 3
import pygame as pg
pg.init()
reso = (750,500)
blue = (0,0,255)
screen = pg.display.set_mode(reso)
scrrect = screen.get_rect()
plane = pg.image.load('plane.jpg')
plane = pg.transform.scale(plane,(150,60))
planerect = plane.get_rect()
xs = 75
ys = 250
vx = 50
tsim = 0.0
tstart = 0.001*pg.time.get_ticks()
dt = 0.01
running = True
while running:
trun = 0.001*pg.time.get_ticks() - tstart
if trun + dt >= tsim:
tsim = tsim + dt
xs = xs + vx*dt
planerect.center = (xs,ys)
pg.draw.rect(screen,blue,scrrect)
screen.blit(plane,planerect)
pg.display.flip()
if xs > 750+75:
running = False
pg.event.pump()
pg.quit()
print("Ready.")
191
#Exercise 4
import pygame as pg
pg.init()
reso = (750,500)
blue = (0,0,255)
screen = pg.display.set_mode(reso)
scrrect = screen.get_rect()
xs = 75
ys = 250
vx = 50
tsim = 0.0
tstart = 0.001*pg.time.get_ticks()
dt = 0.01
running = True
while running:
trun = 0.001*pg.time.get_ticks() - tstart
if trun + dt >= tsim:
tsim = tsim + dt
xs = xs + vx*dt
if xs > 750+75:
running = False
planerect.center = (xs,ys)
pg.draw.rect(screen,blue,scrrect)
screen.blit(plane,planerect)
pg.display.flip()
pg.quit()
192
193
194
195
196
197
198
199