Commit 2e649b41 authored by paugier's avatar paugier
Browse files

Avant jour 2 (clean up)

parent 92266351
Pipeline #75896 passed with stage
in 52 seconds
%% Cell type:markdown id: tags:
# Python training UGA 2017
# Python training UGA 2021
**A training to acquire strong basis in Python to use it efficiently**
Pierre Augier (LEGI), Cyrille Bonamy (LEGI), Eric Maldonado (Irstea), Franck Thollard (ISTerre), Christophe Picard (LJK), Loïc Huder (ISTerre)
......
%% Cell type:markdown id: tags:
# Python training UGA 2017
# Python training UGA 2021
**A training to acquire strong basis in Python to use it efficiently**
Pierre Augier (LEGI), Cyrille Bonamy (LEGI), Eric Maldonado (Irstea), Franck Thollard (ISTerre), Christophe Picard (LJK), Loïc Huder (ISTerre)
......@@ -17,11 +17,11 @@
### [`open` built-in function](https://docs.python.org/3/library/functions.html#open) and file object
%% Cell type:code id: tags:
``` python
file = open('../pyfiles/helloworld.py')
file = open("../pyfiles/helloworld.py")
txt = file.read()
file.close()
print(txt)
```
......@@ -41,11 +41,11 @@
For such objects that need to be closed, it is a good practice to use the keyword `with` (THIS IS MUCH BETTER than using the close function, USE `with`!). Like this, we are sure that the file will be closed even if there is an error:
%% Cell type:code id: tags:
``` python
with open('../pyfiles/helloworld.py') as file:
with open("../pyfiles/helloworld.py") as file:
txt = file.read()
print(txt)
```
%% Cell type:markdown id: tags:
......@@ -53,58 +53,59 @@
### Loop over lines
%% Cell type:code id: tags:
``` python
with open('../pyfiles/helloworld.py') as file:
with open("../pyfiles/helloworld.py") as file:
for line in file:
print(f'line ?: ' + line.strip())
print(f"line ?: " + line.strip())
```
%% Cell type:markdown id: tags:
And now using `enumerate` to get the index of the line:
%% Cell type:code id: tags:
``` python
with open('../pyfiles/helloworld.py') as file:
with open("../pyfiles/helloworld.py") as file:
for i, line in enumerate(file):
print(f'line {i:2d}: {line.strip()}')
print(f"line {i:2d}: {line.strip()}")
```
%% Cell type:markdown id: tags:
### Options of the built-in function open (read, write, append)
%% Cell type:code id: tags:
``` python
from pathlib import Path
Path("tmp").mkdir(exist_ok=True)
```
%% Cell type:code id: tags:
``` python
# write data in a file
with open('tmp/zoo.txt', 'w') as file_zoo:
file_zoo.write('sam;cat;2\n')
file_zoo.write('liloo;lion;2\n')
with open('tmp/zoo.txt', 'a') as file_zoo:
file_zoo.write('peter;panda;5\n')
with open("tmp/zoo.txt", "w") as file_zoo:
file_zoo.write("sam;cat;2\n")
file_zoo.write("liloo;lion;2\n")
with open("tmp/zoo.txt", "a") as file_zoo:
file_zoo.write("peter;panda;5\n")
with open('tmp/zoo.txt') as file_zoo:
with open("tmp/zoo.txt") as file_zoo:
print(file_zoo.read())
```
%% Cell type:code id: tags:
``` python
with open('tmp/zoo.txt', 'r') as file_zoo:
with open("tmp/zoo.txt", "r") as file_zoo:
print(file_zoo.readline())
print(file_zoo.read())
```
%% Cell type:markdown id: tags:
......@@ -118,12 +119,12 @@
Until now, we have only written text files. It can of course be much more efficient to use binary format.
%% Cell type:code id: tags:
``` python
with open('/tmp/test', 'wb') as file:
file.write(b'a')
with open("/tmp/test", "wb") as file:
file.write(b"a")
```
%% Cell type:markdown id: tags:
Remarks:
......
This diff is collapsed.
%% Cell type:markdown id: tags:
# Python training UGA 2017
# Python training UGA 2021
**A training to acquire strong basis in Python to use it efficiently**
Pierre Augier (LEGI), Cyrille Bonamy (LEGI), Eric Maldonado (Irstea), Franck Thollard (ISTerre), Christophe Picard (LJK), Loïc Huder (ISTerre)
......@@ -25,11 +25,11 @@
l0 = []
l1 = list()
assert l0 == l1
# not empty lists
l2 = ['a', 2]
l2 = ["a", 2]
l3 = list(range(3))
print(l2, l3, l2 + l3)
print(3 * l2)
```
......@@ -72,15 +72,15 @@
```
%% Cell type:code id: tags:
``` python
# "pasting" two lists can be done using zip
# "pasting" two lists can be done using zip
l1 = [1, 2, 3]
s = 'abc'
s = "abc"
print(list(zip(l1, s)))
print(list(zip('abc', 'defg')))
print(list(zip("abc", "defg")))
```
%% Cell type:markdown id: tags:
### `list`: list comprehension
......@@ -91,42 +91,42 @@
``` python
l0 = [1, 4, 10]
l1 = []
for number in l0:
l1.append(number**2)
l1.append(number ** 2)
print(l1)
```
%% Cell type:markdown id: tags:
There is a more readable (and slightly more efficient) method to do such things, the "list comprehension":
%% Cell type:code id: tags:
``` python
l1 = [number**2 for number in l0]
l1 = [number ** 2 for number in l0]
print(l1)
```
%% Cell type:code id: tags:
``` python
# list comprehension with a condition
[s for s in ['a', 'bbb', 'e'] if len(s) == 1]
[s for s in ["a", "bbb", "e"] if len(s) == 1]
```
%%%% Output: execute_result
['a', 'e']
%% Cell type:code id: tags:
``` python
# lists comprehensions can be cascaded
[(x,y) for x in [1,2] for y in ['a','b'] ]
[(x, y) for x in [1, 2] for y in ["a", "b"]]
```
%%%% Output: execute_result
[(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
......@@ -144,20 +144,20 @@
t0 = ()
t1 = tuple()
assert t0 == t1
# not empty tuple
t2 = (1, 2, 'a') # with the parenthesis
t2 = 1, 2, 'a' # it also works without parenthesis
t2 = (1, 2, "a") # with the parenthesis
t2 = 1, 2, "a" # it also works without parenthesis
t3 = tuple(l3) # from a list
```
%% Cell type:code id: tags:
``` python
# tuples only have 2 public methods (with a list comprehension)
[name for name in dir(t3) if not name.startswith('__')]
[name for name in dir(t3) if not name.startswith("__")]
```
%%%% Output: execute_result
['count', 'index']
......@@ -183,10 +183,11 @@
``` python
def myfunc():
return 1, 2, 3
t = myfunc()
print(type(t), t)
# Directly unpacking the tuple
a, b, c = myfunc()
print(a, b, c)
......@@ -256,19 +257,19 @@
## DIY: back to the "find the removed element" problem
%% Cell type:code id: tags:
``` python
from random import shuffle, randint
from random import randint, shuffle
n = 20
i = randint(0, n-1)
print('integer remove from the list:', i)
i = randint(0, n - 1)
print("integer remove from the list:", i)
l = list(range(n))
l.remove(i)
shuffle(l)
print('shuffled list: ', l)
print("shuffled list: ", l)
```
%% Cell type:markdown id: tags:
- Could the problem be solved using set ?
......@@ -287,11 +288,11 @@
ns.pop()
```
%%%% Output: execute_result
8
3
%% Cell type:markdown id: tags:
### `dict`: unordered set of key: value pairs
......@@ -301,19 +302,19 @@
%% Cell type:code id: tags:
``` python
d = {}
d['b'] = 2
d['a'] = 1
d["b"] = 2
d["a"] = 1
print(d)
```
%% Cell type:code id: tags:
``` python
d = {'a': 1, 'b': 2, 0: False, 1: True}
d = {"a": 1, "b": 2, 0: False, 1: True}
print(d)
```
%% Cell type:markdown id: tags:
......@@ -367,11 +368,11 @@
%% Cell type:code id: tags:
``` python
# dict have 11 public methods (with a list comprehension)
[name for name in dir(d) if not name.startswith('__')]
[name for name in dir(d) if not name.startswith("__")]
```
%%%% Output: execute_result
['clear',
......@@ -393,11 +394,11 @@
%% Cell type:code id: tags:
``` python
# loop with items
for key, value in d.items():
if isinstance(key, str):
if isinstance(key, str):
print(key, value)
```
%% Cell type:code id: tags:
......@@ -430,11 +431,11 @@
Write a function that returns a dictionary containing the number of occurrences of letters in a text.
%% Cell type:code id: tags:
``` python
text = 'abbbcc'
text = "abbbcc"
```
%% Cell type:markdown id: tags:
#### A possible solution:
......@@ -450,8 +451,8 @@
d[letter] = 1
else:
d[letter] += 1
return d
print("text=", text, "counts=", count_elem(text))
print("text=", text, "counts=", count_elem(text))
```
......
%% Cell type:markdown id: tags:
# Python training UGA 2017
# Python training UGA 2021
**A training to acquire strong basis in Python to use it efficiently**
Pierre Augier (LEGI), Cyrille Bonamy (LEGI), Eric Maldonado (Irstea), Franck Thollard (ISTERRE), Christophe Picard (LJK), Loïc Huder (ISTerre)
......@@ -93,16 +93,16 @@
``` python
paris = {"wind": [10, 0, 20, 30, 20, 0], "temperature": [1, 5, 1, -1, -1, 3]}
def max_temp(station):
""" returns the maximum temperature available in the station"""
"""returns the maximum temperature available in the station"""
return max(station["temperature"])
def arg_max_temp(station):
""" returns the index of maximum temperature available in the station"""
"""returns the index of maximum temperature available in the station"""
max_temperature = max_temp(station)
return station["temperature"].index(max_temperature)
idx_max_temp = arg_max_temp(paris)
......@@ -129,26 +129,26 @@
%% Cell type:code id: tags:
``` python
def build_station(wind, temp):
""" Build a station given wind and temp
"""Build a station given wind and temp
:param wind: (list) floats of winds
:param temp: (list) float of temperatures
"""
if len(wind) != len(temp):
raise ValueError("wind and temperature should have the same size")
return {"wind": list(wind), "temperature": list(temp)}
def max_temp(station):
""" returns the maximum temperature available in the station"""
"""returns the maximum temperature available in the station"""
return max(station["temperature"])
def arg_max_temp(station):
""" returns the index of maximum temperature available in the station"""
"""returns the index of maximum temperature available in the station"""
max_temperature = max_temp(station)
return station["temperature"].index(max_temperature)
paris = build_station([10, 0, 20, 30, 20, 0], [1, 5, 1, -1, -1, 3])
......@@ -178,32 +178,31 @@
%% Cell type:code id: tags:
``` python
class WeatherStation:
""" A weather station that holds wind and temperature
"""A weather station that holds wind and temperature
:param wind: any ordered iterable
:param temperature: any ordered iterable
wind and temperature must have the same length.
"""
def __init__(self, wind, temperature):
self.wind = list(wind)
self.temp = list(temperature)
if len(self.wind) != len(self.temp):
raise ValueError(
"wind and temperature should have the same size"
)
raise ValueError("wind and temperature should have the same size")
def max_temp(self):
""" returns the maximum temperature recorded in the station"""
"""returns the maximum temperature recorded in the station"""
return max(self.temp)
def arg_max_temp(self):
""" returns the index of (one of the) maximum temperature recorded in the station"""
"""returns the index of (one of the) maximum temperature recorded in the station"""
return self.temp.index(self.max_temp())
paris = WeatherStation([10, 0, 20, 30, 20, 0], [1, 5, 1, -1, -1, 3])
idx_max_temp = paris.arg_max_temp()
......
%% Cell type:markdown id: tags:
# Python training UGA 2017
# Python training UGA 2021
**A training to acquire strong basis in Python to use it efficiently**
Pierre Augier (LEGI), Cyrille Bonamy (LEGI), Eric Maldonado (Irstea), Franck Thollard (ISTerre), Christophe Picard (LJK), Loïc Huder (ISTerre)
......@@ -48,33 +48,33 @@
%% Cell type:code id: tags:
``` python
class AdultBee(object):
kind = None
limit_age = 50.
limit_age = 50.0
def __init__(self, mother, father, tag=None):
self.mother = mother
self.father = father
if tag is None:
self.tag = (self.mother.tag, self.father.tag)
else:
self.tag = tag
# age in days
self.age = 0.
self.age = 0.0
self.living = True
def act_and_envolve(self, duration=1):
"""Time stepping method"""
self.age += duration
if self.age > self.limit_age:
self.die()
def die(self):
self.living = False
self.living = False
```
%% Cell type:markdown id: tags:
The first line states that instances of the class `AdultBee` will be Python objects. The class `AdultBee` inherits from the class `object`.
......@@ -94,20 +94,25 @@
We can create objects `AdultBee`. We say that we *instantiate objects of the class `AdultBee`*.
%% Cell type:code id: tags:
``` python
bee0 = AdultBee('mother0', 'father0', tag='0')
bee1 = AdultBee('mother1', 'father1', tag='1')
bee0 = AdultBee("mother0", "father0", tag="0")
bee1 = AdultBee("mother1", "father1", tag="1")
bee_second_generation0 = AdultBee(bee0, bee1)
bee_second_generation1 = AdultBee(bee0, bee1)
bee_third_generation = AdultBee(
bee_second_generation0, bee_second_generation1)
bee_third_generation = AdultBee(bee_second_generation0, bee_second_generation1)
bees = [bee0, bee1, bee_second_generation0, bee_second_generation1, bee_third_generation]
bees = [
bee0,
bee1,
bee_second_generation0,
bee_second_generation1,
bee_third_generation,
]
```
%% Cell type:markdown id: tags:
In this example, we manipulate the notions of class, object (instance), abstraction and encapsulation...
......@@ -115,11 +120,11 @@
#### Syntax to create an object
%% Cell type:code id: tags:
``` python
bee2 = AdultBee('mother2', 'father2', tag='2')
bee2 = AdultBee("mother2", "father2", tag="2")
```
%% Cell type:markdown id: tags:
#### What happens...
......@@ -154,26 +159,26 @@
### Use the objects (instances)
%% Cell type:code id: tags:
``` python
print('second generation:', bee_second_generation0.tag)
print('third generation; ', bee_third_generation.tag)
print('warning: consanguinity...')
print("second generation:", bee_second_generation0.tag)
print("third generation; ", bee_third_generation.tag)
print("warning: consanguinity...")
```
%% Cell type:code id: tags:
``` python
# 100 days
for i in range(100):
for bee in bees:
bee.act_and_envolve()
bees = [bee for bee in bees if bee.living]
if len(bees) == 0:
print('After 100 days, no more bees :-(')
print("After 100 days, no more bees :-(")
```
%% Cell type:markdown id: tags:
## Inheritance
......@@ -184,26 +189,29 @@
%% Cell type:code id: tags:
``` python
class QueenBee(AdultBee):
kind = 'queen'
limit_age = 4*365
kind = "queen"
limit_age = 4 * 365
def act_and_envolve(self, duration=1):
"""Time stepping method"""
super().act_and_envolve(duration)
print('I am the Queen!')
print("I am the Queen!")
class WorkerBee(AdultBee):
kind = 'worker'
kind = "worker"
# actually it depends on the season...
limit_age = 6*7
limit_age = 6 * 7
def dance(self):
print('I communicate by dancing')
print("I communicate by dancing")
def make_honey(self):
print('I make honey')
print("I make honey")
```
%% Cell type:markdown id: tags:
- The methods that are not rewritten are automatically inherited from the parent class.
......@@ -216,11 +224,11 @@
The class `AdultBee` that we defined is also derived from a more generic class that is called `object`. Let's check the content of the class `QueenBee`.
%% Cell type:code id: tags:
``` python
queen = QueenBee('mother0', 'father0', tag='0')
queen =