├── LICENSE
├── README.md
├── assets
└── custom.js
├── bootstrap
├── README.md
└── bootstrap-python-intro.bash
├── images
└── list_vs_array.png
├── notebooks
├── README.md
├── Untitled.ipynb
├── answers
│ ├── .gitignore
│ ├── 2 - Data types and expressions.ipynb
│ ├── 3 - Control Structures.ipynb
│ ├── 4 - Functions and exceptions.ipynb
│ ├── 5 - Modules.ipynb
│ ├── 6 - File IO and String processing.ipynb
│ ├── 7 - NumPy.ipynb
│ ├── 8 - Object oriented programming.ipynb
│ └── Advanced Object oriented programming.ipynb
├── data
│ ├── 5ire.fasta
│ ├── CH4.pdb
│ ├── breast-cancer-wisconsin.data
│ ├── coordinates.txt
│ ├── csc_usage.txt
│ ├── davis.data
│ ├── example.csv
│ ├── example_file.txt
│ ├── example_json_1.json
│ ├── example_json_2.json
│ ├── grep.txt
│ ├── iris.data
│ ├── word_count.txt
│ └── zipped_file.gz
├── examples
│ ├── 1 - Introduction.ipynb
│ ├── 2 - Control Structures.ipynb
│ ├── 3 - Functions.ipynb
│ ├── 4 - Modules.ipynb
│ ├── 5.1- File IO.ipynb
│ ├── 5.2 Strings.ipynb
│ ├── 6 - Objects.ipynb
│ ├── 7 - NumPy.ipynb
│ ├── 8 - Pandas.ipynb
│ ├── 9 - Object oriented programming.ipynb
│ ├── Extra - Language features.ipynb
│ ├── Extra - Python Software Development Practices.ipynb
│ └── Extra Scikit-learn.ipynb
└── exercises
│ ├── 1 - Introduction.ipynb
│ ├── 2 - Data types and expressions.ipynb
│ ├── 3 - Control Structures.ipynb
│ ├── 4 - Functions and exceptions.ipynb
│ ├── 5 - Modules.ipynb
│ ├── 6 - File IO and String processing.ipynb
│ ├── 7 - NumPy.ipynb
│ ├── 8 - Object oriented programming.ipynb
│ ├── Advanced Object oriented programming.ipynb
│ └── sample_module.py
└── requirements.txt
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 CSC - IT Center for Science
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Introduction to Python course at CSC
2 |
3 | This repository contains the content for the Introduction to Python course at
4 | CSC. Material is provided as Jupyter Notebooks which can be found under the [notebooks](notebooks) folder.
5 |
6 | This page has been designed from the get-go to also be a Github Pages page.
7 | This is a test of creating a Github Pages page for a CSC course. Feedback is
8 | welcome and we don't make any promises to maintain the page.
9 |
10 | ## Running examples locally
11 |
12 | First install virtualenvwrapper on your local machine.
13 |
14 | ```
15 | $ mkvirtualenv -p python3 python-intro
16 | [...]
17 | (python-intro) $ pip install -r requirements.txt
18 | (python-intro) $ jupyter notebook
19 | ```
20 |
21 | ## License
22 | Code licensed under MIT License. Examples and non-code artefacts
23 | licensed under Creative Commons BY
24 |
--------------------------------------------------------------------------------
/assets/custom.js:
--------------------------------------------------------------------------------
1 | code_show=true;
2 | function code_toggle() {
3 | if (code_show){
4 | $('div.input').hide();
5 | } else {
6 | $('div.input').show();
7 | }
8 | code_show = !code_show
9 | }
10 |
11 | $([IPython.events]).on("app_initialized.NotebookApp", function () {
12 | $("#view_menu").append("
Toggle Code Cells");
13 | });
14 |
15 | text_show=true;
16 | function text_toggle() {
17 | if (text_show){
18 | $('div.text_cell').hide();
19 | } else {
20 | $('div.text_cell').show();
21 | }
22 | text_show = !text_show
23 | }
24 |
25 | $([IPython.events]).on("app_initialized.NotebookApp", function () {
26 | $("#view_menu").append("Toggle Text Cells");
27 | });
28 |
--------------------------------------------------------------------------------
/bootstrap/README.md:
--------------------------------------------------------------------------------
1 | # Bootstrap script
2 |
3 | This directory contains a bootstrap script that will be downloaded by
4 | Notebooks and used to check out the repo to the user.
5 |
--------------------------------------------------------------------------------
/bootstrap/bootstrap-python-intro.bash:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | ## Script that clones a repository
3 |
4 | cd /home/jovyan/work
5 | # git reflog requires a name and email if user is not in passwd
6 | # even if you're only cloning
7 | export GIT_COMMITTER_NAME=anonymous
8 | export GIT_COMMITTER_EMAIL=anon@localhost
9 | git clone https://github.com/csc-training/python-introduction.git
10 |
11 | # clean up as host script doesn't do so yet
12 | rm bootstrap-python-intro.bash
13 |
--------------------------------------------------------------------------------
/images/list_vs_array.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/csc-training/python-introduction/8212fd6511024fdc8f2428cb5cb06f288a718594/images/list_vs_array.png
--------------------------------------------------------------------------------
/notebooks/README.md:
--------------------------------------------------------------------------------
1 | # Jupyter Notebooks
2 |
3 | The notebooks are organized as follows
4 |
5 | - [examples](examples): Explanation and example snippets of Python concepts
6 | - [exercises](exercises): Exercises assignments and skeleton codes
7 | - [answers](answers): Model solutions to exercises
8 |
--------------------------------------------------------------------------------
/notebooks/Untitled.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [],
3 | "metadata": {},
4 | "nbformat": 4,
5 | "nbformat_minor": 1
6 | }
7 |
--------------------------------------------------------------------------------
/notebooks/answers/.gitignore:
--------------------------------------------------------------------------------
1 | .ipynb_checkpoints
2 |
--------------------------------------------------------------------------------
/notebooks/answers/2 - Data types and expressions.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Exercises\n"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "## Tuples and lists\n",
15 | "1. Create a tuple called ``mytuple``, with the following strings: \"sausage\", \"eggs\" and \"bacon\"\n",
16 | "2. check it's type using ``type()```\n",
17 | "3. coerce it to a list using ``list()`` and assign to ``mylist``"
18 | ]
19 | },
20 | {
21 | "cell_type": "code",
22 | "execution_count": null,
23 | "metadata": {
24 | "collapsed": true
25 | },
26 | "outputs": [],
27 | "source": [
28 | "mytuple = (\"sausage\", \"eggs\", \"bacon\")\n",
29 | "type(mytuple)\n",
30 | "mylist = list(mytuple)"
31 | ]
32 | },
33 | {
34 | "cell_type": "markdown",
35 | "metadata": {},
36 | "source": [
37 | "Attempt to append the string \"spam\" \n",
38 | "to ``mylist`` and ``mytuple`` using ``append``."
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": null,
44 | "metadata": {
45 | "collapsed": true
46 | },
47 | "outputs": [],
48 | "source": [
49 | "mylist.append(\"spam\")\n",
50 | "mytuple.append(\"spam\")"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {},
56 | "source": [
57 | "List objects have a sort()\n",
58 | "function, use that for sorting the list alphabetically (e.g.\n",
59 | "mylist.sort() ). What is now the first item of the list?\n",
60 | "\n",
61 | "Next, remove the first item from the list, investigate the contents and remove then last item from the list."
62 | ]
63 | },
64 | {
65 | "cell_type": "code",
66 | "execution_count": null,
67 | "metadata": {
68 | "collapsed": true
69 | },
70 | "outputs": [],
71 | "source": [
72 | "mylist.sort()\n",
73 | "print(mylist[0])\n",
74 | "del mylist[-1]\n",
75 | "print(mylist)"
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {},
81 | "source": [
82 | "### Slicing\n",
83 | "\n",
84 | "Using ``range()`` create a list that has the numbers from 50 to 0 with a step of -2. Note that in Python 3 ``range()`` returns an *iterator* (we'll discuss iterators more later on), ``list(range(args))`` returns an actual list."
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": null,
90 | "metadata": {
91 | "collapsed": true
92 | },
93 | "outputs": [],
94 | "source": [
95 | "numbers = list(range(50, 0, -2))"
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "metadata": {},
101 | "source": [
102 | "Using slicing syntax, select\n",
103 | "* the last 4 items from the list\n",
104 | "* the items from index 10 to index 13\n",
105 | "* the first 5 items from the list"
106 | ]
107 | },
108 | {
109 | "cell_type": "code",
110 | "execution_count": null,
111 | "metadata": {
112 | "collapsed": true
113 | },
114 | "outputs": [],
115 | "source": [
116 | "print(numbers[-4])\n",
117 | "print(numbers[10:14])\n",
118 | "print(numbers[:5])"
119 | ]
120 | },
121 | {
122 | "cell_type": "markdown",
123 | "metadata": {},
124 | "source": [
125 | "Read up on the [stride syntax](https://en.wikipedia.org/wiki/Array_slicing#1991:_Python) . Then using it select \n",
126 | "* every third value in the list\n",
127 | "* the values with an odd-numbered index in the list"
128 | ]
129 | },
130 | {
131 | "cell_type": "code",
132 | "execution_count": null,
133 | "metadata": {
134 | "collapsed": true
135 | },
136 | "outputs": [],
137 | "source": [
138 | "print(numbers[::3])\n",
139 | "print(numbers[1::2])"
140 | ]
141 | },
142 | {
143 | "cell_type": "markdown",
144 | "metadata": {},
145 | "source": [
146 | "### Multidimensional lists\n",
147 | "Create a two dimensional list of (x,y) value pairs, i.e.\n",
148 | "arbitrary long list whose elements are two element lists.\n",
149 | "\n",
150 | "Are you able to use slicing for extracting only the y values? (Answer is no, but try it in any case)"
151 | ]
152 | },
153 | {
154 | "cell_type": "code",
155 | "execution_count": null,
156 | "metadata": {
157 | "collapsed": true
158 | },
159 | "outputs": [],
160 | "source": [
161 | "coordinates = [[0.1, 4.5], [-1.2, 3], [2.2, -5], [3.4, 1.6]]"
162 | ]
163 | },
164 | {
165 | "cell_type": "markdown",
166 | "metadata": {},
167 | "source": [
168 | "## Dictionaries\n",
169 | "Create a dictionary whose keys are the fruits “pineapple”, “strawberry”, and “banana”. As values use numbers\n",
170 | "representing e.g. prices. \n",
171 | "\n",
172 | "Add “orange” to the dictionary and then remove “banana” from the dictionary. Investigate the contents of dictionary and pay attention to the order of key-value pairs."
173 | ]
174 | },
175 | {
176 | "cell_type": "code",
177 | "execution_count": null,
178 | "metadata": {
179 | "collapsed": true
180 | },
181 | "outputs": [],
182 | "source": [
183 | "fruits = {'banana' : 5, 'strawberry' : 7, 'pineapple' : 3}\n",
184 | "print(fruits)\n",
185 | "fruits['orange'] = 4.5\n",
186 | "print(fruits)\n",
187 | "del fruits['banana']\n",
188 | "print(fruits)"
189 | ]
190 | },
191 | {
192 | "cell_type": "markdown",
193 | "metadata": {},
194 | "source": [
195 | "# Bonus exercises\n",
196 | "Create a new “fruits” dictionary where the values are also\n",
197 | "dictionaries containing key-value pairs for color and weight,\n",
198 | "e.g. \n",
199 | "```\n",
200 | "fruits['apple'] = {'color':'green', 'weight': 120}\n",
201 | "```\n",
202 | "Change the color of *apple* from green to red"
203 | ]
204 | },
205 | {
206 | "cell_type": "code",
207 | "execution_count": null,
208 | "metadata": {
209 | "collapsed": true
210 | },
211 | "outputs": [],
212 | "source": [
213 | "apple = {'color' : 'green', 'weight' : 120}\n",
214 | "orange = {'color' : 'orange', 'weight' : 110}\n",
215 | "fruits = {'apple' : apple, 'orange' : orange}\n",
216 | "print(fruits)\n",
217 | "fruits['apple']['color'] = 'red'\n",
218 | "print(fruits)"
219 | ]
220 | },
221 | {
222 | "cell_type": "markdown",
223 | "metadata": {},
224 | "source": [
225 | "It is often useful idiom to create empty lists or dictionaries\n",
226 | "and add contents little by little.\n",
227 | "\n",
228 | "Create first an empty dictionary for a mid-term grades of\n",
229 | "students. Then, add a key-value pairs where the keys are\n",
230 | "student names and the values are empty lists. \n",
231 | "\n",
232 | "Finally, add values to the lists and investigate the contents of the\n",
233 | "dictionary."
234 | ]
235 | },
236 | {
237 | "cell_type": "code",
238 | "execution_count": null,
239 | "metadata": {
240 | "collapsed": true
241 | },
242 | "outputs": [],
243 | "source": [
244 | "grades = {}\n",
245 | "grades['Jussi'] = []\n",
246 | "grades['Jyry'] = []\n",
247 | "print(grades)\n",
248 | "grades['Jussi'].append(2)\n",
249 | "grades['Jyry'].append(5)\n",
250 | "print(grades)\n",
251 | "grades['Jussi'].append(3)\n",
252 | "grades['Jyry'].append(4)\n",
253 | "print(grades)"
254 | ]
255 | }
256 | ],
257 | "metadata": {
258 | "kernelspec": {
259 | "display_name": "Python 3",
260 | "language": "python",
261 | "name": "python3"
262 | },
263 | "language_info": {
264 | "codemirror_mode": {
265 | "name": "ipython",
266 | "version": 3
267 | },
268 | "file_extension": ".py",
269 | "mimetype": "text/x-python",
270 | "name": "python",
271 | "nbconvert_exporter": "python",
272 | "pygments_lexer": "ipython3",
273 | "version": "3.4.9"
274 | }
275 | },
276 | "nbformat": 4,
277 | "nbformat_minor": 2
278 | }
279 |
--------------------------------------------------------------------------------
/notebooks/answers/3 - Control Structures.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Control Structures"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "## Simple for loop \n",
15 | "\n",
16 | "Write a ``for`` loop which iterates over the list of breakfast items \"sausage\", \"eggs\", \"bacon\" and \"spam\" and prints out the name of item\n"
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": null,
22 | "metadata": {
23 | "collapsed": true
24 | },
25 | "outputs": [],
26 | "source": [
27 | "breakfast = [\"sausage\", \"eggs\", \"bacon\", \"spam\"]\n",
28 | "for item in breakfast:\n",
29 | " print(item)"
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {},
35 | "source": [
36 | "Write then a ``for`` which loop determines the squares of the odd\n",
37 | "integers up to 10. Use the ``range()`` function."
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": null,
43 | "metadata": {
44 | "collapsed": true
45 | },
46 | "outputs": [],
47 | "source": [
48 | "squares = []\n",
49 | "for i in range(1, 10, 2):\n",
50 | " squares.append(i**2)\n",
51 | "print(squares)"
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {},
57 | "source": [
58 | "## Looping through a dictionary\n",
59 | "Write a loop that prints out the names of the fruits in the dictionary containing the fruit prices."
60 | ]
61 | },
62 | {
63 | "cell_type": "code",
64 | "execution_count": null,
65 | "metadata": {
66 | "collapsed": true
67 | },
68 | "outputs": [],
69 | "source": [
70 | "fruits = {'banana' : 5, 'strawberry' : 7, 'pineapple' : 3}\n",
71 | "for fruit in fruits:\n",
72 | " print(fruit)"
73 | ]
74 | },
75 | {
76 | "cell_type": "markdown",
77 | "metadata": {},
78 | "source": [
79 | "Next, write a loop that sums up the prices."
80 | ]
81 | },
82 | {
83 | "cell_type": "code",
84 | "execution_count": null,
85 | "metadata": {
86 | "collapsed": true
87 | },
88 | "outputs": [],
89 | "source": [
90 | "sum = 0\n",
91 | "for price in fruits.values():\n",
92 | " sum += price\n",
93 | "print(sum)"
94 | ]
95 | },
96 | {
97 | "cell_type": "markdown",
98 | "metadata": {},
99 | "source": [
100 | "## While loop\n",
101 | "\n",
102 | "Fibonacci numbers are a sequence of integers defined by the recurrence relation\n",
103 | "```\n",
104 | "\t\tF[n] = F[n-1] + F[n-2]\n",
105 | "```\n",
106 | "with the initial values F[0]=0, F[1]=1. \n",
107 | "Create a list of Fibonacci numbers F[n] < 100 using a while loop."
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": null,
113 | "metadata": {},
114 | "outputs": [],
115 | "source": [
116 | "f = [0, 1]\n",
117 | "while True:\n",
118 | " new = f[-1] + f[-2]\n",
119 | " if new > 100:\n",
120 | " break\n",
121 | " f.append(new)\n",
122 | "print(f)"
123 | ]
124 | },
125 | {
126 | "cell_type": "markdown",
127 | "metadata": {},
128 | "source": [
129 | "## If - else\n",
130 | "\n",
131 | "Write a control structure which checks whether an integer is\n",
132 | "negative, zero, or belongs to the prime numbers 3,5,7,11,17\n",
133 | "and perform e.g. corresponding print statement.\n",
134 | "\n",
135 | "Use keyword ``in`` when checking for belonging to prime numbers."
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": null,
141 | "metadata": {
142 | "collapsed": true
143 | },
144 | "outputs": [],
145 | "source": [
146 | "number = 7\n",
147 | "if number < 0:\n",
148 | " print(\"Negative\")\n",
149 | "elif number == 0:\n",
150 | " print(\"Zero\")\n",
151 | "elif number in [3, 5, 7, 11, 17]:\n",
152 | " print(\"Prime\")"
153 | ]
154 | },
155 | {
156 | "cell_type": "markdown",
157 | "metadata": {},
158 | "source": [
159 | "# Advanced exercises\n",
160 | "\n",
161 | "Don't worry if you don't have time to finish all of these. They are not essential."
162 | ]
163 | },
164 | {
165 | "cell_type": "markdown",
166 | "metadata": {},
167 | "source": [
168 | "## Looping through multidimensional lists\n",
169 | "\n",
170 | "Start from a two dimensional list of (x,y) value pairs, and sort it according to y values. (Hint: you may need to create a temporary list)."
171 | ]
172 | },
173 | {
174 | "cell_type": "code",
175 | "execution_count": null,
176 | "metadata": {
177 | "collapsed": true
178 | },
179 | "outputs": [],
180 | "source": [
181 | "xys = [[2, 3], [0, -1], [4, -2], [1, 6]]\n",
182 | "tmp = []\n",
183 | "for x, y in xys:\n",
184 | " tmp.append([y,x])\n",
185 | "tmp.sort()\n",
186 | "for i, (y,x) in enumerate(tmp):\n",
187 | " xys[i] = [x,y]\n",
188 | "print(xys)"
189 | ]
190 | },
191 | {
192 | "cell_type": "markdown",
193 | "metadata": {},
194 | "source": [
195 | "Next, create a new list containing only the sorted y values."
196 | ]
197 | },
198 | {
199 | "cell_type": "code",
200 | "execution_count": null,
201 | "metadata": {
202 | "collapsed": true
203 | },
204 | "outputs": [],
205 | "source": [
206 | "ys = []\n",
207 | "for x, y in xys:\n",
208 | " ys.append(y)\n",
209 | "print(ys)"
210 | ]
211 | },
212 | {
213 | "cell_type": "markdown",
214 | "metadata": {},
215 | "source": [
216 | "Finally, create a new list consisting of sums the (x,y) pairs where both x and y are positive."
217 | ]
218 | },
219 | {
220 | "cell_type": "code",
221 | "execution_count": null,
222 | "metadata": {
223 | "collapsed": true
224 | },
225 | "outputs": [],
226 | "source": [
227 | "sums = []\n",
228 | "for x, y in xys:\n",
229 | " if x > 0 and y > 0:\n",
230 | " sums.append(x + y)\n",
231 | "print(sums)"
232 | ]
233 | },
234 | {
235 | "cell_type": "markdown",
236 | "metadata": {},
237 | "source": [
238 | "List comprehension is often convenient in this kind of situations:"
239 | ]
240 | },
241 | {
242 | "cell_type": "code",
243 | "execution_count": null,
244 | "metadata": {
245 | "collapsed": true
246 | },
247 | "outputs": [],
248 | "source": [
249 | "xys = [[2, 3], [0, -1], [4, -2], [1, 6]]\n",
250 | "tmp = [[y, x] for x, y in xys]\n",
251 | "tmp.sort()\n",
252 | "xys = [[x, y] for y, x in tmp]\n",
253 | "\n",
254 | "# One liner is possible but not very readable anymore:\n",
255 | "xys = [[x, y] for y, x in sorted([[ytmp, xtmp] for xtmp, ytmp in xys])]\n",
256 | "\n",
257 | "# Summing positives with one liner is ok:\n",
258 | "sums = [x+y for x,y in xys if x > 0 and y > 0]"
259 | ]
260 | },
261 | {
262 | "cell_type": "markdown",
263 | "metadata": {},
264 | "source": [
265 | "## FizzBuzz\n",
266 | "\n",
267 | "This is a classic job interview question. Depending on the interviewer or interviewee it can filter out up to 95% of the interviewees for a position. The task is not difficult but it's easy to make simple mistakes.\n",
268 | "\n",
269 | "If a number is divisible by 3, instead of the number print \"Fizz\", if a number is divisible by 5, print \"Buzz\" and if the number is divisible by both 3 and 5, print \"FizzBuzz\". "
270 | ]
271 | },
272 | {
273 | "cell_type": "code",
274 | "execution_count": 8,
275 | "metadata": {},
276 | "outputs": [
277 | {
278 | "name": "stdout",
279 | "output_type": "stream",
280 | "text": [
281 | "1\n",
282 | "2\n",
283 | "Fizz\n",
284 | "3\n",
285 | "4\n",
286 | "Buzz\n",
287 | "5\n",
288 | "Fizz\n",
289 | "6\n",
290 | "7\n",
291 | "8\n",
292 | "Fizz\n",
293 | "9\n",
294 | "Buzz\n",
295 | "10\n",
296 | "11\n",
297 | "Fizz\n",
298 | "12\n",
299 | "13\n",
300 | "14\n",
301 | "FizzBuzz\n",
302 | "15\n",
303 | "16\n",
304 | "17\n",
305 | "Fizz\n",
306 | "18\n",
307 | "19\n",
308 | "Buzz\n",
309 | "20\n",
310 | "Fizz\n",
311 | "21\n",
312 | "22\n",
313 | "23\n",
314 | "Fizz\n",
315 | "24\n",
316 | "Buzz\n",
317 | "25\n",
318 | "26\n",
319 | "Fizz\n",
320 | "27\n",
321 | "28\n",
322 | "29\n",
323 | "FizzBuzz\n",
324 | "30\n",
325 | "31\n",
326 | "32\n",
327 | "Fizz\n",
328 | "33\n",
329 | "34\n",
330 | "Buzz\n",
331 | "35\n",
332 | "Fizz\n",
333 | "36\n",
334 | "37\n",
335 | "38\n",
336 | "Fizz\n",
337 | "39\n",
338 | "Buzz\n",
339 | "40\n",
340 | "41\n",
341 | "Fizz\n",
342 | "42\n",
343 | "43\n",
344 | "44\n",
345 | "FizzBuzz\n",
346 | "45\n",
347 | "46\n",
348 | "47\n",
349 | "Fizz\n",
350 | "48\n",
351 | "49\n",
352 | "Buzz\n",
353 | "50\n",
354 | "Fizz\n",
355 | "51\n",
356 | "52\n",
357 | "53\n",
358 | "Fizz\n",
359 | "54\n",
360 | "Buzz\n",
361 | "55\n",
362 | "56\n",
363 | "Fizz\n",
364 | "57\n",
365 | "58\n",
366 | "59\n",
367 | "FizzBuzz\n",
368 | "60\n",
369 | "61\n",
370 | "62\n",
371 | "Fizz\n",
372 | "63\n",
373 | "64\n",
374 | "Buzz\n",
375 | "65\n",
376 | "Fizz\n",
377 | "66\n",
378 | "67\n",
379 | "68\n",
380 | "Fizz\n",
381 | "69\n",
382 | "Buzz\n",
383 | "70\n",
384 | "71\n",
385 | "Fizz\n",
386 | "72\n",
387 | "73\n",
388 | "74\n",
389 | "FizzBuzz\n",
390 | "75\n",
391 | "76\n",
392 | "77\n",
393 | "Fizz\n",
394 | "78\n",
395 | "79\n",
396 | "Buzz\n",
397 | "80\n",
398 | "Fizz\n",
399 | "81\n",
400 | "82\n",
401 | "83\n",
402 | "Fizz\n",
403 | "84\n",
404 | "Buzz\n",
405 | "85\n",
406 | "86\n",
407 | "Fizz\n",
408 | "87\n",
409 | "88\n",
410 | "89\n",
411 | "FizzBuzz\n",
412 | "90\n",
413 | "91\n",
414 | "92\n",
415 | "Fizz\n",
416 | "93\n",
417 | "94\n",
418 | "Buzz\n",
419 | "95\n",
420 | "Fizz\n",
421 | "96\n",
422 | "97\n",
423 | "98\n",
424 | "Fizz\n",
425 | "99\n",
426 | "Buzz\n",
427 | "100\n"
428 | ]
429 | }
430 | ],
431 | "source": [
432 | "for number in range(1, 101):\n",
433 | " if number % 3 == 0 and number % 5 == 0:\n",
434 | " print(\"FizzBuzz\")\n",
435 | " elif number % 3 == 0:\n",
436 | " print(\"Fizz\")\n",
437 | " elif number % 5 == 0:\n",
438 | " print(\"Buzz\")\n",
439 | " print(number)"
440 | ]
441 | },
442 | {
443 | "cell_type": "markdown",
444 | "metadata": {},
445 | "source": [
446 | "*Food for thought:* How do people commonly fail this test and why?"
447 | ]
448 | },
449 | {
450 | "cell_type": "code",
451 | "execution_count": null,
452 | "metadata": {
453 | "collapsed": true
454 | },
455 | "outputs": [],
456 | "source": []
457 | },
458 | {
459 | "cell_type": "markdown",
460 | "metadata": {},
461 | "source": [
462 | "## Breaking\n",
463 | "\n",
464 | "The python `random` module generates pseudorandom numbers.\n",
465 | "\n",
466 | "Write a *while* loop that runs until \n",
467 | "the output of random.random() is below 0.1 and `break` when \n",
468 | "the value is below 0.1."
469 | ]
470 | },
471 | {
472 | "cell_type": "code",
473 | "execution_count": 10,
474 | "metadata": {},
475 | "outputs": [
476 | {
477 | "name": "stdout",
478 | "output_type": "stream",
479 | "text": [
480 | "done\n"
481 | ]
482 | }
483 | ],
484 | "source": [
485 | "import random\n",
486 | "\n",
487 | "while True:\n",
488 | " value = random.random() \n",
489 | " if value < 0.1:\n",
490 | " break\n",
491 | "print(\"done\")"
492 | ]
493 | },
494 | {
495 | "cell_type": "markdown",
496 | "metadata": {},
497 | "source": [
498 | "## List comprehension\n",
499 | "\n",
500 | "Using a list comprehension create a new list, `temperatures_kelvin` from following Celsius temperatures and convert them by adding the value 273.15 to each."
501 | ]
502 | },
503 | {
504 | "cell_type": "code",
505 | "execution_count": 12,
506 | "metadata": {
507 | "collapsed": true
508 | },
509 | "outputs": [],
510 | "source": [
511 | "temperatures_celsius = [0, -15, 20.15, 13.3, -5.2]\n",
512 | "\n",
513 | "temperatures_kelvin = [c+273.15 for c in temperatures_celsius]"
514 | ]
515 | }
516 | ],
517 | "metadata": {
518 | "kernelspec": {
519 | "display_name": "Python 3",
520 | "language": "python",
521 | "name": "python3"
522 | },
523 | "language_info": {
524 | "codemirror_mode": {
525 | "name": "ipython",
526 | "version": 3
527 | },
528 | "file_extension": ".py",
529 | "mimetype": "text/x-python",
530 | "name": "python",
531 | "nbconvert_exporter": "python",
532 | "pygments_lexer": "ipython3",
533 | "version": "3.4.9"
534 | }
535 | },
536 | "nbformat": 4,
537 | "nbformat_minor": 2
538 | }
539 |
--------------------------------------------------------------------------------
/notebooks/answers/4 - Functions and exceptions.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Functions and exceptions"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "## Functions\n",
15 | "\n",
16 | "Write a function that converts from Celsius to Kelvin.\n",
17 | "\n",
18 | "To convert from Centigrade to Kelvin you add 273.15 to the value.\n",
19 | "\n",
20 | "Try your solution for a few values."
21 | ]
22 | },
23 | {
24 | "cell_type": "code",
25 | "execution_count": null,
26 | "metadata": {},
27 | "outputs": [],
28 | "source": [
29 | "def celsius_to_kelvin(c):\n",
30 | " return c + 273.15\n",
31 | "\n",
32 | "celsius_to_kelvin(0)"
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {
38 | "collapsed": true
39 | },
40 | "source": [
41 | "Now write another function to convert from Fahrenheit to Celsius.\n",
42 | "\n",
43 | "The formulato do so is \n",
44 | "\n",
45 | "C = 5/9*(F-32)\n",
46 | "\n",
47 | "Again, verify that your function does what is expected."
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": null,
53 | "metadata": {},
54 | "outputs": [],
55 | "source": [
56 | "def fahrenheit_to_celsius(f):\n",
57 | " return 5/9*(f-32)\n",
58 | "\n",
59 | "fahrenheit_to_celsius(0)"
60 | ]
61 | },
62 | {
63 | "cell_type": "markdown",
64 | "metadata": {},
65 | "source": [
66 | "Now make a function to convert from Fahrenheit to Kelvin.\n",
67 | "\n",
68 | "Before you start coding, stop to think for a second. You can actually re-use the two other functions you have made. Fahrenheit to Kelvin can be represented as Fahrenheit to Celsius followed by Celsius to Kelvin."
69 | ]
70 | },
71 | {
72 | "cell_type": "code",
73 | "execution_count": null,
74 | "metadata": {},
75 | "outputs": [],
76 | "source": [
77 | "def fahrenheit_to_kelvin(f):\n",
78 | " return celsius_to_kelvin(fahrenheit_to_celsius(f))\n",
79 | "\n",
80 | "fahrenheit_to_kelvin(0)"
81 | ]
82 | },
83 | {
84 | "cell_type": "markdown",
85 | "metadata": {},
86 | "source": [
87 | "Finally, implement a more general conversion function that takes as arguments also the input and output scales, e.g. **from_scale** and **to_scale**. Provide default values for **from_scale** and **to_scale**, and call the function with different number of arguments. Try to call the function using both positional and keyword arguments. Which approach is more readable for you?"
88 | ]
89 | },
90 | {
91 | "cell_type": "code",
92 | "execution_count": null,
93 | "metadata": {},
94 | "outputs": [],
95 | "source": [
96 | "def temperature_converter(value, from_scale='C', to_scale='K'):\n",
97 | " if from_scale == 'C' and to_scale == 'K':\n",
98 | " return celsius_to_kelvin(value)\n",
99 | " elif from_scale == 'F' and to_scale == 'C':\n",
100 | " return fahrenheit_to_celsius(value)\n",
101 | " elif from_scale == 'F' and to_scale == 'K':\n",
102 | " return fahrenheit_to_kelvin(value)\n",
103 | " else:\n",
104 | " raise NotImplementedError('Unknown conversion: {} -> {}'.format(from_scale, to_scale))\n",
105 | " \n",
106 | "t = temperature_converter(25.2, from_scale='F')\n",
107 | "print(t)"
108 | ]
109 | },
110 | {
111 | "cell_type": "markdown",
112 | "metadata": {},
113 | "source": [
114 | "## Exceptions\n",
115 | "\n",
116 | "Ok, here's some code that fails. Find out at least 2 errors it raises by giving different inputs.\n",
117 | "\n",
118 | "Then construct a try-except clause around the lines of code."
119 | ]
120 | },
121 | {
122 | "cell_type": "code",
123 | "execution_count": null,
124 | "metadata": {},
125 | "outputs": [],
126 | "source": [
127 | "try:\n",
128 | " var = float(input(\"give a number\"))\n",
129 | " divided = 1/var\n",
130 | "except TypeError:\n",
131 | " print(\"user didn't give a number\")\n",
132 | "except ZeroDivisionError:\n",
133 | " print(\"user divided by zero\")"
134 | ]
135 | },
136 | {
137 | "cell_type": "markdown",
138 | "metadata": {},
139 | "source": [
140 | "The `open` function is used to open files for reading or writing. We'll get to that but first let's try to open a file that doesn't exist.\n",
141 | "\n",
142 | "Filesystem related errors are very common. A file might not exist or for some reason the user might not have the rights to open the file. Go ahead and make a try-except clause to catch this error."
143 | ]
144 | },
145 | {
146 | "cell_type": "code",
147 | "execution_count": null,
148 | "metadata": {},
149 | "outputs": [],
150 | "source": [
151 | "try:\n",
152 | " file_handle = open(\"i_dont_exist\", \"r\")\n",
153 | "except FileNotFoundError:\n",
154 | " print(\"file not found\")"
155 | ]
156 | },
157 | {
158 | "cell_type": "markdown",
159 | "metadata": {},
160 | "source": [
161 | "## Compound"
162 | ]
163 | },
164 | {
165 | "cell_type": "markdown",
166 | "metadata": {},
167 | "source": [
168 | "Implement the three remaining functions so you can convert freely between Fahrenheit and Kelvin.\n",
169 | "\n",
170 | "Now look at the temperature_converter function. Try to figure out what errors malformed user input can cause. You can either wrap the function call in a `try-except` or you can wrap parts of the function.\n",
171 | "\n",
172 | "If you have time you can increase the complexity of the function to cover centigrade conversions as well but this is not required. Hint: if you always convert the value to centigrade if it is not and to the desired output if desired output is not you can simplify the code."
173 | ]
174 | },
175 | {
176 | "cell_type": "code",
177 | "execution_count": null,
178 | "metadata": {},
179 | "outputs": [],
180 | "source": [
181 | "def celsius_to_fahrenheit(c):\n",
182 | " pass\n",
183 | "\n",
184 | "def kelvin_to_celsius(k):\n",
185 | " pass\n",
186 | "\n",
187 | "def kelvin_to_fahrenheit(k):\n",
188 | " pass\n",
189 | "\n",
190 | "def temperature_converter():\n",
191 | " from_scale = input(\"Give scale to convert from: \")\n",
192 | " to_scale = input(\"Give scale to convert to: \")\n",
193 | " try:\n",
194 | " value = float(input(\"Give temperature: \"))\n",
195 | " except TypeError:\n",
196 | " print(\"user didn't give a number\")\n",
197 | " return\n",
198 | " if from_scale == \"K\" and to_scale == \"F\":\n",
199 | " return kelvin_to_fahrenheit(value)\n",
200 | " elif from_scale == \"F\" and to_scale == \"K\":\n",
201 | " return fahrenheit_to_kelvin(value)\n",
202 | " elif from_scale == \"C\" or to_scale == \"C\":\n",
203 | " raise NotImplementedError(\"Conversion to Centigrade not implemented!\")\n",
204 | " return\n",
205 | "\n",
206 | "temperature_converter()"
207 | ]
208 | }
209 | ],
210 | "metadata": {
211 | "kernelspec": {
212 | "display_name": "Python 3",
213 | "language": "python",
214 | "name": "python3"
215 | },
216 | "language_info": {
217 | "codemirror_mode": {
218 | "name": "ipython",
219 | "version": 3
220 | },
221 | "file_extension": ".py",
222 | "mimetype": "text/x-python",
223 | "name": "python",
224 | "nbconvert_exporter": "python",
225 | "pygments_lexer": "ipython3",
226 | "version": "3.4.9"
227 | }
228 | },
229 | "nbformat": 4,
230 | "nbformat_minor": 2
231 | }
232 |
--------------------------------------------------------------------------------
/notebooks/answers/5 - Modules.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Modules"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "## import\n",
15 | "Let's start by using a module. \n",
16 | "\n",
17 | "There is a module called `sample_module` in the same directory as this notebook. Inside it there is a function called `sample_function`.\n",
18 | "\n",
19 | "Import the function and call it to see what happens. Can you do the import in two different ways?"
20 | ]
21 | },
22 | {
23 | "cell_type": "code",
24 | "execution_count": 5,
25 | "metadata": {},
26 | "outputs": [
27 | {
28 | "name": "stdout",
29 | "output_type": "stream",
30 | "text": [
31 | "Nobody expects the Spanish inquisition!\n"
32 | ]
33 | }
34 | ],
35 | "source": [
36 | "import sys\n",
37 | "sys.path.append('../exercises')\n",
38 | "import sample_module\n",
39 | "sample_module.sample_function()"
40 | ]
41 | },
42 | {
43 | "cell_type": "markdown",
44 | "metadata": {},
45 | "source": [
46 | "## import as\n",
47 | "\n",
48 | "It is possible to rename the function you are importing by using the syntax\n",
49 | "\n",
50 | "```from module import function_name as another_function_name\n",
51 | "```\n",
52 | "\n",
53 | "Go ahead and import `sample_function` using a more descriptive name and call it."
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": 6,
59 | "metadata": {},
60 | "outputs": [
61 | {
62 | "name": "stdout",
63 | "output_type": "stream",
64 | "text": [
65 | "Nobody expects the Spanish inquisition!\n"
66 | ]
67 | }
68 | ],
69 | "source": [
70 | "from sample_module import sample_function as samp_func\n",
71 | "samp_func()"
72 | ]
73 | },
74 | {
75 | "cell_type": "markdown",
76 | "metadata": {},
77 | "source": [
78 | "## Creating a module\n",
79 | "\n",
80 | "Now create a module called mymodule (i.e. mymodule.py) using the text editor functionality of Jupyter Notebooks.\n",
81 | "\n",
82 | "Add the following code to the module.\n",
83 | "\n",
84 | "```\n",
85 | "def add(a, b):\n",
86 | " return a + b\n",
87 | "```\n",
88 | "\n",
89 | "Save the file and import your newly created module in the cell below.\n",
90 | "\n",
91 | "If you want you can also use a more inventive name than mymodule.py."
92 | ]
93 | },
94 | {
95 | "cell_type": "code",
96 | "execution_count": null,
97 | "metadata": {
98 | "collapsed": true
99 | },
100 | "outputs": [],
101 | "source": []
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "## Extra: reloading the module\n",
108 | "\n",
109 | "Add a new function ``subtract`` to your above module and try to import it again. Are you able to use the ``subtract`` function?"
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": null,
115 | "metadata": {
116 | "collapsed": true
117 | },
118 | "outputs": [],
119 | "source": []
120 | },
121 | {
122 | "cell_type": "markdown",
123 | "metadata": {},
124 | "source": [
125 | "Python keeps track of modules that are imported, and performs the actual import only with the first ``import mymodule`` statement. If a module is modified during an interactive session, module needs to be explicitly reloaded in order to changes take effect. Reloading can be done with the function ``reload`` in the built-in module ``importlib``:"
126 | ]
127 | },
128 | {
129 | "cell_type": "code",
130 | "execution_count": null,
131 | "metadata": {
132 | "collapsed": true
133 | },
134 | "outputs": [],
135 | "source": [
136 | "from importlib import reload\n",
137 | "reload(mymodule)"
138 | ]
139 | }
140 | ],
141 | "metadata": {
142 | "kernelspec": {
143 | "display_name": "Python 3",
144 | "language": "python",
145 | "name": "python3"
146 | },
147 | "language_info": {
148 | "codemirror_mode": {
149 | "name": "ipython",
150 | "version": 3
151 | },
152 | "file_extension": ".py",
153 | "mimetype": "text/x-python",
154 | "name": "python",
155 | "nbconvert_exporter": "python",
156 | "pygments_lexer": "ipython3",
157 | "version": "3.4.9"
158 | }
159 | },
160 | "nbformat": 4,
161 | "nbformat_minor": 2
162 | }
163 |
--------------------------------------------------------------------------------
/notebooks/answers/6 - File IO and String processing.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Exercises"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {
14 | "collapsed": true
15 | },
16 | "outputs": [],
17 | "source": []
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {
22 | "collapsed": true
23 | },
24 | "source": [
25 | "## Simple reading\n",
26 | "\n",
27 | "The file [../data/coordinates.txt](../data/coordinates.txt) contains list of (x, y) value pairs.\n",
28 | "Read the values into two lists x and y."
29 | ]
30 | },
31 | {
32 | "cell_type": "code",
33 | "execution_count": null,
34 | "metadata": {
35 | "collapsed": true
36 | },
37 | "outputs": [],
38 | "source": [
39 | "xs = []\n",
40 | "ys = []\n",
41 | "with open(\"../data/coordinates.txt\", \"r\") as f:\n",
42 | " for line in f:\n",
43 | " line = line.split()\n",
44 | " xs.append(float(line[0]))\n",
45 | " ys.append(float(line[1]))\n",
46 | "print(xs)\n",
47 | "print(ys)"
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {},
53 | "source": [
54 | "## Nontrivial reading and conversion\n",
55 | "\n",
56 | "The file [../data/CH4.pdb](../data/CH4.pdb) contains the coordinates of methane molecule in a PDB format. The file consists of header followed by record lines which contain the following fields:\n",
57 | "\n",
58 | "record name(=ATOM), atom serial number, atom name, x-,y-,z-coordinates, occupancy and temperature factor.\n",
59 | "\n",
60 | "i.e.\n",
61 | "```\n",
62 | "ATOM 2 H -0.627 -0.627 0.627 0.00 0.00\n",
63 | "```\n",
64 | "\n",
65 | "Convert the file into XYZ format: first line contains the\n",
66 | "number of atoms, second line is title string, and the\n",
67 | "following lines contain the atomic symbols and x-, y-, z-\n",
68 | "coordinates, all separated by white space. Write the\n",
69 | "coordinates with 6 decimals:\n",
70 | "\n",
71 | "```\n",
72 | "5\n",
73 | "Converted from PDB\n",
74 | "C 0.000000 0.000000 0.000000\n",
75 | "...\n",
76 | "```"
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "metadata": {
83 | "collapsed": true
84 | },
85 | "outputs": [],
86 | "source": [
87 | "infile = '../data/CH4.pdb'\n",
88 | "outfile = infile.replace('.pdb', '.xyz')\n",
89 | "atoms = []\n",
90 | "with open(infile, \"r\") as f:\n",
91 | " for line in f:\n",
92 | " if 'ATOM' in line:\n",
93 | " line = line.split()\n",
94 | " symbol = line[2]\n",
95 | " coords = [float(x) for x in line[3:6]]\n",
96 | " atoms.append((symbol, coords))\n",
97 | " \n",
98 | "with open(outfile, \"w\") as f:\n",
99 | " f.write(\"{0}\\n\".format(len(atoms)))\n",
100 | " f.write(\"Converted from PDB\\n\")\n",
101 | " for atom in atoms:\n",
102 | " f.write(\"{0:2s} {1:10.6f} {2:10.6f} {3:10.6f}\\n\".format(atom[0],\n",
103 | " atom[1][0], atom[1][1], atom[1][2]))\n"
104 | ]
105 | },
106 | {
107 | "cell_type": "markdown",
108 | "metadata": {},
109 | "source": [
110 | "# Bonus exercises"
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {},
116 | "source": [
117 | "## Delimiter separated values\n",
118 | "\n",
119 | "Many data exchange formats are so-called *[delimiter separated values](https://en.wikipedia.org/wiki/Delimiter-separated_values)*. The most commonly known of these is [CSV](https://en.wikipedia.org/wiki/Comma-separated_values).\n",
120 | "\n",
121 | "There are multiple caveats in the format, e.g. European languages use comma (,) as a decimal separator and semicolon (;) as the field separator. Most pure-English systems use the dot (.) for decimal separation and the comma (,) for field separation. \n",
122 | "\n",
123 | "Another family of systems uses whitespace, like space or tab characters to separate fields.\n",
124 | "\n",
125 | "Python's [csv](https://docs.python.org/3/library/csv.html) library supports most of the variance in different formats and it can be a time-saving tool to those who use Python and deal with file formats a lot.\n",
126 | "\n",
127 | "The file \"../data/iris.data\" is actually in CSV format even though the file ending doesn't explicitly say so (this is common).\n",
128 | "\n",
129 | "Read in iris.data and write out a tab-separated file \"iris.tsv\" using the `csv` module.\n",
130 | "\n",
131 | "Hint: because the first line of the input file has labels, csv.DictReader and csv.DictWriter are a good choice."
132 | ]
133 | },
134 | {
135 | "cell_type": "code",
136 | "execution_count": null,
137 | "metadata": {},
138 | "outputs": [],
139 | "source": [
140 | "import csv\n",
141 | "irises = []\n",
142 | "with open(\"../data/iris.data\") as inputfile:\n",
143 | " chreader = csv.DictReader(inputfile)\n",
144 | " for line in chreader:\n",
145 | " irises.append(line)\n",
146 | " \n",
147 | "print(irises[0])\n",
148 | "with open(\"../data/iris.tsv\", \"w\") as outputfile:\n",
149 | " writer = csv.DictWriter(outputfile, delimiter=\"\\t\", fieldnames=[\"sepal.length\",\"sepal.width\",\"petal.length\",\"petal.width\",\"class\"])\n",
150 | " writer.writeheader()\n",
151 | " for iris in irises:\n",
152 | " writer.writerow(iris)"
153 | ]
154 | },
155 | {
156 | "cell_type": "markdown",
157 | "metadata": {},
158 | "source": [
159 | "The file [../data/word_count.txt](../data/word_count.txt) contains a short piece of text. Determine the frequency of words in the file, i.e. how many times each word appears. Print out the ten most frequent words.\n",
160 | "\n",
161 | "Read the file line by line and use the split() function for separating a line into words.\n",
162 | "The frequencies are stored most conveniently into a dictionary. The dictionary method **setdefault** can be useful\n",
163 | "here. \n",
164 | "\n",
165 | "For sorting, convert the dictionary into a list of (key, value) pairs with the items() function:\n",
166 | "```\n",
167 | "words = {\"foo\" : 1, \"bar\" : 2}\n",
168 | "print(words.items())\n",
169 | "[('foo', 1), ('bar', 2)]\n",
170 | "```"
171 | ]
172 | },
173 | {
174 | "cell_type": "code",
175 | "execution_count": null,
176 | "metadata": {
177 | "collapsed": true
178 | },
179 | "outputs": [],
180 | "source": [
181 | "words = {}\n",
182 | "with open(\"../data/word_count.txt\", \"r\") as f:\n",
183 | " for line in f:\n",
184 | " line = line.split()\n",
185 | " for word in line:\n",
186 | " words.setdefault(word, 0)\n",
187 | " words[word] += 1\n",
188 | "\n",
189 | "word_list = [(value, key) for key, value in words.items()]\n",
190 | "word_list.sort()\n",
191 | "word_list.reverse()\n",
192 | "for freq, word in word_list[:10]:\n",
193 | " word = '\"%s\"' % word\n",
194 | " print(\"The word {0:^15} appears {1:5} times\".format(word, freq))\n"
195 | ]
196 | },
197 | {
198 | "cell_type": "markdown",
199 | "metadata": {},
200 | "source": [
201 | "## Reading nucleotide sequences\n",
202 | "\n",
203 | "Fasta is a fileformat for storing nucleotide sequences. The sequences consist of header line, starting with **>**, followed by one or more lines containing the amino acids of the sequence presented by single-letter codes:\n",
204 | "```\n",
205 | ">5IRE:A|PDBID|CHAIN|SEQUENCE\n",
206 | "IRCIGVSNRDFVEGMSGGTWVDVVLEHGGCVTVMAQDKPTVDIELVTTTVSNMAEVRSYCYEASISDMASDSRCPTQGEA\n",
207 | "YLDKQSDTQYVCKRTLVDRGWGNGCGLFGKGSLVTCAKFACSKKMTGKSIQPENLEYRIMLSVHGSQHSGMIVNDTGHET\n",
208 | "...\n",
209 | "```\n",
210 | "The file [../data/5ire.fasta](../data/5ire.fasta) contains sequences for multiple chains of Zika virus. Read from the file the sequence of chain C (the chain ids are given in the header, i.e. the chain above is A).\n",
211 | "\n",
212 | "Find out which chains contain the subsequence **LDFSDL**.\n",
213 | "\n",
214 | "Hint: as the sequence is given in multiple lines, you should combine all the lines of a sequence into a single string. String object's **.strip()** method which removes newlines from the end of string is useful here."
215 | ]
216 | },
217 | {
218 | "cell_type": "code",
219 | "execution_count": null,
220 | "metadata": {},
221 | "outputs": [],
222 | "source": [
223 | "chains = {}\n",
224 | "with open(\"../data/5ire.fasta\", \"r\") as f:\n",
225 | " for line in f:\n",
226 | " if line.startswith('>'):\n",
227 | " # We have a header\n",
228 | " key = line.split('|')[0].split(':')[1] \n",
229 | " chains[key] = \"\"\n",
230 | " else:\n",
231 | " chains[key] += line.strip()\n",
232 | "\n",
233 | "print('Chain C:')\n",
234 | "print(chains['C'])\n",
235 | "print()\n",
236 | "\n",
237 | "subsequence = 'LDFSDL'\n",
238 | "for key, sequence in chains.items():\n",
239 | " if subsequence in sequence:\n",
240 | " print(\"Chain {0} contains subsequence {1}\".format(key, subsequence))\n",
241 | " "
242 | ]
243 | }
244 | ],
245 | "metadata": {
246 | "kernelspec": {
247 | "display_name": "Python 3",
248 | "language": "python",
249 | "name": "python3"
250 | },
251 | "language_info": {
252 | "codemirror_mode": {
253 | "name": "ipython",
254 | "version": 3
255 | },
256 | "file_extension": ".py",
257 | "mimetype": "text/x-python",
258 | "name": "python",
259 | "nbconvert_exporter": "python",
260 | "pygments_lexer": "ipython3",
261 | "version": "3.4.9"
262 | }
263 | },
264 | "nbformat": 4,
265 | "nbformat_minor": 2
266 | }
267 |
--------------------------------------------------------------------------------
/notebooks/answers/8 - Object oriented programming.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Exercises - Objects"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "## Using an object\n",
15 | "\n",
16 | "Below is the definition of an object. Run the cell and create at least two instances of it."
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": null,
22 | "metadata": {},
23 | "outputs": [],
24 | "source": [
25 | "class Car(object):\n",
26 | " \n",
27 | " def __init__(self, make, model, year, mpg=25, tank_capacity=30.0, miles=0):\n",
28 | " self.make = make\n",
29 | " self.model = model\n",
30 | " self.year = year\n",
31 | " self.mpg = mpg\n",
32 | " self.gallons_in_tank = tank_capacity # cars start with a full tank\n",
33 | " self.tank_capacity = tank_capacity\n",
34 | " self.miles = miles\n",
35 | " \n",
36 | " def __str__(self):\n",
37 | " return \"{} {} ({}), {} miles and {} gallons in tank\".format(self.make, \n",
38 | " self.model, \n",
39 | " self.year, \n",
40 | " self.miles, \n",
41 | " self.gallons_in_tank)\n",
42 | " \n",
43 | " def drive(self, new_miles):\n",
44 | " \"\"\"Drive the car X miles and return number of miles driven.\n",
45 | " If there is not enough fuel, drive 0 miles.\"\"\"\n",
46 | " fuel_need = new_miles/self.mpg\n",
47 | " if fuel_need <= self.gallons_in_tank:\n",
48 | " self.miles = self.miles + new_miles\n",
49 | " self.gallons_in_tank = self.gallons_in_tank - fuel_need\n",
50 | " return new_miles\n",
51 | " else:\n",
52 | " raise ValueError(\"Would run out of gas!\")\n",
53 | " \n",
54 | " def fill_up(self):\n",
55 | " self.gallons_in_tank = self.tank_capacity\n",
56 | " "
57 | ]
58 | },
59 | {
60 | "cell_type": "code",
61 | "execution_count": null,
62 | "metadata": {},
63 | "outputs": [],
64 | "source": [
65 | "volvo = Car(\"Volvo\", \"S40\", \"2017\", 25, 40, 0)\n",
66 | "print(volvo)"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {},
72 | "source": [
73 | "## Simple modification to class\n",
74 | "\n",
75 | "OK, our car has a major problem: it can't be filled up.\n",
76 | "\n",
77 | "Add a method called `fill_up()` to your class. It is up to you if you want to enable filling by an arbitary number or only back to the full state.\n",
78 | "\n",
79 | "If you allow arbitary amounts of liquid remember to consider overfilling the tank.\n",
80 | "\n",
81 | "Once you edit your class, the old objects do not automatically adopt to the changes you made. You will need to re-create them."
82 | ]
83 | },
84 | {
85 | "cell_type": "markdown",
86 | "metadata": {},
87 | "source": [
88 | "## Exceptions"
89 | ]
90 | },
91 | {
92 | "cell_type": "markdown",
93 | "metadata": {},
94 | "source": [
95 | "Now make a modification to the `drive`-method: if an attempt is made to drive more than the gas will allow, create and raise an exception.\n",
96 | "\n",
97 | "Instead of creating your own exception you may use a [ValueError](https://docs.python.org/3/library/exceptions.html#ValueError) for this case, as it is a logical choice.\n",
98 | "\n",
99 | "Now add a try-except clause to the following:"
100 | ]
101 | },
102 | {
103 | "cell_type": "code",
104 | "execution_count": null,
105 | "metadata": {},
106 | "outputs": [],
107 | "source": [
108 | "try:\n",
109 | " suv = Car(\"Ford\", \"Escape\", 2017, mpg=18, tank_capacity=30)\n",
110 | " suv.drive(600)\n",
111 | "except ValueError:\n",
112 | " print(\"Can't drive that far\")"
113 | ]
114 | }
115 | ],
116 | "metadata": {
117 | "kernelspec": {
118 | "display_name": "Python 3",
119 | "language": "python",
120 | "name": "python3"
121 | },
122 | "language_info": {
123 | "codemirror_mode": {
124 | "name": "ipython",
125 | "version": 3
126 | },
127 | "file_extension": ".py",
128 | "mimetype": "text/x-python",
129 | "name": "python",
130 | "nbconvert_exporter": "python",
131 | "pygments_lexer": "ipython3",
132 | "version": "3.4.9"
133 | }
134 | },
135 | "nbformat": 4,
136 | "nbformat_minor": 1
137 | }
138 |
--------------------------------------------------------------------------------
/notebooks/data/5ire.fasta:
--------------------------------------------------------------------------------
1 | >5IRE:A|PDBID|CHAIN|SEQUENCE
2 | IRCIGVSNRDFVEGMSGGTWVDVVLEHGGCVTVMAQDKPTVDIELVTTTVSNMAEVRSYCYEASISDMASDSRCPTQGEA
3 | YLDKQSDTQYVCKRTLVDRGWGNGCGLFGKGSLVTCAKFACSKKMTGKSIQPENLEYRIMLSVHGSQHSGMIVNDTGHET
4 | DENRAKVEITPNSPRAEATLGGFGSLGLDCEPRTGLDFSDLYYLTMNNKHWLVHKEWFHDIPLPWHAGADTGTPHWNNKE
5 | ALVEFKDAHAKRQTVVVLGSQEGAVHTALAGALEAEMDGAKGRLSSGHLKCRLKMDKLRLKGVSYSLCTAAFTFTKIPAE
6 | TLHGTVTVEVQYAGTDGPCKVPAQMAVDMQTLTPVGRLITANPVITESTENSKMMLELDPPFGDSYIVIGVGEKKITHHW
7 | HRSGSTIGKAFEATVRGAKRMAVLGDTAWDFGSVGGALNSLGKGIHQIFGAAFKSLFGGMSWFSQILIGTLLMWLGLNTK
8 | NGSISLMCLALGGVLIFLSTAVSA
9 | >5IRE:B|PDBID|CHAIN|SEQUENCE
10 | AVTLPSHSTRKLQTRSQTWLESREYTKHLIRVENWIFRNPGFALAAAAIAWLLGSSTSQKVIYLVMILLIAPAYS
11 | >5IRE:C|PDBID|CHAIN|SEQUENCE
12 | IRCIGVSNRDFVEGMSGGTWVDVVLEHGGCVTVMAQDKPTVDIELVTTTVSNMAEVRSYCYEASISDMASDSRCPTQGEA
13 | YLDKQSDTQYVCKRTLVDRGWGNGCGLFGKGSLVTCAKFACSKKMTGKSIQPENLEYRIMLSVHGSQHSGMIVNDTGHET
14 | DENRAKVEITPNSPRAEATLGGFGSLGLDCEPRTGLDFSDLYYLTMNNKHWLVHKEWFHDIPLPWHAGADTGTPHWNNKE
15 | ALVEFKDAHAKRQTVVVLGSQEGAVHTALAGALEAEMDGAKGRLSSGHLKCRLKMDKLRLKGVSYSLCTAAFTFTKIPAE
16 | TLHGTVTVEVQYAGTDGPCKVPAQMAVDMQTLTPVGRLITANPVITESTENSKMMLELDPPFGDSYIVIGVGEKKITHHW
17 | HRSGSTIGKAFEATVRGAKRMAVLGDTAWDFGSVGGALNSLGKGIHQIFGAAFKSLFGGMSWFSQILIGTLLMWLGLNTK
18 | NGSISLMCLALGGVLIFLSTAVSA
19 | >5IRE:D|PDBID|CHAIN|SEQUENCE
20 | AVTLPSHSTRKLQTRSQTWLESREYTKHLIRVENWIFRNPGFALAAAAIAWLLGSSTSQKVIYLVMILLIAPAYS
21 | >5IRE:E|PDBID|CHAIN|SEQUENCE
22 | IRCIGVSNRDFVEGMSGGTWVDVVLEHGGCVTVMAQDKPTVDIELVTTTVSNMAEVRSYCYEASISDMASDSRCPTQGEA
23 | YLDKQSDTQYVCKRTLVDRGWGNGCGLFGKGSLVTCAKFACSKKMTGKSIQPENLEYRIMLSVHGSQHSGMIVNDTGHET
24 | DENRAKVEITPNSPRAEATLGGFGSLGLDCEPRTGLDFSDLYYLTMNNKHWLVHKEWFHDIPLPWHAGADTGTPHWNNKE
25 | ALVEFKDAHAKRQTVVVLGSQEGAVHTALAGALEAEMDGAKGRLSSGHLKCRLKMDKLRLKGVSYSLCTAAFTFTKIPAE
26 | TLHGTVTVEVQYAGTDGPCKVPAQMAVDMQTLTPVGRLITANPVITESTENSKMMLELDPPFGDSYIVIGVGEKKITHHW
27 | HRSGSTIGKAFEATVRGAKRMAVLGDTAWDFGSVGGALNSLGKGIHQIFGAAFKSLFGGMSWFSQILIGTLLMWLGLNTK
28 | NGSISLMCLALGGVLIFLSTAVSA
29 | >5IRE:F|PDBID|CHAIN|SEQUENCE
30 | AVTLPSHSTRKLQTRSQTWLESREYTKHLIRVENWIFRNPGFALAAAAIAWLLGSSTSQKVIYLVMILLIAPAYS
31 |
--------------------------------------------------------------------------------
/notebooks/data/CH4.pdb:
--------------------------------------------------------------------------------
1 | MODEL 1
2 | ATOM 0 C 0.000 0.000 0.000 0.00 0.00
3 | ATOM 1 H 0.627 0.627 0.627 0.00 0.00
4 | ATOM 2 H -0.627 -0.627 0.627 0.00 0.00
5 | ATOM 3 H -0.627 0.627 -0.627 0.00 0.00
6 | ATOM 4 H 0.627 -0.627 -0.627 0.00 0.00
7 | ENDMDL
8 |
--------------------------------------------------------------------------------
/notebooks/data/coordinates.txt:
--------------------------------------------------------------------------------
1 | -5.000000 25.131953
2 | -3.888889 15.056032
3 | -2.777778 7.261712
4 | -1.666667 2.908772
5 | -0.555556 -0.141217
6 | 0.555556 0.176612
7 | 1.666667 2.833694
8 | 2.777778 7.643842
9 | 3.888889 14.979309
10 | 5.000000 25.299547
11 |
--------------------------------------------------------------------------------
/notebooks/data/csc_usage.txt:
--------------------------------------------------------------------------------
1 | # discipline usage %
2 | Physics 33
3 | Biosciences 20
4 | Chemistry 17
5 | Astronomy 8
6 | Others 22
7 |
--------------------------------------------------------------------------------
/notebooks/data/davis.data:
--------------------------------------------------------------------------------
1 | "","sex","weight","height","repwt","repht"
2 | "1","M",77,182,77,180
3 | "2","F",58,161,51,159
4 | "3","F",53,161,54,158
5 | "4","M",68,177,70,175
6 | "5","F",59,157,59,155
7 | "6","M",76,170,76,165
8 | "7","M",76,167,77,165
9 | "8","M",69,186,73,180
10 | "9","M",71,178,71,175
11 | "10","M",65,171,64,170
12 | "11","M",70,175,75,174
13 | "12","F",166,57,56,163
14 | "13","F",51,161,52,158
15 | "14","F",64,168,64,165
16 | "15","F",52,163,57,160
17 | "16","F",65,166,66,165
18 | "17","M",92,187,101,185
19 | "18","F",62,168,62,165
20 | "19","M",76,197,75,200
21 | "20","F",61,175,61,171
22 | "21","M",119,180,124,178
23 | "22","F",61,170,61,170
24 | "23","M",65,175,66,173
25 | "24","M",66,173,70,170
26 | "25","F",54,171,59,168
27 | "26","F",50,166,50,165
28 | "27","F",63,169,61,168
29 | "28","F",58,166,60,160
30 | "29","F",39,157,41,153
31 | "30","M",101,183,100,180
32 | "31","F",71,166,71,165
33 | "32","M",75,178,73,175
34 | "33","M",79,173,76,173
35 | "34","F",52,164,52,161
36 | "35","F",68,169,63,170
37 | "36","M",64,176,65,175
38 | "37","F",56,166,54,165
39 | "38","M",69,174,69,171
40 | "39","M",88,178,86,175
41 | "40","M",65,187,67,188
42 | "41","F",54,164,53,160
43 | "42","M",80,178,80,178
44 | "43","F",63,163,59,159
45 | "44","M",78,183,80,180
46 | "45","M",85,179,82,175
47 | "46","F",54,160,55,158
48 | "47","M",73,180,NA,NA
49 | "48","F",49,161,NA,NA
50 | "49","F",54,174,56,173
51 | "50","F",75,162,75,158
52 | "51","M",82,182,85,183
53 | "52","F",56,165,57,163
54 | "53","M",74,169,73,170
55 | "54","M",102,185,107,185
56 | "55","M",64,177,NA,NA
57 | "56","M",65,176,64,172
58 | "57","F",66,170,65,NA
59 | "58","M",73,183,74,180
60 | "59","M",75,172,70,169
61 | "60","M",57,173,58,170
62 | "61","M",68,165,69,165
63 | "62","M",71,177,71,170
64 | "63","M",71,180,76,175
65 | "64","F",78,173,75,169
66 | "65","M",97,189,98,185
67 | "66","F",60,162,59,160
68 | "67","F",64,165,63,163
69 | "68","F",64,164,62,161
70 | "69","F",52,158,51,155
71 | "70","M",80,178,76,175
72 | "71","F",62,175,61,171
73 | "72","M",66,173,66,175
74 | "73","F",55,165,54,163
75 | "74","F",56,163,57,159
76 | "75","F",50,166,50,161
77 | "76","F",50,171,NA,NA
78 | "77","F",50,160,55,150
79 | "78","F",63,160,64,158
80 | "79","M",69,182,70,180
81 | "80","M",69,183,70,183
82 | "81","F",61,165,60,163
83 | "82","M",55,168,56,170
84 | "83","F",53,169,52,175
85 | "84","F",60,167,55,163
86 | "85","F",56,170,56,170
87 | "86","M",59,182,61,183
88 | "87","M",62,178,66,175
89 | "88","F",53,165,53,165
90 | "89","F",57,163,59,160
91 | "90","F",57,162,56,160
92 | "91","M",70,173,68,170
93 | "92","F",56,161,56,161
94 | "93","M",84,184,86,183
95 | "94","M",69,180,71,180
96 | "95","M",88,189,87,185
97 | "96","F",56,165,57,160
98 | "97","M",103,185,101,182
99 | "98","F",50,169,50,165
100 | "99","F",52,159,52,153
101 | "100","F",55,155,NA,154
102 | "101","F",55,164,55,163
103 | "102","M",63,178,63,175
104 | "103","F",47,163,47,160
105 | "104","F",45,163,45,160
106 | "105","F",62,175,63,173
107 | "106","F",53,164,51,160
108 | "107","F",52,152,51,150
109 | "108","F",57,167,55,164
110 | "109","F",64,166,64,165
111 | "110","F",59,166,55,163
112 | "111","M",84,183,90,183
113 | "112","M",79,179,79,171
114 | "113","F",55,174,57,171
115 | "114","M",67,179,67,179
116 | "115","F",76,167,77,165
117 | "116","F",62,168,62,163
118 | "117","M",83,184,83,181
119 | "118","M",96,184,94,183
120 | "119","M",75,169,76,165
121 | "120","M",65,178,66,178
122 | "121","M",78,178,77,175
123 | "122","M",69,167,73,165
124 | "123","F",68,178,68,175
125 | "124","F",55,165,55,163
126 | "125","M",67,179,NA,NA
127 | "126","F",52,169,56,NA
128 | "127","F",47,153,NA,154
129 | "128","F",45,157,45,153
130 | "129","F",68,171,68,169
131 | "130","F",44,157,44,155
132 | "131","F",62,166,61,163
133 | "132","M",87,185,89,185
134 | "133","F",56,160,53,158
135 | "134","F",50,148,47,148
136 | "135","M",83,177,84,175
137 | "136","F",53,162,53,160
138 | "137","F",64,172,62,168
139 | "138","F",62,167,NA,NA
140 | "139","M",90,188,91,185
141 | "140","M",85,191,83,188
142 | "141","M",66,175,68,175
143 | "142","F",52,163,53,160
144 | "143","F",53,165,55,163
145 | "144","F",54,176,55,176
146 | "145","F",64,171,66,171
147 | "146","F",55,160,55,155
148 | "147","F",55,165,55,165
149 | "148","F",59,157,55,158
150 | "149","F",70,173,67,170
151 | "150","M",88,184,86,183
152 | "151","F",57,168,58,165
153 | "152","F",47,162,47,160
154 | "153","F",47,150,45,152
155 | "154","F",55,162,NA,NA
156 | "155","F",48,163,44,160
157 | "156","M",54,169,58,165
158 | "157","M",69,172,68,174
159 | "158","F",59,170,NA,NA
160 | "159","F",58,169,NA,NA
161 | "160","F",57,167,56,165
162 | "161","F",51,163,50,160
163 | "162","F",54,161,54,160
164 | "163","F",53,162,52,158
165 | "164","F",59,172,58,171
166 | "165","M",56,163,58,161
167 | "166","F",59,159,59,155
168 | "167","F",63,170,62,168
169 | "168","F",66,166,66,165
170 | "169","M",96,191,95,188
171 | "170","F",53,158,50,155
172 | "171","M",76,169,75,165
173 | "172","F",54,163,NA,NA
174 | "173","M",61,170,61,170
175 | "174","M",82,176,NA,NA
176 | "175","M",62,168,64,168
177 | "176","M",71,178,68,178
178 | "177","F",60,174,NA,NA
179 | "178","M",66,170,67,165
180 | "179","M",81,178,82,175
181 | "180","M",68,174,68,173
182 | "181","M",80,176,78,175
183 | "182","F",43,154,NA,NA
184 | "183","M",82,181,NA,NA
185 | "184","F",63,165,59,160
186 | "185","M",70,173,70,173
187 | "186","F",56,162,56,160
188 | "187","F",60,172,55,168
189 | "188","F",58,169,54,166
190 | "189","M",76,183,75,180
191 | "190","F",50,158,49,155
192 | "191","M",88,185,93,188
193 | "192","M",89,173,86,173
194 | "193","F",59,164,59,165
195 | "194","F",51,156,51,158
196 | "195","F",62,164,61,161
197 | "196","M",74,175,71,175
198 | "197","M",83,180,80,180
199 | "198","M",81,175,NA,NA
200 | "199","M",90,181,91,178
201 | "200","M",79,177,81,178
202 |
--------------------------------------------------------------------------------
/notebooks/data/example.csv:
--------------------------------------------------------------------------------
1 | name,birthyear,dead
2 | Graham Chapham,1941,True
3 | Eric Idle,1943,False
4 | Terry Gilliam,1940,False
5 | Terry Jones,1942,False
6 | John Cleese,1939,False
7 | Michael Palin,1939,False
8 |
--------------------------------------------------------------------------------
/notebooks/data/example_file.txt:
--------------------------------------------------------------------------------
1 | Hello
2 | Hey
3 | moi
4 |
--------------------------------------------------------------------------------
/notebooks/data/example_json_1.json:
--------------------------------------------------------------------------------
1 | [{"name": "Graham Chapham", "birthyear": 1941, "dead": true}, {"name": "Eric Idle", "birthyear": 1943, "dead": false}, {"name": "Terry Gilliam", "birthyear": 1940, "dead": false}, {"name": "Terry Jones", "birthyear": 1942, "dead": false}, {"name": "John Cleese", "birthyear": 1939, "dead": false}, {"name": "Michael Palin", "birthyear": 1939, "dead": false}]
--------------------------------------------------------------------------------
/notebooks/data/example_json_2.json:
--------------------------------------------------------------------------------
1 | {"name": "Graham Chapham", "birthyear": 1941, "dead": true}
2 | {"name": "Eric Idle", "birthyear": 1943, "dead": false}
3 | {"name": "Terry Gilliam", "birthyear": 1940, "dead": false}
4 | {"name": "Terry Jones", "birthyear": 1942, "dead": false}
5 | {"name": "John Cleese", "birthyear": 1939, "dead": false}
6 | {"name": "Michael Palin", "birthyear": 1939, "dead": false}
7 |
--------------------------------------------------------------------------------
/notebooks/data/grep.txt:
--------------------------------------------------------------------------------
1 | this is a test
2 | this is a Test
3 | yet another test
4 |
--------------------------------------------------------------------------------
/notebooks/data/iris.data:
--------------------------------------------------------------------------------
1 | sepal.length,sepal.width,petal.length,petal.width,class
2 | 5.1,3.5,1.4,0.2,Iris-setosa
3 | 4.9,3.0,1.4,0.2,Iris-setosa
4 | 4.7,3.2,1.3,0.2,Iris-setosa
5 | 4.6,3.1,1.5,0.2,Iris-setosa
6 | 5.0,3.6,1.4,0.2,Iris-setosa
7 | 5.4,3.9,1.7,0.4,Iris-setosa
8 | 4.6,3.4,1.4,0.3,Iris-setosa
9 | 5.0,3.4,1.5,0.2,Iris-setosa
10 | 4.4,2.9,1.4,0.2,Iris-setosa
11 | 4.9,3.1,1.5,0.1,Iris-setosa
12 | 5.4,3.7,1.5,0.2,Iris-setosa
13 | 4.8,3.4,1.6,0.2,Iris-setosa
14 | 4.8,3.0,1.4,0.1,Iris-setosa
15 | 4.3,3.0,1.1,0.1,Iris-setosa
16 | 5.8,4.0,1.2,0.2,Iris-setosa
17 | 5.7,4.4,1.5,0.4,Iris-setosa
18 | 5.4,3.9,1.3,0.4,Iris-setosa
19 | 5.1,3.5,1.4,0.3,Iris-setosa
20 | 5.7,3.8,1.7,0.3,Iris-setosa
21 | 5.1,3.8,1.5,0.3,Iris-setosa
22 | 5.4,3.4,1.7,0.2,Iris-setosa
23 | 5.1,3.7,1.5,0.4,Iris-setosa
24 | 4.6,3.6,1.0,0.2,Iris-setosa
25 | 5.1,3.3,1.7,0.5,Iris-setosa
26 | 4.8,3.4,1.9,0.2,Iris-setosa
27 | 5.0,3.0,1.6,0.2,Iris-setosa
28 | 5.0,3.4,1.6,0.4,Iris-setosa
29 | 5.2,3.5,1.5,0.2,Iris-setosa
30 | 5.2,3.4,1.4,0.2,Iris-setosa
31 | 4.7,3.2,1.6,0.2,Iris-setosa
32 | 4.8,3.1,1.6,0.2,Iris-setosa
33 | 5.4,3.4,1.5,0.4,Iris-setosa
34 | 5.2,4.1,1.5,0.1,Iris-setosa
35 | 5.5,4.2,1.4,0.2,Iris-setosa
36 | 4.9,3.1,1.5,0.1,Iris-setosa
37 | 5.0,3.2,1.2,0.2,Iris-setosa
38 | 5.5,3.5,1.3,0.2,Iris-setosa
39 | 4.9,3.1,1.5,0.1,Iris-setosa
40 | 4.4,3.0,1.3,0.2,Iris-setosa
41 | 5.1,3.4,1.5,0.2,Iris-setosa
42 | 5.0,3.5,1.3,0.3,Iris-setosa
43 | 4.5,2.3,1.3,0.3,Iris-setosa
44 | 4.4,3.2,1.3,0.2,Iris-setosa
45 | 5.0,3.5,1.6,0.6,Iris-setosa
46 | 5.1,3.8,1.9,0.4,Iris-setosa
47 | 4.8,3.0,1.4,0.3,Iris-setosa
48 | 5.1,3.8,1.6,0.2,Iris-setosa
49 | 4.6,3.2,1.4,0.2,Iris-setosa
50 | 5.3,3.7,1.5,0.2,Iris-setosa
51 | 5.0,3.3,1.4,0.2,Iris-setosa
52 | 7.0,3.2,4.7,1.4,Iris-versicolor
53 | 6.4,3.2,4.5,1.5,Iris-versicolor
54 | 6.9,3.1,4.9,1.5,Iris-versicolor
55 | 5.5,2.3,4.0,1.3,Iris-versicolor
56 | 6.5,2.8,4.6,1.5,Iris-versicolor
57 | 5.7,2.8,4.5,1.3,Iris-versicolor
58 | 6.3,3.3,4.7,1.6,Iris-versicolor
59 | 4.9,2.4,3.3,1.0,Iris-versicolor
60 | 6.6,2.9,4.6,1.3,Iris-versicolor
61 | 5.2,2.7,3.9,1.4,Iris-versicolor
62 | 5.0,2.0,3.5,1.0,Iris-versicolor
63 | 5.9,3.0,4.2,1.5,Iris-versicolor
64 | 6.0,2.2,4.0,1.0,Iris-versicolor
65 | 6.1,2.9,4.7,1.4,Iris-versicolor
66 | 5.6,2.9,3.6,1.3,Iris-versicolor
67 | 6.7,3.1,4.4,1.4,Iris-versicolor
68 | 5.6,3.0,4.5,1.5,Iris-versicolor
69 | 5.8,2.7,4.1,1.0,Iris-versicolor
70 | 6.2,2.2,4.5,1.5,Iris-versicolor
71 | 5.6,2.5,3.9,1.1,Iris-versicolor
72 | 5.9,3.2,4.8,1.8,Iris-versicolor
73 | 6.1,2.8,4.0,1.3,Iris-versicolor
74 | 6.3,2.5,4.9,1.5,Iris-versicolor
75 | 6.1,2.8,4.7,1.2,Iris-versicolor
76 | 6.4,2.9,4.3,1.3,Iris-versicolor
77 | 6.6,3.0,4.4,1.4,Iris-versicolor
78 | 6.8,2.8,4.8,1.4,Iris-versicolor
79 | 6.7,3.0,5.0,1.7,Iris-versicolor
80 | 6.0,2.9,4.5,1.5,Iris-versicolor
81 | 5.7,2.6,3.5,1.0,Iris-versicolor
82 | 5.5,2.4,3.8,1.1,Iris-versicolor
83 | 5.5,2.4,3.7,1.0,Iris-versicolor
84 | 5.8,2.7,3.9,1.2,Iris-versicolor
85 | 6.0,2.7,5.1,1.6,Iris-versicolor
86 | 5.4,3.0,4.5,1.5,Iris-versicolor
87 | 6.0,3.4,4.5,1.6,Iris-versicolor
88 | 6.7,3.1,4.7,1.5,Iris-versicolor
89 | 6.3,2.3,4.4,1.3,Iris-versicolor
90 | 5.6,3.0,4.1,1.3,Iris-versicolor
91 | 5.5,2.5,4.0,1.3,Iris-versicolor
92 | 5.5,2.6,4.4,1.2,Iris-versicolor
93 | 6.1,3.0,4.6,1.4,Iris-versicolor
94 | 5.8,2.6,4.0,1.2,Iris-versicolor
95 | 5.0,2.3,3.3,1.0,Iris-versicolor
96 | 5.6,2.7,4.2,1.3,Iris-versicolor
97 | 5.7,3.0,4.2,1.2,Iris-versicolor
98 | 5.7,2.9,4.2,1.3,Iris-versicolor
99 | 6.2,2.9,4.3,1.3,Iris-versicolor
100 | 5.1,2.5,3.0,1.1,Iris-versicolor
101 | 5.7,2.8,4.1,1.3,Iris-versicolor
102 | 6.3,3.3,6.0,2.5,Iris-virginica
103 | 5.8,2.7,5.1,1.9,Iris-virginica
104 | 7.1,3.0,5.9,2.1,Iris-virginica
105 | 6.3,2.9,5.6,1.8,Iris-virginica
106 | 6.5,3.0,5.8,2.2,Iris-virginica
107 | 7.6,3.0,6.6,2.1,Iris-virginica
108 | 4.9,2.5,4.5,1.7,Iris-virginica
109 | 7.3,2.9,6.3,1.8,Iris-virginica
110 | 6.7,2.5,5.8,1.8,Iris-virginica
111 | 7.2,3.6,6.1,2.5,Iris-virginica
112 | 6.5,3.2,5.1,2.0,Iris-virginica
113 | 6.4,2.7,5.3,1.9,Iris-virginica
114 | 6.8,3.0,5.5,2.1,Iris-virginica
115 | 5.7,2.5,5.0,2.0,Iris-virginica
116 | 5.8,2.8,5.1,2.4,Iris-virginica
117 | 6.4,3.2,5.3,2.3,Iris-virginica
118 | 6.5,3.0,5.5,1.8,Iris-virginica
119 | 7.7,3.8,6.7,2.2,Iris-virginica
120 | 7.7,2.6,6.9,2.3,Iris-virginica
121 | 6.0,2.2,5.0,1.5,Iris-virginica
122 | 6.9,3.2,5.7,2.3,Iris-virginica
123 | 5.6,2.8,4.9,2.0,Iris-virginica
124 | 7.7,2.8,6.7,2.0,Iris-virginica
125 | 6.3,2.7,4.9,1.8,Iris-virginica
126 | 6.7,3.3,5.7,2.1,Iris-virginica
127 | 7.2,3.2,6.0,1.8,Iris-virginica
128 | 6.2,2.8,4.8,1.8,Iris-virginica
129 | 6.1,3.0,4.9,1.8,Iris-virginica
130 | 6.4,2.8,5.6,2.1,Iris-virginica
131 | 7.2,3.0,5.8,1.6,Iris-virginica
132 | 7.4,2.8,6.1,1.9,Iris-virginica
133 | 7.9,3.8,6.4,2.0,Iris-virginica
134 | 6.4,2.8,5.6,2.2,Iris-virginica
135 | 6.3,2.8,5.1,1.5,Iris-virginica
136 | 6.1,2.6,5.6,1.4,Iris-virginica
137 | 7.7,3.0,6.1,2.3,Iris-virginica
138 | 6.3,3.4,5.6,2.4,Iris-virginica
139 | 6.4,3.1,5.5,1.8,Iris-virginica
140 | 6.0,3.0,4.8,1.8,Iris-virginica
141 | 6.9,3.1,5.4,2.1,Iris-virginica
142 | 6.7,3.1,5.6,2.4,Iris-virginica
143 | 6.9,3.1,5.1,2.3,Iris-virginica
144 | 5.8,2.7,5.1,1.9,Iris-virginica
145 | 6.8,3.2,5.9,2.3,Iris-virginica
146 | 6.7,3.3,5.7,2.5,Iris-virginica
147 | 6.7,3.0,5.2,2.3,Iris-virginica
148 | 6.3,2.5,5.0,1.9,Iris-virginica
149 | 6.5,3.0,5.2,2.0,Iris-virginica
150 | 6.2,3.4,5.4,2.3,Iris-virginica
151 | 5.9,3.0,5.1,1.8,Iris-virginica
152 |
153 |
--------------------------------------------------------------------------------
/notebooks/data/word_count.txt:
--------------------------------------------------------------------------------
1 | Python is modern, object-oriented programming language which has become popular in several areas of software development. This course introduces the basic concepts of the Python programming language and how Python can ne used in the context of scientific computing. Examples include prototyping numerical problems with Python, steering simulations with Python scripts and analysing results with the help of Python scripts. Course consists of lectures and of hands-on exercises.
2 |
3 | Participants are expected to know basic programming concepts (e.g. variables, statements, control structures, subroutines) but previous knowledge of Python is not required.
4 |
5 |
--------------------------------------------------------------------------------
/notebooks/data/zipped_file.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/csc-training/python-introduction/8212fd6511024fdc8f2428cb5cb06f288a718594/notebooks/data/zipped_file.gz
--------------------------------------------------------------------------------
/notebooks/examples/2 - Control Structures.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Conditional statements\n",
8 | "\n",
9 | "The most common conditional statement in Python is the if-elif-else statement:\n",
10 | "\n",
11 | "```\n",
12 | "if variable > 5:\n",
13 | " do_something()\n",
14 | "elif variable > 0:\n",
15 | " do_something_else()\n",
16 | "else:\n",
17 | " give_up()\n",
18 | "```\n",
19 | "\n",
20 | "Compared to languages like C, Java or Lisp, do you feel something is missing?\n",
21 | "\n",
22 | "Python is whitespace-aware and it uses the so-called [off-side rule](https://en.wikipedia.org/wiki/Off-side_rule) to annotate **code blocks**. This has several benefits\n",
23 | "* It's easy to read at a glance\n",
24 | "* levels of indentation are processed [pre-attentively](https://en.wikipedia.org/wiki/Pre-attentive_processing) to conserve brain power for everything\n",
25 | "* It's easy to write without having to worry too much\n",
26 | "\n",
27 | "One corollary of the indentation is that you need to be very aware of when you're using the tabulator character and when you're using a space. Most Python programmers only use whitespace and configure their editor to output several spaces when tab is pressed.\n",
28 | "\n",
29 | "**Note**: the line before a deeper level of indentation ends in a colon \":\". This syntax is part of beginning a new code block and surprisingly easy to forget."
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": null,
35 | "metadata": {
36 | "collapsed": true
37 | },
38 | "outputs": [],
39 | "source": [
40 | "value = 4\n",
41 | "value = value + 1\n",
42 | "if value < 5:\n",
43 | " print(\"value is less than 5\")\n",
44 | "elif value > 5:\n",
45 | " print(\"value is more than 5\")\n",
46 | "else:\n",
47 | " print(\"value is precisely 5\")\n",
48 | "# go ahead and experiment by changing the value\n"
49 | ]
50 | },
51 | {
52 | "cell_type": "markdown",
53 | "metadata": {},
54 | "source": [
55 | "There is no switch-case type of statement in Python.\n",
56 | "\n",
57 | "**Note**: When evaluating conditional statements the values 0, an empty string and an empty list all evaluate to False. This can be confusing as it is one of the few places where Python doesn't enforce strong typing."
58 | ]
59 | },
60 | {
61 | "cell_type": "code",
62 | "execution_count": null,
63 | "metadata": {
64 | "collapsed": true
65 | },
66 | "outputs": [],
67 | "source": [
68 | "list_ = [1]\n",
69 | "list_.pop()\n",
70 | "if not list_:\n",
71 | " print(\"list is None or empty\")"
72 | ]
73 | },
74 | {
75 | "cell_type": "markdown",
76 | "metadata": {},
77 | "source": [
78 | "### While statement\n",
79 | "\n",
80 | "Python supports ``while`` statement familiar from many languages. It is not nearly as much used because of iterators (covered later).\n",
81 | "\n",
82 | "```\n",
83 | "value = 5\n",
84 | "while value > 0:\n",
85 | " value = do_something(value)\n",
86 | "```\n",
87 | "\n",
88 | "The following example shows how a list is used as the conditional."
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": null,
94 | "metadata": {
95 | "collapsed": true
96 | },
97 | "outputs": [],
98 | "source": [
99 | "list_ = [1, 2, 3, 4]\n",
100 | "while list_: # remember, an empty list evaluates as False for conditional purposes\n",
101 | " print(list_.pop()) # pop() removes the last entry from the list"
102 | ]
103 | },
104 | {
105 | "cell_type": "markdown",
106 | "metadata": {},
107 | "source": [
108 | "## Iterating\n",
109 | "\n",
110 | "Python has a ``for``-loop statement that is similar to the foreach statement in a lot of other languages.\n",
111 | "\n",
112 | "It is possible to loop over any iterables, i.e. lists, sets, tuples, even dicts."
113 | ]
114 | },
115 | {
116 | "cell_type": "code",
117 | "execution_count": null,
118 | "metadata": {
119 | "collapsed": true
120 | },
121 | "outputs": [],
122 | "source": [
123 | "synonyms = [\"is dead\", \"has kicked the bucket\", \"is no more\", \"ceased to be\"]\n",
124 | "for phrase in synonyms:\n",
125 | " print(\"This parrot \" + phrase + \".\")"
126 | ]
127 | },
128 | {
129 | "cell_type": "markdown",
130 | "metadata": {},
131 | "source": [
132 | "It is possible to unpack things in this stage if that is required."
133 | ]
134 | },
135 | {
136 | "cell_type": "code",
137 | "execution_count": null,
138 | "metadata": {
139 | "collapsed": true
140 | },
141 | "outputs": [],
142 | "source": [
143 | "pairs = (\n",
144 | " (1, 2),\n",
145 | " [3, 4],\n",
146 | " (5, 6),\n",
147 | ")\n",
148 | "\n",
149 | "for x, y in pairs:\n",
150 | " print(\"A is \" + str(x))\n",
151 | " print(\"B is \" + str(y))"
152 | ]
153 | },
154 | {
155 | "cell_type": "markdown",
156 | "metadata": {},
157 | "source": [
158 | "In dictionaries the **keys** are iterated over by default."
159 | ]
160 | },
161 | {
162 | "cell_type": "code",
163 | "execution_count": null,
164 | "metadata": {
165 | "collapsed": true
166 | },
167 | "outputs": [],
168 | "source": [
169 | "airspeed_swallows = {\"African\": 20, \"European\": 30}\n",
170 | "for swallow in airspeed_swallows:\n",
171 | " print(\"The air speed of \" + swallow + \" swallows is \"+ str(airspeed_swallows[swallow]))"
172 | ]
173 | },
174 | {
175 | "cell_type": "markdown",
176 | "metadata": {},
177 | "source": [
178 | "It is still possible to loop through numbers using the built-in ``range`` function that returns an iterable with numbers in sequence. "
179 | ]
180 | },
181 | {
182 | "cell_type": "code",
183 | "execution_count": null,
184 | "metadata": {
185 | "collapsed": true
186 | },
187 | "outputs": [],
188 | "source": [
189 | "for i in range(5):\n",
190 | " print(str(i))"
191 | ]
192 | },
193 | {
194 | "cell_type": "code",
195 | "execution_count": null,
196 | "metadata": {
197 | "collapsed": true
198 | },
199 | "outputs": [],
200 | "source": [
201 | "# The function supports arbitary step lengths and going backwards\n",
202 | "\n",
203 | "for i in range(99, 90, -2): # parameters are from, to and step length in that order\n",
204 | " print(str(i) +\" boxes of bottles of beer on the wall\")"
205 | ]
206 | },
207 | {
208 | "cell_type": "markdown",
209 | "metadata": {},
210 | "source": [
211 | "The function ``enumerate`` returns the values it's given with their number in the collection."
212 | ]
213 | },
214 | {
215 | "cell_type": "code",
216 | "execution_count": null,
217 | "metadata": {
218 | "collapsed": true
219 | },
220 | "outputs": [],
221 | "source": [
222 | "my_list = [\"a\", \"b\", \"c\", \"d\", \"e\"]\n",
223 | "for index, string in enumerate(my_list):\n",
224 | " print(string +\" is the alphabet number \"+ str(index))"
225 | ]
226 | },
227 | {
228 | "cell_type": "markdown",
229 | "metadata": {},
230 | "source": [
231 | "### Breaking and continuing\n",
232 | "\n",
233 | "Sometimes it is necessary to stop the execution of a loop before it's time. For that there is the ``break`` keyword.\n",
234 | "\n",
235 | "At other times it is desired to end that particular step in the loop and immediately move to the next one.\n",
236 | "\n",
237 | "Both of the keywords could be substituted with complex if-else statements but a well-considered break or continue statement is more readable to the next programmer."
238 | ]
239 | },
240 | {
241 | "cell_type": "code",
242 | "execution_count": null,
243 | "metadata": {
244 | "collapsed": true
245 | },
246 | "outputs": [],
247 | "source": [
248 | "for i in range(20):\n",
249 | " if i % 7 == 6: # modulo operator\n",
250 | " break #\n",
251 | " print(i)"
252 | ]
253 | },
254 | {
255 | "cell_type": "code",
256 | "execution_count": null,
257 | "metadata": {
258 | "collapsed": true
259 | },
260 | "outputs": [],
261 | "source": [
262 | "for i in range(-5, 5, 1):\n",
263 | " if i == 0:\n",
264 | " print (\"not dividing by 0\")\n",
265 | " continue\n",
266 | " print(\"5/\" + str(i) + \" equals \" + str(5/i))"
267 | ]
268 | },
269 | {
270 | "cell_type": "markdown",
271 | "metadata": {},
272 | "source": [
273 | "## List comprehension\n",
274 | "\n",
275 | "The act of modifying all the values in a list into a new list is so common in programming that there is a special syntax for it in python, the list comprehension.\n"
276 | ]
277 | },
278 | {
279 | "cell_type": "code",
280 | "execution_count": null,
281 | "metadata": {
282 | "collapsed": true
283 | },
284 | "outputs": [],
285 | "source": [
286 | "list_ = [value*3-1 for value in range(5)]\n",
287 | "list_"
288 | ]
289 | },
290 | {
291 | "cell_type": "markdown",
292 | "metadata": {},
293 | "source": [
294 | "It is not necessary to use list comprehensions but they are mentioned so they can be understood if discovered in other programs.\n",
295 | "\n",
296 | "Part of the Zen of Python says\n",
297 | "\n",
298 | " There should be one-- and preferably only one --obvious way to do it.\n",
299 | " Although that way may not be obvious at first unless you're Dutch.\n",
300 | " \n",
301 | "List comprehensions are the one and obvious way to do these kinds of operations so they are presented even though they may be considered \"advanced\" syntax.\n",
302 | "\n",
303 | "There is also possibility to add a simple test to the statement."
304 | ]
305 | },
306 | {
307 | "cell_type": "code",
308 | "execution_count": null,
309 | "metadata": {
310 | "collapsed": true
311 | },
312 | "outputs": [],
313 | "source": [
314 | "list_2 = [value*3-1 for value in range(10) if value % 2 == 0] #only take even numbers\n",
315 | "list_2"
316 | ]
317 | },
318 | {
319 | "cell_type": "markdown",
320 | "metadata": {},
321 | "source": [
322 | "**Note:** List comprehensions always create the entire list in memory. When handling large amounts of data or in an environment with limited memory it's often a good idea to avoid creating large data structures in memory.\n",
323 | "\n",
324 | "In Python a language feature called **generators** helps you do this. There is extra material about this in another notebook."
325 | ]
326 | },
327 | {
328 | "cell_type": "markdown",
329 | "metadata": {},
330 | "source": [
331 | "## Exercises"
332 | ]
333 | },
334 | {
335 | "cell_type": "markdown",
336 | "metadata": {},
337 | "source": [
338 | "See under ../exercises/"
339 | ]
340 | }
341 | ],
342 | "metadata": {
343 | "kernelspec": {
344 | "display_name": "Python 3",
345 | "language": "python",
346 | "name": "python3"
347 | },
348 | "language_info": {
349 | "codemirror_mode": {
350 | "name": "ipython",
351 | "version": 3
352 | },
353 | "file_extension": ".py",
354 | "mimetype": "text/x-python",
355 | "name": "python",
356 | "nbconvert_exporter": "python",
357 | "pygments_lexer": "ipython3",
358 | "version": "3.4.9"
359 | }
360 | },
361 | "nbformat": 4,
362 | "nbformat_minor": 2
363 | }
364 |
--------------------------------------------------------------------------------
/notebooks/examples/3 - Functions.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Functions\n"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "## Functions and function arguments\n",
15 | "\n",
16 | "Functions are the building blocks of writing software. If a function is associated with an object and it's data, it is called a method. \n",
17 | "\n",
18 | "Functions are defined using the keyword ``def``.\n",
19 | "\n",
20 | "There are two types of arguments\n",
21 | "* regular arguments, which must always be given when calling the function\n",
22 | "* keyword arguments, that have a default value that can be overriden if desired\n",
23 | "\n",
24 | "Values are returned using the ``return`` keyword. If not ``return`` is defined, the default return value of all functions and methods is **None**, which is the null object in Python."
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": null,
30 | "metadata": {
31 | "collapsed": true
32 | },
33 | "outputs": [],
34 | "source": [
35 | "def my_function(arg_one, arg_two, optional_1=6, optional_2=\"seven\"):\n",
36 | " return \" \".join([str(arg_one), str(arg_two), str(optional_1), str(optional_2)])\n",
37 | "\n",
38 | "print(my_function(\"a\", \"b\"))\n",
39 | "print(my_function(\"a\", \"b\", optional_2=\"eight\"))\n",
40 | "\n",
41 | "#go ahead and try out different components"
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "metadata": {},
47 | "source": [
48 | "Python has special syntax for catching an arbitary number of parameters. For regular parameters it is a variable with one asterisk \\* and for keyword parameters it is a variable with two asterisks. It is conventional to name these ``*args`` and ``**kwargs``, but this is not required."
49 | ]
50 | },
51 | {
52 | "cell_type": "code",
53 | "execution_count": null,
54 | "metadata": {
55 | "collapsed": true
56 | },
57 | "outputs": [],
58 | "source": [
59 | "def count_args(*args, **kwargs):\n",
60 | " print(\"i was called with \" + str(len(args)) + \" arguments and \" + str(len(kwargs)) + \" keyword arguments\")\n",
61 | " \n",
62 | "count_args(1, 2, 3, 4, 5, foo=1, bar=2)"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "The length of sequences can be checked using the built-in **len()** function.\n"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "It is standard practice to document a function using **docstrings**. A docstring is just a simple triple-quoted string immediately after the function definition. It is also possible to have docstrings in the beginning of a source code file and after a class definition."
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "metadata": {
83 | "collapsed": true
84 | },
85 | "outputs": [],
86 | "source": [
87 | "def random():\n",
88 | " \"\"\"\n",
89 | " Always the number 4. \n",
90 | " Chosen by fair dice roll. Guaranteed to be random.\n",
91 | " \"\"\"\n",
92 | " return 4"
93 | ]
94 | },
95 | {
96 | "cell_type": "markdown",
97 | "metadata": {},
98 | "source": [
99 | "#### Functions as parameters\n",
100 | "\n",
101 | "Functions are first-class citizens in Python, which means that they can be e.g. passed to other functions. This is the first step into the world of functional programming, an elegant weapon for a more civilized age."
102 | ]
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": null,
107 | "metadata": {
108 | "collapsed": true
109 | },
110 | "outputs": [],
111 | "source": [
112 | "def print_dashes():\n",
113 | " print(\"---\")\n",
114 | " \n",
115 | "def print_asterisks():\n",
116 | " print(\"***\")\n",
117 | " \n",
118 | "def pretty_print(string, function):\n",
119 | " function()\n",
120 | " print(string)\n",
121 | " function()\n",
122 | " \n",
123 | "pretty_print(\"hello\", print_dashes)\n",
124 | "pretty_print(\"hey\", print_asterisks)"
125 | ]
126 | },
127 | {
128 | "cell_type": "markdown",
129 | "metadata": {},
130 | "source": [
131 | "### Extra: Lambda\n",
132 | "\n",
133 | "When we use the keyword `def` we are making a named function. Sometimes we want a simple function to use once without without binding it to any name.\n",
134 | "\n",
135 | "\n",
136 | "Consider the following data structure."
137 | ]
138 | },
139 | {
140 | "cell_type": "code",
141 | "execution_count": null,
142 | "metadata": {
143 | "collapsed": true
144 | },
145 | "outputs": [],
146 | "source": [
147 | "dictionaries = [\n",
148 | " {\"name\": \"Jack\", \"age\": 35, \"telephone\": \"555-1234\"},\n",
149 | " {\"name\": \"Jane\", \"age\": 40, \"telephone\": \"555-3331\"},\n",
150 | " {\"name\": \"Joe\", \"age\": 20, \"telephone\": \"555-8765\"}\n",
151 | "]"
152 | ]
153 | },
154 | {
155 | "cell_type": "markdown",
156 | "metadata": {},
157 | "source": [
158 | "Now if we want to sort it using Python's built-in `sort()` function the sort won't know which attribute to base the sorting on.\n",
159 | "\n",
160 | "Fortunately the `sort()` function takes a named parameter called `key` which is a function to be called on each item in the list. The return value will be used for the name.\n",
161 | "\n",
162 | "(Python's `sort()` sorts the list in-place. If you want to keep the list unmodified use `sorted()`)"
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "execution_count": null,
168 | "metadata": {
169 | "collapsed": true
170 | },
171 | "outputs": [],
172 | "source": [
173 | "def get_age(x):\n",
174 | " return x[\"age\"]\n",
175 | "\n",
176 | "dictionaries.sort(key=get_age)\n",
177 | "dictionaries"
178 | ]
179 | },
180 | {
181 | "cell_type": "markdown",
182 | "metadata": {},
183 | "source": [
184 | "This is all nice and well, but now you have a function called get_age that you don't intend to use a second time.\n",
185 | "\n",
186 | "An alternative way to give this would be using a lambda expression. "
187 | ]
188 | },
189 | {
190 | "cell_type": "code",
191 | "execution_count": null,
192 | "metadata": {
193 | "collapsed": true
194 | },
195 | "outputs": [],
196 | "source": [
197 | "dictionaries.sort(key=lambda x: x[\"age\"], reverse=True)\n",
198 | "dictionaries"
199 | ]
200 | },
201 | {
202 | "cell_type": "markdown",
203 | "metadata": {},
204 | "source": [
205 | "The keyword `lambda` is followed by one or more names of parameters, in this case just the one x. The colon separates the the function definition from the function and a `return` is implied.\n",
206 | "\n",
207 | "The lambda expression and the get_age function do the exact same thing.\n",
208 | "\n"
209 | ]
210 | }
211 | ],
212 | "metadata": {
213 | "kernelspec": {
214 | "display_name": "Python 3",
215 | "language": "python",
216 | "name": "python3"
217 | },
218 | "language_info": {
219 | "codemirror_mode": {
220 | "name": "ipython",
221 | "version": 3
222 | },
223 | "file_extension": ".py",
224 | "mimetype": "text/x-python",
225 | "name": "python",
226 | "nbconvert_exporter": "python",
227 | "pygments_lexer": "ipython3",
228 | "version": "3.4.9"
229 | }
230 | },
231 | "nbformat": 4,
232 | "nbformat_minor": 2
233 | }
234 |
--------------------------------------------------------------------------------
/notebooks/examples/4 - Modules.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Modules"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "## Modules and importing\n",
15 | "\n",
16 | "Python projects are structured into modules. \n",
17 | "\n",
18 | "There are a plethora of modules available in the [Python standard library](https://docs.python.org/3/library/). Those are always available to you but you must import them.\n",
19 | "\n",
20 | "Of course, you must also be aware of the fact that such a module exists. It is usually beneficial to be a bit lazy and assume someone has already solved your problem. Most of the time someone already has!"
21 | ]
22 | },
23 | {
24 | "cell_type": "code",
25 | "execution_count": null,
26 | "metadata": {
27 | "collapsed": true
28 | },
29 | "outputs": [],
30 | "source": [
31 | "import math\n",
32 | "\n",
33 | "def circle_circumference(r):\n",
34 | " return 2*math.pi*r\n",
35 | "\n",
36 | "circle_circumference(3)"
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "metadata": {},
42 | "source": [
43 | "At it's simplest a module can just be a python file.\n",
44 | "\n",
45 | "\n",
46 | "Let's create a file called mymodule.py in using jupyter (New -> Text File). Make sure to create the file in the same directory as this notebook. Edit the contents of the file to be:\n",
47 | "\n",
48 | "```\n",
49 | "def fancy_function(x):\n",
50 | " return x + x\n",
51 | "```\n",
52 | "\n",
53 | "And save the file.\n",
54 | "\n",
55 | "Now you can"
56 | ]
57 | },
58 | {
59 | "cell_type": "code",
60 | "execution_count": null,
61 | "metadata": {
62 | "collapsed": true
63 | },
64 | "outputs": [],
65 | "source": [
66 | "from mymodule import fancy_function\n",
67 | "\n",
68 | "print(fancy_function(1))\n",
69 | "print(fancy_function(\"hi\"))"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "Modules can also have more structure in them. To make a directory a module, you must place a special file, called **__init__.py** in the directory.\n",
77 | "\n",
78 | "```\n",
79 | "main.py\n",
80 | "bigmodule/\n",
81 | " __init__.py\n",
82 | " module_a.py\n",
83 | " module_b.py\n",
84 | "```\n",
85 | "Now in main.py, you could ``import bigmodule.module_a``.\n",
86 | "\n",
87 | "It is also possible to import only a single member from a module, like a variable or a fuction."
88 | ]
89 | },
90 | {
91 | "cell_type": "code",
92 | "execution_count": null,
93 | "metadata": {},
94 | "outputs": [],
95 | "source": [
96 | "from math import exp\n",
97 | "\n",
98 | "print(exp(1)) # which exponent is this\n",
99 | "\n",
100 | "def circle_area(r):\n",
101 | " if r < 0:\n",
102 | " return 0\n",
103 | " else:\n",
104 | " # you can also import inside functions or other code blocks\n",
105 | " from math import pi\n",
106 | " return pi*r*r\n",
107 | "print(circle_area(2))"
108 | ]
109 | },
110 | {
111 | "cell_type": "markdown",
112 | "metadata": {},
113 | "source": [
114 | "Whether to import the entire module or only what you need depends on your circumstances and how the module has been designed to be used. It's usually good to pick a practice inside a project and stick to it."
115 | ]
116 | },
117 | {
118 | "cell_type": "markdown",
119 | "metadata": {},
120 | "source": [
121 | "## Exercises\n",
122 | "\n",
123 | "See ../exercises/"
124 | ]
125 | }
126 | ],
127 | "metadata": {
128 | "kernelspec": {
129 | "display_name": "Python 3",
130 | "language": "python",
131 | "name": "python3"
132 | },
133 | "language_info": {
134 | "codemirror_mode": {
135 | "name": "ipython",
136 | "version": 3
137 | },
138 | "file_extension": ".py",
139 | "mimetype": "text/x-python",
140 | "name": "python",
141 | "nbconvert_exporter": "python",
142 | "pygments_lexer": "ipython3",
143 | "version": "3.4.9"
144 | }
145 | },
146 | "nbformat": 4,
147 | "nbformat_minor": 1
148 | }
149 |
--------------------------------------------------------------------------------
/notebooks/examples/5.2 Strings.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Strings\n",
8 | "\n",
9 | "The most major difference between Python versions 2 and 3 is in string handling. \n",
10 | "\n",
11 | "In Python 3 all strings are by default Unicode strings. The Python interpreter expects Python source files to be UTF-8 encoded Unicode strings.\n",
12 | "\n",
13 | "What Unicode is beyond the scope of this course, but you can check\n",
14 | "* [the Python documentation](https://docs.python.org/3/howto/unicode.html)\n",
15 | "* [the Wikipedia article on Unicode](https://docs.python.org/3/howto/unicode.html)\n",
16 | "* [the Unicode consortium home pages](http://www.unicode.org/)\n",
17 | "* your resident programmer (warning: you may be in for along monologue)\n",
18 | "\n",
19 | "If you don't what Unicode or encodings are, do not despair. You will find out if you need to find out and people have lived their entire lives happily without knowing what encodings are.\n",
20 | "\n",
21 | "Suffice to say that it is safe to use Unicode characters in strings and in variable names in Python 3."
22 | ]
23 | },
24 | {
25 | "cell_type": "code",
26 | "execution_count": null,
27 | "metadata": {
28 | "collapsed": false
29 | },
30 | "outputs": [],
31 | "source": [
32 | "ananasakäämä = \"höhö 电脑\"\n",
33 | "print(ananasakäämä)"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "## Extra material\n",
41 | "\n",
42 | "If you want to represent a character that for some reason you can't enter in your system or if you want to keep your source code ASCII-only (not necessarily a bad idea) you can enter non-ASCII characters "
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": null,
48 | "metadata": {
49 | "collapsed": false
50 | },
51 | "outputs": [],
52 | "source": [
53 | "print(\"\\N{GREEK CAPITAL LETTER DELTA}\") # using the character name\n",
54 | "print(\"\\u0394\") # using a 16-bit hex value\n",
55 | "print(\"\\U00000394\") # using a 32-bit hex value"
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "If you have a bytes-object you can call the ``decode()`` method on it and give an encoding as an argument. Conversely you can ``encode()`` a string. \n"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "## Creating Strings\n",
70 | "\n",
71 | "Both single '' and double \"\" quotes denote a string. They are equally valid and it is a question of preference which to use. It is recommended to be consistent within the same file, though.\n",
72 | "\n",
73 | "It is permissible to use single quotes inside a double-quoted string or double quotes inside a single quoted string.\n",
74 | "\n",
75 | "If you want to have the same kind of quotes inside a string, you must **escape** the quotes in the string with a backslash \\\\. As it is the escape character, any backslashes must be entered as double \\\\\\\\ to create a single literal backslash in a string."
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": null,
81 | "metadata": {
82 | "collapsed": false
83 | },
84 | "outputs": [],
85 | "source": [
86 | "permissible = \"la'l'a'a\"\n",
87 | "print(permissible)\n",
88 | "permissible = 'la\"l\"a\"a'\n",
89 | "print(permissible)\n",
90 | "permissible = \"\\\"i am a quote \\\\ \\\"\"\n",
91 | "print(permissible)"
92 | ]
93 | },
94 | {
95 | "cell_type": "markdown",
96 | "metadata": {},
97 | "source": [
98 | "There are several ways to create multiline strings\n",
99 | "* multiline string notation using triple quotes\n",
100 | "* having multiple consecutive string literals inside parentheses, they will be interpreted as one"
101 | ]
102 | },
103 | {
104 | "cell_type": "code",
105 | "execution_count": null,
106 | "metadata": {
107 | "collapsed": false
108 | },
109 | "outputs": [],
110 | "source": [
111 | "permissible = \"\"\"\n",
112 | "i am a multi\n",
113 | "line\n",
114 | "string\n",
115 | "\"\"\"\n",
116 | "print(permissible)"
117 | ]
118 | },
119 | {
120 | "cell_type": "code",
121 | "execution_count": null,
122 | "metadata": {
123 | "collapsed": false
124 | },
125 | "outputs": [],
126 | "source": [
127 | "permissible = (\"i\"\n",
128 | " \" am\" #note the whitespace before the word inside the string\n",
129 | " ' a'\n",
130 | " \" multiline\"\n",
131 | " ' string')\n",
132 | "print(permissible)"
133 | ]
134 | },
135 | {
136 | "cell_type": "markdown",
137 | "metadata": {},
138 | "source": [
139 | "## String wrangling\n",
140 | "\n",
141 | "First it is essential to remember that strings are immutable: whatever you do with a string, it will not change. Most methods on strings will return a new, modified string or some other object.\n",
142 | "\n",
143 | "If you have any programming experience many of the following examples will seem familiar to you.\n",
144 | "\n",
145 | "A complete list can, as always be found at the [documentation](https://docs.python.org/3/library/stdtypes.html#string-methods)."
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": null,
151 | "metadata": {
152 | "collapsed": true
153 | },
154 | "outputs": [],
155 | "source": [
156 | "example = \"The quick brown fox jumps over the lazy dog \""
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "metadata": {
163 | "collapsed": false
164 | },
165 | "outputs": [],
166 | "source": [
167 | "## the split function splits at whitespace by default\n",
168 | "example.split()"
169 | ]
170 | },
171 | {
172 | "cell_type": "markdown",
173 | "metadata": {},
174 | "source": [
175 | "It can be given any parameter. Te return value is a list so it can be indexed with []."
176 | ]
177 | },
178 | {
179 | "cell_type": "code",
180 | "execution_count": null,
181 | "metadata": {
182 | "collapsed": false
183 | },
184 | "outputs": [],
185 | "source": [
186 | "example.split(\"e\")[0]"
187 | ]
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "metadata": {},
192 | "source": [
193 | "Strings can be indexed and sliced using the same notation as lists"
194 | ]
195 | },
196 | {
197 | "cell_type": "code",
198 | "execution_count": null,
199 | "metadata": {
200 | "collapsed": false
201 | },
202 | "outputs": [],
203 | "source": [
204 | "example[5:10]"
205 | ]
206 | },
207 | {
208 | "cell_type": "markdown",
209 | "metadata": {},
210 | "source": [
211 | "The ``strip()`` function removes the first and last instances of a character from the string, defaulting to whitespace. This is surprisingly often needed."
212 | ]
213 | },
214 | {
215 | "cell_type": "code",
216 | "execution_count": null,
217 | "metadata": {
218 | "collapsed": false
219 | },
220 | "outputs": [],
221 | "source": [
222 | "example.strip()"
223 | ]
224 | },
225 | {
226 | "cell_type": "markdown",
227 | "metadata": {},
228 | "source": [
229 | "Strings can be coerced to ``lower()`` or ``upper()`` case."
230 | ]
231 | },
232 | {
233 | "cell_type": "code",
234 | "execution_count": null,
235 | "metadata": {
236 | "collapsed": false
237 | },
238 | "outputs": [],
239 | "source": [
240 | "example.upper()"
241 | ]
242 | },
243 | {
244 | "cell_type": "markdown",
245 | "metadata": {},
246 | "source": [
247 | "Seeking a substring is also implemented with the ``find()`` method. It returns an index."
248 | ]
249 | },
250 | {
251 | "cell_type": "code",
252 | "execution_count": null,
253 | "metadata": {
254 | "collapsed": false
255 | },
256 | "outputs": [],
257 | "source": [
258 | "example.find(\"ick\")"
259 | ]
260 | },
261 | {
262 | "cell_type": "markdown",
263 | "metadata": {},
264 | "source": [
265 | "Sometimes it's important to know if a string is a digit or numeric."
266 | ]
267 | },
268 | {
269 | "cell_type": "code",
270 | "execution_count": null,
271 | "metadata": {
272 | "collapsed": false
273 | },
274 | "outputs": [],
275 | "source": [
276 | "\"124\".isdigit()"
277 | ]
278 | },
279 | {
280 | "cell_type": "markdown",
281 | "metadata": {},
282 | "source": []
283 | }
284 | ],
285 | "metadata": {
286 | "kernelspec": {
287 | "display_name": "Python 3",
288 | "language": "python",
289 | "name": "python3"
290 | },
291 | "language_info": {
292 | "codemirror_mode": {
293 | "name": "ipython",
294 | "version": 3
295 | },
296 | "file_extension": ".py",
297 | "mimetype": "text/x-python",
298 | "name": "python",
299 | "nbconvert_exporter": "python",
300 | "pygments_lexer": "ipython3",
301 | "version": "3.5.2"
302 | }
303 | },
304 | "nbformat": 4,
305 | "nbformat_minor": 2
306 | }
307 |
--------------------------------------------------------------------------------
/notebooks/examples/6 - Objects.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Objects\n",
8 | "\n",
9 | "An object is a combination of data and methods associated with the data. \n",
10 | "\n",
11 | "Here's a concrete example with docstrings explaining what goes on in each part.\n"
12 | ]
13 | },
14 | {
15 | "cell_type": "code",
16 | "execution_count": null,
17 | "metadata": {},
18 | "outputs": [],
19 | "source": [
20 | "class Student(object):\n",
21 | " \"\"\"\n",
22 | " The above states that the code-block (indented area) below will define a \n",
23 | " class Student, that derives from a class called 'object'. Inheriting from 'object' is S\n",
24 | " \n",
25 | " \"\"\"\n",
26 | " \n",
27 | " def __init__(self, name, birthyear, interest=None):\n",
28 | " \"\"\"__init__ is special method that is called when instantiating the object. \n",
29 | " Typically the methods can then be used to \"\"\"\n",
30 | " self.name = name\n",
31 | " self.birthyear = birthyear\n",
32 | " self.interest = interest\n",
33 | " \n",
34 | " def say_hi(self):\n",
35 | " \"\"\" This is a classical example of a function that prints something. \n",
36 | " The more complex your system, the less likely it is that it is a good idea to print anything other than \n",
37 | " warnings from whithin your classes.\"\"\"\n",
38 | " if not self.interest:\n",
39 | " print(\"Hi, my name is \" + self.name + \"!\")\n",
40 | " else:\n",
41 | " print(\"Hi, my name is \" + self.name + \" and I'm interested in \" + self.interest + \".\")\n",
42 | " \n",
43 | " def get_age(self):\n",
44 | " \"\"\" This is a much more style-pure example of classes. \n",
45 | " Recording a birthyear instead of age is a good idea because next year we'll all be a year older.\n",
46 | " However requiring everyone who uses your class is impolite and would lead to duplicate code. \n",
47 | " Doing it once and asking everyone to use that implementation reduces code complexity and improves \n",
48 | " maintainability.\n",
49 | " \"\"\"\n",
50 | " import datetime\n",
51 | " return datetime.datetime.now().year-self.birthyear"
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {},
57 | "source": [
58 | "The above construct is a class, which is to say a model for creating objects.\n",
59 | "\n",
60 | "To create an object we say we instantiate a class."
61 | ]
62 | },
63 | {
64 | "cell_type": "code",
65 | "execution_count": null,
66 | "metadata": {},
67 | "outputs": [],
68 | "source": [
69 | "jyry = Student(\"Jyry\", 1984, interest=\"Python\")"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "Now we have an object called \"jyry\", which has the value\n",
77 | "s listed above. We can call methods of the object and access the variables associated with the object."
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "execution_count": null,
83 | "metadata": {},
84 | "outputs": [],
85 | "source": [
86 | "jyry.say_hi()"
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": null,
92 | "metadata": {},
93 | "outputs": [],
94 | "source": [
95 | "print(jyry.birthyear)"
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "metadata": {},
101 | "source": [
102 | "One can create multiple objects that all have their own identity, even though they share some variables."
103 | ]
104 | },
105 | {
106 | "cell_type": "code",
107 | "execution_count": null,
108 | "metadata": {},
109 | "outputs": [],
110 | "source": [
111 | "tuomas = Student(\"Tuomas\", 1984, interest=\"Java\")\n",
112 | "tuomas.say_hi()\n"
113 | ]
114 | },
115 | {
116 | "cell_type": "markdown",
117 | "metadata": {},
118 | "source": [
119 | "Typically object comparison is done using the same syntax as for basic types (which, by the way are objects too in Python).\n",
120 | "\n",
121 | "If you want to implement special logic for comparisons in your own classes, look up **magic methods** either online or in another part of this introduction. It is a very common task and helps people who use your code (i.e. you)."
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": null,
127 | "metadata": {},
128 | "outputs": [],
129 | "source": [
130 | "tuomas == jyry"
131 | ]
132 | },
133 | {
134 | "cell_type": "markdown",
135 | "metadata": {},
136 | "source": [
137 | "Python permits the programmer to edit objects without any access control mechanics. See for example."
138 | ]
139 | },
140 | {
141 | "cell_type": "code",
142 | "execution_count": null,
143 | "metadata": {},
144 | "outputs": [],
145 | "source": [
146 | "jyry.interest = \"teaching\"\n",
147 | "jyry.say_hi()"
148 | ]
149 | },
150 | {
151 | "cell_type": "markdown",
152 | "metadata": {},
153 | "source": [
154 | "## Figuring out an object\n",
155 | "\n",
156 | "Opening a file using the `open` method returns an object."
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "metadata": {},
163 | "outputs": [],
164 | "source": [
165 | "fobj = open(\"../data/grep.txt\")"
166 | ]
167 | },
168 | {
169 | "cell_type": "markdown",
170 | "metadata": {},
171 | "source": [
172 | "How can we find things out about this object? Below are a few examples:\n",
173 | "\n",
174 | "* printing calls the `__str__()`-method of the object, which should return a (more or less) human-readable definition of the object\n",
175 | "* `dir()` lists the attributes of an object, that is to say functions and variables associated with it\n",
176 | "* the `help`-function attempts to find the docstring for your function\n",
177 | "* the `__doc__` attribute of object members contains the docstring if available to the interpreter\n",
178 | "\n",
179 | "This list is not comprehensive."
180 | ]
181 | },
182 | {
183 | "cell_type": "code",
184 | "execution_count": null,
185 | "metadata": {},
186 | "outputs": [],
187 | "source": [
188 | "print(fobj)"
189 | ]
190 | },
191 | {
192 | "cell_type": "code",
193 | "execution_count": null,
194 | "metadata": {},
195 | "outputs": [],
196 | "source": [
197 | "dir(fobj)"
198 | ]
199 | },
200 | {
201 | "cell_type": "code",
202 | "execution_count": null,
203 | "metadata": {},
204 | "outputs": [],
205 | "source": [
206 | "help(jyry.say_hi)"
207 | ]
208 | },
209 | {
210 | "cell_type": "code",
211 | "execution_count": null,
212 | "metadata": {},
213 | "outputs": [],
214 | "source": [
215 | "jyry.say_hi.__doc__"
216 | ]
217 | },
218 | {
219 | "cell_type": "markdown",
220 | "metadata": {},
221 | "source": [
222 | "## Exceptions\n",
223 | "\n",
224 | "In Python, exceptions are lightweight, i.e. handling them doesn't cause a notable decrease in performance as happens in some languages.\n",
225 | "\n",
226 | "The purpose of exceptions is to communicate that something didn't go right. The name of the exception typically tells what kind of error ocurred and the exception can also contain a more explicit message."
227 | ]
228 | },
229 | {
230 | "cell_type": "code",
231 | "execution_count": null,
232 | "metadata": {
233 | "collapsed": true
234 | },
235 | "outputs": [],
236 | "source": [
237 | "class Container(object):\n",
238 | " \n",
239 | " def __init__(self):\n",
240 | " self.bag = {}\n",
241 | " \n",
242 | " def put(self, key, item):\n",
243 | " self.bag[key] = item\n",
244 | " \n",
245 | " def get(self, key):\n",
246 | " return self.bag[key]"
247 | ]
248 | },
249 | {
250 | "cell_type": "markdown",
251 | "metadata": {},
252 | "source": [
253 | "The container-class can exhibit at least two different exceptions."
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": null,
259 | "metadata": {},
260 | "outputs": [],
261 | "source": [
262 | "container = Container()\n",
263 | "container.put([1, 2, 3], \"example\")"
264 | ]
265 | },
266 | {
267 | "cell_type": "code",
268 | "execution_count": null,
269 | "metadata": {},
270 | "outputs": [],
271 | "source": [
272 | "container.get(\"not_in_it\")"
273 | ]
274 | },
275 | {
276 | "cell_type": "markdown",
277 | "metadata": {},
278 | "source": [
279 | "Who should worry about the various issues is a good philosophical question. We could either make the Container-class secure in that it doesn't raise any errors to whoever calls it or we could let the caller worry about such errors.\n",
280 | "\n",
281 | "For now let's assume that the programmer is competent and knows what is a valid key and what isn't."
282 | ]
283 | },
284 | {
285 | "cell_type": "code",
286 | "execution_count": null,
287 | "metadata": {},
288 | "outputs": [],
289 | "source": [
290 | "try:\n",
291 | " container = Container()\n",
292 | " container.put([1,2,3], \"value\")\n",
293 | "except TypeError as err:\n",
294 | " print(\"Stupid programmer caused an error: \" + str(err))"
295 | ]
296 | },
297 | {
298 | "cell_type": "markdown",
299 | "metadata": {},
300 | "source": [
301 | "A try-except may contain a ``finally``block, which is always guaranteed to execute.\n",
302 | "\n",
303 | "Also, it is permissible to catch multiple different errors."
304 | ]
305 | },
306 | {
307 | "cell_type": "code",
308 | "execution_count": null,
309 | "metadata": {},
310 | "outputs": [],
311 | "source": [
312 | "try:\n",
313 | " container = Container()\n",
314 | " container.put(3, \"value\")\n",
315 | " container.get(3)\n",
316 | "except TypeError as err:\n",
317 | " print(\"Stupid programmer caused an error: \" + str(err))\n",
318 | "except KeyError as err:\n",
319 | " print(\"Stupid programmer caused another error: \" + str(err))\n",
320 | "finally:\n",
321 | " print(\"all is well in the end\")\n",
322 | " \n",
323 | "# go ahead, make changes that cause one of the exceptions to be raised"
324 | ]
325 | },
326 | {
327 | "cell_type": "markdown",
328 | "metadata": {},
329 | "source": [
330 | "There is also syntax for catching multiple error types in the same catch clause.\n",
331 | "\n",
332 | "The keyword ``raise`` is used to continue error handling. This is useful if you want to log errors but let them pass onward anyway.\n",
333 | "\n",
334 | "A ``raise`` without arguments will re-raise the error that was being handled."
335 | ]
336 | },
337 | {
338 | "cell_type": "code",
339 | "execution_count": null,
340 | "metadata": {},
341 | "outputs": [],
342 | "source": [
343 | "try:\n",
344 | " container = Container()\n",
345 | " container.put(3, \"value\")\n",
346 | " container.get(5)\n",
347 | "except (TypeError, KeyError) as err:\n",
348 | " print(\"please shoot me\")\n",
349 | " if type(err) == TypeError:\n",
350 | " raise Exception(\"That's it I quit!\")\n",
351 | " else:\n",
352 | " raise"
353 | ]
354 | }
355 | ],
356 | "metadata": {
357 | "kernelspec": {
358 | "display_name": "Python 3",
359 | "language": "python",
360 | "name": "python3"
361 | },
362 | "language_info": {
363 | "codemirror_mode": {
364 | "name": "ipython",
365 | "version": 3
366 | },
367 | "file_extension": ".py",
368 | "mimetype": "text/x-python",
369 | "name": "python",
370 | "nbconvert_exporter": "python",
371 | "pygments_lexer": "ipython3",
372 | "version": "3.4.9"
373 | }
374 | },
375 | "nbformat": 4,
376 | "nbformat_minor": 1
377 | }
378 |
--------------------------------------------------------------------------------
/notebooks/examples/8 - Pandas.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Pandas and data wrangling\n",
8 | "\n",
9 | "Pandas is a tool for accessing columnar data, like that in SQL tables or CSV files."
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "metadata": {
16 | "collapsed": false
17 | },
18 | "outputs": [],
19 | "source": [
20 | "# convention recommended in documentation\n",
21 | "import pandas as pd\n",
22 | "import numpy as np\n",
23 | "\n",
24 | "import matplotlib.pyplot as plt\n",
25 | "\n",
26 | "#enable inline plotting in notebook\n",
27 | "\n",
28 | "%matplotlib inline\n"
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "metadata": {},
34 | "source": [
35 | "Let's start by reading in a dataset. This dataset is about different subclasses of the iris flower.\n",
36 | "\n",
37 | "We'll use it for another exercise later on."
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": null,
43 | "metadata": {
44 | "collapsed": false
45 | },
46 | "outputs": [],
47 | "source": [
48 | "df = pd.read_csv(\"../data/iris.data\")\n",
49 | "df = df.sample(frac=0.2) # only use 20% of the data so the results aren't so long\n",
50 | "type(df)"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {},
56 | "source": [
57 | "DataFrame is the basic building block of Pandas. It represents two-dimensional data with labeled rows and columns. \n",
58 | "\n"
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": null,
64 | "metadata": {
65 | "collapsed": false
66 | },
67 | "outputs": [],
68 | "source": [
69 | "# Columns can have different types.\n",
70 | "# you can check the data types of the values\n",
71 | "df.dtypes"
72 | ]
73 | },
74 | {
75 | "cell_type": "code",
76 | "execution_count": null,
77 | "metadata": {
78 | "collapsed": false
79 | },
80 | "outputs": [],
81 | "source": [
82 | "# you can access the dataframe with a single column name\n",
83 | "df[\"petal.width\"]\n",
84 | "# this leaves the original unmodified"
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": null,
90 | "metadata": {
91 | "collapsed": false,
92 | "scrolled": true
93 | },
94 | "outputs": [],
95 | "source": [
96 | "# then the returned type is a Series, the second major concept in Pandas\n",
97 | "type(df[\"petal.width\"])"
98 | ]
99 | },
100 | {
101 | "cell_type": "code",
102 | "execution_count": null,
103 | "metadata": {
104 | "collapsed": true
105 | },
106 | "outputs": [],
107 | "source": [
108 | "# "
109 | ]
110 | },
111 | {
112 | "cell_type": "code",
113 | "execution_count": null,
114 | "metadata": {
115 | "collapsed": false
116 | },
117 | "outputs": [],
118 | "source": [
119 | "# alternately you can index a dataframe with a list of column names\n",
120 | "df[[\"sepal.length\", \"petal.width\", \"class\"]]"
121 | ]
122 | },
123 | {
124 | "cell_type": "code",
125 | "execution_count": null,
126 | "metadata": {
127 | "collapsed": false
128 | },
129 | "outputs": [],
130 | "source": [
131 | "# the comparison operator returns a list of boolean \n",
132 | "matching = df[\"sepal.width\"] > df[\"petal.length\"]\n",
133 | "matching\n"
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": null,
139 | "metadata": {
140 | "collapsed": false
141 | },
142 | "outputs": [],
143 | "source": [
144 | "# which can also be used to query the dataframe\n",
145 | "df[list_]\n",
146 | "\n",
147 | "# or more idiomatically\n",
148 | "\n",
149 | "df[df[\"sepal.width\"] > df[\"petal.length\"]]"
150 | ]
151 | },
152 | {
153 | "cell_type": "code",
154 | "execution_count": null,
155 | "metadata": {
156 | "collapsed": false
157 | },
158 | "outputs": [],
159 | "source": [
160 | "# one can get aggregates of single dimensions\n",
161 | "\n",
162 | "df[\"sepal.width\"].var() # try min, max, mean, median, sum, var"
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "execution_count": null,
168 | "metadata": {
169 | "collapsed": false
170 | },
171 | "outputs": [],
172 | "source": [
173 | "# or of the whole thing\n",
174 | "\n",
175 | "df.sum() # same operations as above"
176 | ]
177 | },
178 | {
179 | "cell_type": "code",
180 | "execution_count": null,
181 | "metadata": {
182 | "collapsed": false
183 | },
184 | "outputs": [],
185 | "source": [
186 | "# it's also possible to plot simple graphs using a simpleish syntax\n",
187 | "\n",
188 | "df[\"sepal.width\"].plot.box()"
189 | ]
190 | },
191 | {
192 | "cell_type": "code",
193 | "execution_count": null,
194 | "metadata": {
195 | "collapsed": false
196 | },
197 | "outputs": [],
198 | "source": [
199 | "df[\"sepal.width\"].plot.hist()"
200 | ]
201 | },
202 | {
203 | "cell_type": "code",
204 | "execution_count": null,
205 | "metadata": {
206 | "collapsed": false
207 | },
208 | "outputs": [],
209 | "source": [
210 | "df.boxplot(column=\"sepal.width\", by=\"class\")"
211 | ]
212 | },
213 | {
214 | "cell_type": "code",
215 | "execution_count": null,
216 | "metadata": {
217 | "collapsed": false
218 | },
219 | "outputs": [],
220 | "source": [
221 | "df.plot.scatter(x=\"sepal.length\", y=\"sepal.width\")"
222 | ]
223 | },
224 | {
225 | "cell_type": "code",
226 | "execution_count": null,
227 | "metadata": {
228 | "collapsed": false
229 | },
230 | "outputs": [],
231 | "source": [
232 | "df.groupby(\"class\").mean()"
233 | ]
234 | },
235 | {
236 | "cell_type": "code",
237 | "execution_count": null,
238 | "metadata": {
239 | "collapsed": false
240 | },
241 | "outputs": [],
242 | "source": [
243 | "# creating a grouped by plot requires a loop\n",
244 | "fig, ax = plt.subplots(figsize=(8,6))\n",
245 | "for label, df_ in df.groupby('class'):\n",
246 | " df_[\"sepal.length\"].plot(kind=\"kde\", ax=ax, label=label)\n",
247 | "plt.legend()"
248 | ]
249 | },
250 | {
251 | "cell_type": "markdown",
252 | "metadata": {},
253 | "source": [
254 | "## Exercises: Davis data set\n",
255 | "\n",
256 | "Read in the Davis data set of self reported heights and weights from \"../data/davis.data\"."
257 | ]
258 | },
259 | {
260 | "cell_type": "code",
261 | "execution_count": null,
262 | "metadata": {
263 | "collapsed": true
264 | },
265 | "outputs": [],
266 | "source": []
267 | },
268 | {
269 | "cell_type": "markdown",
270 | "metadata": {},
271 | "source": [
272 | "Plot box plots of the data. Is there a value that is off? "
273 | ]
274 | },
275 | {
276 | "cell_type": "code",
277 | "execution_count": null,
278 | "metadata": {
279 | "collapsed": true
280 | },
281 | "outputs": [],
282 | "source": []
283 | },
284 | {
285 | "cell_type": "markdown",
286 | "metadata": {},
287 | "source": [
288 | "How do you remove it?"
289 | ]
290 | }
291 | ],
292 | "metadata": {
293 | "kernelspec": {
294 | "display_name": "Python 3",
295 | "language": "python",
296 | "name": "python3"
297 | },
298 | "language_info": {
299 | "codemirror_mode": {
300 | "name": "ipython",
301 | "version": 3
302 | },
303 | "file_extension": ".py",
304 | "mimetype": "text/x-python",
305 | "name": "python",
306 | "nbconvert_exporter": "python",
307 | "pygments_lexer": "ipython3",
308 | "version": "3.5.2"
309 | }
310 | },
311 | "nbformat": 4,
312 | "nbformat_minor": 2
313 | }
314 |
--------------------------------------------------------------------------------
/notebooks/examples/9 - Object oriented programming.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Objects and exceptions"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "Object-oriented programming is a widespread paradigm that helps programmers create intuitive layers of abstraction. This example notebook is aimed at helping people along with the concepts of object-oriented programming and may require more time than is possible in a one-day workshop.\n",
15 | "\n",
16 | "In Python, classes are defined with the keyword ``class``. All classes should inherit either some other class or a base-class confusingly called ``object``.\n",
17 | "\n",
18 | "When a function is associated with a class, it is called a method."
19 | ]
20 | },
21 | {
22 | "cell_type": "code",
23 | "execution_count": null,
24 | "metadata": {
25 | "collapsed": true
26 | },
27 | "outputs": [],
28 | "source": [
29 | "class Vector2D(object):\n",
30 | " \"\"\"Represents a 2-dimensional vector\"\"\"\n",
31 | " \n",
32 | " def __init__(self, x, y):\n",
33 | " self.x = x\n",
34 | " self.y = y"
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {},
40 | "source": [
41 | "Typically classes are made to store some data that is logically related to a single entity. \n",
42 | "\n",
43 | "When a class is **instantiated**, i.e. given a set of values , the result of the action is an **object**."
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": null,
49 | "metadata": {
50 | "collapsed": false
51 | },
52 | "outputs": [],
53 | "source": [
54 | "vector1 = Vector2D(1,1)\n",
55 | "vector2 = Vector2D(0,0)\n",
56 | "type(vector1)(2, 3)"
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "metadata": {},
62 | "source": [
63 | "Object-oriented design can let programmers re-use code by inheriting other classes to extend their functionality.\n"
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": null,
69 | "metadata": {
70 | "collapsed": true
71 | },
72 | "outputs": [],
73 | "source": [
74 | "class AddableVector2D(Vector2D):\n",
75 | " \"\"\"Represents a 2D vector that can be added to another\"\"\"\n",
76 | " def add(self, another):\n",
77 | " return type(self)(self.x + another.x, self.y + another.y)"
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "execution_count": null,
83 | "metadata": {
84 | "collapsed": false
85 | },
86 | "outputs": [],
87 | "source": [
88 | "addvec1 = AddableVector2D(1,1)\n",
89 | "addvec2 = AddableVector2D(2,2)\n",
90 | "addvec3 = addvec1.add(addvec2)"
91 | ]
92 | },
93 | {
94 | "cell_type": "markdown",
95 | "metadata": {},
96 | "source": [
97 | "Python has plenty of so-called **magic methods** for classes. For instance, the ``__str__`` method defines how a vector is textually represented when you call it's str. The ``__repr__`` controls how the object is represented in the interpreter.\n"
98 | ]
99 | },
100 | {
101 | "cell_type": "code",
102 | "execution_count": null,
103 | "metadata": {
104 | "collapsed": false
105 | },
106 | "outputs": [],
107 | "source": [
108 | "class RepresentableVector2D(Vector2D):\n",
109 | " \"\"\" A vector that has textual representations\"\"\"\n",
110 | " \n",
111 | " def __str__(self):\n",
112 | " return \"Vector2D({},{})\".format(self.x, self.y)\n",
113 | " \n",
114 | " def __repr__(self):\n",
115 | " return str(self)"
116 | ]
117 | },
118 | {
119 | "cell_type": "code",
120 | "execution_count": null,
121 | "metadata": {
122 | "collapsed": false
123 | },
124 | "outputs": [],
125 | "source": [
126 | "rv1 = RepresentableVector2D(1, 2)\n",
127 | "print(str(rv1))\n",
128 | "rv1"
129 | ]
130 | },
131 | {
132 | "cell_type": "markdown",
133 | "metadata": {},
134 | "source": [
135 | "Python supports multiple inheritance. This is another very powerful tool, but can sometimes lead to confusion when the same function is defined in many classes. If this confuses you, the concept to look for is [Method Resolution Order](https://www.python.org/download/releases/2.3/mro/) . \n",
136 | "\n",
137 | "It is possible to call a parent class's methods using the keyword ``super``.\n",
138 | "\n",
139 | "Also, it is possible to define what regular operators do to a class."
140 | ]
141 | },
142 | {
143 | "cell_type": "code",
144 | "execution_count": null,
145 | "metadata": {
146 | "collapsed": true
147 | },
148 | "outputs": [],
149 | "source": [
150 | "class ExtendedVector2D(AddableVector2D, RepresentableVector2D):\n",
151 | " \"\"\" A vector that has several features\"\"\"\n",
152 | " \n",
153 | " def __str__(self):\n",
154 | " return \"Extended\" + super(ExtendedVector2D, self).__str__()\n",
155 | " \n",
156 | " # addition with +\n",
157 | " def __add__(self, other):\n",
158 | " return self.add(other)\n",
159 | " # negation with - prefix\n",
160 | " \n",
161 | " def __neg__(self):\n",
162 | " return type(self)(-self.x, -self.y)\n",
163 | " # subtraction with -\n",
164 | " \n",
165 | " def __sub__(self, other):\n",
166 | " return self + (-other)\n",
167 | " \n",
168 | " def __mul__(self, scalar):\n",
169 | " return type(self)(self.x*scalar, self.y*scalar)"
170 | ]
171 | },
172 | {
173 | "cell_type": "code",
174 | "execution_count": null,
175 | "metadata": {
176 | "collapsed": false
177 | },
178 | "outputs": [],
179 | "source": [
180 | "vec1 = ExtendedVector2D(1, 4)\n",
181 | "vec2 = vec1 * 0.5\n",
182 | "vec3 = vec1 - (vec2*3)\n",
183 | "vec3"
184 | ]
185 | },
186 | {
187 | "cell_type": "markdown",
188 | "metadata": {},
189 | "source": [
190 | "Observe that in most cases we don't check for the types of the arguments given. This is idiomatic Python and contrary to some other object-oriented languages.\n",
191 | "\n",
192 | " It is better to ask for forgiveness than permission"
193 | ]
194 | },
195 | {
196 | "cell_type": "markdown",
197 | "metadata": {},
198 | "source": [
199 | "Another powerful feature of classes is composability: you can abstract something to another level.\n",
200 | "\n",
201 | "Let's make a class to represent a very rough vector-based drawing."
202 | ]
203 | },
204 | {
205 | "cell_type": "code",
206 | "execution_count": null,
207 | "metadata": {
208 | "collapsed": true
209 | },
210 | "outputs": [],
211 | "source": [
212 | "class Drawing2D(object):\n",
213 | " def __init__(self, x=0, y=0, initial_vectors=None):\n",
214 | " self.x = x\n",
215 | " self.y = y\n",
216 | " self.vectors = initial_vectors if initial_vectors else []\n",
217 | " \n",
218 | " def add(self, vector):\n",
219 | " self.vectors.append(vector)\n",
220 | " \n",
221 | " def scale(self, scalar):\n",
222 | " self.vectors = [v*scalar for v in self.vectors]\n",
223 | " \n",
224 | " def __str__(self):\n",
225 | " output = \"start at {},{}.\\n\".format(self.x, self.y)\n",
226 | " for vector in self.vectors:\n",
227 | " output += \"draw vector {},{}\\n\".format(vector.x, vector.y)\n",
228 | " return output\n"
229 | ]
230 | },
231 | {
232 | "cell_type": "markdown",
233 | "metadata": {},
234 | "source": [
235 | "As in all Python one should be aware of when an operation changes the state of an object, like our drawing and when it returns a new object, like multiplying vectors with a scalar.\n",
236 | "\n",
237 | "Instead of text we could create a Scalable Vector Graphics (SVG) image using this class."
238 | ]
239 | },
240 | {
241 | "cell_type": "code",
242 | "execution_count": null,
243 | "metadata": {
244 | "collapsed": false
245 | },
246 | "outputs": [],
247 | "source": [
248 | "vectors = [vec1, vec2, vec3]\n",
249 | "drawing = Drawing2D(0,0, vectors)\n",
250 | "print(drawing)\n",
251 | "drawing.scale(0.75)\n",
252 | "print('---')\n",
253 | "print(drawing)\n",
254 | "print('---')\n",
255 | "drawing.add(ExtendedVector2D(-1,-1))\n",
256 | "print(drawing)"
257 | ]
258 | },
259 | {
260 | "cell_type": "markdown",
261 | "metadata": {},
262 | "source": [
263 | "## Exceptions"
264 | ]
265 | },
266 | {
267 | "cell_type": "markdown",
268 | "metadata": {},
269 | "source": [
270 | "In Python, exceptions are lightweight, i.e. handling them doesn't cause a notable decrease in performance as happens in some languages.\n",
271 | "\n",
272 | "The purpose of exceptions is to communicate that something didn't go right. The name of the exception typically tells what kind of error ocurred and the exception can also contain a more explicit message."
273 | ]
274 | },
275 | {
276 | "cell_type": "code",
277 | "execution_count": null,
278 | "metadata": {
279 | "collapsed": true
280 | },
281 | "outputs": [],
282 | "source": [
283 | "class Container(object):\n",
284 | " \n",
285 | " def __init__(self):\n",
286 | " self.bag = {}\n",
287 | " \n",
288 | " def put(self, key, item):\n",
289 | " self.bag[key] = item\n",
290 | " \n",
291 | " def get(self, key):\n",
292 | " return self.bag[key]"
293 | ]
294 | },
295 | {
296 | "cell_type": "markdown",
297 | "metadata": {},
298 | "source": [
299 | "The container-class can exhibit at least two different exceptions."
300 | ]
301 | },
302 | {
303 | "cell_type": "code",
304 | "execution_count": null,
305 | "metadata": {
306 | "collapsed": false
307 | },
308 | "outputs": [],
309 | "source": [
310 | "container = Container()\n",
311 | "container.put([1, 2, 3], \"example\")"
312 | ]
313 | },
314 | {
315 | "cell_type": "code",
316 | "execution_count": null,
317 | "metadata": {
318 | "collapsed": false
319 | },
320 | "outputs": [],
321 | "source": [
322 | "container.get(\"not_in_it\")"
323 | ]
324 | },
325 | {
326 | "cell_type": "markdown",
327 | "metadata": {},
328 | "source": [
329 | "Who should worry about the various issues is a good philosophical question. We could either make the Container-class secure in that it doesn't raise any errors to whoever calls it or we could let the caller worry about such errors.\n",
330 | "\n",
331 | "For now let's assume that the programmer is competent and knows what is a valid key and what isn't.\n"
332 | ]
333 | },
334 | {
335 | "cell_type": "code",
336 | "execution_count": null,
337 | "metadata": {
338 | "collapsed": false
339 | },
340 | "outputs": [],
341 | "source": [
342 | "try:\n",
343 | " container = Container()\n",
344 | " container.put([1,2,3], \"value\")\n",
345 | "except TypeError as err:\n",
346 | " print(\"Stupid programmer caused an error: \" + str(err))\n",
347 | " "
348 | ]
349 | },
350 | {
351 | "cell_type": "markdown",
352 | "metadata": {},
353 | "source": [
354 | "A try-except may contain a ``finally``block, which is always guaranteed to execute.\n",
355 | "\n",
356 | "Also, it is permissible to catch multiple different errors."
357 | ]
358 | },
359 | {
360 | "cell_type": "code",
361 | "execution_count": null,
362 | "metadata": {
363 | "collapsed": false
364 | },
365 | "outputs": [],
366 | "source": [
367 | "try:\n",
368 | " container = Container()\n",
369 | " container.put(3, \"value\")\n",
370 | " container.get(3)\n",
371 | "except TypeError as err:\n",
372 | " print(\"Stupid programmer caused an error: \" + str(err))\n",
373 | "except KeyError as err:\n",
374 | " print(\"Stupid programmer caused another error: \" + str(err))\n",
375 | "finally:\n",
376 | " print(\"all is well in the end\")\n",
377 | " \n",
378 | "# go ahead, make changes that cause one of the exceptions to be raised"
379 | ]
380 | },
381 | {
382 | "cell_type": "markdown",
383 | "metadata": {},
384 | "source": [
385 | "There is also syntax for catching multiple error types in the same catch clause.\n",
386 | "\n",
387 | "The keyword ``raise`` is used to continue error handling. This is useful if you want to log errors but let them pass onward anyway.\n",
388 | "\n",
389 | "A ``raise`` without arguments will re-raise the error that was being handled."
390 | ]
391 | },
392 | {
393 | "cell_type": "code",
394 | "execution_count": null,
395 | "metadata": {
396 | "collapsed": false
397 | },
398 | "outputs": [],
399 | "source": [
400 | "try:\n",
401 | " container = Container()\n",
402 | " container.put(3, \"value\")\n",
403 | " container.get(5)\n",
404 | "except (TypeError, KeyError) as err:\n",
405 | " print(\"please shoot me\")\n",
406 | " if type(err) == TypeError:\n",
407 | " raise Exception(\"That's it I quit!\")\n",
408 | " else:\n",
409 | " raise"
410 | ]
411 | }
412 | ],
413 | "metadata": {
414 | "kernelspec": {
415 | "display_name": "Python 3",
416 | "language": "python",
417 | "name": "python3"
418 | },
419 | "language_info": {
420 | "codemirror_mode": {
421 | "name": "ipython",
422 | "version": 3
423 | },
424 | "file_extension": ".py",
425 | "mimetype": "text/x-python",
426 | "name": "python",
427 | "nbconvert_exporter": "python",
428 | "pygments_lexer": "ipython3",
429 | "version": "3.5.2"
430 | }
431 | },
432 | "nbformat": 4,
433 | "nbformat_minor": 2
434 | }
435 |
--------------------------------------------------------------------------------
/notebooks/examples/Extra - Language features.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Extras\n",
8 | "\n",
9 | "This covers additional useful material that we may or may not have time to go over in the course."
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {},
15 | "source": [
16 | "## Generators\n",
17 | "\n",
18 | "Consider the following code that computes the sum of squared numbers up to N."
19 | ]
20 | },
21 | {
22 | "cell_type": "code",
23 | "execution_count": null,
24 | "metadata": {
25 | "collapsed": false
26 | },
27 | "outputs": [],
28 | "source": [
29 | "def squared_numbers(n):\n",
30 | " return [x*x for x in range(n)]\n",
31 | "\n",
32 | "def sum_squares(n):\n",
33 | " return sum(squared_numbers(n+1))\n",
34 | "\n",
35 | "sum_squares(20000000)"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "The code works and is all great, but it has one flaw: it creates a list of all the numbers from 1 to N in memory. If N were large, we would use a lot of extra memory, which might lead to the system swapping or running out of memory. \n",
43 | "\n",
44 | "In this case it is not necessary to create the entire list in memory. The ```sum``` function iterates over it's input and only needs the cumulative sum and the next value at a time.\n",
45 | "\n",
46 | "The Python keyword ``yield``is used to achieve this. Using ``yield`` in a statement automatically makes that statement a generator expression. A generator expression can be iterated over like a list, but it only creates new values as they are needed."
47 | ]
48 | },
49 | {
50 | "cell_type": "code",
51 | "execution_count": null,
52 | "metadata": {
53 | "collapsed": false
54 | },
55 | "outputs": [],
56 | "source": [
57 | "def squared_numbers_alternate(n):\n",
58 | " for x in range(n):\n",
59 | " yield x*x\n",
60 | " \n",
61 | "def sum_squares_alternate(n):\n",
62 | " return sum(squared_numbers_alternate(n+1))\n",
63 | "\n",
64 | "sum_squares(20000000)"
65 | ]
66 | },
67 | {
68 | "cell_type": "markdown",
69 | "metadata": {},
70 | "source": [
71 | "At this you may wonder, doesn't ``range()`` return a list? The short answer is no, but the details are complicated."
72 | ]
73 | },
74 | {
75 | "cell_type": "markdown",
76 | "metadata": {},
77 | "source": [
78 | "### Synthesis\n",
79 | "\n",
80 | "Python is often used to process text files, some of which may be quite large. Typically a single row in a text file isn't large, however. The following type of pattern permits one to cleanly read in a file much larger than what would fit memory one line at a time."
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": null,
86 | "metadata": {
87 | "collapsed": false
88 | },
89 | "outputs": [],
90 | "source": [
91 | "import os\n",
92 | "print(os.getcwd())\n",
93 | "def grep(fileobject, pattern):\n",
94 | " for index, line in enumerate(fileobject):\n",
95 | " if pattern in line:\n",
96 | " # start indexing from 1 for humans\n",
97 | " # remove the white space at the end\n",
98 | " yield index+1, line.strip()\n",
99 | " \n",
100 | "def process_file(input_, pattern):\n",
101 | " with open(input_, \"r\") as file_:\n",
102 | " for idx, line in grep(file_, pattern):\n",
103 | " print(\"line {} matches: {}\".format(idx, line))\n",
104 | " print(\"done searching\") \n",
105 | "\n",
106 | "process_file(\"../data/grep.txt\", \"test\")"
107 | ]
108 | },
109 | {
110 | "cell_type": "markdown",
111 | "metadata": {},
112 | "source": [
113 | "## Lambdas\n",
114 | "\n",
115 | "\n",
116 | "One of the paradigms Python supports are lambdas\n",
117 | "\n",
118 | "```\n",
119 | "square = lambda x: x*x\n",
120 | "```\n",
121 | "Here the result of the lambda statement, a function object is assigned to the variable square. The statement ```lambda x```denotes that this lambda statement takes in one parameter, x. The ``: x*x``say that the return value of the lambda statement is x*x.\n",
122 | "\n",
123 | "It is equivalent to\n",
124 | "```\n",
125 | "def square(x):\n",
126 | " return x*x\n",
127 | "```\n",
128 | "\n",
129 | "The beauty of lambda statements is that they don't need to be assigned, but can rather created on the fly."
130 | ]
131 | },
132 | {
133 | "cell_type": "code",
134 | "execution_count": null,
135 | "metadata": {
136 | "collapsed": false
137 | },
138 | "outputs": [],
139 | "source": [
140 | "square = lambda x: x*x\n",
141 | "print(square(4))\n",
142 | "\n",
143 | "(lambda x: x-1).__call__(1)"
144 | ]
145 | },
146 | {
147 | "cell_type": "markdown",
148 | "metadata": {},
149 | "source": [
150 | "A typical use case for lambda might be in accessing members of an object in a generic function.\n",
151 | "\n",
152 | "For instance the sort-function takes in a keyword parameter ``key``. It is trivial to do simple operations, like invert a value etc."
153 | ]
154 | },
155 | {
156 | "cell_type": "code",
157 | "execution_count": 8,
158 | "metadata": {
159 | "collapsed": false
160 | },
161 | "outputs": [
162 | {
163 | "data": {
164 | "text/plain": [
165 | "[('banana', 3), ('apple', 5), ('pear', 10)]"
166 | ]
167 | },
168 | "execution_count": 8,
169 | "metadata": {},
170 | "output_type": "execute_result"
171 | }
172 | ],
173 | "source": [
174 | "my_list = [\n",
175 | " (\"apple\", 5),\n",
176 | " (\"banana\", 3),\n",
177 | " (\"pear\", 10)\n",
178 | "]\n",
179 | "my_list.sort(key= lambda x: x[1]) #sort by the number\n",
180 | "my_list"
181 | ]
182 | },
183 | {
184 | "cell_type": "markdown",
185 | "metadata": {},
186 | "source": [
187 | "Lambda has many other uses but those are left as a thought exercise.\n",
188 | "\n",
189 | "Write a ``mean`` function that takes in a list and computes a mean of the values accessed by function ``key`` that is given as a parameter to the function.\n",
190 | "\n",
191 | "The default key is best left as a function that returns it's parameter, i.e. \n",
192 | "``lambda x: x```\n",
193 | "."
194 | ]
195 | },
196 | {
197 | "cell_type": "code",
198 | "execution_count": null,
199 | "metadata": {
200 | "collapsed": false
201 | },
202 | "outputs": [],
203 | "source": [
204 | "def mean(...):\n",
205 | " pass"
206 | ]
207 | }
208 | ],
209 | "metadata": {
210 | "kernelspec": {
211 | "display_name": "Python 3",
212 | "language": "python",
213 | "name": "python3"
214 | },
215 | "language_info": {
216 | "codemirror_mode": {
217 | "name": "ipython",
218 | "version": 3
219 | },
220 | "file_extension": ".py",
221 | "mimetype": "text/x-python",
222 | "name": "python",
223 | "nbconvert_exporter": "python",
224 | "pygments_lexer": "ipython3",
225 | "version": "3.5.2"
226 | }
227 | },
228 | "nbformat": 4,
229 | "nbformat_minor": 2
230 | }
231 |
--------------------------------------------------------------------------------
/notebooks/examples/Extra - Python Software Development Practices.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Software development practices\n",
8 | "\n",
9 | "This exercise and demo are hands-on and done in your own system.\n",
10 | "\n",
11 | "However as all other exercises are notebooks, the instructions are distributed as a notebook as well."
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "metadata": {},
17 | "source": [
18 | "## Set-up\n",
19 | "\n",
20 | "In an appropriate directory, run the following commands to clone the example git repository.\n",
21 | "\n",
22 | "```\n",
23 | "$ git clone https://github.com/csc-training/python-quality-exercise.git\n",
24 | "$ cd python-quality-exercise\n",
25 | "```\n",
26 | "\n",
27 | "Now you are in the repository. You can view the README file for an explanation.\n",
28 | "\n",
29 | "Create a virtual environment (with Python3 with the following\n",
30 | "\n",
31 | "```\n",
32 | "$ virtualenv -p python3 python-quality\n",
33 | " [...]\n",
34 | "$ source python-quality/bin/activate\n",
35 | "(python-quality) $\n",
36 | "```\n",
37 | "\n",
38 | "Install the required package versions with\n",
39 | "\n",
40 | "```\n",
41 | "(python-quality) $ pip install -r requirements.txt\n",
42 | "```\n",
43 | "\n",
44 | "Now, whenever you want to activate the virtual environment you run:\n",
45 | "\n",
46 | "```\n",
47 | "$ source python-quality/bin/activate\n",
48 | "(python-quality) $\n",
49 | "``````\n"
50 | ]
51 | },
52 | {
53 | "cell_type": "markdown",
54 | "metadata": {},
55 | "source": [
56 | "## Tests\n",
57 | "\n",
58 | "You can now run tests using pytest with\n",
59 | "\n",
60 | "```\n",
61 | "(python-quality) $ pytest\n",
62 | "```\n",
63 | "\n",
64 | "Go ahead and find out the functions you can test and write unit tests for some of them.\n",
65 | "\n",
66 | "You might want to use mock for some tests, for instance to avoid the initialization of DemoClass, but at least the find_median function should be simple to test with a few examples."
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {},
72 | "source": [
73 | "### Test coverage\n",
74 | "\n",
75 | "You can check the coverage of your tests with pytest-cov, a coverage plugin for pytest by running.\n",
76 | "\n",
77 | "```\n",
78 | "pytest --cov demolib\n",
79 | "```\n",
80 | "\n",
81 | "Observe that initially ``demomodule.py`` isn't even imported so it's not in the report."
82 | ]
83 | },
84 | {
85 | "cell_type": "markdown",
86 | "metadata": {},
87 | "source": [
88 | "## Style\n",
89 | "\n",
90 | "You can test style with pep8 by running\n",
91 | "```\n",
92 | "(python-quality) $ pep8 .\n",
93 | "```\n",
94 | "\n",
95 | "Or with pylint by running\n",
96 | "\n",
97 | "```\n",
98 | "(python-quality) $ pylint demolib\n",
99 | "```\n",
100 | "\n",
101 | "Go ahead and fix coverage mistakes."
102 | ]
103 | },
104 | {
105 | "cell_type": "markdown",
106 | "metadata": {},
107 | "source": [
108 | "## Setup script\n",
109 | "\n",
110 | "To make the package installable, you should put a setup.py at the top level.\n",
111 | "\n",
112 | "A minimal one like [in the Python documentation](https://docs.python.org/3.6/distutils/setupscript.html) will suffice. The name of the package you wish to expose is, of course demolib.\n",
113 | "\n",
114 | "Go ahead and make a setup script. You can test that the package is installable with\n",
115 | "\n",
116 | "```\n",
117 | "(python-quality) $ pip install .\n",
118 | "```"
119 | ]
120 | },
121 | {
122 | "cell_type": "markdown",
123 | "metadata": {},
124 | "source": [
125 | "## Tox\n",
126 | "\n",
127 | "To facilitate running test for more than one version of python, use tox.\n",
128 | "\n",
129 | "Create a file called tox.ini, with the following contents\n",
130 | "```\n",
131 | "[tox]\n",
132 | "envlist = py27,py35\n",
133 | "[testenv]\n",
134 | "deps= -rrequirements.txt\n",
135 | "commands=py.test --cov demolib # run pytest\n",
136 | " pep8 # run pep8\n",
137 | "\n",
138 | "```\n",
139 | "\n",
140 | "If you still have any errors go ahead and fix them.\n",
141 | "\n",
142 | "You should now be able to run tox with\n",
143 | "```\n",
144 | "(python-quality) $ tox\n",
145 | "```\n",
146 | "\n",
147 | "That's it. If you had an open source project you could e.g. enable Travis to automatically run your tests and style checks against every branch your team makes."
148 | ]
149 | }
150 | ],
151 | "metadata": {
152 | "kernelspec": {
153 | "display_name": "Python 3",
154 | "language": "python",
155 | "name": "python3"
156 | },
157 | "language_info": {
158 | "codemirror_mode": {
159 | "name": "ipython",
160 | "version": 3
161 | },
162 | "file_extension": ".py",
163 | "mimetype": "text/x-python",
164 | "name": "python",
165 | "nbconvert_exporter": "python",
166 | "pygments_lexer": "ipython3",
167 | "version": "3.5.2"
168 | }
169 | },
170 | "nbformat": 4,
171 | "nbformat_minor": 2
172 | }
173 |
--------------------------------------------------------------------------------
/notebooks/examples/Extra Scikit-learn.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Classification with Scikit-learn\n",
8 | "\n",
9 | "First we use pandas to read in the csv file and separate the Y (target class, final column in CSV) from the X, the predicting values."
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "metadata": {
16 | "collapsed": false
17 | },
18 | "outputs": [],
19 | "source": [
20 | "import pandas as pd\n",
21 | "\n",
22 | "data = pd.read_csv(\"../data/iris.data\")\n",
23 | "\n",
24 | "# convert to NumPy arrays because they are the easiest to handle in sklearn\n",
25 | "variables = data.drop([\"class\"], axis=1).as_matrix()\n",
26 | "classes = data[[\"class\"]].as_matrix().reshape(-1)"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": null,
32 | "metadata": {
33 | "collapsed": false
34 | },
35 | "outputs": [],
36 | "source": [
37 | "# import cross-validation scorer and KNeighborsClassifier\n",
38 | "from sklearn.model_selection import train_test_split\n",
39 | "from sklearn.neighbors import KNeighborsClassifier\n",
40 | "\n",
41 | "train_X, test_X, train_Y, test_Y = train_test_split(variables, classes)\n",
42 | "\n",
43 | "# initialize classifier object\n",
44 | "classifier = KNeighborsClassifier()\n",
45 | "\n",
46 | "# fit the object using training data and sample labels\n",
47 | "classifier.fit(train_X, train_Y)\n",
48 | "\n",
49 | "# evaluate the results for held-out test sample\n",
50 | "classifier.score(test_X, test_Y)\n",
51 | "# value is the mean accuracy "
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": null,
57 | "metadata": {
58 | "collapsed": false
59 | },
60 | "outputs": [],
61 | "source": [
62 | "# if we wanted to predict values for unseen data, we would use the predict()-method\n",
63 | "\n",
64 | "classifier.predict(test_X) # note no known Y-values passed"
65 | ]
66 | },
67 | {
68 | "cell_type": "markdown",
69 | "metadata": {},
70 | "source": [
71 | "## Exercise\n",
72 | "\n",
73 | "* Import the classifier object ``sklearn.svm.SVC```\n",
74 | "* initialize it\n",
75 | "* fit it with the training data (no need to split a second time)\n",
76 | "* evaluate the quality of the created classifier using ``score()``"
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "metadata": {
83 | "collapsed": true
84 | },
85 | "outputs": [],
86 | "source": []
87 | },
88 | {
89 | "cell_type": "markdown",
90 | "metadata": {},
91 | "source": [
92 | "# Pipelining and cross-validation\n",
93 | "\n",
94 | "It's common to want to preprocess data somehow or in general have several steps. This can be easily done with the Pipeline class. \n",
95 | "\n",
96 | "There are typically parameters involved and you might want to select the best possible parameter."
97 | ]
98 | },
99 | {
100 | "cell_type": "code",
101 | "execution_count": null,
102 | "metadata": {
103 | "collapsed": false
104 | },
105 | "outputs": [],
106 | "source": [
107 | "from sklearn.decomposition import PCA # pca is a subspace method that projects the data into a lower-dimensional space\n",
108 | "\n",
109 | "from sklearn.model_selection import GridSearchCV\n",
110 | "from sklearn.neighbors import KNeighborsClassifier\n",
111 | "\n",
112 | "\n",
113 | "pca = PCA(n_components=2)\n",
114 | "knn = KNeighborsClassifier(n_neighbors=3)\n",
115 | "\n",
116 | "from sklearn.pipeline import Pipeline\n",
117 | "\n",
118 | "pipeline = Pipeline([(\"pca\", pca), (\"kneighbors\", knn)])\n",
119 | "\n",
120 | "parameters_grid = dict(\n",
121 | " pca__n_components=[1,2,3,4],\n",
122 | " kneighbors__n_neighbors=[1,2,3,4,5,6]\n",
123 | " )\n",
124 | "grid_search = GridSearchCV(pipeline, parameters_grid)\n",
125 | "grid_search.fit(train_X, train_Y)\n",
126 | "grid_search.best_estimator_"
127 | ]
128 | },
129 | {
130 | "cell_type": "code",
131 | "execution_count": null,
132 | "metadata": {
133 | "collapsed": false
134 | },
135 | "outputs": [],
136 | "source": [
137 | "# you can now test agains the held out part\n",
138 | "grid_search.best_estimator_.score(test_X, test_Y)"
139 | ]
140 | },
141 | {
142 | "cell_type": "markdown",
143 | "metadata": {},
144 | "source": [
145 | "## Exercise\n",
146 | "\n",
147 | "There is another dataset, \"breast-cancer-wisconsin.data\". For a description see [here] (https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/) . \n",
148 | "\n",
149 | "It contains samples with patient ID (that you should remove), measurements and as last the doctors judgment of the biopsy: malignant or benign.\n",
150 | "\n",
151 | "Read in the file and create a classifier.\n",
152 | "\n",
153 | "You can alternately just split the input and use some classifier or do a grid cross-validation over a larger space of potential parameters.\n",
154 | "\n"
155 | ]
156 | },
157 | {
158 | "cell_type": "code",
159 | "execution_count": null,
160 | "metadata": {
161 | "collapsed": true
162 | },
163 | "outputs": [],
164 | "source": []
165 | }
166 | ],
167 | "metadata": {
168 | "kernelspec": {
169 | "display_name": "Python 3",
170 | "language": "python",
171 | "name": "python3"
172 | },
173 | "language_info": {
174 | "codemirror_mode": {
175 | "name": "ipython",
176 | "version": 3
177 | },
178 | "file_extension": ".py",
179 | "mimetype": "text/x-python",
180 | "name": "python",
181 | "nbconvert_exporter": "python",
182 | "pygments_lexer": "ipython3",
183 | "version": "3.5.2"
184 | }
185 | },
186 | "nbformat": 4,
187 | "nbformat_minor": 2
188 | }
189 |
--------------------------------------------------------------------------------
/notebooks/exercises/1 - Introduction.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Exercises\n",
8 | "## Hello world\n",
9 | "\n",
10 | "Most introduction to programming session start with a Hello World example.\n",
11 | "\n",
12 | "The gray cell below is what is called a code-cell. You can execute it by clicking on it and pressing ctrl+enter. Alternately you can find the button that looks like the \"Play\"-symbol in the toolbar above."
13 | ]
14 | },
15 | {
16 | "cell_type": "code",
17 | "execution_count": null,
18 | "metadata": {},
19 | "outputs": [],
20 | "source": [
21 | "print(\"Hello World!\")"
22 | ]
23 | },
24 | {
25 | "cell_type": "markdown",
26 | "metadata": {},
27 | "source": [
28 | "The system that creates this webpage is called [Jupyter Notebooks](http://jupyter.org/). It is a language-independent system for displaying program code on a webpage, running the code in a server environment and displaying the output of the system to the user.\n",
29 | "\n",
30 | "The exercises here will be conducted in Python 3, but the system supports multiple other languages. The purpose of having this very simple introduction early on is to make sure everyone is able to access their environment.\n",
31 | "\n",
32 | "Go ahead and make your own Hello World below."
33 | ]
34 | },
35 | {
36 | "cell_type": "code",
37 | "execution_count": null,
38 | "metadata": {
39 | "collapsed": true
40 | },
41 | "outputs": [],
42 | "source": []
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "metadata": {},
47 | "source": [
48 | "## Using the interactive interpreter\n",
49 | "\n",
50 | "When working in the command line the interactive IPython interpreter can sometimes be more convenient than Jupyter notebook. Launch a terminal using the \"New\" -> \"Terminal\" functionality and start IPython by typing ``ipython`` in the terminal. Execute ``print(\"Hello\")`` in the interactive interpreter. You can exit the interactive interpreter with the ``quit`` command"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {},
56 | "source": [
57 | "## Working with Python scripts\n",
58 | "\n",
59 | "In larger problems one typical writes the Python code in one or multiple .py files. In the terminal opened above create a file ``hello.py`` (use e.g. the **nano** texteditor) and place a proper ``print`` function there. After saving the file and exiting the editor execute the script with ``python hello.py``."
60 | ]
61 | },
62 | {
63 | "cell_type": "markdown",
64 | "metadata": {},
65 | "source": [
66 | "## Extra: calculator"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {},
72 | "source": [
73 | "You can use Python as a simple calculator. Try it out below if you have time. \n",
74 | "\n",
75 | "Try to figure out (or google) how to do exponentiation, e.g. $2^5$."
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": null,
81 | "metadata": {
82 | "collapsed": true
83 | },
84 | "outputs": [],
85 | "source": []
86 | }
87 | ],
88 | "metadata": {
89 | "kernelspec": {
90 | "display_name": "Python 3",
91 | "language": "python",
92 | "name": "python3"
93 | },
94 | "language_info": {
95 | "codemirror_mode": {
96 | "name": "ipython",
97 | "version": 3
98 | },
99 | "file_extension": ".py",
100 | "mimetype": "text/x-python",
101 | "name": "python",
102 | "nbconvert_exporter": "python",
103 | "pygments_lexer": "ipython3",
104 | "version": "3.4.9"
105 | }
106 | },
107 | "nbformat": 4,
108 | "nbformat_minor": 2
109 | }
110 |
--------------------------------------------------------------------------------
/notebooks/exercises/2 - Data types and expressions.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Exercises\n",
8 | "## Playing with the interpreter\n",
9 | "\n",
10 | "Try to execute some simple statements and expressions (one at a time) e.g\n",
11 | "```\n",
12 | "print(\"Hello!\")\n",
13 | "1j**2\n",
14 | "1 / 2\n",
15 | "1 // 2\n",
16 | "5 + 5\n",
17 | "10 / 2 + 5\n",
18 | "my_tuple = (1, 2, 3)\n",
19 | "my_tuple[0] = 1\n",
20 | "2.3**4.5\n",
21 | "```\n",
22 | "Do you understand what is going on in all cases?"
23 | ]
24 | },
25 | {
26 | "cell_type": "code",
27 | "execution_count": null,
28 | "metadata": {
29 | "collapsed": true
30 | },
31 | "outputs": [],
32 | "source": []
33 | },
34 | {
35 | "cell_type": "markdown",
36 | "metadata": {},
37 | "source": [
38 | "Most Python functions and objects can provide documentation via **help** function. Look the documentation of e.g open function with ```help(open)```\n"
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": null,
44 | "metadata": {
45 | "collapsed": true
46 | },
47 | "outputs": [],
48 | "source": []
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {},
53 | "source": [
54 | "Play with tabulator completion, by typing just ```pr``` and pressing then tabulator key. Pressing Shift-tab (after finalising completion) one sees also short documentation about the function or object. This works also on variable names, try e.g.\n",
55 | "```\n",
56 | "my_extremely_long_variable_name = 5\n",
57 | "my \n",
58 | "```"
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": null,
64 | "metadata": {
65 | "collapsed": true
66 | },
67 | "outputs": [],
68 | "source": []
69 | },
70 | {
71 | "cell_type": "markdown",
72 | "metadata": {},
73 | "source": [
74 | "## Basic syntax\n",
75 | "Try to assign the value 6 to the following variable names\n",
76 | "````\n",
77 | "first-name\n",
78 | "family_name\n",
79 | "3PO\n",
80 | "____variable\n",
81 | "inb4tool8\n",
82 | "print\n",
83 | "in\n",
84 | "```\n",
85 | "\n",
86 | "Which of them are valid to assign to? \n",
87 | "\n",
88 | "Extra: why do you think the ones that cause an error are not valid? What's the reason?"
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": null,
94 | "metadata": {
95 | "collapsed": true
96 | },
97 | "outputs": [],
98 | "source": []
99 | },
100 | {
101 | "cell_type": "markdown",
102 | "metadata": {},
103 | "source": [
104 | "You probably noticed that even though ``print`` is a method in the namespace it was still valid to create a variable called ``print``. If you now try to actually print something, you will get an error. For built-in functions (such as print) one can recover with the following code"
105 | ]
106 | },
107 | {
108 | "cell_type": "code",
109 | "execution_count": null,
110 | "metadata": {},
111 | "outputs": [],
112 | "source": [
113 | "print = __builtin__.print\n",
114 | "print(\"hello\")"
115 | ]
116 | },
117 | {
118 | "cell_type": "markdown",
119 | "metadata": {},
120 | "source": [
121 | "Are the following pieces valid Python code?\n",
122 | "\n",
123 | "** Case 1 **\n",
124 | "```\n",
125 | "numbers = [4, 5, 6, 9, 11]\n",
126 | "sum = 0\n",
127 | "for n in numbers:\n",
128 | " sum += n\n",
129 | " print(\"Sum is now\"), sum\n",
130 | "```\n",
131 | "\n",
132 | "** Case 2 **\n",
133 | "```\n",
134 | "x = 11\n",
135 | "test(x)\n",
136 | "\n",
137 | "def test(a):\n",
138 | " if a < 0:\n",
139 | " print(\"negative number\")\n",
140 | "```"
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": null,
146 | "metadata": {
147 | "collapsed": true
148 | },
149 | "outputs": [],
150 | "source": []
151 | },
152 | {
153 | "cell_type": "markdown",
154 | "metadata": {},
155 | "source": [
156 | "## Tuples and lists\n",
157 | "1. Create a tuple called ``mytuple``, with the following strings: \"sausage\", \"eggs\" and \"bacon\"\n",
158 | "2. check it's type using ``type()``\n",
159 | "3. Create than a list called ``mylist`` with the same contents. You use can the normal list definition syntax (``[]``) or coerce it from the tuple with the ``list()`` function."
160 | ]
161 | },
162 | {
163 | "cell_type": "code",
164 | "execution_count": null,
165 | "metadata": {
166 | "collapsed": true
167 | },
168 | "outputs": [],
169 | "source": []
170 | },
171 | {
172 | "cell_type": "markdown",
173 | "metadata": {},
174 | "source": [
175 | "Attempt to append the string \"spam\" \n",
176 | "to ``mylist`` and ``mytuple`` using ``append``."
177 | ]
178 | },
179 | {
180 | "cell_type": "code",
181 | "execution_count": null,
182 | "metadata": {
183 | "collapsed": true
184 | },
185 | "outputs": [],
186 | "source": []
187 | },
188 | {
189 | "cell_type": "markdown",
190 | "metadata": {},
191 | "source": [
192 | "List objects have a sort()\n",
193 | "function, use that for sorting the list alphabetically (e.g.\n",
194 | "mylist.sort() ). What is now the first item of the list?\n",
195 | "\n",
196 | "Next, remove the first item from the list, investigate the contents and remove then last item from the list."
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": null,
202 | "metadata": {
203 | "collapsed": true
204 | },
205 | "outputs": [],
206 | "source": []
207 | },
208 | {
209 | "cell_type": "markdown",
210 | "metadata": {},
211 | "source": [
212 | "### Slicing\n",
213 | "\n",
214 | "Using ``range()`` create a list that has the numbers from 50 to 0 with a step of -2. Note that in Python 3 ``range()`` returns an *iterator* (we'll discuss iterators more later on), ``list(range(args))`` returns an actual list."
215 | ]
216 | },
217 | {
218 | "cell_type": "code",
219 | "execution_count": null,
220 | "metadata": {
221 | "collapsed": true
222 | },
223 | "outputs": [],
224 | "source": []
225 | },
226 | {
227 | "cell_type": "markdown",
228 | "metadata": {},
229 | "source": [
230 | "Using slicing syntax, select\n",
231 | "* the last 4 items from the list\n",
232 | "* the items from index 10 to index 13\n",
233 | "* the first 5 items from the list"
234 | ]
235 | },
236 | {
237 | "cell_type": "code",
238 | "execution_count": null,
239 | "metadata": {
240 | "collapsed": true
241 | },
242 | "outputs": [],
243 | "source": []
244 | },
245 | {
246 | "cell_type": "markdown",
247 | "metadata": {},
248 | "source": [
249 | "Read up on the [stride syntax](https://en.wikipedia.org/wiki/Array_slicing#1991:_Python) . Then using it select \n",
250 | "* every third value in the list\n",
251 | "* the values with an odd-numbered index in the list"
252 | ]
253 | },
254 | {
255 | "cell_type": "code",
256 | "execution_count": null,
257 | "metadata": {
258 | "collapsed": true
259 | },
260 | "outputs": [],
261 | "source": []
262 | },
263 | {
264 | "cell_type": "markdown",
265 | "metadata": {},
266 | "source": [
267 | "### Multidimensional lists\n",
268 | "Create a two dimensional list of (x,y) value pairs, i.e.\n",
269 | "arbitrary long list whose elements are two element lists.\n",
270 | "\n",
271 | "Are you able to use slicing for extracting only the y values? (Answer is no, but try it in any case)"
272 | ]
273 | },
274 | {
275 | "cell_type": "code",
276 | "execution_count": null,
277 | "metadata": {
278 | "collapsed": true
279 | },
280 | "outputs": [],
281 | "source": []
282 | },
283 | {
284 | "cell_type": "markdown",
285 | "metadata": {},
286 | "source": [
287 | "## Dictionaries\n",
288 | "Create a dictionary whose keys are the fruits “pineapple”, “strawberry”, and “banana”. As values use numbers\n",
289 | "representing e.g. prices. \n",
290 | "\n",
291 | "Add “orange” to the dictionary and then remove “banana” from the dictionary. Investigate the contents of dictionary and pay attention to the order of key-value pairs."
292 | ]
293 | },
294 | {
295 | "cell_type": "code",
296 | "execution_count": null,
297 | "metadata": {
298 | "collapsed": true
299 | },
300 | "outputs": [],
301 | "source": []
302 | },
303 | {
304 | "cell_type": "markdown",
305 | "metadata": {},
306 | "source": [
307 | "# Bonus exercises\n",
308 | "Create a new “fruits” dictionary where the values are also\n",
309 | "dictionaries containing key-value pairs for color and weight,\n",
310 | "e.g. \n",
311 | "```\n",
312 | "fruits['apple'] = {'color':'green', 'weight': 120}\n",
313 | "```\n",
314 | "Change the color of *apple* from green to red"
315 | ]
316 | },
317 | {
318 | "cell_type": "code",
319 | "execution_count": null,
320 | "metadata": {
321 | "collapsed": true
322 | },
323 | "outputs": [],
324 | "source": []
325 | },
326 | {
327 | "cell_type": "markdown",
328 | "metadata": {},
329 | "source": [
330 | "It is often useful idiom to create empty lists or dictionaries\n",
331 | "and add contents little by little.\n",
332 | "\n",
333 | "Create first an empty dictionary for a mid-term grades of\n",
334 | "students. Then, add a key-value pairs where the keys are\n",
335 | "student names and the values are empty lists. \n",
336 | "\n",
337 | "Finally, add values to the lists and investigate the contents of the\n",
338 | "dictionary."
339 | ]
340 | },
341 | {
342 | "cell_type": "code",
343 | "execution_count": null,
344 | "metadata": {
345 | "collapsed": true
346 | },
347 | "outputs": [],
348 | "source": []
349 | }
350 | ],
351 | "metadata": {
352 | "kernelspec": {
353 | "display_name": "Python 3",
354 | "language": "python",
355 | "name": "python3"
356 | },
357 | "language_info": {
358 | "codemirror_mode": {
359 | "name": "ipython",
360 | "version": 3
361 | },
362 | "file_extension": ".py",
363 | "mimetype": "text/x-python",
364 | "name": "python",
365 | "nbconvert_exporter": "python",
366 | "pygments_lexer": "ipython3",
367 | "version": "3.4.9"
368 | }
369 | },
370 | "nbformat": 4,
371 | "nbformat_minor": 2
372 | }
373 |
--------------------------------------------------------------------------------
/notebooks/exercises/3 - Control Structures.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Control Structures"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "## Simple for loop \n",
15 | "\n",
16 | "Write a ``for`` loop which iterates over the list of breakfast items \"sausage\", \"eggs\", \"bacon\" and \"spam\" and prints out the name of item\n"
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": null,
22 | "metadata": {
23 | "collapsed": true
24 | },
25 | "outputs": [],
26 | "source": [
27 | "breakfast = [\"sausage\", \"eggs\", \"bacon\", \"spam\"]\n"
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {
33 | "collapsed": true
34 | },
35 | "source": [
36 | "Write then a ``for`` which loop determines the squares of the odd\n",
37 | "integers up to 10. Use the ``range()`` function."
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": null,
43 | "metadata": {
44 | "collapsed": true
45 | },
46 | "outputs": [],
47 | "source": []
48 | },
49 | {
50 | "cell_type": "markdown",
51 | "metadata": {},
52 | "source": [
53 | "## Looping through a dictionary\n",
54 | "Write a loop that prints out the names of the fruits in the dictionary containing the fruit prices."
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": null,
60 | "metadata": {
61 | "collapsed": true
62 | },
63 | "outputs": [],
64 | "source": [
65 | "fruits = {'banana' : 5, 'strawberry' : 7, 'pineapple' : 3}\n"
66 | ]
67 | },
68 | {
69 | "cell_type": "markdown",
70 | "metadata": {},
71 | "source": [
72 | "Next, write a loop that sums up the prices."
73 | ]
74 | },
75 | {
76 | "cell_type": "code",
77 | "execution_count": null,
78 | "metadata": {
79 | "collapsed": true
80 | },
81 | "outputs": [],
82 | "source": []
83 | },
84 | {
85 | "cell_type": "markdown",
86 | "metadata": {},
87 | "source": [
88 | "## While loop\n",
89 | "\n",
90 | "Fibonacci numbers are a sequence of integers defined by the recurrence relation\n",
91 | "```\n",
92 | "\t\tF[n] = F[n-1] + F[n-2]\n",
93 | "```\n",
94 | "with the initial values F[0]=0, F[1]=1. \n",
95 | "Create a list of Fibonacci numbers F[n] < 100 using a while loop."
96 | ]
97 | },
98 | {
99 | "cell_type": "code",
100 | "execution_count": null,
101 | "metadata": {
102 | "collapsed": true
103 | },
104 | "outputs": [],
105 | "source": []
106 | },
107 | {
108 | "cell_type": "markdown",
109 | "metadata": {},
110 | "source": [
111 | "## If - else\n",
112 | "\n",
113 | "Write a control structure which checks whether an integer is\n",
114 | "negative, zero, or belongs to the prime numbers 3,5,7,11,17\n",
115 | "and perform e.g. corresponding print statement.\n",
116 | "\n",
117 | "Use keyword ``in`` when checking for belonging to prime numbers."
118 | ]
119 | },
120 | {
121 | "cell_type": "code",
122 | "execution_count": null,
123 | "metadata": {
124 | "collapsed": true
125 | },
126 | "outputs": [],
127 | "source": []
128 | },
129 | {
130 | "cell_type": "markdown",
131 | "metadata": {},
132 | "source": [
133 | "# Advanced exercises\n",
134 | "\n",
135 | "Don't worry if you don't have time to finish all of these. They are not essential."
136 | ]
137 | },
138 | {
139 | "cell_type": "markdown",
140 | "metadata": {},
141 | "source": [
142 | "## Looping through multidimensional lists\n",
143 | "\n",
144 | "Start from a two dimensional list of (x,y) value pairs, and sort it according to y values. (Hint: you may need to create a temporary list)."
145 | ]
146 | },
147 | {
148 | "cell_type": "code",
149 | "execution_count": null,
150 | "metadata": {
151 | "collapsed": true
152 | },
153 | "outputs": [],
154 | "source": [
155 | "xys = [[2, 3], [0, -1], [4, -2], [1, 6]]\n"
156 | ]
157 | },
158 | {
159 | "cell_type": "markdown",
160 | "metadata": {},
161 | "source": [
162 | "Next, create a new list containing only the sorted y values."
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "execution_count": null,
168 | "metadata": {
169 | "collapsed": true
170 | },
171 | "outputs": [],
172 | "source": []
173 | },
174 | {
175 | "cell_type": "markdown",
176 | "metadata": {},
177 | "source": [
178 | "Then, create a new list consisting of sums of the (x,y) pairs."
179 | ]
180 | },
181 | {
182 | "cell_type": "code",
183 | "execution_count": null,
184 | "metadata": {
185 | "collapsed": true
186 | },
187 | "outputs": [],
188 | "source": []
189 | },
190 | {
191 | "cell_type": "markdown",
192 | "metadata": {},
193 | "source": [
194 | "Finally, create a new list consisting of sums the (x,y) pairs where both x and y are positive."
195 | ]
196 | },
197 | {
198 | "cell_type": "code",
199 | "execution_count": null,
200 | "metadata": {
201 | "collapsed": true
202 | },
203 | "outputs": [],
204 | "source": []
205 | },
206 | {
207 | "cell_type": "markdown",
208 | "metadata": {},
209 | "source": [
210 | "## FizzBuzz\n",
211 | "\n",
212 | "This is a classic job interview question. Depending on the interviewer or interviewee it can filter out up to 95% of the interviewees for a position. The task is not difficult but it's easy to make simple mistakes.\n",
213 | "\n",
214 | "If a number is divisible by 3, instead of the number print \"Fizz\", if a number is divisible by 5, print \"Buzz\" and if the number is divisible by both 3 and 5, print \"FizzBuzz\". "
215 | ]
216 | },
217 | {
218 | "cell_type": "code",
219 | "execution_count": 2,
220 | "metadata": {
221 | "collapsed": true
222 | },
223 | "outputs": [],
224 | "source": [
225 | "numbers = range(1, 101)"
226 | ]
227 | },
228 | {
229 | "cell_type": "markdown",
230 | "metadata": {},
231 | "source": [
232 | "*Food for thought:* How do people commonly fail this test and why?"
233 | ]
234 | },
235 | {
236 | "cell_type": "code",
237 | "execution_count": null,
238 | "metadata": {
239 | "collapsed": true
240 | },
241 | "outputs": [],
242 | "source": []
243 | },
244 | {
245 | "cell_type": "markdown",
246 | "metadata": {},
247 | "source": [
248 | "## Breaking\n",
249 | "\n",
250 | "The python `random` module generates pseudorandom numbers.\n",
251 | "\n",
252 | "Write a *while* loop that runs until \n",
253 | "the output of random.random() is below 0.1 and `break` when \n",
254 | "the value is below 0.1."
255 | ]
256 | },
257 | {
258 | "cell_type": "code",
259 | "execution_count": 5,
260 | "metadata": {},
261 | "outputs": [
262 | {
263 | "data": {
264 | "text/plain": [
265 | "0.3504138821505054"
266 | ]
267 | },
268 | "execution_count": 5,
269 | "metadata": {},
270 | "output_type": "execute_result"
271 | }
272 | ],
273 | "source": [
274 | "import random\n",
275 | "\n",
276 | "value = random.random()\n",
277 | "value"
278 | ]
279 | },
280 | {
281 | "cell_type": "markdown",
282 | "metadata": {},
283 | "source": [
284 | "## List comprehension\n",
285 | "\n",
286 | "Using a list comprehension create a new list, `temperatures_kelvin` from following Celsius temperatures and convert them by adding the value 273.15 to each."
287 | ]
288 | },
289 | {
290 | "cell_type": "code",
291 | "execution_count": null,
292 | "metadata": {
293 | "collapsed": true
294 | },
295 | "outputs": [],
296 | "source": [
297 | "temperatures_celsius = [0, -15, 20.15, 13.3, -5.2]"
298 | ]
299 | }
300 | ],
301 | "metadata": {
302 | "kernelspec": {
303 | "display_name": "Python 3",
304 | "language": "python",
305 | "name": "python3"
306 | },
307 | "language_info": {
308 | "codemirror_mode": {
309 | "name": "ipython",
310 | "version": 3
311 | },
312 | "file_extension": ".py",
313 | "mimetype": "text/x-python",
314 | "name": "python",
315 | "nbconvert_exporter": "python",
316 | "pygments_lexer": "ipython3",
317 | "version": "3.4.9"
318 | }
319 | },
320 | "nbformat": 4,
321 | "nbformat_minor": 2
322 | }
323 |
--------------------------------------------------------------------------------
/notebooks/exercises/4 - Functions and exceptions.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Functions and exceptions"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "## Functions\n",
15 | "\n",
16 | "Write a function that converts from Celsius to Kelvin.\n",
17 | "\n",
18 | "To convert from Celsius to Kelvin you add 273.15 from the value.\n",
19 | "\n",
20 | "Try your solution for a few values."
21 | ]
22 | },
23 | {
24 | "cell_type": "code",
25 | "execution_count": null,
26 | "metadata": {
27 | "collapsed": true
28 | },
29 | "outputs": [],
30 | "source": [
31 | "def celsius_to_kelvin(c):\n",
32 | " # implementation here\n",
33 | " pass\n",
34 | "\n",
35 | "celsius_to_kelvin(0)"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {
41 | "collapsed": true
42 | },
43 | "source": [
44 | "Now write another function to convert from Fahrenheit to Celsius.\n",
45 | "\n",
46 | "The formula for doing so is \n",
47 | "\n",
48 | "C = 5/9*(F-32)\n",
49 | "\n",
50 | "Again, verify that your function does what is expected."
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": null,
56 | "metadata": {
57 | "collapsed": true
58 | },
59 | "outputs": [],
60 | "source": [
61 | "def fahrenheit_to_celsius(f):\n",
62 | " pass\n",
63 | "\n",
64 | "fahrenheit_to_celsius(0)"
65 | ]
66 | },
67 | {
68 | "cell_type": "markdown",
69 | "metadata": {},
70 | "source": [
71 | "Now make a function to convert from Fahrenheit to Kelvin.\n",
72 | "\n",
73 | "Before you start coding, stop to think for a second. You can actually re-use the two other functions you have made. Fahrenheit to Kelvin can be represented as Fahrenheit to Celsius followed by Celsius to Kelvin."
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": null,
79 | "metadata": {
80 | "collapsed": true
81 | },
82 | "outputs": [],
83 | "source": [
84 | "def fahrenheit_to_kelvin(f):\n",
85 | " pass\n",
86 | "\n",
87 | "fahrenheit_to_kelvin(0)"
88 | ]
89 | },
90 | {
91 | "cell_type": "markdown",
92 | "metadata": {},
93 | "source": [
94 | "Finally, implement a more general conversion function that takes as arguments also the input and output scales, e.g. **from_scale** and **to_scale**. Provide default values for **from_scale** and **to_scale**, and call the function with different number of arguments. Try to call the function using both positional and keyword arguments. Which approach is more readable for you?"
95 | ]
96 | },
97 | {
98 | "cell_type": "code",
99 | "execution_count": null,
100 | "metadata": {
101 | "collapsed": true
102 | },
103 | "outputs": [],
104 | "source": []
105 | },
106 | {
107 | "cell_type": "markdown",
108 | "metadata": {},
109 | "source": [
110 | "## Exceptions\n",
111 | "\n",
112 | "Ok, here's some code that fails. Find out at least 2 errors it raises by giving different inputs.\n",
113 | "\n",
114 | "Then construct a ``try-except`` clause around the lines of code."
115 | ]
116 | },
117 | {
118 | "cell_type": "code",
119 | "execution_count": null,
120 | "metadata": {
121 | "collapsed": true
122 | },
123 | "outputs": [],
124 | "source": [
125 | "var = float(input(\"give a number: \"))\n",
126 | "divided = 1/var"
127 | ]
128 | },
129 | {
130 | "cell_type": "markdown",
131 | "metadata": {},
132 | "source": [
133 | "The `open` function is used to open files for reading or writing. We'll get to that but first let's try to open a file that doesn't exist.\n",
134 | "\n",
135 | "Filesystem related errors are very common. A file might not exist or for some reason the user might not have the rights to open the file. Go ahead and make a try-except clause to catch this error."
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": null,
141 | "metadata": {
142 | "collapsed": true
143 | },
144 | "outputs": [],
145 | "source": [
146 | "file_handle = open(\"i_dont_exist\", \"r\")"
147 | ]
148 | },
149 | {
150 | "cell_type": "markdown",
151 | "metadata": {},
152 | "source": [
153 | "## Compound"
154 | ]
155 | },
156 | {
157 | "cell_type": "markdown",
158 | "metadata": {},
159 | "source": [
160 | "Implement the three remaining functions so you can convert freely between Fahrenheit and Kelvin.\n",
161 | "\n",
162 | "Now look at the temperature_converter function. Try to figure out what errors malformed user input can cause. You can either wrap the function call in a ``try-except`` or you can wrap parts of the function.\n",
163 | "\n",
164 | "If you have time you can increase the complexity of the function to cover centigrade conversions as well but this is not required. Hint: if you always convert the value to centigrade if it is not and to the desired output if desired output is not you can simplify the code."
165 | ]
166 | },
167 | {
168 | "cell_type": "code",
169 | "execution_count": null,
170 | "metadata": {
171 | "collapsed": true
172 | },
173 | "outputs": [],
174 | "source": [
175 | "def celsius_to_fahrenheit(c):\n",
176 | " pass\n",
177 | "\n",
178 | "def kelvin_to_celsius(k):\n",
179 | " pass\n",
180 | "\n",
181 | "def kelvin_to_fahrenheit(k):\n",
182 | " pass\n",
183 | "\n",
184 | "def temperature_converter():\n",
185 | " from_scale = input(\"Give scale to convert from: \")\n",
186 | " to_scale = input(\"Give scale to convert to: \")\n",
187 | " value = float(input(\"Give temperature: \"))\n",
188 | " if from_scale == \"K\" and to_scale == \"F\":\n",
189 | " return kelvin_to_fahrenheit(value)\n",
190 | " elif from_scale == \"F\" and to_scale == \"K\":\n",
191 | " return fahrenheit_to_kelvin\n",
192 | " elif from_scale == \"C\" or to_scale == \"C\":\n",
193 | " raise NotImplementedError(\"Conversion to Celsius not implemented!\")\n",
194 | " return\n",
195 | "\n",
196 | "temperature_converter()"
197 | ]
198 | }
199 | ],
200 | "metadata": {
201 | "kernelspec": {
202 | "display_name": "Python 3",
203 | "language": "python",
204 | "name": "python3"
205 | },
206 | "language_info": {
207 | "codemirror_mode": {
208 | "name": "ipython",
209 | "version": 3
210 | },
211 | "file_extension": ".py",
212 | "mimetype": "text/x-python",
213 | "name": "python",
214 | "nbconvert_exporter": "python",
215 | "pygments_lexer": "ipython3",
216 | "version": "3.4.9"
217 | }
218 | },
219 | "nbformat": 4,
220 | "nbformat_minor": 2
221 | }
222 |
--------------------------------------------------------------------------------
/notebooks/exercises/5 - Modules.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Modules"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "## import\n",
15 | "Let's start by using a module. \n",
16 | "\n",
17 | "There is a module called `sample_module` in the same directory as this notebook. Inside it there is a function called `sample_function`.\n",
18 | "\n",
19 | "Import the function and call it to see what happens. Can you do the import in two different ways?"
20 | ]
21 | },
22 | {
23 | "cell_type": "code",
24 | "execution_count": null,
25 | "metadata": {},
26 | "outputs": [],
27 | "source": []
28 | },
29 | {
30 | "cell_type": "markdown",
31 | "metadata": {},
32 | "source": [
33 | "## import as\n",
34 | "\n",
35 | "It is possible to rename the function you are importing by using the syntax\n",
36 | "\n",
37 | "```from module import function_name as another_function_name\n",
38 | "```\n",
39 | "\n",
40 | "Go ahead and import `sample_function` using a more descriptive name and call it."
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": null,
46 | "metadata": {
47 | "collapsed": true
48 | },
49 | "outputs": [],
50 | "source": []
51 | },
52 | {
53 | "cell_type": "markdown",
54 | "metadata": {},
55 | "source": [
56 | "## Creating a module\n",
57 | "\n",
58 | "Now create a module called mymodule (i.e. mymodule.py) using the text editor functionality of Jupyter Notebooks.\n",
59 | "\n",
60 | "Add the following code to the module.\n",
61 | "\n",
62 | "```\n",
63 | "def add(a, b):\n",
64 | " return a + b\n",
65 | "```\n",
66 | "\n",
67 | "Save the file and import your newly created module in the cell below.\n",
68 | "\n",
69 | "If you want you can also use a more inventive name than mymodule.py."
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": null,
75 | "metadata": {
76 | "collapsed": true
77 | },
78 | "outputs": [],
79 | "source": []
80 | },
81 | {
82 | "cell_type": "markdown",
83 | "metadata": {},
84 | "source": [
85 | "## Extra: reloading the module\n",
86 | "\n",
87 | "Add a new function ``subtract`` to your above module and try to import it again. Are you able to use the ``subtract`` function?"
88 | ]
89 | },
90 | {
91 | "cell_type": "code",
92 | "execution_count": null,
93 | "metadata": {},
94 | "outputs": [],
95 | "source": []
96 | },
97 | {
98 | "cell_type": "markdown",
99 | "metadata": {},
100 | "source": [
101 | "Python keeps track of modules that are imported, and performs the actual import only with the first ``import mymodule`` statement. If a module is modified during an interactive session, module needs to be explicitly reloaded in order to changes take effect. Reloading can be done with the function ``reload`` in the built-in module ``importlib``:"
102 | ]
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": null,
107 | "metadata": {
108 | "collapsed": true
109 | },
110 | "outputs": [],
111 | "source": [
112 | "from importlib import reload\n",
113 | "reload(mymodule)"
114 | ]
115 | }
116 | ],
117 | "metadata": {
118 | "kernelspec": {
119 | "display_name": "Python 3",
120 | "language": "python",
121 | "name": "python3"
122 | },
123 | "language_info": {
124 | "codemirror_mode": {
125 | "name": "ipython",
126 | "version": 3
127 | },
128 | "file_extension": ".py",
129 | "mimetype": "text/x-python",
130 | "name": "python",
131 | "nbconvert_exporter": "python",
132 | "pygments_lexer": "ipython3",
133 | "version": "3.4.9"
134 | }
135 | },
136 | "nbformat": 4,
137 | "nbformat_minor": 2
138 | }
139 |
--------------------------------------------------------------------------------
/notebooks/exercises/6 - File IO and String processing.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Exercises"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {
13 | "collapsed": true
14 | },
15 | "source": [
16 | "# Simple reading\n",
17 | "\n",
18 | "The file \"../data/coordinates.txt\" contains list of (x, y) value pairs.\n",
19 | "Read the values into two lists x and y."
20 | ]
21 | },
22 | {
23 | "cell_type": "code",
24 | "execution_count": null,
25 | "metadata": {
26 | "collapsed": true
27 | },
28 | "outputs": [],
29 | "source": []
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "metadata": {},
34 | "source": [
35 | "## Nontrivial reading and conversion\n",
36 | "\n",
37 | "The file \"../data/CH4.pdb\" contains the coordinates of methane molecule in a PDB format. The file consists of header followed by record lines which contain the following fields:\n",
38 | "\n",
39 | "record name(=ATOM), atom serial number, atom name, x-,y-,z-coordinates, occupancy and temperature factor.\n",
40 | "\n",
41 | "i.e.\n",
42 | "```\n",
43 | "ATOM 2 H -0.627 -0.627 0.627 0.00 0.00\n",
44 | "```\n",
45 | "\n",
46 | "Convert the file into XYZ format: first line contains the\n",
47 | "number of atoms, second line is title string, and the\n",
48 | "following lines contain the atomic symbols and x-, y-, z-\n",
49 | "coordinates, all separated by white space. Write the\n",
50 | "coordinates with 6 decimals:\n",
51 | "\n",
52 | "```\n",
53 | "5\n",
54 | "Converted from PDB\n",
55 | "C 0.000000 0.000000 0.000000\n",
56 | "...\n",
57 | "```\n",
58 | "Only focus on printing the output now. Writing into a file comes next.\n",
59 | "\n",
60 | "Hints:\n",
61 | "\n",
62 | "* separating the conversion logic to a function may help with readability and re-usability of your code"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": null,
68 | "metadata": {
69 | "collapsed": true
70 | },
71 | "outputs": [],
72 | "source": []
73 | },
74 | {
75 | "cell_type": "markdown",
76 | "metadata": {
77 | "collapsed": true
78 | },
79 | "source": [
80 | "## Writing\n",
81 | "\n",
82 | "Go ahead and edit the code above to write the output to a file.\n"
83 | ]
84 | },
85 | {
86 | "cell_type": "code",
87 | "execution_count": null,
88 | "metadata": {
89 | "collapsed": true
90 | },
91 | "outputs": [],
92 | "source": []
93 | },
94 | {
95 | "cell_type": "markdown",
96 | "metadata": {},
97 | "source": [
98 | "# Bonus exercises"
99 | ]
100 | },
101 | {
102 | "cell_type": "markdown",
103 | "metadata": {},
104 | "source": [
105 | "## Delimiter separated values\n",
106 | "\n",
107 | "Many data exchange formats are so-called *[delimiter separated values](https://en.wikipedia.org/wiki/Delimiter-separated_values)*. The most commonly known of these is [CSV](https://en.wikipedia.org/wiki/Comma-separated_values).\n",
108 | "\n",
109 | "There are multiple caveats in the format, e.g. European languages use comma (,) as a decimal separator and semicolon (;) as the field separator. Most pure-English systems use the dot (.) for decimal separation and the comma (,) for field separation. \n",
110 | "\n",
111 | "Another family of systems uses whitespace, like space or tab characters to separate fields.\n",
112 | "\n",
113 | "Python's [csv](https://docs.python.org/3/library/csv.html) library supports most of the variance in different formats and it can be a time-saving tool to those who use Python and deal with file formats a lot.\n",
114 | "\n",
115 | "The file \"../data/iris.data\" is actually in CSV format even though the file ending doesn't explicitly say so (this is common).\n",
116 | "\n",
117 | "Read in iris.data and write out a tab-separated file \"iris.tsv\" using the `csv` module.\n",
118 | "\n",
119 | "Hint: because the first line of the input file has labels, csv.DictReader and csv.DictWriter are a good choice."
120 | ]
121 | },
122 | {
123 | "cell_type": "code",
124 | "execution_count": null,
125 | "metadata": {
126 | "collapsed": true
127 | },
128 | "outputs": [],
129 | "source": []
130 | },
131 | {
132 | "cell_type": "markdown",
133 | "metadata": {},
134 | "source": [
135 | "## Counting words\n",
136 | "\n",
137 | "The file \"../data/word_count.txt\" contains a short piece of text. Determine the frequency of words in the file, i.e. how many times each word appears. Print out the ten most frequent words.\n",
138 | "\n",
139 | "Read the file line by line and use the split() function for separating a line into words.\n",
140 | "The frequencies are stored most conveniently into a dictionary. The dictionary method **setdefault** can be useful\n",
141 | "here. \n",
142 | "\n",
143 | "For sorting, convert the dictionary into a list of (key, value) pairs with the items() function:\n",
144 | "```\n",
145 | "words = {\"foo\" : 1, \"bar\" : 2}\n",
146 | "print(words.items())\n",
147 | "[('foo', 1), ('bar', 2)]\n",
148 | "```"
149 | ]
150 | },
151 | {
152 | "cell_type": "code",
153 | "execution_count": null,
154 | "metadata": {
155 | "collapsed": true
156 | },
157 | "outputs": [],
158 | "source": []
159 | },
160 | {
161 | "cell_type": "markdown",
162 | "metadata": {},
163 | "source": [
164 | "## Reading nucleotide sequences\n",
165 | "\n",
166 | "Fasta is a fileformat for storing nucleotide sequences. The sequences consist of header line, starting with **>**, followed by one or more lines containing the amino acids of the sequence presented by single-letter codes:\n",
167 | "```\n",
168 | ">5IRE:A|PDBID|CHAIN|SEQUENCE\n",
169 | "IRCIGVSNRDFVEGMSGGTWVDVVLEHGGCVTVMAQDKPTVDIELVTTTVSNMAEVRSYCYEASISDMASDSRCPTQGEA\n",
170 | "YLDKQSDTQYVCKRTLVDRGWGNGCGLFGKGSLVTCAKFACSKKMTGKSIQPENLEYRIMLSVHGSQHSGMIVNDTGHET\n",
171 | "...\n",
172 | "```\n",
173 | "The file \"../data/5ire.fasta\" contains sequences for multiple chains of Zika virus. Read from the file the sequence of chain C (the chain ids are given in the header, i.e. the chain above is A).\n",
174 | "\n",
175 | "Find out which chains contain the subsequence **LDFSDL**.\n",
176 | "\n",
177 | "Hints: \n",
178 | "\n",
179 | "* as the sequence is given in multiple lines, you should combine all the lines of a sequence into a single string. String object's **.strip()** method which removes newlines from the end of string is useful here.\n",
180 | "* you can split reading and converting to a standard format to a function to create a re-usable component and then separate the subsequence finding to another function\n"
181 | ]
182 | },
183 | {
184 | "cell_type": "code",
185 | "execution_count": null,
186 | "metadata": {
187 | "collapsed": true
188 | },
189 | "outputs": [],
190 | "source": []
191 | }
192 | ],
193 | "metadata": {
194 | "kernelspec": {
195 | "display_name": "Python 3",
196 | "language": "python",
197 | "name": "python3"
198 | },
199 | "language_info": {
200 | "codemirror_mode": {
201 | "name": "ipython",
202 | "version": 3
203 | },
204 | "file_extension": ".py",
205 | "mimetype": "text/x-python",
206 | "name": "python",
207 | "nbconvert_exporter": "python",
208 | "pygments_lexer": "ipython3",
209 | "version": "3.4.9"
210 | }
211 | },
212 | "nbformat": 4,
213 | "nbformat_minor": 2
214 | }
215 |
--------------------------------------------------------------------------------
/notebooks/exercises/7 - NumPy.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "collapsed": true
7 | },
8 | "source": [
9 | "# Exercises"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {},
15 | "source": [
16 | "## Simple array manipulation\n",
17 | "\n",
18 | "Investigate the behavior of the statements below by looking\n",
19 | "at the values of the arrays a and b after assignments:\n",
20 | "```\n",
21 | "a = np.arange(5)\n",
22 | "b = a\n",
23 | "b[2] = -1\n",
24 | "b = a[:]\n",
25 | "b[1] = -1\n",
26 | "b = a.copy()\n",
27 | "b[0] = -1\n",
28 | "```"
29 | ]
30 | },
31 | {
32 | "cell_type": "code",
33 | "execution_count": null,
34 | "metadata": {
35 | "collapsed": true
36 | },
37 | "outputs": [],
38 | "source": []
39 | },
40 | {
41 | "cell_type": "markdown",
42 | "metadata": {},
43 | "source": [
44 | "Generate a 1D NumPy array containing numbers from -2 to 2\n",
45 | "in increments of 0.2. Use optional start and step arguments\n",
46 | "of **np.arange()** function."
47 | ]
48 | },
49 | {
50 | "cell_type": "code",
51 | "execution_count": null,
52 | "metadata": {
53 | "collapsed": true
54 | },
55 | "outputs": [],
56 | "source": []
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "Generate another 1D NumPy array containing 11 equally\n",
63 | "spaced values between 0.5 and 1.5. Extract every second\n",
64 | "element of the array"
65 | ]
66 | },
67 | {
68 | "cell_type": "code",
69 | "execution_count": null,
70 | "metadata": {
71 | "collapsed": true
72 | },
73 | "outputs": [],
74 | "source": []
75 | },
76 | {
77 | "cell_type": "markdown",
78 | "metadata": {},
79 | "source": [
80 | "Create a 4x4 array with arbitrary values."
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": null,
86 | "metadata": {
87 | "collapsed": true
88 | },
89 | "outputs": [],
90 | "source": []
91 | },
92 | {
93 | "cell_type": "markdown",
94 | "metadata": {},
95 | "source": [
96 | "Extract every element from the second row"
97 | ]
98 | },
99 | {
100 | "cell_type": "code",
101 | "execution_count": null,
102 | "metadata": {
103 | "collapsed": true
104 | },
105 | "outputs": [],
106 | "source": []
107 | },
108 | {
109 | "cell_type": "markdown",
110 | "metadata": {},
111 | "source": [
112 | "Extract every element from the third column"
113 | ]
114 | },
115 | {
116 | "cell_type": "code",
117 | "execution_count": null,
118 | "metadata": {
119 | "collapsed": true
120 | },
121 | "outputs": [],
122 | "source": []
123 | },
124 | {
125 | "cell_type": "markdown",
126 | "metadata": {},
127 | "source": [
128 | "Assign a value of 0.21 to upper left 2x2 subarray."
129 | ]
130 | },
131 | {
132 | "cell_type": "code",
133 | "execution_count": null,
134 | "metadata": {
135 | "collapsed": true
136 | },
137 | "outputs": [],
138 | "source": []
139 | },
140 | {
141 | "cell_type": "markdown",
142 | "metadata": {},
143 | "source": [
144 | "## Simple plotting\n",
145 | "\n",
146 | "Plot to the same graph **sin** and **cos** functions in the interval $[-\\pi/2, \\pi/2]$. Use $\\theta$ as x-label and insert also legends."
147 | ]
148 | },
149 | {
150 | "cell_type": "code",
151 | "execution_count": null,
152 | "metadata": {
153 | "collapsed": true
154 | },
155 | "outputs": [],
156 | "source": []
157 | },
158 | {
159 | "cell_type": "markdown",
160 | "metadata": {},
161 | "source": [
162 | "## Pie chart\n",
163 | "\n",
164 | "The file \"../data/csc_usage.txt\" contains the usage of CSC servers by different disciplines. Plot a pie chart about the resource usage."
165 | ]
166 | },
167 | {
168 | "cell_type": "code",
169 | "execution_count": null,
170 | "metadata": {
171 | "collapsed": true
172 | },
173 | "outputs": [],
174 | "source": []
175 | },
176 | {
177 | "cell_type": "markdown",
178 | "metadata": {},
179 | "source": [
180 | "## Bonus exercises\n",
181 | "\n",
182 | "### Numerical derivative with finite differences\n",
183 | "\n",
184 | "Derivatives can be calculated numerically with the finite-difference method\n",
185 | "as: \n",
186 | "\n",
187 | "$$ f'(x_i) = \\frac{f(x_i + \\Delta x)- f(x_i - \\Delta x)}{2 \\Delta x} $$\n",
188 | "\n",
189 | "Construct 1D Numpy array containing the values of xi in the interval $[0, \\pi/2]$ with spacing\n",
190 | "$\\Delta x = 0.1$. Evaluate numerically the derivative of **sin** in this\n",
191 | "interval (excluding the end points) using the above formula. Try to avoid\n",
192 | "`for` loops. Compare the result to function **cos** in the same interval."
193 | ]
194 | },
195 | {
196 | "cell_type": "code",
197 | "execution_count": null,
198 | "metadata": {
199 | "collapsed": true
200 | },
201 | "outputs": [],
202 | "source": []
203 | },
204 | {
205 | "cell_type": "markdown",
206 | "metadata": {},
207 | "source": [
208 | "### Game of Life\n",
209 | "\n",
210 | "Game of life is a cellular automaton devised by John Conway\n",
211 | "in 70's: http://en.wikipedia.org/wiki/Conway's_Game_of_Life\n",
212 | "\n",
213 | "The game consists of two dimensional orthogonal grid of\n",
214 | "cells. Cells are in two possible states, alive or dead. Each cell\n",
215 | "interacts with its eight neighbours, and at each time step the\n",
216 | "following transitions occur:\n",
217 | "* Any live cell with fewer than two live neighbours dies, as if\n",
218 | "caused by underpopulation\n",
219 | "* Any live cell with more than three live neighbours dies, as if\n",
220 | "by overcrowding\n",
221 | "* Any live cell with two or three live neighbours lives on to\n",
222 | "the next generation\n",
223 | "* Any dead cell with exactly three live neighbours becomes a\n",
224 | "live cell\n",
225 | "\n",
226 | "The initial pattern constitutes the seed of the system, and\n",
227 | "the system is left to evolve according to rules. Deads and\n",
228 | "births happen simultaneously.\n",
229 | "\n",
230 | "Implement the Game of Life using Numpy, and visualize the\n",
231 | "evolution with Matplotlib's **imshow**. Try first 32x32\n",
232 | "square grid and cross-shaped initial pattern:\n",
233 | "\n",
234 | "Try also other grids and initial patterns (e.g. random\n",
235 | "pattern). Try to avoid **for** loops."
236 | ]
237 | },
238 | {
239 | "cell_type": "code",
240 | "execution_count": null,
241 | "metadata": {
242 | "collapsed": true
243 | },
244 | "outputs": [],
245 | "source": []
246 | }
247 | ],
248 | "metadata": {
249 | "kernelspec": {
250 | "display_name": "Python 3",
251 | "language": "python",
252 | "name": "python3"
253 | },
254 | "language_info": {
255 | "codemirror_mode": {
256 | "name": "ipython",
257 | "version": 3
258 | },
259 | "file_extension": ".py",
260 | "mimetype": "text/x-python",
261 | "name": "python",
262 | "nbconvert_exporter": "python",
263 | "pygments_lexer": "ipython3",
264 | "version": "3.4.9"
265 | }
266 | },
267 | "nbformat": 4,
268 | "nbformat_minor": 2
269 | }
270 |
--------------------------------------------------------------------------------
/notebooks/exercises/8 - Object oriented programming.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Object oriented programming"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "## Using an object\n",
15 | "\n",
16 | "Below is the definition of an object. Run the cell and create at least two instances of it."
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": null,
22 | "metadata": {},
23 | "outputs": [],
24 | "source": [
25 | "class Car:\n",
26 | " \n",
27 | " def __init__(self, make, model, year, mpg=25, tank_capacity=30.0, miles=0):\n",
28 | " self.make = make\n",
29 | " self.model = model\n",
30 | " self.year = year\n",
31 | " self.mpg = mpg\n",
32 | " self.gallons_in_tank = tank_capacity # cars start with a full tank\n",
33 | " self.tank_capacity = tank_capacity\n",
34 | " self.miles = miles\n",
35 | " \n",
36 | " def __str__(self):\n",
37 | " return \"{} {} ({}), {} miles and {} gallons in tank\".format(self.make, \n",
38 | " self.model, \n",
39 | " self.year, \n",
40 | " self.miles, \n",
41 | " self.gallons_in_tank)\n",
42 | " \n",
43 | " def drive(self, new_miles):\n",
44 | " \"\"\"Drive the car X miles and return number of miles driven.\n",
45 | " If there is not enough fuel, drive 0 miles.\"\"\"\n",
46 | " fuel_need = new_miles/self.mpg\n",
47 | " if fuel_need <= self.gallons_in_tank:\n",
48 | " self.miles = self.miles + new_miles\n",
49 | " self.gallons_in_tank = self.gallons_in_tank - fuel_need\n",
50 | " return new_miles\n",
51 | " else:\n",
52 | " return 0\n",
53 | " \n",
54 | " "
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": null,
60 | "metadata": {},
61 | "outputs": [],
62 | "source": []
63 | },
64 | {
65 | "cell_type": "markdown",
66 | "metadata": {},
67 | "source": [
68 | "## Simple modification to class\n",
69 | "\n",
70 | "OK, our car has a major problem: it can't be filled up.\n",
71 | "\n",
72 | "Add a method called `fill_up()` to your class. It is up to you if you want to enable filling by an arbitary number or only back to the full state.\n",
73 | "\n",
74 | "If you allow arbitary amounts of liquid remember to consider overfilling the tank.\n",
75 | "\n",
76 | "Once you edit your class, the old objects do not automatically adopt to the changes you made. You will need to re-create them."
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "metadata": {},
82 | "source": [
83 | "## Exceptions"
84 | ]
85 | },
86 | {
87 | "cell_type": "markdown",
88 | "metadata": {},
89 | "source": [
90 | "Now make a modification to the `drive`-method: if an attempt is made to drive more than the gas will allow, create and raise an exception.\n",
91 | "\n",
92 | "Instead of creating your own exception you may use a [ValueError](https://docs.python.org/3/library/exceptions.html#ValueError) for this case, as it is a logical choice.\n",
93 | "\n",
94 | "Then add a try-except clause to the following:"
95 | ]
96 | },
97 | {
98 | "cell_type": "code",
99 | "execution_count": null,
100 | "metadata": {},
101 | "outputs": [],
102 | "source": [
103 | "suv = Car(\"Ford\", \"Escape\", 2017, mpg=18, tank_capacity=30)\n",
104 | "suv.drive(600)"
105 | ]
106 | },
107 | {
108 | "cell_type": "markdown",
109 | "metadata": {},
110 | "source": [
111 | "## Bonus exercises\n",
112 | "\n",
113 | "### Magic methods\n",
114 | "\n",
115 | "Create a class called element for storing the following data\n",
116 | "* name\n",
117 | "* symbol\n",
118 | "* atomic number\n",
119 | "* molecular weight\n",
120 | "\n",
121 | "You can use the following data for creating instances of a few elements:\n",
122 | "\n",
123 | "| Element | symbol | atomic number | molecular weight |\n",
124 | "|----------|--------|---------------|---------------|\n",
125 | "| Hydrogen | H | 1 | 1.01 |\n",
126 | "| Iron | Fe | 26 | 55.85 |\n",
127 | "| Silver | Ag | 47 | 107.87 |\n"
128 | ]
129 | },
130 | {
131 | "cell_type": "code",
132 | "execution_count": null,
133 | "metadata": {
134 | "collapsed": true
135 | },
136 | "outputs": [],
137 | "source": []
138 | },
139 | {
140 | "cell_type": "markdown",
141 | "metadata": {},
142 | "source": [
143 | "Next, we would like to be able to sort elements according to their atomic number. In order to do this, let's implement magic methods ``__lt__`` and ``__eq__`` as described [here](https://docs.python.org/3.5/reference/datamodel.html#object.__lt__).\n",
144 | "\n",
145 | "Once finished, store few instances of a elements in a list, and try to sort it using list's ``sort`` method."
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": null,
151 | "metadata": {
152 | "collapsed": true
153 | },
154 | "outputs": [],
155 | "source": []
156 | }
157 | ],
158 | "metadata": {
159 | "kernelspec": {
160 | "display_name": "Python 3",
161 | "language": "python",
162 | "name": "python3"
163 | },
164 | "language_info": {
165 | "codemirror_mode": {
166 | "name": "ipython",
167 | "version": 3
168 | },
169 | "file_extension": ".py",
170 | "mimetype": "text/x-python",
171 | "name": "python",
172 | "nbconvert_exporter": "python",
173 | "pygments_lexer": "ipython3",
174 | "version": "3.4.9"
175 | }
176 | },
177 | "nbformat": 4,
178 | "nbformat_minor": 1
179 | }
180 |
--------------------------------------------------------------------------------
/notebooks/exercises/Advanced Object oriented programming.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Object-oriented programming"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "This notebooks contains assingments that are more complex. They are aimed at students who already know about [object- oriented Programming](https://en.wikipedia.org/wiki/Object-oriented_programming) from prior experience and who are familiar with the concepts but now how OOP is done on Python.\n",
15 | "\n",
16 | "The scope of this introduction is insufficient to give a good tutorial on OOP as a whole.\n",
17 | "\n",
18 | "Our first example is an example of composition. We create a Company that consists a list of Persons and an account balance.\n",
19 | "\n",
20 | "Then after we structure our classes with desired behaviour we can use them quite freely.\n",
21 | "\n",
22 | "Create a class called Person for storing the following information about a person:\n",
23 | "- name\n",
24 | "\n",
25 | "Create a method say_hi that returns the string \"Hi, I'm \" + the person's name."
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": null,
31 | "metadata": {},
32 | "outputs": [],
33 | "source": [
34 | "class Person:\n",
35 | " def __init__(self, name):\n",
36 | " pass\n",
37 | " \n",
38 | " def say_hi(self):\n",
39 | " pass"
40 | ]
41 | },
42 | {
43 | "cell_type": "markdown",
44 | "metadata": {},
45 | "source": [
46 | "Run the following code to test that you have created the person correctly:"
47 | ]
48 | },
49 | {
50 | "cell_type": "code",
51 | "execution_count": null,
52 | "metadata": {
53 | "collapsed": true
54 | },
55 | "outputs": [],
56 | "source": [
57 | "persons = []\n",
58 | "joe = Person(\"Joe\")\n",
59 | "jane = Person(\"Jane\")\n",
60 | "persons.append(joe)\n",
61 | "persons.append(jane)"
62 | ]
63 | },
64 | {
65 | "cell_type": "markdown",
66 | "metadata": {},
67 | "source": [
68 | "Now create a class Employee that **inherits** the class Person. \n",
69 | "In addition to a name, Employees have a title (string), \n",
70 | "salary (number) and an account_balance (number).\n",
71 | "\n",
72 | "**Override** the say_hi method to say \"Hi I'm \" + name + \" and i work as a \" + title"
73 | ]
74 | },
75 | {
76 | "cell_type": "code",
77 | "execution_count": null,
78 | "metadata": {},
79 | "outputs": [],
80 | "source": [
81 | "# the reference to Person on the line below means that the object inherits \n",
82 | "# Employee\n",
83 | "class Employee(Person):\n",
84 | " def __init__(self, \n",
85 | " name, \n",
86 | " salary, \n",
87 | " title=\"Software Specialist\", \n",
88 | " account_balance=0):\n",
89 | " # this calls the constructor of Person class\n",
90 | " super().__init__(name)\n",
91 | " # you still need to implement the rest\n",
92 | " pass\n",
93 | " \n",
94 | " def say_hi(self):\n",
95 | " pass"
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "metadata": {},
101 | "source": [
102 | "Every employee is also a person. "
103 | ]
104 | },
105 | {
106 | "cell_type": "code",
107 | "execution_count": null,
108 | "metadata": {},
109 | "outputs": [],
110 | "source": [
111 | "persons = []\n",
112 | "joe = Person(\"Joe\")\n",
113 | "jane = Person(\"Jane\")\n",
114 | "persons.append(joe)\n",
115 | "persons.append(jane)\n",
116 | "emp1 = Employee(\"Jack\", 3000)\n",
117 | "emp2 = Employee(\"Jill\", 3000)\n",
118 | "persons.append(emp1)\n",
119 | "persons.append(emp2)\n",
120 | "for person in persons:\n",
121 | " print(person.say_hi())"
122 | ]
123 | },
124 | {
125 | "cell_type": "markdown",
126 | "metadata": {},
127 | "source": [
128 | "Now create a class called Company, which has a name \n",
129 | "and a list of Employee objects called `employees` and an \n",
130 | "account balance for the company.\n",
131 | "\n",
132 | "Make a method `payday(self)` that will go through \n",
133 | "the list of employees and deduct their salary from \n",
134 | "the corporate account and add it to the employee \n",
135 | "account. Before you start deducting money compute the sum of salaries and make sure it is higher than the account balance. If it is not, raise an instance of the NotEnoughMoneyError. \n",
136 | "\n",
137 | "Make a method `layoff(self)` that will remove\n",
138 | "one employe from the list of employees. If there are no more employees raise a NoMoreEmployeesException."
139 | ]
140 | },
141 | {
142 | "cell_type": "code",
143 | "execution_count": null,
144 | "metadata": {},
145 | "outputs": [],
146 | "source": [
147 | "class NotEnoughMoneyError(Exception):\n",
148 | " pass\n",
149 | "\n",
150 | "class NoMoreEmployeesError(Exception):\n",
151 | " pass\n",
152 | "\n",
153 | "class Company(object):\n",
154 | " def __init__(self, title, employees = [], account_balance=0):\n",
155 | " pass\n",
156 | " \n",
157 | "\n",
158 | " def payday(self):\n",
159 | " pass\n",
160 | "\n",
161 | " def layoff(self):\n",
162 | " pass"
163 | ]
164 | },
165 | {
166 | "cell_type": "markdown",
167 | "metadata": {},
168 | "source": [
169 | "Okay, you've worked this far just creating the model, let's put it to use.\n",
170 | "\n",
171 | "Make a method `smart_payday(company)`. The method should attempt to call the payday method of the company. If the call raises a NotEnoughMoneyException lay off a worker and then try again. Don't catch the NoMoreEmployeesException as that should be handled at a higher level.\n",
172 | "\n",
173 | "You will probably need to use a while loop to implement the re-trying until a condition is met."
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "execution_count": null,
179 | "metadata": {},
180 | "outputs": [],
181 | "source": [
182 | "def smart_payday(company):\n",
183 | " pass"
184 | ]
185 | },
186 | {
187 | "cell_type": "code",
188 | "execution_count": null,
189 | "metadata": {},
190 | "outputs": [],
191 | "source": [
192 | "# a bit of test code\n",
193 | "names_and_salaries = [\n",
194 | " (\"Jane\", 3000), \n",
195 | " (\"Joe\", 2000),\n",
196 | " (\"Jill\", 2000),\n",
197 | " (\"Jack\", 1500)\n",
198 | "]\n",
199 | "\n",
200 | "workers = [Employee(name, salary) \\\n",
201 | " for name, salary in names_and_salaries]\n",
202 | "scs = Company(\"SCS\", employees=workers, account_balance=12000)\n",
203 | "\n",
204 | "smart_payday(scs)\n",
205 | "print(scs.account_balance)\n",
206 | "print(len(scs.employees))\n",
207 | "smart_payday(scs)\n",
208 | "print(scs.account_balance)\n",
209 | "print(len(scs.employees))\n",
210 | "print(scs.employees)"
211 | ]
212 | },
213 | {
214 | "cell_type": "markdown",
215 | "metadata": {
216 | "collapsed": true
217 | },
218 | "source": [
219 | "Observe how printing the employees list is not very informative? Adding a magic method called `__repr__` will help with that."
220 | ]
221 | },
222 | {
223 | "cell_type": "markdown",
224 | "metadata": {},
225 | "source": [
226 | "## Extra: more Exceptions"
227 | ]
228 | },
229 | {
230 | "cell_type": "markdown",
231 | "metadata": {},
232 | "source": [
233 | "Consider the following method, it will raise errors randomly. This type of failure is pretty common for IO-related tasks."
234 | ]
235 | },
236 | {
237 | "cell_type": "code",
238 | "execution_count": null,
239 | "metadata": {
240 | "collapsed": true
241 | },
242 | "outputs": [],
243 | "source": [
244 | "class RandomException(Exception):\n",
245 | " pass\n",
246 | " \n",
247 | "\n",
248 | "def do_wonky_stuff():\n",
249 | " import random\n",
250 | " if random.random() > 0.5:\n",
251 | " raise RandomException(\"this exception happened randomly\")\n",
252 | " return"
253 | ]
254 | },
255 | {
256 | "cell_type": "markdown",
257 | "metadata": {},
258 | "source": [
259 | "Wrap a call to ``do_wonky_stuff`` with a try-except clause."
260 | ]
261 | },
262 | {
263 | "cell_type": "code",
264 | "execution_count": null,
265 | "metadata": {},
266 | "outputs": [],
267 | "source": [
268 | "do_wonky_stuff()\n",
269 | "print(\"yay it worked\")"
270 | ]
271 | },
272 | {
273 | "cell_type": "markdown",
274 | "metadata": {},
275 | "source": [
276 | "OK, now let's go even deeper."
277 | ]
278 | },
279 | {
280 | "cell_type": "code",
281 | "execution_count": null,
282 | "metadata": {},
283 | "outputs": [],
284 | "source": [
285 | "class ReallyRandomException(Exception):\n",
286 | " pass\n",
287 | "\n",
288 | "def do_really_wonky_stuff():\n",
289 | " import random\n",
290 | " val = random.random()\n",
291 | " if val > 0.75:\n",
292 | " raise RandomException(\"this exception happened randomly\")\n",
293 | " elif val < 0.15:\n",
294 | " raise ReallyRandomException(\"This exception is actually quite rare\")\n",
295 | " return"
296 | ]
297 | },
298 | {
299 | "cell_type": "markdown",
300 | "metadata": {},
301 | "source": [
302 | "Wrap do_really_wonky_stuff in a try-except -clause with two excepts. In the rarer of the excepts print out something so you'll if it's your lucky day.\n",
303 | "\n",
304 | "In real life you'd probably want to handle different errors in a different way, or at least log or inform the user of what caused the error."
305 | ]
306 | },
307 | {
308 | "cell_type": "code",
309 | "execution_count": null,
310 | "metadata": {},
311 | "outputs": [],
312 | "source": [
313 | "do_really_wonky_stuff()\n"
314 | ]
315 | }
316 | ],
317 | "metadata": {
318 | "kernelspec": {
319 | "display_name": "Python 3",
320 | "language": "python",
321 | "name": "python3"
322 | },
323 | "language_info": {
324 | "codemirror_mode": {
325 | "name": "ipython",
326 | "version": 3
327 | },
328 | "file_extension": ".py",
329 | "mimetype": "text/x-python",
330 | "name": "python",
331 | "nbconvert_exporter": "python",
332 | "pygments_lexer": "ipython3",
333 | "version": "3.4.9"
334 | }
335 | },
336 | "nbformat": 4,
337 | "nbformat_minor": 2
338 | }
339 |
--------------------------------------------------------------------------------
/notebooks/exercises/sample_module.py:
--------------------------------------------------------------------------------
1 | def sample_function():
2 | print("Nobody expects the Spanish inquisition!")
3 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | jupyter==1.0.0
2 |
--------------------------------------------------------------------------------