Commit 28ca6ad1 authored by paugier's avatar paugier
Browse files

Use assert instead of unittest + improve presentation on for loops

parent eabc7703
Pipeline #32528 passed with stage
in 52 seconds
This diff is collapsed.
This diff is collapsed.
......@@ -33,7 +33,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 1,
"metadata": {},
"outputs": [
{
......@@ -49,7 +49,7 @@
"NoneType"
]
},
"execution_count": 7,
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
......@@ -60,7 +60,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 2,
"metadata": {},
"outputs": [
{
......@@ -81,7 +81,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 3,
"metadata": {},
"outputs": [
{
......@@ -128,7 +128,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 4,
"metadata": {},
"outputs": [
{
......@@ -154,7 +154,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 5,
"metadata": {},
"outputs": [
{
......@@ -195,7 +195,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 6,
"metadata": {},
"outputs": [
{
......@@ -247,7 +247,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 7,
"metadata": {},
"outputs": [
{
......@@ -273,7 +273,7 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 8,
"metadata": {},
"outputs": [
{
......@@ -330,7 +330,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 9,
"metadata": {},
"outputs": [
{
......@@ -346,7 +346,7 @@
"16"
]
},
"execution_count": 6,
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
......@@ -387,7 +387,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 10,
"metadata": {},
"outputs": [
{
......@@ -403,7 +403,7 @@
"8"
]
},
"execution_count": 16,
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
......@@ -429,21 +429,7 @@
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"test_myfunc1 (__main__.TestMyStuff)\n",
"test myfunc1 ... ok\n",
"\n",
"----------------------------------------------------------------------\n",
"Ran 1 test in 0.003s\n",
"\n",
"OK\n"
]
}
],
"outputs": [],
"source": [
"def my_count(arg0, elem=None):\n",
" \"\"\"return the number of elem in arg0 if elem is None, else \n",
......@@ -454,20 +440,20 @@
" for e in arg0:\n",
" if e == elem:\n",
" nb_elem += 1\n",
" return nb_elem\n",
"\n",
"import unittest\n",
"class TestMyStuff(unittest.TestCase): \n",
" def test_myfunc1(self):\n",
" \"\"\" test myfunc1 \"\"\"\n",
" self.assertEqual(3, my_count(\"abb\"))\n",
" self.assertEqual(1, my_count(\"abb\", \"a\"))\n",
" self.assertEqual(2, my_count(\"abb\", \"b\"))\n",
" self.assertEqual(0, my_count(\"\"))\n",
" self.assertEqual(0, my_count(\"abb\", \"c\"))\n",
" self.assertEqual(None, None)\n",
"\n",
"_res = unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(TestMyStuff))\n"
" return nb_elem"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"assert my_count(\"abb\") == 3\n",
"assert my_count(\"abb\", \"a\") == 1\n",
"assert my_count(\"abb\", \"b\") == 2\n",
"assert my_count(\"\") == 0\n",
"assert my_count(\"abb\", \"c\") == 0"
]
},
{
......@@ -485,7 +471,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
......@@ -516,7 +502,7 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 14,
"metadata": {
"collapsed": true
},
......@@ -529,7 +515,7 @@
},
{
"cell_type": "code",
"execution_count": 21,
"execution_count": 15,
"metadata": {},
"outputs": [
{
......@@ -550,81 +536,39 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"def how_to_use_list_as_default_arg(l=None):\n",
" if l is None:\n",
" l = []\n",
" l.append(1)\n",
" print(l)\n",
" return l"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"test_myfunc1 (__main__.TestMyStuff)\n",
"test myfunc1 ... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 1]\n",
"[1]\n",
"running function\n",
"[1]\n",
"[1]\n",
"[1]\n",
"[1, 2, 3, 1]\n"
"[1]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"ok\n",
"\n",
"----------------------------------------------------------------------\n",
"Ran 1 test in 0.003s\n",
"\n",
"OK\n"
]
},
{
"data": {
"text/plain": [
"[1, 2, 3, 1]"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def how_to_use_list_as_default_arg(l=None):\n",
" if l is None:\n",
" l = []\n",
" l.append(1)\n",
" print(l)\n",
" return l\n",
" \n",
"\n",
"import unittest\n",
"class TestMyStuff(unittest.TestCase): \n",
" def test_myfunc1(self):\n",
" \"\"\" test myfunc1 \"\"\"\n",
" l1 = [1, 2, 3]\n",
" how_to_use_list_as_default_arg(l1)\n",
" self.assertEqual(l1, [1, 2, 3, 1])\n",
" l = how_to_use_list_as_default_arg()\n",
" self.assertEqual(l, [1])\n",
"\n",
"_res = unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(TestMyStuff))\n",
"\n",
"print(\"running function\")\n",
"how_to_use_list_as_default_arg()\n",
"how_to_use_list_as_default_arg()\n",
"how_to_use_list_as_default_arg()\n",
"l1 = [1,2,3]\n",
"l1 = [1, 2, 3]\n",
"how_to_use_list_as_default_arg(l1)\n",
"l1"
"assert l1 == [1, 2, 3, 1]\n",
"assert how_to_use_list_as_default_arg() == [1]\n",
"assert how_to_use_list_as_default_arg() == [1]"
]
},
{
......@@ -644,7 +588,7 @@
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": 18,
"metadata": {},
"outputs": [
{
......@@ -665,7 +609,7 @@
"18"
]
},
"execution_count": 23,
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
......@@ -742,36 +686,17 @@
},
{
"cell_type": "code",
"execution_count": 29,
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"test_multiply (__main__.TestMyStuff)\n",
"test multiply ... FAIL\n",
"\n",
"======================================================================\n",
"FAIL: test_multiply (__main__.TestMyStuff)\n",
"test multiply\n",
"----------------------------------------------------------------------\n",
"Traceback (most recent call last):\n",
" File \"<ipython-input-29-4cb7c16c95a1>\", line 12, in test_multiply\n",
" self.assertEqual([2, 4], l1)\n",
"AssertionError: Lists differ: [2, 4] != [1, 2]\n",
"\n",
"First differing element 0:\n",
"2\n",
"1\n",
"\n",
"- [2, 4]\n",
"+ [1, 2]\n",
"\n",
"----------------------------------------------------------------------\n",
"Ran 1 test in 0.003s\n",
"\n",
"FAILED (failures=1)\n"
" File \"<ipython-input-20-411d52618068>\", line 12, in test_func\n",
" assert l1 == [2, 4]\n",
"AssertionError\n"
]
}
],
......@@ -781,24 +706,27 @@
" of the list by the number. If not set, number is defaulted to 2.\"\"\"\n",
" pass\n",
"\n",
"import unittest\n",
"class TestMyStuff(unittest.TestCase): \n",
" def test_multiply(self):\n",
" \"\"\" test multiply \"\"\"\n",
"import traceback\n",
"\n",
"def test_func(func):\n",
" try:\n",
" l1 = [1, 2]\n",
" multiply(l1)\n",
" self.assertEqual([2, 4], l1)\n",
" multiply(l1, 4)\n",
" self.assertEqual([8, 16], l1)\n",
" func(l1)\n",
" assert l1 == [2, 4]\n",
" func(l1, 4)\n",
" assert l1 == [8, 16]\n",
" l1 = []\n",
" multiply(l1)\n",
" self.assertEqual([], l1)\n",
" func(l1)\n",
" assert l1 == []\n",
" l1 = ['a', 'b']\n",
" multiply(l1)\n",
" self.assertEqual([\"aa\", \"bb\"], l1)\n",
" \n",
" func(l1)\n",
" assert l1 == [\"aa\", \"bb\"]\n",
" except AssertionError:\n",
" traceback.print_exc()\n",
" else:\n",
" print(\"All tests pass!\")\n",
"\n",
"_res = unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(TestMyStuff))\n"
"test_func(multiply)"
]
},
{
......@@ -814,37 +742,14 @@
},
{
"cell_type": "code",
"execution_count": 28,
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"test_multiply (__main__.TestMyStuff)\n",
"test multiply ... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0, 1, 2]\n",
"[0, 2, 4]\n",
"[0, 8, 16]\n",
"['aaaa', 'bbbb']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"ok\n",
"\n",
"----------------------------------------------------------------------\n",
"Ran 1 test in 0.002s\n",
"\n",
"OK\n"
"All tests pass!\n"
]
}
],
......@@ -853,35 +758,7 @@
" for i, val in enumerate(l):\n",
" l[i] = a * val\n",
"\n",
"\n",
"import unittest\n",
"class TestMyStuff(unittest.TestCase): \n",
" def test_multiply(self):\n",
" \"\"\" test multiply \"\"\"\n",
" l1 = [1, 2]\n",
" multiply(l1)\n",
" self.assertEqual([2, 4], l1)\n",
" multiply(l1, 4)\n",
" self.assertEqual([8, 16], l1)\n",
" l1 = []\n",
" multiply(l1)\n",
" self.assertEqual([], l1)\n",
" l1 = ['a', 'b']\n",
" multiply(l1)\n",
" self.assertEqual([\"aa\", \"bb\"], l1)\n",
" \n",
"\n",
"_res = unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(TestMyStuff))\n",
"\n",
"l = list(range(3))\n",
"print(l)\n",
"func(l)\n",
"print(l)\n",
"func(l, 4)\n",
"print(l)\n",
"l = ['a', 'b']\n",
"func(l, 4)\n",
"print(l)\n"
"test_func(multiply)"
]
},
{
......@@ -902,7 +779,7 @@
},
{
"cell_type": "code",
"execution_count": 26,
"execution_count": 22,
"metadata": {},
"outputs": [
{
......@@ -911,7 +788,7 @@
"3"
]
},
"execution_count": 26,
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
......@@ -948,7 +825,7 @@
},
{
"cell_type": "code",
"execution_count": 27,
"execution_count": 23,
"metadata": {},
"outputs": [
{
......@@ -965,7 +842,7 @@
},
{
"cell_type": "code",
"execution_count": 28,
"execution_count": 24,
"metadata": {},
"outputs": [
{
......@@ -994,7 +871,7 @@
},
{
"cell_type": "code",
"execution_count": 29,
"execution_count": 25,
"metadata": {
"slideshow": {
"slide_type": "-"
......@@ -1005,14 +882,14 @@
"name": "stdin",
"output_type": "stream",
"text": [
"what's your name ? eric\n"
"what's your name ? toto\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"your name is eric\n"
"your name is toto\n"
]
}
],
......@@ -1039,7 +916,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.5"
"version": "3.7.2"
}
},
"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)
# Functions
A function is a block of organized, reusable code that is used to perform a single, related action. Functions provide better modularity for your application and a high degree of code
reusing.
%% Cell type:markdown id: tags:
## All Python functions return exactly one object but... `None` and `tuple`
%% Cell type:code id: tags:
``` python
type(print())
```
%%%% Output: stream
%%%% Output: execute_result
NoneType
%% Cell type:code id: tags:
``` python
def return_a_tuple():
return 1, 'hello', 3 # a tuple, same as (1, 'hello', 3)
my_tuple = return_a_tuple()
print(my_tuple)
```
%%%% Output: stream
(1, 'hello', 3)
%% Cell type:code id: tags:
``` python
a, b, c = return_a_tuple()
print(b)
```
%%%% Output: stream
hello
%% Cell type:markdown id: tags:
## Function call: namespaces and objects "passed by references"
For each function call:
- a **new namespace** is created (as at the beginning of a module)
- the objects are **"passed by references"**: new names of the arguments are created in the function namespace and they point towards the objects given as arguments to the function (so it is possible to modify the mutable objects).
%% Cell type:markdown id: tags:
## Function call: objects "passed by references"
Exercice: use 2 schemes "namespaces-objects" to understand these 2 pieces of code.
%% Cell type:code id: tags:
``` python
number = 2
mylist = []
def my_strange_append_square(l, n):
# new function namespace with names "l" and "n"
n = n**2
l.append(n)
my_strange_append_square(mylist, number)
print(mylist, number)
```
%%%% Output: stream
[4] 2
%% Cell type:code id: tags:
``` python
number = 2
mylist = []
def my_strange_append_square(mylist, number):
# new function namespace with names "mylist" and "number"
number = number**2
mylist.append( number)
my_strange_append_square(mylist, number)
print(mylist, number)
```
%%%% Output: stream
[4] 2
%% Cell type:markdown id: tags:
## Global vs Local variables
Variables that are defined inside a function body have a local scope (i.e. are defined in the function namespace), and those defined outside have a global scope.
This means that local variables can be accessed only inside the function in which they are declared, whereas global variables can be accessed throughout the module by all functions.
%% Cell type:code id: tags:
``` python
# global variables
result = 0
multiplicator = 2
def multiply(arg0):
# here we create a new name `result` in the function namespace
# `result` is a local variable
# we can use the global variable `multiplicator`
result = multiplicator * arg0
print('Inside the function local result:\t', result)
return result
multiply(10)
print('Outside the function global result:\t', result)
```
%%%% Output: stream
Inside the function local result: 20
Outside the function global result: 0
%% Cell type:markdown id: tags:
- Global variables can be used in a function.
- Global variables can not be modified in a function (except with the `global` keyword. Discourage!).
%% Cell type:markdown id: tags:
## Global vs Local variables: `global` keyword
There is a keyword `global` to define inside a function a global variable and to modify a global variable in the function. **It is often a bad idea to use it :-)**
%% Cell type:code id: tags:
``` python
def func():
global me
# Defined locally but declared as global
me = 'global variable locally defined'
print(me)
func()
# Ask for a global variable
print(me)
```
%%%% Output: stream
global variable locally defined
global variable locally defined
%% Cell type:code id: tags:
``` python
delta = 0
def add_1_to_delta():
global delta
# global variable modified in a function
delta += 1
for i in range(4):
add_1_to_delta()
print(delta, end=', ')
```
%%%% Output: stream
1, 2, 3, 4,
%% Cell type:markdown id: tags:
## Function Arguments
You can call a function by using the following types of formal arguments:
- Required arguments
- Keyword arguments
- Default arguments
- Variable-length arguments
%% Cell type:markdown id: tags:
### Required arguments
Required arguments are the arguments passed to a function in correct positional order. Here, the number of arguments in the function call should match exactly with the function definition.
%% Cell type:code id: tags:
``` python
def myfunc(arg0, arg1):
"Return the sum of the first argument with twice the second one."
result = arg0 + 2*arg1
print(f'arg0 + 2*arg1 = {arg0} + 2*{arg1} = {result}')
return result
myfunc(4, 6)
```
%%%% Output: stream
arg0 + 2*arg1 = 4 + 2*6 = 16
%%%% Output: execute_result
16
%% Cell type:markdown id: tags:
To call the function `myfunc`, you definitely need to pass two arguments, otherwise it gives a syntax error.
%% Cell type:markdown id: tags:
### Keyword arguments
Keyword arguments are related to the function calls. When you use keyword arguments in a function call, Python identifies the arguments by the parameter name.
%% Cell type:code id: tags:
``` python
myfunc(arg1=3, arg0=2)
```
%%%% Output: stream
arg0 + 2*arg1 = 2 + 2*3 = 8
%%%% Output: execute_result
8
%% Cell type:markdown id: tags:
### Default arguments
A default argument is an argument that assumes a default value if a value is not provided in the function call for that argument.
%% Cell type:code id: tags:
``` python
def my_count(arg0, elem=None):
"""return the number of elem in arg0 if elem is None, else
the number of times elem appears"""
if elem is None:
return len(arg0)
nb_elem = 0
for e in arg0:
if e == elem:
nb_elem += 1
return nb_elem
import unittest
class TestMyStuff(unittest.TestCase):
def test_myfunc1(self):
""" test myfunc1 """
self.assertEqual(3, my_count("abb"))
self.assertEqual(1, my_count("abb", "a"))
self.assertEqual(2, my_count("abb", "b"))
self.assertEqual(0, my_count(""))
self.assertEqual(0, my_count("abb", "c"))
self.assertEqual(None, None)
_res = unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(TestMyStuff))
```
%%%% Output: stream
%% Cell type:code id: tags:
test_myfunc1 (__main__.TestMyStuff)
test myfunc1 ... ok
----------------------------------------------------------------------
Ran 1 test in 0.003s
OK
``` python
assert my_count("abb") == 3
assert my_count("abb", "a") == 1
assert my_count("abb", "b") == 2
assert my_count("") == 0