Commit 7c9c74eb authored by paugier's avatar paugier
Browse files

After training 04/2019

parent a9ceb33c
......@@ -6,10 +6,14 @@
\#*\#
ipynb/*.slides.html
.ipynb_checkpoints
*/.ipynb_checkpoints/*
**/Untitled.ipynb
**/*.egg-info/
ipynb/index.html
.vscode
\ No newline at end of file
.vscode
TP/TP2_package/mypackuga/build
TP/TP2_package/mypackuga/dist
\ No newline at end of file
......@@ -310,7 +310,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.2"
"version": "3.6.6"
}
},
"nbformat": 4,
......
......@@ -902,7 +902,7 @@
" | a | b | c | d | e | f | \n",
" +---+---+---+---+---+---+ \n",
"Slice from front: 0 1 2 3 4 5 6 \n",
"Slice from rear: -6 -5 -4 -3 -2 -1 0\n",
"Slice from rear: -6 -5 -4 -3 -2 -1 None\n",
"```"
]
},
......@@ -2486,7 +2486,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.7"
"version": "3.6.6"
}
},
"nbformat": 4,
......
%% Cell type:markdown id: tags:
# Python training UGA 2017
**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)
# More standard types and basic statements
%% Cell type:markdown id: tags:
## More on standard types
- Simple types (`int`, `float`, `bool`, `complex`)
- Standard type `str`
- Standard type `list`
- Standard type `tuple`
%% Cell type:markdown id: tags:
### `int` (integers)
%% Cell type:code id: tags:
``` python
a = 4
c = -10
# binary notation (base 2)
b = 0b010
# octal notation (base 8)
o = 0o011
# hexadecimal (base 16)
h = 0x1cf0
a = int('1') # base 10
a = int('111', 2) # base 2
a = int('70', 8) # base 8
a = int('16', 16) # base 16
```
%% Cell type:markdown id: tags:
Remark: `int` in Python 3 are impressive! No limit! See https://docs.python.org/3.1/whatsnew/3.0.html#integers
%% Cell type:markdown id: tags:
## Arithmetic operations
%% Cell type:code id: tags:
``` python
print(10 + 3)
print(10 - 3)
print(10 * 3)
print(10 / 3) # float division
print(10 // 3) # integer division
print(10 % 3)
```
%%%% Output: stream
13
7
30
3.3333333333333335
3
1
%% Cell type:markdown id: tags:
### `bool` (booleans)
%% Cell type:code id: tags:
``` python
b = bool('1')
b = False
b = True
```
%% Cell type:markdown id: tags:
##### Comparison operations (bool)
- `==` equal
- `!=` différent
- `<` inferior
- `<=` inferior or equal
- `>` superior
- `>=` superior or equal
%% Cell type:markdown id: tags:
##### Keyword `is`: check identity
%% Cell type:code id: tags:
``` python
a = None
print(a is None)
print(a is not None)
```
%%%% Output: stream
True
False
%% Cell type:markdown id: tags:
##### Keywords `and` and `or`
%% Cell type:code id: tags:
``` python
True and True
```
%%%% Output: execute_result
True
%% Cell type:code id: tags:
``` python
True and False
```
%%%% Output: execute_result
False
%% Cell type:code id: tags:
``` python
False and False
```
%%%% Output: execute_result
False
%% Cell type:code id: tags:
``` python
True or True
```
%%%% Output: execute_result
True
%% Cell type:code id: tags:
``` python
True or False
```
%%%% Output: execute_result
True
%% Cell type:code id: tags:
``` python
False or False
```
%%%% Output: execute_result
False
%% Cell type:markdown id: tags:
### `float` (real, double precision) and `complex`
%% Cell type:code id: tags:
``` python
# float
a = float('1')
a = 1.234
a = 1e2
a = -1e-2
a = .2
```
%% Cell type:code id: tags:
``` python
# complex (2 floats)
c = complex('1')
c = 1 + 2j
print(c, c.real, c.imag)
```
%%%% Output: stream
(1+2j) 1.0 2.0
%% Cell type:markdown id: tags:
Remark: notation `var_name.attr_name` to access to an attribute of an object.
%% Cell type:markdown id: tags:
## Warning about floating-point arithmetic and numerical errors!
%% Cell type:code id: tags:
``` python
b = 1e16
c = 1.2 + b
d = c - b
print(d)
```
%%%% Output: stream
2.0
%% Cell type:markdown id: tags:
Very general issue (not Python):
see https://en.wikipedia.org/wiki/Floating-point_arithmetic
%% Cell type:markdown id: tags:
### Standard type `str`
%% Cell type:code id: tags:
``` python
s = 'hello'
s = "hello"
s = ('How is it possible to write a very very '
'very long string with lines limited to 79 characters?')
s = """Strings on
more thand
one line.
"""
print(s)
```
%%%% Output: stream
Strings on
more thand
one line.
%% Cell type:markdown id: tags:
Warning: big difference between Python 2 and Python 3. In Python 3, `str` are unicode and there is another type `bytes`.
%% Cell type:markdown id: tags:
#### Methods of the type `str`
Objects of built-in types have methods associated with their type (object oriented programming). The built-in function `dir` returns a list of name of the attributes. For a string, these attributes are python system attributes (with double-underscores) and several public methods:
%% Cell type:code id: tags:
``` python
s = 'abcdef'
print(dir(s))
```
%%%% Output: stream
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
%% Cell type:markdown id: tags:
To access an attribute of an object (here, the method `str.startswith`), we use the dot:
%% Cell type:code id: tags:
``` python
s.startswith('a')
```
%%%% Output: execute_result
True
%% Cell type:markdown id: tags:
### standard type `str`
#### function `str.format`
```text
Docstring:
S.format(*args, **kwargs) -> str
Return a formatted version of S, using substitutions from args and kwargs.
The substitutions are identified by braces ('{' and '}').
```
%% Cell type:code id: tags:
``` python
a = 1.23456789
'a = {}'.format(a)
```
%%%% Output: execute_result
'a = 1.23456789'
%% Cell type:code id: tags:
``` python
'a = {:.4f}'.format(a)
```
%%%% Output: execute_result
'a = 1.2346'
%% Cell type:code id: tags:
``` python
'a = {:8.4f}'.format(a)
```
%%%% Output: execute_result
'a = 1.2346'
%% Cell type:code id: tags:
``` python
'a = {:.4e} (scientific notation)'.format(a)
```
%%%% Output: execute_result
'a = 1.2346e+00 (scientific notation)'
%% Cell type:code id: tags:
``` python
print('{}\t{}\t{}'.format(1, 2, 3))
```
%%%% Output: stream
1 2 3
%% Cell type:markdown id: tags:
### standard type `str`
#### New in Python 3.6: format strings
%% Cell type:code id: tags:
``` python
a = 1.23456789
f'a = {a}'
```
%%%% Output: execute_result
'a = 1.23456789'
%% Cell type:code id: tags:
``` python
f'a = {a:.4f}'
```
%%%% Output: execute_result
'a = 1.2346'
%% Cell type:code id: tags:
``` python
f'a = {a:8.4f}'
```
%%%% Output: execute_result
'a = 1.2346'
%% Cell type:code id: tags:
``` python
f'a = {a:.4e} (scientific notation)'
```
%%%% Output: execute_result
'a = 1.2346e+00 (scientific notation)'
%% Cell type:code id: tags:
``` python
print(f'{1}\t{1+1}\t{2+1}')
```
%%%% Output: stream
1 2 3
%% Cell type:markdown id: tags:
### standard type `str`
Strings are immutable **["sequences"](https://docs.python.org/3/library/stdtypes.html)**.
- lookup
%% Cell type:code id: tags:
``` python
s = 'abcdef'
print('a' in s)
print('hello' not in s)
```
%%%% Output: stream
True
True
%% Cell type:markdown id: tags:
- We can get an element of a string (**index starts from 0**):
%% Cell type:code id: tags:
``` python
print(s[0])
```
%%%% Output: stream
a
%% Cell type:markdown id: tags:
- since strings are immutable, they can not be modified inplace. If we try, we get an error:
```python
s[0] = 'b'
```
```text
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-55620f378bce> in <module>()
----> 1 s[0] = 'b'
TypeError: 'str' object does not support item assignment
```
- since strings are sequences, they can be "sliced" (we will soon study in details this powerful notation):
%% Cell type:code id: tags:
``` python
s[1:3]
```
%%%% Output: execute_result
'bc'
%% Cell type:markdown id: tags:
- it is very simple to manipulate strings in many ways:
%% Cell type:code id: tags:
``` python
print((s.capitalize() + ' ' + s.upper() + '\n') * 4 )
```
%%%% Output: stream
Abcdef ABCDEF
Abcdef ABCDEF
Abcdef ABCDEF
Abcdef ABCDEF
%% Cell type:markdown id: tags:
### Slicing
Very general, can be used on all sequences as `str`, `list`, etc... Not simple for beginners but very powerfull (see [here](http://stackoverflow.com/questions/509211/explain-pythons-slice-notation) and [here](http://avilpage.com/2015/03/a-slice-of-python-intelligence-behind.html)).
Python indexes and slices for a six-element str. Indexes enumerate the elements, slices enumerate the spaces between the elements.
```text
Index from rear: -6 -5 -4 -3 -2 -1
Index from front: 0 1 2 3 4 5
+---+---+---+---+---+---+
| a | b | c | d | e | f |
+---+---+---+---+---+---+
Slice from front: 0 1 2 3 4 5 6
Slice from rear: -6 -5 -4 -3 -2 -1 0
Slice from rear: -6 -5 -4 -3 -2 -1 None
```
%% Cell type:code id: tags:
``` python
s = 'abcdef'
# s[start:stop:step]
s[2:6:2]
```
%%%% Output: execute_result
'ce'
%% Cell type:code id: tags:
``` python
# s[start:stop]
s[2:6]
```
%%%% Output: execute_result
'cdef'
%% Cell type:code id: tags:
``` python
# s[start:]
s[1:]
```
%%%% Output: execute_result
'bcdef'
%% Cell type:code id: tags:
``` python
# s[:stop]
s[:2]
```
%%%% Output: execute_result
'ab'
%% Cell type:code id: tags:
``` python
# step = -1: goes through the string in reverse order
s[::-1]
```
%%%% Output: execute_result
'fedcba'
%% Cell type:markdown id: tags:
### Do it yourself
Suppose we have a string representing a header line of the form:
%% Cell type:code id: tags:
``` python
s = ' wind;temperature;;pressure '
```
%% Cell type:markdown id: tags:
- Remove leading and ending blanks (see `str.replace` and `str.strip`)
- Extract the first field (e.g. using `find` method and slicing)
- Extract the last field (e.g. using `rfind` method and slicing)
- Check for empty field (e.g. `find` ";;" pattern)
- Remove empty field (e.g. using replace method)
- BONUS : Extract the second field (tip :`find` can take an argument that tells where to start the search)
%% Cell type:markdown id: tags:
#### A possible solution:
%% Cell type:code id: tags:
``` python
s = ' wind;temperature;;pressure '
# remove leading blanks
s = s.strip()
print("--{}--".format(s))
# extract the first field
idx = s.find(";")
s0 = s[0:idx]
print(s0)
# extract the second field
idx1 = s.find(";", idx+1) # start the search after the first ";"
s1 = s[idx+1:idx1]
print(s1)
# extract the last field
idx2 = s.rfind(";")
s2 = s[idx2+1:]
print(s2)
idx_first_empty_field = s.find(";;")
print(idx_first_empty_field)
# remove empty field
s_no_empty = s.replace(";;", ";")
print(s_no_empty)
```
%%%% Output: stream
--wind;temperature;;pressure--
wind
temperature
pressure
16
wind;temperature;pressure
%% Cell type:markdown id: tags:
### standard type `list`
A list is a **mutable sequence of (possibly inhomogeneous) elements**.
%% Cell type:code id: tags:
``` python
type([0, 'a'])
```
%%%% Output: execute_result
list
%% Cell type:code id: tags:
``` python
# create an empty list
l = []
# fill the list (with the function append)
l.append('2')
# fill the list (with the function extend)
l.extend([6, 3.])
print(l)
```
%%%% Output: stream
['2', 6, 3.0]
%% Cell type:code id: tags:
``` python
# concatenate lists with the operator +
print(l + ['hello', 3])
```
%%%% Output: stream
['2', 6, 3.0, 'hello', 3]
%% Cell type:code id: tags:
``` python
# get values
print(l[0], l[2], l[-2])
# slicing
print(l[0:2])
```
%%%% Output: stream
2 3.0 6
['2', 6]
%% Cell type:markdown id: tags:
### standard type `tuple`
A tuple is a **immutable sequence of (possibly inhomogeneous) elements**.
Remark: when you need a sequence that won't be modified, tuple is usually more efficient than list.
%% Cell type:code id: tags:
``` python
t = 0, 'a', 1.2
t1 = (5, 'hello')
t2 = tuple([1.1, 2])
type(t)
```
%%%% Output: execute_result
tuple
%% Cell type:code id: tags:
``` python
t[1] # indexing
```
%%%% Output: execute_result
'a'
%% Cell type:code id: tags:
``` python
t[1:] # slicing
```
%%%% Output: execute_result
('a', 1.2)
%% Cell type:code id: tags:
``` python
a, b = t1 # tuple assigment
print(b)
```
%%%% Output: stream
hello
%% Cell type:markdown id: tags:
## Mutable and immutable objects
The objects of type `str`, `int`, `float`, `bool` are immutable. They can not be modified. Of course, a name that points towards an integer can point towards a different integer.
%% Cell type:code id: tags:
``` python
i = 1
i = i + 2 # (or i += 2)
print(i)
i = 10
print(i)
```
%%%% Output: stream
3
10
%% Cell type:markdown id: tags:
Here, the objects `1` and `3` have not been modified.
%% Cell type:markdown id: tags:
## Mutable and immutable objects
An object of type `list` is mutable:
%% Cell type:code id: tags:
``` python
l = [0, 5]
print(l)
l.append('hello')
print(l)
```
%%%% Output: stream
[0, 5]
[0, 5, 'hello']
%% Cell type:markdown id: tags:
Here, the object list tagged by the name `l` has been modified inplace.
%% Cell type:markdown id: tags:
## References and `del` keyword
`del` removes a reference. If an object in not binded to any names, Python can delete it from its internal memory.
%% Cell type:code id: tags:
``` python
l = ['a', 'b']
del l[1]
print(l)
```
%%%% Output: stream
['a']
%% Cell type:markdown id: tags:
### More on slicing
Very general, can be used on all sequences as `str`, `list`, etc... Not simple for beginners but very powerfull (see [here](http://stackoverflow.com/questions/509211/explain-pythons-slice-notation) and [here](http://avilpage.com/2015/03/a-slice-of-python-intelligence-behind.html)).
Python indexes and slices for a six-element str. Indexes enumerate the elements, slices enumerate the spaces between the elements.
```text
Index from rear: -6 -5 -4 -3 -2 -1
Index from front: 0 1 2 3 4 5
+---+---+---+---+---+---+
| a | b | c | d | e | f |
+---+---+---+---+---+---+
Slice from front: 0 1 2 3 4 5 6
Slice from rear: -6 -5 -4 -3 -2 -1 0
```
%% Cell type:code id: tags:
``` python
s = 'abcdef'
# s[start:stop:step]
s[2:6:2]
```
%%%% Output: execute_result
'ce'
%% Cell type:markdown id: tags:
### More on slicing
#### Assigment to mutable object
%% Cell type:code id: tags:
``` python
l = [0, 1, 2, 3, 4, 5]
l1 = l # assigment to a new name l1 (no copy of the object).
# the names l and l1 points towards the same object.
l1.append('a')
print(l1)
print(l)
```
%%%% Output: stream
[0, 1, 2, 3, 4, 5, 'a']
[0, 1, 2, 3, 4, 5, 'a']
%% Cell type:markdown id: tags:
#### Shallow copy
%% Cell type:code id: tags:
``` python
l = [0, 1, 2, 3, 4, 5]
l1 = l[:] # shallow copy of l
l1.append('a')
print(l1)
print(l)
```
%%%% Output: stream
[0, 1, 2, 3, 4, 5, 'a']
[0, 1, 2, 3, 4, 5]
%% Cell type:markdown id: tags:
### More on slicing
Other examples of slices for a six-element list. Indexes enumerate the elements, slices enumerate the spaces between the elements.
%% Cell type:code id: tags:
``` python
a = [0, 1, 2, 3, 4, 5]
all([
len(a) == 6,
a[1:] == [1, 2, 3, 4, 5],
a[:5] == [0, 1, 2, 3, 4],
a[0] == 0,
a[:-2] == [0, 1, 2, 3],
a[5] == 5,
a[1:2] == [1],
a[-1] == 5,
a[1:-1] == [1, 2, 3, 4],
a[-2] == 4,
])
```
%%%% Output: execute_result
True
%% Cell type:markdown id: tags:
### Do it yourself
Suppose we have the string containing header line.
%% Cell type:code id: tags:
``` python
s = 'wind;temperature;pressure'
```
%% Cell type:markdown id: tags:
- Extract the list of items (i.e. "wind", "temperature", "pressure"; see `str.split`).
- Add "Snow level" to the list of items (e.g. using append)
- Build a new header such that items are capitalized (e.g. using the methods `str.join` and `str.capitalize` and iterating on the list)
%% Cell type:markdown id: tags:
#### A possible solution:
%% Cell type:code id: tags:
``` python
s = 'wind;temperature;pressure'
list_items = s.split(";")
print(list_items)
list_items.append("snow level".capitalize())
list_items[0] = list_items[0].capitalize()
list_items[1] = list_items[1].capitalize()
list_items[2] = list_items[2].capitalize()
print(list_items)
";".join(list_items)
```
%%%% Output: stream
['wind', 'temperature', 'pressure']
['Wind', 'Temperature', 'Pressure', 'Snow level']
%%%% Output: execute_result
'Wind;Temperature;Pressure;Snow level'
%% Cell type:markdown id: tags:
### The function `range`
The function returns a range object:
%% Cell type:code id: tags:
``` python
# start, stop, step
range(1, 8, 2)
```
%%%% Output: execute_result
range(1, 8, 2)
%% Cell type:markdown id: tags:
We can make a list with the range object:
%% Cell type:code id: tags:
``` python
# start, stop, step
list(range(1, 8, 2))
```
%%%% Output: execute_result
[1, 3, 5, 7]
%% Cell type:code id: tags:
``` python
# start, stop (step=1)
list(range(2, 8))
```
%%%% Output: execute_result
[2, 3, 4, 5, 6, 7]
%% Cell type:code id: tags:
``` python
# stop argument (start=0, step=1)
list(range(8))
```
%%%% Output: execute_result
[0, 1, 2, 3, 4, 5, 6, 7]
%% Cell type:markdown id: tags:
### Do it yourself
Build a list of odd numbers in decreasing order.
%% Cell type:markdown id: tags:
## Conditions: `if`, `elif`, `else`
```python
if expression:
statement(s)
else:
statement(s)
```
The statement contains the block of code that executes if the conditional expression in the if statement resolves to 1 or a TRUE value.
%% Cell type:code id: tags:
``` python
a = 0
if a == 0:
print('a is equal to 0.')
```
%%%% Output: stream
a is equal to 0.
%% Cell type:code id: tags:
``` python
a = 1
if a < 0:
print('a is negative.')
elif a == 0:
print('a is equal to 0.')
elif a > 0:
print('a is positive.')
else:
print("I don't know.")
```
%%%% Output: stream
a is positive.
%% Cell type:markdown id: tags:
## Loops
%% Cell type:markdown id: tags:
### Loops with the keyword `while`
%% Cell type:code id: tags:
``` python
i = 0
while i < 4:
i += 1
print('i =', i)
```
%%%% Output: stream
i = 4
%% Cell type:code id: tags:
``` python
i = 0
while i < 4:
i += 1
print('i =', i)
```
%%%% Output: stream
i = 1
i = 2
i = 3
i = 4
%% Cell type:markdown id: tags:
### Do it yourself
- Edit a script with the spyder editor that calculates the average of a set of numbers. For example `numbers = [67, 12, 2, 9, 23, 5]`
* using the functions `sum` and `len`
* manually, using the keyword `while`
- Run the script
* in spyder,
* in a ipython session opened from another terminal,
* with the command `python`.
%% Cell type:markdown id: tags:
#### A possible solution:
%% Cell type:code id: tags:
``` python
numbers = [67, 12, 2, 9, 23, 5]
local_sum = 0
i = 0
while i < len(numbers):
local_sum = local_sum + numbers[i]
i = i+1
avg = local_sum / len(numbers)
print(avg)
```
%%%% Output: stream
19.666666666666668
%% Cell type:markdown id: tags:
### Loops with the keyword `for`
%% Cell type:code id: tags:
``` python
values = range(5)
for value in values:
print(value, end=', ')
```
%%%% Output: stream
0, 1, 2, 3, 4,
%% Cell type:code id: tags:
``` python
# the built-in function enumerate is very useful
for index, value in enumerate(['a', 'b', 'c']):
print('({}, {})'.format(index, value))
```
%%%% Output: stream
(0, a)
(1, b)
(2, c)
%% Cell type:markdown id: tags:
### Loops: keywords `continue` and `break`
- `continue`: passes the block in the loop and continues the loop.
%% Cell type:code id: tags:
``` python
for x in range(1, 8):
if x == 5:
continue
print(x, end=', ')
```
%%%% Output: stream
1, 2, 3, 4, 6, 7,
%% Cell type:markdown id: tags:
- `break`: stop the loop.
%% Cell type:code id: tags:
``` python
for x in range(1, 11):
if x == 5:
break
print(x, end=', ')
```
%%%% Output: stream
1, 2, 3, 4,
%% Cell type:markdown id: tags:
### Do it yourself
- Simplify your script by using a `for` loops.
- In ipython, try to understand how the function `enumerate` works. Use it in your script.
%% Cell type:markdown id: tags:
#### A possible solution:
%% Cell type:code id: tags:
``` python
l = [67, 12, 2, 9, 23, 5]
local_sum = 0
for e in l:
local_sum += e
avg = local_sum / len(l)
print(avg)
```
%%%% Output: stream
19.666666666666668
%% Cell type:markdown id: tags:
### Do it yourself
We build a list:
%% Cell type:code id: tags:
``` python
from random import shuffle, randint
n = 20
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)
```
%%%% Output: stream
integer remove from the list: 3
shuffled list: [13, 16, 6, 10, 17, 19, 4, 2, 5, 9, 0, 7, 11, 12, 14, 8, 1, 15, 18]
%% Cell type:markdown id: tags:
One element has been removed:
- Find this element (given that you can change the ordering of `l`).
- Find this element (given that you cannot change the ordering of `l`).
%% Cell type:markdown id: tags:
#### A possible solution:
%% Cell type:code id: tags:
``` python
# we can change ordering, let's sort
print(l)
l_sorted = sorted(l)
print(l_sorted)
found = None
for idx, elem in enumerate(l_sorted):
if elem != idx:
found = idx
break
if found is None:
found = len(l)
print("missing ", idx)
```
%%%% Output: stream
[13, 16, 6, 10, 17, 19, 4, 2, 5, 9, 0, 7, 11, 12, 14, 8, 1, 15, 18]
[0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
missing 3
%% Cell type:code id: tags:
``` python
# we cannot sort -> higher complexity
for elem in range(len(l)+1):
if elem not in l:
break
print("missing ", elem)
```
%%%% Output: stream
missing 3
%% Cell type:code id: tags:
``` python
# another solution
actual_sum = sum(l)
len_l = len(l)
original_sum = (len_l + 1) * (len_l) // 2
print("missing ", original_sum - actual_sum)
```
%%%% Output: stream
missing 3
%% Cell type:markdown id: tags:
## Exceptions and `try`, `except` syntax
%% Cell type:markdown id: tags:
Exceptions and errors are common in all codes. There is a good system to handle them in Python. Let's first see what gives such buggy code
```python
l = ['a']
i = 1
print(l[i])
```
When these lines are executed, Python stops its execution and print a traceback:
```text
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-30-8df9cec1a0ec> in <module>()
1 l = ['a']
2 i = 1
----> 3 print(l[i])
IndexError: list index out of range
```
%% Cell type:markdown id: tags:
## Exceptions and `try`, `except` syntax
Handling exception:
%% Cell type:code id: tags:
``` python
l = ['a']
i = 1
try:
print(l[i])
except IndexError as e:
print(e)
```
%%%% Output: stream
list index out of range
%% Cell type:markdown id: tags:
Remark: never use
```python
except:
```
It means "except all errors and exceptions". A user Control-C is an exception (`KeyboardInterrupt`) so it would be caught and have no effect.
%% Cell type:markdown id: tags:
## Full syntax
```python
try:
...
except <exception1> as e1:
...
except <exception2> as e2:
...
else:
...
finally:
...
```
[Non exhaustive error list](https://docs.python.org/3/library/exceptions.html):
- ArithmeticError
- ZeroDivisionError
- IndexError
- KeyError
- AttributeError
- IOError
- ImportError
- NameError
- SyntaxError
- TypeError
%% Cell type:markdown id: tags:
### Do it yourself:
For each line of this string, append a variable of correct type in a list (i.e. "hello" should stay hello,
2 should become an int and 1.5 a float). Do it by catching errors.
**Hints:**
- int("a") and float("a") raise ValueError
- the above str_variable can be split using "\n"
%% Cell type:code id: tags:
``` python
str_variables = """hello
1.5
2"""
the_list_you_should_get = ["hello", 1.5, 2]
```
%% Cell type:markdown id: tags:
#### A possible solution:
%% Cell type:code id: tags:
``` python
split_list = []
for value in str_variables.split("\n"):
try:
value = int(value)
except ValueError:
print(value, "is not a int")
try:
value = float(value)
except ValueError:
print(value, 'is not a float')
split_list.append(value)
print(split_list)
```
%%%% Output: stream
hello is not a int
hello is not a float
1.5 is not a int
['hello', 1.5, 2]
......
......@@ -561,6 +561,17 @@
"https://en.wikipedia.org/wiki/Hash_table"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## DIY: back to the \"find the removed element\" problem"
]
},
{
"cell_type": "code",
"execution_count": 1,
......@@ -591,19 +602,21 @@
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
"slide_type": "-"
}
},
"source": [
"## DIY: back to the \"find the removed element\" problem\n",
"\n",
" - Could the problem be solved using set ? \n",
" - What is the complexity of this solution ? "
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"## A possible solution : "
]
......@@ -630,21 +643,6 @@
"full_set - changed_set"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Complity :\n",
"\n",
" - line 1: n insertions --> O(n)\n",
" - line 2 : n insertions --> O(n)\n",
" - line 3: one traversal O(n), with one lookup at each time (O(1) -> O(n) \n",
" \n",
" -> Complixity of the whole algorithm : O(n)\n",
" \n",
"# Note "
]
},
{
"cell_type": "markdown",
"metadata": {
......@@ -1169,7 +1167,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.2+"
"version": "3.6.6"
}
},
"nbformat": 4,
......
%% Cell type:markdown id: tags:
# Python training UGA 2017
**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)
# [Data structures](https://docs.python.org/3.6/tutorial/datastructures.html)
%% Cell type:markdown id: tags:
### list: mutable sequence
Lists are mutable ordered tables of inhomogeneous objects. They can be viewed as an array of references (nearly pointers) to objects.
%% Cell type:code id: tags:
``` python
# 2 equivalent ways to define an empty list
l0 = []
l1 = list()
assert l0 == l1
# not empty lists
l2 = ['a', 2]
l3 = list(range(3))
print(l2, l3, l2 + l3)
print(3*l2)
```
%%%% Output: stream
['a', 2] [0, 1, 2] ['a', 2, 0, 1, 2]
['a', 2, 'a', 2, 'a', 2]
%% Cell type:markdown id: tags:
The `itertools` module provide other ways of iterating over lists or set of lists (e.g. cartesian product, permutation, filter, ... ): https://docs.python.org/3/library/itertools.html
%% Cell type:markdown id: tags:
### list: mutable sequence
The builtin function `dir` returns a list of name of the attributes. For a list, these attributes are python system attributes (with double-underscores) and 11 public methods:
%% Cell type:code id: tags:
``` python
print(dir(l3))
```
%%%% Output: stream
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
%% Cell type:code id: tags:
``` python
l3.append(10)
print(l3)
l3.reverse()
print(l3)
```
%%%% Output: stream
[0, 1, 2, 10]
[10, 2, 1, 0]
%% Cell type:code id: tags:
``` python
# Built-in functions applied on lists
# return lower value
print(min(l3))
# return higher value
print(max(l3))
# return sorted list
print(sorted([5, 2, 10, 0]))
```
%%%% Output: stream
0
10
[0, 2, 5, 10]
%% Cell type:code id: tags:
``` python
# "pasting" two lists can be done using zip
l1 = [1, 2, 3]
s = 'abc'
print(list(zip(l1, l2)))
print(list(zip('abc', 'defg')))
```
%%%% Output: stream
[(1, 'a'), (2, 'b'), (3, 'c')]
[('a', 'd'), ('b', 'e'), ('c', 'f')]
%% Cell type:markdown id: tags:
### `list`: list comprehension
They are iterable so they are often used to make loops. We have already seen how to use the keyword `for`. For example to build a new list (side note: `x**2` computes `x^2`):
%% Cell type:code id: tags:
``` python
l0 = [1, 4, 10]
l1 = []
for number in l0:
l1.append(number**2)
print(l1)
```
%%%% Output: stream
[1, 16, 100]
%% 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]
print(l1)
```
%%%% Output: stream
[1, 16, 100]
%% Cell type:code id: tags:
``` python
# list comprehension with a condition
[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'] ]
```
%%%% Output: execute_result
[(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
%% Cell type:markdown id: tags:
### Do it yourself (advanced)
- Write a function `extract_patterns(text, n=3)` extracting the list of patterns of size `n=3` from a long string (e.g. if `text = "basically"`, patterns would be the list `['bas', 'asi', 'sic', ..., 'lly']`). Use list comprehension, range, slicing. Use a sliding window.
- You can apply your function to a long "ipsum lorem" string (ask to your favorite web search engine).
%% Cell type:markdown id: tags:
#### A possible solution
%% Cell type:code id: tags:
``` python
text = "basically"
def extract_patterns(text, n=3):
pat = [text[i:i+n] for i in range(len(text)-n+1)]
return pat
print("patterns=", extract_patterns(text))
print("patterns=", extract_patterns(text, n=5))
```
%%%% Output: stream
patterns= ['bas', 'asi', 'sic', 'ica', 'cal', 'all', 'lly']
patterns= ['basic', 'asica', 'sical', 'icall', 'cally']
%% Cell type:markdown id: tags:
### `tuple`: immutable sequence
Tuples are very similar to lists but they are immutable (they can not be modified).
%% Cell type:code id: tags:
``` python
# 2 equivalent notations to define an empty tuple (not very useful...)
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
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('__')]
```
%%%% Output: execute_result
['count', 'index']
%% Cell type:code id: tags:
``` python
# assigment of multiple variables in 1 line
a, b = 1, 2
print(a, b)
# exchange of values
b, a = a, b
print(a, b)
```
%%%% Output: stream
1 2
2 1
%% Cell type:markdown id: tags:
### `tuple`: immutable sequence
Tuples are used *a lot* with the keyword `return` in functions:
%% Cell type:code id: tags:
``` 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)
```
%%%% Output: stream
<class 'tuple'> (1, 2, 3)
1 2 3
%% Cell type:markdown id: tags:
### `set`: a hashtable
Unordered collections of unique elements (a hashtable). Sets are mutable. The elements of a set must be [hashable](https://docs.python.org/3/glossary.html#term-hashable).
%% Cell type:code id: tags:
``` python
s0 = set()
```
%% Cell type:code id: tags:
``` python
{1, 1, 1, 3}
```
%%%% Output: execute_result
{1, 3}
%% Cell type:code id: tags:
``` python
set([1, 1, 1, 3])
```
%%%% Output: execute_result
{1, 3}
%% Cell type:code id: tags:
``` python
s1 = {1, 2}
s2 = {2, 3}
print(s1.intersection(s2))
print(s1.union(s2))
```
%%%% Output: stream
{2}
{1, 2, 3}
%% Cell type:markdown id: tags:
### `set`: lookup
Hashtable lookup (for example `1 in s1`) is algorithmically efficient (complexity O(1)), i.e. theoretically faster than a look up in a list or a tuple (complexity O(size iterable)).
%% Cell type:code id: tags:
``` python
print(1 in s1, 1 in s2)
```
%%%% Output: stream
True False
%% Cell type:markdown id: tags:
### What is a hashtable?
https://en.wikipedia.org/wiki/Hash_table
%% Cell type:markdown id: tags:
## DIY: back to the "find the removed element" problem
%% Cell type:code id: tags:
``` python
from random import shuffle, randint
n = 20
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)
```
%%%% Output: stream
integer remove from the list: 5
shuffled list: [4, 19, 14, 1, 8, 17, 15, 2, 3, 12, 0, 6, 16, 9, 11, 10, 7, 13, 18]
%% Cell type:markdown id: tags:
## DIY: back to the "find the removed element" problem
- Could the problem be solved using set ?
- What is the complexity of this solution ?
%% Cell type:markdown id: tags:
## A possible solution :
%% Cell type:code id: tags:
``` python
full_set = set(range(n))
changed_set = set(l)
full_set - changed_set
```
%%%% Output: execute_result
{5}
%% Cell type:markdown id: tags:
## Complity :
- line 1: n insertions --> O(n)
- line 2 : n insertions --> O(n)
- line 3: one traversal O(n), with one lookup at each time (O(1) -> O(n)
-> Complixity of the whole algorithm : O(n)
# Note
%% Cell type:markdown id: tags:
### `dict`: unordered set of key: value pairs
The dictionary (`dict`) is a very important data structure in Python. All namespaces are (nearly) dictionaries and "Namespaces are one honking great idea -- let's do more of those!" (The zen of Python).
A dict is a hashtable (a set) + associated values.
%% Cell type:code id: tags:
``` python
d = {}
d['b'] = 2
d['a'] = 1
print(d)
```
%%%% Output: stream
{'b': 2, 'a': 1}
%% Cell type:code id: tags:
``` python
d = {'a': 1, 'b': 2, 0: False, 1: True}
print(d)
```
%%%% Output: stream
{'a': 1, 'b': 2, 0: False, 1: True}
%% Cell type:markdown id: tags:
### Tip: parallel between `dict` and `list`
You can first think about `dict` as a super `list` which can be indexed with other objects than integers (and in particular with `str`).
%% Cell type:code id: tags:
``` python
l = ["value0", "value1"]
l.append("value2")
print(l)
```
%%%% Output: stream
['value0', 'value1', 'value2']
%% Cell type:code id: tags:
``` python
l[1]
```
%%%% Output: execute_result
'value1'
%% Cell type:code id: tags:
``` python
d = {"key0": "value0", "key1": "value1"}
d["key2"] = "value2"
print(d)
```
%%%% Output: stream
{'key0': 'value0', 'key1': 'value1', 'key2': 'value2'}
%% Cell type:code id: tags:
``` python
d["key1"]
```
%%%% Output: execute_result
'value1'
%% Cell type:markdown id: tags:
But warning, `dict` are not ordered (since they are based on a hashtable)!
%% Cell type:markdown id: tags:
### `dict`: public methods
%% 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('__')]
```
%%%% Output: execute_result
['clear',
'copy',
'fromkeys',
'get',
'items',
'keys',
'pop',
'popitem',
'setdefault',
'update',
'values']
%% Cell type:markdown id: tags:
### `dict`: different ways to loops over a dictionary
%% Cell type:code id: tags:
``` python
# loop with items
for key, value in d.items():
if isinstance(key, str):
print(key, value)
```
%%%% Output: stream
key0 value0
key1 value1
key2 value2
%% Cell type:code id: tags:
``` python
# loop with values
for value in d.values():
print(value)
```
%%%% Output: stream
value0
value1
value2
%% Cell type:code id: tags:
``` python
# loop with keys
for key in d.keys():
print(key)
```
%%%% Output: stream
key0
key1
key2
%% Cell type:code id: tags:
``` python
# dict comprehension (here for the "inversion" of the dictionary)
print(d)
d1 = {v: k for k, v in d.items()}
```
%%%% Output: stream
{'key0': 'value0', 'key1': 'value1', 'key2': 'value2'}
%% Cell type:markdown id: tags:
## Do it yourself:
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'
```
%% Cell type:markdown id: tags:
#### A possible solution:
%% Cell type:code id: tags:
``` python
def count_elem(sequence):
d = {}
for letter in sequence:
if letter not in d:
d[letter] = 1
else:
d[letter] += 1
return d
print("text=", text, "counts=", count_elem(text))
```
%%%% Output: stream
text= Las Vegas Overlook Loop is a 6.3 mile loop trail located near Las Vegas counts= {'L': 3, 'a': 8, 's': 5, ' ': 13, 'V': 2, 'e': 6, 'g': 2, 'O': 1, 'v': 1, 'r': 3, 'l': 5, 'o': 7, 'k': 1, 'p': 2, 'i': 3, '6': 1, '.': 1, '3': 1, 'm': 1, 't': 2, 'c': 1, 'd': 1, 'n': 1}
%% Cell type:markdown id: tags:
## Do it yourself : smart completion (advanced)
We will reuse our function `extract_patterns`.
- For a text, count the appearance of each pattern (using a dictionary).
- Given a query pattern of size 2, propose the pattern of size 3 with the same prefix that has the highest frequency. Filter the keys of the previous dictionary so that they starts with the query pattern.
%% Cell type:markdown id: tags:
#### A possible solution
%% Cell type:code id: tags:
``` python
text="Las Vegas Overlook Loop is a 6.3 mile loop trail located near Las Vegas"
def extract_patterns(text, n=3):
"extracts the patterns of size n from text and return it"
pat = [text[i:i+n] for i in range(len(text)-n+1)]
return pat
def guess(prefix, count):
"complete the prefix with the most probable pattern (according to count)"
# get all the pattern in keys of count that starts with prefix
# compat_prefix = DIY
# find among the compatible prefixes the one wich score best according to count
best_prefix = "?"
return best_prefix
patterns = extract_patterns(text)
print("patterns = ", patterns)
patterns_count = count_elem(patterns)
print("patterns_counts = ", patterns_count)
print("guess for oo = ", guess("oo", patterns_count))
print("guess for eg = ", guess("eg", patterns_count))
```
%%%% Output: stream
patterns = ['Las', 'as ', 's V', ' Ve', 'Veg', 'ega', 'gas', 'as ', 's O', ' Ov', 'Ove', 'ver', 'erl', 'rlo', 'loo', 'ook', 'ok ', 'k L', ' Lo', 'Loo', 'oop', 'op ', 'p i', ' is', 'is ', 's a', ' a ', 'a 6', ' 6.', '6.3', '.3 ', '3 m', ' mi', 'mil', 'ile', 'le ', 'e l', ' lo', 'loo', 'oop', 'op ', 'p t', ' tr', 'tra', 'rai', 'ail', 'il ', 'l l', ' lo', 'loc', 'oca', 'cat', 'ate', 'ted', 'ed ', 'd n', ' ne', 'nea', 'ear', 'ar ', 'r L', ' La', 'Las', 'as ', 's V', ' Ve', 'Veg', 'ega', 'gas']
patterns_counts = {'Las': 2, 'as ': 3, 's V': 2, ' Ve': 2, 'Veg': 2, 'ega': 2, 'gas': 2, 's O': 1, ' Ov': 1, 'Ove': 1, 'ver': 1, 'erl': 1, 'rlo': 1, 'loo': 2, 'ook': 1, 'ok ': 1, 'k L': 1, ' Lo': 1, 'Loo': 1, 'oop': 2, 'op ': 2, 'p i': 1, ' is': 1, 'is ': 1, 's a': 1, ' a ': 1, 'a 6': 1, ' 6.': 1, '6.3': 1, '.3 ': 1, '3 m': 1, ' mi': 1, 'mil': 1, 'ile': 1, 'le ': 1, 'e l': 1, ' lo': 2, 'p t': 1, ' tr': 1, 'tra': 1, 'rai': 1, 'ail': 1, 'il ': 1, 'l l': 1, 'loc': 1, 'oca': 1, 'cat': 1, 'ate': 1, 'ted': 1, 'ed ': 1, 'd n': 1, ' ne': 1, 'nea': 1, 'ear': 1, 'ar ': 1, 'r L': 1, ' La': 1}
guess for oo = ?
guess for eg = ?
%% Cell type:code id: tags:
``` python
text="Las Vegas Overlook Loop is a 6.3 mile loop trail located near Las Vegas"
def extract_patterns(text, n=3):
pat = [text[i:i+n] for i in range(len(text)-n+1)]
return pat
def guess(prefix, count):
"complete the prefix with the most probable pattern (according to count)"
# get all the pattern in keys of count that starts with prefix
compatibles_prefixes = [x for x in count.keys() if x.startswith(prefix)]
if len(compatibles_prefixes) == 0:
return None
best_prefix = compatibles_prefixes[0]
best_score = count[best_prefix]
for pref in compatibles_prefixes[1:]:
if best_score < count[best_prefix]:
best_score = count[pref]
best_prefix = pref
return best_prefix
patterns = extract_patterns(text)
print("patterns = ", patterns)
patterns_count = count_elem(patterns)
print("patterns_counts = ", patterns_count)
print("guess for oo = ", guess("oo", patterns_count))
print("guess for eg = ", guess("eg", patterns_count))
```
%%%% Output: stream
patterns = ['Las', 'as ', 's V', ' Ve', 'Veg', 'ega', 'gas', 'as ', 's O', ' Ov', 'Ove', 'ver', 'erl', 'rlo', 'loo', 'ook', 'ok ', 'k L', ' Lo', 'Loo', 'oop', 'op ', 'p i', ' is', 'is ', 's a', ' a ', 'a 6', ' 6.', '6.3', '.3 ', '3 m', ' mi', 'mil', 'ile', 'le ', 'e l', ' lo', 'loo', 'oop', 'op ', 'p t', ' tr', 'tra', 'rai', 'ail', 'il ', 'l l', ' lo', 'loc', 'oca', 'cat', 'ate', 'ted', 'ed ', 'd n', ' ne', 'nea', 'ear', 'ar ', 'r L', ' La', 'Las', 'as ', 's V', ' Ve', 'Veg', 'ega', 'gas']
patterns_counts = {'Las': 2, 'as ': 3, 's V': 2, ' Ve': 2, 'Veg': 2, 'ega': 2, 'gas': 2, 's O': 1, ' Ov': 1, 'Ove': 1, 'ver': 1, 'erl': 1, 'rlo': 1, 'loo': 2, 'ook': 1, 'ok ': 1, 'k L': 1, ' Lo': 1, 'Loo': 1, 'oop': 2, 'op ': 2, 'p i': 1, ' is': 1, 'is ': 1, 's a': 1, ' a ': 1, 'a 6': 1, ' 6.': 1, '6.3': 1, '.3 ': 1, '3 m': 1, ' mi': 1, 'mil': 1, 'ile': 1, 'le ': 1, 'e l': 1, ' lo': 2, 'p t': 1, ' tr': 1, 'tra': 1, 'rai': 1, 'ail': 1, 'il ': 1, 'l l': 1, 'loc': 1, 'oca': 1, 'cat': 1, 'ate': 1, 'ted': 1, 'ed ': 1, 'd n': 1, ' ne': 1, 'nea': 1, 'ear': 1, 'ar ': 1, 'r L': 1, ' La': 1}
guess for oo = ook
guess for eg = ega
%% Cell type:code id: tags:
``` python
text="Las Vegas Overlook Loop is a 6.3 mile loop trail located near Las Vegas"
def extract_patterns(text, n=3):
pat = [text[i:i+n] for i in range(len(text)-n+1)]
return pat
def guess(prefix, count):
"complete the prefix with the most probable pattern (according to count)"
# get all the pattern in keys of count that starts with prefix
compat_prefix = [(x, count[x]) for x in count.keys() if x.startswith(prefix)]
ordered_compat_pref = sorted(compat_prefix, key=lambda x: x[1],
reverse=True)
return ordered_compat_pref
patterns = extract_patterns(text)
print("patterns = ", patterns)
patterns_count = count_elem(patterns)
print("patterns_counts = ", patterns_count)
print("guess for oo = ", guess("oo", patterns_count))
print("guess for eg = ", guess("eg", patterns_count))
```
%%%% Output: stream
patterns = ['Las', 'as ', 's V', ' Ve', 'Veg', 'ega', 'gas', 'as ', 's O', ' Ov', 'Ove', 'ver', 'erl', 'rlo', 'loo', 'ook', 'ok ', 'k L', ' Lo', 'Loo', 'oop', 'op ', 'p i', ' is', 'is ', 's a', ' a ', 'a 6', ' 6.', '6.3', '.3 ', '3 m', ' mi', 'mil', 'ile', 'le ', 'e l', ' lo', 'loo', 'oop', 'op ', 'p t', ' tr', 'tra', 'rai', 'ail', 'il ', 'l l', ' lo', 'loc', 'oca', 'cat', 'ate', 'ted', 'ed ', 'd n', ' ne', 'nea', 'ear', 'ar ', 'r L', ' La', 'Las', 'as ', 's V', ' Ve', 'Veg', 'ega', 'gas']
patterns_counts = {'Las': 2, 'as ': 3, 's V': 2, ' Ve': 2, 'Veg': 2, 'ega': 2, 'gas': 2, 's O': 1, ' Ov': 1, 'Ove': 1, 'ver': 1, 'erl': 1, 'rlo': 1, 'loo': 2, 'ook': 1, 'ok ': 1, 'k L': 1, ' Lo': 1, 'Loo': 1, 'oop': 2, 'op ': 2, 'p i': 1, ' is': 1, 'is ': 1, 's a': 1, ' a ': 1, 'a 6': 1, ' 6.': 1, '6.3': 1, '.3 ': 1, '3 m': 1, ' mi': 1, 'mil': 1, 'ile': 1, 'le ': 1, 'e l': 1, ' lo': 2, 'p t': 1, ' tr': 1, 'tra': 1, 'rai': 1, 'ail': 1, 'il ': 1, 'l l': 1, 'loc': 1, 'oca': 1, 'cat': 1, 'ate': 1, 'ted': 1, 'ed ': 1, 'd n': 1, ' ne': 1, 'nea': 1, 'ear': 1, 'ar ': 1, 'r L': 1, ' La': 1}
guess for oo = [('oop', 2), ('ook', 1)]
guess for eg = [('ega', 2)]
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment