Python pour les débutants

Fabien Boutantin

Janvier 2019

Merci à Benjamin et Louis pour leur aide active.

Presenter Notes

Outils utilisés pour cette présentation

  • Rédaction
    • Langage de formattage : Markdown
    • Editeur de texte : nano/vim/vscode/gedit...
  • Affichage & rendu :
  • Travail collaboratif
    • git
    • Jenkins

Presenter Notes

Python ?

  • Pour quoi ?
  • Pour qui ?
  • Comment ?

Presenter Notes

Quelle version de Python?

  • Python 2.X ?
  • Python 3.X ?

Presenter Notes

Installons Python

Presenter Notes

Linux

$ sudo apt install python

Presenter Notes

Windows

  • Aller sur le site officiel Python
  • Cliquer sur "download"
  • Chercher la dernière version de 2.X (2.7.15)
  • Choisir le MSI 32 bits (pour des problèmes de compatibilité avec certain modules, mais la 64 bits fonctionne aussi)
  • L’exécuter, next, next, next, next...

Presenter Notes

Windows... encore.

  • Ajouter Python dans le PATH :
    • Raccourcis : [Win] (la touche windows du clavier) + [Pause]
    • Avancé
    • Variables d’environnement
    • Ajouter C:\Python27\ dans le PATH s'il n'y est pas déjà
  • Voila. (Linux c'est compliqué qu'ils disent ;) )

Presenter Notes

Où se renseigner sur Python ?

Presenter Notes

Pour s'entraîner en s'amusant

Un site sur des bonnes pratiques Python.

Presenter Notes

Bonjour, monde!

Ou notre premier code Python

Presenter Notes

Lancer Python

  • Il faut lancer un terminal
  • puis taper python

Presenter Notes

Le résultat attendu

$ python
Python 2.7.15rc1 (default, Nov 12 2018, 14:31:15)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

Cela veut dire plusieurs choses :

  • Python est bien installé et capable de fonctionner
  • L'invite de commandes a changé et s'est mis "en mode Python" (les >>>)
  • Nous allons donc pouvoir taper nos commandes !

Presenter Notes

Première commande

C'est parti, tapez :

>>> print "Hello, world!"

Presenter Notes

Le résultat attendu

Vous devriez avoir quelque chose comme cela à l'écran maintenant :

>>> print "Hello, world!"
Hello, world !

Presenter Notes

Affichage de texte (1/2)

  • Mot-clé : print
    • Dire à Python que l'on veut inscire quelque chose dans le terminal
  • Double quotes : "
    • Préciser que l'on veut du texte

Presenter Notes

Affichage de texte (1/2)

print "Hello, world!"

Permet donc d'écrire le texte Hello, world ! dans le terminal.

Presenter Notes

Quitter l'interpréteur

>>> quit()
$

Presenter Notes

Un autre interpreteur: iPython

  • Complétion
  • Historique des commandes utilisées (y compris lors de précédentes sessions)
  • Affichage des valeurs plus agréable
  • ...

Presenter Notes

Les Pythons aiment les maths

>>> 1+1
2
>>> ( 1 + 2 * 12 ) / 3
8

Presenter Notes

Note sur les divisions

Mais, la division est fausse, non ?
25/3 ça ne vaut pas 8 !

En Python, quand on divise des entiers, on fait la division entière.

Presenter Notes

Nombres complexes

>>> (1+3j)**2
(-8+6j)

Presenter Notes

Et même la trigonométrie

>>> sinus(3.14159)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sinus' is not defined

Presenter Notes

OUPS!

  • On ne peut pas (encore) demander à Python de faire nos exercices de géométrie,
  • On voit ce qu'il se passe quand Python n'est pas content :
    • Il nous donne le nom du fichier qu'on exécute (ici <stdin>),
    • Il nous donne la ligne où il y a un problème (ici la ligne 1),
    • Il nous dit même ce qui ne va pas : sinus est inconnu pour Python, il n'est pas défini.

Presenter Notes

Mais une minute, on nous parle de nom de fichier, de scripts Python, etc. Comment ça marche ?

Presenter Notes

On va scripter !

Presenter Notes

Si nous fonctionnions toujours avec l'invite de commande Python, nous serions obligés de réécrire toujours nos commandes Python et cela ne serait pas très efficace.

Un script c'est un fichier qu'un programmeur (vous) écrit et que l'on demande à Python d’exécuter. C'est un ensemble de commandes, identique à celui que l'on pourrait écrire dans le terminal.

C'est d'ailleurs ce que nous allons faire avec nos premières commandes (print et maths).

Je laisse le choix de l’éditeur (IDE) au lecteur, personnellement, j'utilise vim, nano, gedit, atom, VSCode, KDevelop, tout dépend de mon humeur.

Premiers scripts : rédaction

Nous allons créer un nouveau fichier hello.py :

print "Hello, world!"

Presenter Notes

Premiers scripts : exécution

Dans un nouveau terminal, il suffit de faire :

$ python Training_Python/1_first_script/hello.py
Hello, world!

Comme on peut le voir, notre commande Python s'est bien exécutée.

Presenter Notes

Premiers scripts : Maths

Maintenant, créons un fichier maths.py avec le contenu suivant :

1+1
( 1 + 2 * 12 ) / 3
(1+3j)**2
sinus(3.14159)

Presenter Notes

Première erreur

Demandons à Python de l’exécuter comme tout à l'heure :

$ python Training_Python/1_first_script/maths.py
Traceback (most recent call last):
  File "Training_Python/1_first_script/maths.py", line 4, in <module>
    sinus(3.14159)
NameError: name 'sinus' is not defined

Rien ne va plus... Que c'est-il passé ?

Presenter Notes

En 5 mots : ce que nous avons demandé ! Et oui un ordinateur (et un langage informatique aussi) est bête et discipliné. Nous avons demandé à Python de faire des maths, et il l'a fait. Il a effectivement calculé 1+1, puis les différentes formules qu'on lui a demandé. Jusqu'à la ligne avec sinus, qui une fois encore a fait une erreur. Cette fois-ci on peut remarquer que le nom du fichier où l’erreur s'est produite est donné, ainsi que le numéro de ligne (ligne 4 dans maths.py). Python nous recopie même la ligne pour "voir" où se trouve l’erreur.

OK, il nous donne l’erreur, mais où sont nos calculs ??? À votre avis ?

Et bien il manque quelque chose : print. Contrairement au mode interactif, où Python écrit le résultat automatiquement dans le terminal, avec un script, il faut dire à Python d'écrire (imprimer) le résultat.

Premiers scripts : affichage

Ré-essayons avec ce contenu maintenant dans le fichier maths2.py

print 1+1
print ( 1 + 2 * 12 ) / 3
print (1+3j)**2

Ce qui donne :

$ python Training_Python/1_first_script/maths2.py
2
8
(-8+6j)

YES, c'est bon cette fois !

Presenter Notes

Le ZEN du Python

Presenter Notes

Python est sans cesse amélioré, nous l'avons déjà dit. Les améliorations du langage passent par des PEP Python Extension Proposals. Ces PEPs sont acceptés ou non par la communauté, et finissent ou non dans les versions publiques de Python.

Très tôt dans le développement de Python, il y a eu des propositions visant à rendre le langage un peu particulier par rapport à nombre d'autres langages PEP8 & PEP20.

Le premier, PEP8, concerne le formatage du code. C'est assez classique, mais la lecture de ce PEP est une bonne idée pour qui veut faire du Python. Tout fichier inclus dans Python doit suivre ces conventions de codage. De même, toute correction proposée pour aider au développement de Python doit aussi suivre ces règles. Il y a des IDEs (atom, VSCode) qui proposent des extensions afin de vérifier que le code est bien compatible avec PEP8.

Le second, PEP20, est encore plus intéressante à lire. Il donne des règles de bonne conduite lorsque l'on écrit du code :

  • Beautiful is better than ugly.
  • Explicit is better than implicit.
  • Simple is better than complex.
  • Complex is better than complicated.
  • ...
  • Readability counts.
  • ...

Pour voir l’intégralité du PEP20, dans l'invite de commandes Python, tapez ceci :

>>> import this
Beautiful is better than ugly.
...

Presenter Notes

Et oui, en Python, la lecture du code est importante, et il est préférable de faire simple plutôt que complexe, etc. C'est en partie pour cela que le code Python est facile à lire, même pour un enfant de 8 ans.

Commentaires

La lisibilité est importante.

Pour rendre du code plus lisible on peut utiliser des lignes d'explications qui ne seront pas exécutées par Python : les commentaires.

En Python, pour écrire un commentaire, il suffit d'écrire # puis votre commentaire, comme cela :

# compute 1+1 ?
print 1+1

print 1+1 # expected result : 2

Presenter Notes

Types de données

Presenter Notes

Comme je l'ai déjà dit, Python est un langage simple, mais complet. En effet, la lecture du code est importante (Python zen), mais les types de données que peut manipuler (facilement) Python sont énormes.

Les entiers : int

Comme on l'a vu récemment, on peut manipuler des entiers :

>>> 3*5
15

Presenter Notes

Les réels : float

On peut aussi manipuler des nombres réels :

>>> 3.14159*2
6.28318

Presenter Notes

Les nombres imaginaires

Et oui, on l'a déjà vu aussi:

>>> (3+2j)**3
(-9+46j)

Presenter Notes

Les très grands nombres

Contrairement à beaucoup de langages, il n'y a pas besoin, en Python, de dire que l'on veut manipuler des grands nombres, Python adapte tout seul :

>>> 10*9*8*7*6*5*4*3*2*1*100000000
362880000000000

Presenter Notes

Les textes (1/2)

Un texte est un ensemble de lettres qui sont placées entre des double quotes.

>>> "Hello!"
'Hello!'

Et bien, en Python on peut aussi le placer entre simple quote cela n'a pas d'importance.

>>> 'Hello!'
'Hello!'

Presenter Notes

Les textes (2/2)

Et pour taper des textes sur plusieurs lignes on peut aussi utiliser les triples simple quotes, ou les triples double quotes.

>>> """Hello
... world"""
'Hello\nworld'

Presenter Notes

Note : L'invite de commandes Python mets trois petits points lorsque la commande est sur plusieurs lignes.

Note 2 : Dans la majeure partie des langages de programmation, \n signifie "saut à la ligne".

Les variables

Presenter Notes

Utiliser Python pour simplement faire des calculs c'est un peu comme ne pas passer la seconde vitesse dans une voiture. On peut faire beaucoup mieux.

Définition mathématique

La notion mathématique de variable est la suivante (Wikipédia) :

Dans les mathématiques élémentaires, une variable est une grandeur dont la valeur est (provisoirement) indéterminée, mais sur laquelle est effectuée une combinaison d'opérations avec soit des constantes, soit d'autres variables. Une variable n'est pas totalement précisée, sa valeur peut même être inconnue...

Presenter Notes

Les variables en informatique ne sont pas tout à fait identique. On peut plutôt voir cela comme une "boîte" sur laquelle on met une étiquette. Sur les calculatrices, il y a souvent 2 variables : M+ et M-. Ce sont des boites dans lesquelles on peut ranger des nombres pour ensuite les réutiliser. En Python c'est sensiblement pareil, sauf que les boîtes ont une étiquette, un nom, et que pour utiliser ce qui ce trouve dans la boite on peut réutiliser l'étiquette.

Par exemple, on peut facilement se dire que taper 3.14159 à chaque fois que l'on veut utiliser PI, c'est assez lassant. Pourquoi ne pas utiliser une variable et mettre 3.14159 dedans ? Voyons cela :

Variables en python

Exemple :

>>> pi = 3.14159
>>> print pi
3.14159
>>> pi*2
6.28318

Presenter Notes

Nous avons mis la valeurs 3.14159 dans la boite avec l'étiquette pi. On dit plutôt que nous avons crée une variable pi à laquelle nous avons affecté la valeur 3.14159.

Nous avons ensuite utilisé cette valeur pour faire des calculs.

C'est un peu la base de la programmation, mettre des valeurs en mémoire pour ensuite les utiliser.

Règles sur les noms de variables

  • Un nom de variable peut contenir des lettres, des chiffres et _
  • Un nom de variable peut avoir des majuscules
  • Un nom de variable peut avoir la taille que l'on souhaite
  • Un nom de variable ne peut commencer par un chiffre
  • Une variable doit avoir un nom qui reflète son contenu (vous vous souvenez du zen ? Readability counts)

Presenter Notes

Types des variables en Python

Il est important de remarquer qu'en Python, une variable n'est pas figée, et aussi bizarre que ça paraisse, on peut changer le type de donnée stocké dans une variable :

>>> pi = 3.14159
>>> pi
3.14159
>>> pi = "Hi"
>>> pi
'Hi'

Presenter Notes

pi est tour à tour un nombre réel, puis un texte.

Bien sûr, cet exemple est très mauvais car le code qui suivrait en devient illisible : une variable qui s'appelle PI ne devrait pas contenir autre chose que PI, surtout pas ce texte.

Structures de données

Presenter Notes

Maintenant que nous avons des variables, nous pouvons stocker des données en mémoire, mais comment stocker des données en grand nombre ? Utiliser des variables comme a1, a2, a3, a4, etc. ? Comment stocker alors des milliers de valeurs ?

Les listes : list()

Comment allons nous stocker des notes pour des élèves afin de calculer une moyenne ? Une variable par élève avec son prénom, ou son nom ? Non, Python a une structure pour stocker ce genre de données : les listes.

Pour créer une liste il suffit de taper ce code :

>>> my_first_list = list()
>>> print my_first_list
[]

Presenter Notes

Jusque là, rien d'extraordinaire, mais on n'a pas dit quelle taille devait faire cette liste. Et oui, en Python une liste peut faire (presque) la taille que l'on veut, mais pour l'instant elle est vide.

Remplissage d'une liste (1/2)

Pour remplir une liste il suffit d'appeler append() sur cette liste :

>>> my_first_list.append(1)
>>> my_first_list
[1]
>>> my_first_list.append(2)
>>> my_first_list.append(3)
>>> my_first_list.append(4)
>>> my_first_list
[1, 2, 3, 4]

Presenter Notes

Remplissage d'une liste (2/2)

Écrire append() pour chaque élément de la liste n'est pas très aisé, mais aussi pas très "lisible", ni simple. On peut donc aussi initialiser une liste avec ses éléments en écrivant :

>>> a_second_list = [1,2,3,4]
>>> a_second_list
[1, 2, 3, 4]

C'est tout de suite plus simple.

Presenter Notes

Listes complexes

On peut aussi mélanger les types dans une liste :

>>> misc_list = [1.0, "a", [1,2,3]]
>>> misc_list
[1.0, 'a', [1,2,3]]

Presenter Notes

Accès à un élément d'une liste

Pour accéder à un élément donné, connaissant son ordre dans la liste, on utilise les crochets :

>>> misc_list[1]
'a'
>>> misc_list[0]
1.0

On peut aussi partir de la fin en utilisant un index négatif : -1 permet de récupérer le dernier élément d'une liste; -2 l'avant dernier...

>>> misc_list[-1]
[1,2,3]
>>> misc_list[-2]
'a'

Presenter Notes

Et oui, en informatique tout commence à 0; donc le zeroième élément est en fait le premier en langage courant.

Modification d'un élement

On peut aussi changer un élément :

>>> l = [1, 2, 3]
>>> l[0] = 5
>>> l
[5, 2, 3]

Presenter Notes

Taille d'une liste

On peut connaître la taille d'une liste en utilisant la fonction pré-définie len() :

>>> len(misc_list)
3
>>> misc_list.append(2)
>>> len(misc_list)
4

Presenter Notes

Opérations sur les listes (1/2)

On peut aussi connaître le maximum ou le minimum d'une liste (il faut cependant que la liste soit triable) :

>>> min(my_first_list)
1
>>> max(my_first_list)
4

Presenter Notes

Opérations sur les listes (2/2)

On peut connaître la somme des éléments d'une liste (il faut une liste constituée que de nombres donc) :

>>> sum([1, 2, 3])
6

On peut trier une liste :

>>> sorted([2,3,1,4])
[1, 2, 3, 4]

Presenter Notes

Suppression d'élement d'une liste

On peut enlever un élément de la liste :

>>> misc_list.pop(0)
1.0
>>> misc_list
['a', [1, 2, 3], 2]
>>> misc_list.pop()
2
>>> misc_list.pop()
[1, 2, 3]
>>> misc_list.pop()
'a'
>>> len(misc_list)
0

Presenter Notes

Exercice

Une classe de 10 élèves a fait un contrôle, les notes sont les suivantes :

9 11 19 3 13.5 12 7 5 15 16

Donner la note minimum, maximum et la moyenne de la classe.

Presenter Notes

(Réponses : 3 19 11.05)

La liste range()

Il existe une liste en Python un peu spéciale : range()

Cette liste est constituée des entiers compris entre 0 et n-1 lorsque l'on appelle range(n).

range(3) est donc équivalent à [0, 1, 2]

Cette liste est très pratique pour les boucles que nous verrons plus tard.

Presenter Notes

Les tuples : tuple

Les tuples sont une sorte de liste, mais dont le contenu est figé : on ne peut pas ajouter de nouvel élément et on ne peut pas changer un élément.

Les tuples sont utiles pour des questions de performances et de place mémoire.

Pour créer un tuple on fait comme pour une liste mais on échange [] par () :

>>> t = (1,2,3)
>>> t
(1, 2, 3)

Presenter Notes

Création d'un tuple avec une liste

On peut aussi créer un tuple à partir d'une liste :

>>> t = tuple([1,2,3])
>>> t
(1, 2, 3)

Presenter Notes

Excercice

Comment échanger le contenu de deux variable ?

Presenter Notes

(Réponse : a,b = b,a)

Les sets : set

Un set est comme une liste, mais diffère sur 2 points :

  • Il n'est pas ordonné : l'ordre de création n'est pas conservé
  • Il ne peut contenir qu'une seule fois le même élément

On peut créer dynamiquement un ensemble d'élements uniques par exemple, à partir d'une liste :

>>> uniq_set_of_values = set([1, 2, 1, 3, 1, 4, 2])
>>> uniq_set_of_values
set([1, 2, 3, 4])

Presenter Notes

Ce deuxième point est la principale raison d'être des sets.

Utilisation des sets

On peut aussi ajouter des éléments dans un set, en enlever, connaître sa taille :

>>> uniq_set_of_values.add(1)
>>> len(uniq_set_of_values)
4
>>> uniq_set_of_values.add(5)
>>> len(uniq_set_of_values)
5
>>> uniq_set_of_values.remove(5)
>>> uniq_set_of_values
set([1, 2, 3, 4])

Presenter Notes

Les dictionnaires : dict()

Notés dict en Python, les dictionnaires permettent de faire correspondre une clé à une valeur dans une table.

Si nous reprenons notre exemple des notes dans une classe, on peut faire correspondre à chaque élève sa note lors d'un contrôle.

Un dictionnaire vide peut se créer avec la fonction dict():

>>> marks = dict()

Presenter Notes

Création d'un dictionnaire

Par exemple :

>>> marks = {
    "toto": 0,
    "riri": 12,
    "fifi": 14,
    "loulou": 20
}

On peut connaître la note d'un élève en demandant la valeur dans la table qui correspond à son prénom :

>>> marks["toto"]
0
>>> marks["loulou"]
20

Presenter Notes

Utilisation des dictionnaires (1/2)

On peut demander la taille d'un dictionnaire, comme pour les autres types en passant par len():

>>> len(marks)
4

On peut changer une valeurs affecté à une clé (existante ou non) :

>>> marks["fabien"] = 10
>>> marks["toto"] = 2

Presenter Notes

Et oui, toto avait quand même mis son nom sur la copie.

Utilisation des dictionnaires (2/2)

On peut supprimer une entrée dans la table avec le mot-clé del :

>>> del marks["fabien"]
>>> len(marks)
4

Sur un dictionnaires il est intéressant d'avoir la liste de clés (keys()) et la liste des valeurs (values()) :

>>> marks.keys()
['riri', 'fifi', 'toto', 'loulou']
>>> marks.values()
[12, 14, 2, 20]

Presenter Notes

Généralités

Les types que je vous ai présentés sont très puissants et permettent de représenter beaucoup de données.

Il existe cependant d'autres type de données. Pour les personnes intéressées, il est possible de regarder la documentation de NumPy ainsi que de pandas.

Je n'ai pas décrit toutes les possibilités d'action sur les types, pour plus de détails, se référer a docs.python.org, ou bien jouez sur HackerRank.

Presenter Notes

Introspection

L'introspection c'est le fait que l'on puisse avoir des informations sur des objets dans le langage même. En Python, cela passe par plusieurs fonctions que l'on va voir de suite : help(), dir() et hasattr().

Presenter Notes

help()

help() affiche l'aide d'un objet.
Interactif dans la console

Dans un script :
Donne le "texte" de l'aide, telle qu'on peut la voir sur docs.python.org Il faut passer par print pour voir le texte.

>>> help(set)
Help on class set in module __builtin__:

class set(object)
 |  set() -> new empty set object
 |  set(iterable) -> new set object
...

Presenter Notes

type()

type() done le type d'une variable ou d'un objet.

>>> d = dict()
>>> type(d)
<type 'dict'>
>>> type(3.14159)
<type 'float'>

Presenter Notes

dir()

dir() donne la liste de ce que propose un objet en Python.

Vraiment très puissant et permet d'avoir plein d'informations lorsque l'on écrit un script.

Un petit exemple :

>>> dir(dict)
[...
    'keys',
    'values',
    ...]

Presenter Notes

Comme vous pouvez le voir, dans un dictionnaire, il y a keys et values comme nous avons vu précédemment. À l'heure actuelle, on ne va pas pouvoir en faire grand chose, mais par la suite, vous verrez que c'est vraiment très puissant et permet d'avoir plein d'informations lorsque l'on écrit un script.

hasattr()

hasattr() permet de savoir si un objet détient un attribut.

L'exemple étant plus parlant qu'un long discours :

>>> hasattr(dict, 'keys')
True
>>> hasattr(dict, 'val')
False

Presenter Notes

Comme on peut le voir, un dictionnaire a keys (pour obtenir la liste des clés), mais ne connaît pas val. Et pour cause, c'est values qu'il faut utiliser pour avoir la liste des valeurs dans la table.

Contrôle de flot d'exécution

Presenter Notes

Pour l'instant, nous avons vu comment taper des commandes les unes après les autres. En gros, on ne peut faire qu'une suite de commandes bien définie et ne jamais sortir des clous.

Mais en informatique on ne fait pas que cela, une des premières choses que l'on a envie de faire c'est d'exécuter un bloc de code que si une condition est vraie, par exemple, calculer 1 / x que si x est différent de 0.

Bloc de code - Généralités

Ensemble de lignes de codes que l'on veut exécuter "d'un bloc".

Très souvent délimité par un indicateur (un caractère) de début et de fin (un autre caractère). En C++ :

{CODE_BLOCK}

Indentation pour rendre le code plus clair :

{
    CODE_BLOCK
}

Seulement une bonne pratique, pas d'obligations.

Presenter Notes

Cas particulier de Python (1/2)

En Python pas de séparateur, il faut indenter. Readability counts

Pour crééer des blocs, il faut changer l'indentation :

BLOCK_1
    BLOCK_2

Un retrait d'intentation fait revenir dans le bloc parent :

BLOCK_1
    BLOCK_2  # added indentation: new code block
BLOCK_1      # we removed indentation: back to BLOCK_1

Presenter Notes

Cas particulier de Python (2/2)

On ne peut par contre pas revenir dans un bloc qui a été fermé : dans notre exemple, on ne peut pas revenir dans le bloc 2 :

BLOCK_1
    BLOCK_2
BLOCK_1
    BLOCK_3

Presenter Notes

if

En début de ce chapitre, je disais que nous voulions exécuter du code si une certaine condition était vérifiée, nous y voila avec la structure de contrôle if.

Pour exécuter un bloc de code si une condition est vraie il faut taper :

if CONDITION:
    CODE_BLOCK

Presenter Notes

Conditions

Une condition est une sorte de formule qui est soit vraie soit fausse.

Par exemple, on peut tester si une variable a une valeur donnée en utilisant == :

>>> note = 10   # assign a value to variable
>>> note == 11  # check value content against another value
False
>>> note == 10
True

Presenter Notes

Conditions : différence

On peut tester si une variable a une valeur different d'une autre en utilisant != :

>>> note = 10   # assign a value to variable
>>> note != 11  # check value content against another value
True
>>> note != 10
False

Presenter Notes

Conditions : comparaisons

On peut aussi tester si une variable est supérieure, inférieure, stricte ou non à une certaine valeur :

>>> note = 10
>>> note <= 10
True
>>> note < 10
False
>>> note >= 10
True
>>> note >10
False

Presenter Notes

Conditions : appartenance à un intervale

On peut tester en une fois qu'une variable est est dans un intervale:

>>> note = 10
>>> 0 <= note <= 20
True
>>> 5 < note < 10
False

Presenter Notes

Le mot-clé in

Le mot-clé in est très important en Python, et son usage doit être privilegié dans les conditions. Plusieurs cas sont possibles :

Presenter Notes

in : Tester dans une liste

>>> 5 in range(10)
True
>>> 5 in range(2)
False

Presenter Notes

in :Tester dans un dictionnaire

>>> d = {1: 0, 2: 0}
>>> 0 in d
False
>>> 1 in d
True

Presenter Notes

in : Tester un texte dans un autre

>>> "abc" in "abcdef"
True
>>> "bac" in "abcdef"
False

Presenter Notes

Le mot-clé in - Readability

in est un mot-clé vraiment très pratique, et surtout très lisible non?

"Si cet élément est dans ma liste, alors faire ce bout de code" s'écrit pratiquement comme si on parlait :

if element in my_list:
    CODE_BLOCK

Presenter Notes

La négation : not

Le mot clé not, permet d'inverser une condition. Donc si une condition est vraie, alors not condition est fausse, et vice-versa.

Les parenthèses ne sont pas nécessaires, mais conseillées lorsque la condition devient complexe, pour améliorer la lisibilité.

>>> not True
False
>>> not( True )
False
>>> not False
True

Presenter Notes

not in

  • Afin d'améliorer la lisibilité, il y a une exception pour le mot clé in.
  • Il est possible d'écrire not élément in liste.
  • Mais c'est moins lisible que élément not in liste

Exemple : deux codes équivalents, mais le second est bien plus facile à lire et à comprendre !

>>> if not 1 in range(5):
...     print True
>>> if 1 not in range(5):
...     print True

Presenter Notes

Les opérations logiques : "et" et "ou"

Afin de pouvoir faire des conditions un peu plus compliquées, on utilise des mots clés spécifiques : and et or.

Presenter Notes

Les opérations logiques : and

and permet de faire un "et logique" entre deux conditions.

La condition formée par un and entre deux sous conditions n'est vraie que si les deux sous conditions sont vraies :

>>> False and False
False
>>> False and True
False
>>> True and False
False
>>> True and True
True

Presenter Notes

Les opérations logiques : or

or permet de faire un "ou logique" entre deux conditions.

Il suffit qu'une seule sous condition soit vraie pour que la condition globale soit vraie :

>>> False or False
False
>>> True or False
True
>>> False or True
True
>>> True or True
True

Presenter Notes

Le cas de la non valeur : None

Je n'en ai pas encore parlé, mais il est temps maintenant de vous parler d'une valeur particulière en Python : None.

None permet d'initialiser une variable à une sorte de non-valeur. Ceci est très pratique lorsqu'on veut avoir une variable mais que, par défaut, on ne sait pas encore quoi mettre dedans. Pour revenir à l'exemple de la classe, un élève absent ne doit pas avoir 0 comme note, on pourra dont utiliser 'None' comme note pour cet élève.

>>> marks["McFly"] = None

Presenter Notes

is None dans les conditions

Pour savoir si une valeur est None, on peut utiliser les doubles égale :

>>> marks["McFly"] == None
True

On peut aussi utiliser un mot clé : is

>>> n is None
True
>>> 1 is None
False

Presenter Notes

Ceci permet une fois de plus d'améliorer la lisibilité du code, et force est de reconnaître que tout le monde utilise is dès qu'il s'agit de tester si une variable est à None ou non.

is not None dans les conditions

Il se peut que l'on ai besoin de tester si une variable n'est pas à None. Auquel cas on peut utiliser not, comme précédemment, mais une fois de plus pour la lisibilité, on peut utiliser is not :

>>> if not( marks["loulou"] is None ):
...     marks_sum += marks["loulou"]
>>> if marks["loulou"] is not None:
...     marks_sum += marks["loulou"]

Presenter Notes

Note : a += b permet d'additionner le contenu de la variable a avec le contenu de la variable b, et de l'assigner à la variable a.

Exercice

  1. Écrire une condition qui vérifie qu'une variable est plus grande que 10 et plus petite que 20.
  2. Écrire une condition qui vérifie qu'une variable est soit positive et plus petite que 15, soit négative et plus petite que -10.

Presenter Notes

Boucles

On peut vouloir exécuter un bloc de code un certain nombre de fois. On fait cela avec une boucle.

Il existe 2 types de boucles en Python : for et while.

Presenter Notes

for

for permet d’itérer sur les éléments d'une liste :

for element in list:
    CODE_BLOCK

Presenter Notes

Ici on voit une autre utilisation du mot-clé in qui permet une très bonne lisibilité de la ligne de code : on veut faire une boucle pour tout élément element dans la liste list.

Dans le bloc de code, la variable element contient un élément de la liste.

Exercice

  1. Afficher les éléments d'une liste quelconque.
  2. Calculer la somme, à la main, de la liste [1,2,3,4].

Presenter Notes

Boucle sans listes

Mais alors, vous me direz, comment je fais si je dois faire un certain nombre d’opérations mais que je ne n'ai pas de liste ? Et bien, vous vous souvenez du chapitre sur les listes, on a vu une liste particulière : range(). C'est à elle que nous allons demander de faire le travail :

result = 0
for i in range(4):
    result = result + i
print result

Presenter Notes

En fait je ne suis pas honnête à ce moment du jeu : pour les boucles vous trouverez (en Python 2.x) une utilisation majoritaire de xrange() au lieu de range(). Pour faire simple sans rentrer dans les détails, range() crée la liste en mémoire, alors que xrange() ne crée qu'un élément à la fois : d'où un gain en performance et utilisation mémoire assez monstrueux. Pour vous en rendre compte, essayez ceci :

Boucle et mémoire

>>> range(1000000000000000000)
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
MemoryError
>>> xrange(1000000000000000000)
xrange(1000000000000000000)

Presenter Notes

while

while permet d'exécuter un bloc de code tant qu'une condition est vraie :

while condition:
    CODE_BLOCK

Presenter Notes

Attention, il est très facile de se retrouver dans une "boucle infinie" avec while !

Exercice

Calculer la liste des entiers jusqu’à 15 en utilisant une boucle while.

Presenter Notes

Sortir du bloc sans sortir de la boucle

Il est possible de faire en sorte que Python n'aille pas plus loin dans l’exécution du bloc d'une boucle (for ou while) afin de passer à l'élément suivant. Pour cela on utilise le mot-clé continue. Par exemple :

for i in xrange(2):
    if i == 1:
        continue
    CODE_BLOCK

Presenter Notes

Ici, on va donc exécuter un bloc de code que s'il est différent de 1, car dans ce cas, on "continue".

Sortir du bloc et sortir de la boucle

Si on veut sortir de la boucle en elle même, on peut utiliser break. Il s'utilise comme continue, mais permet de stopper la boucle :

while True:
    if condition:
        break
    CODE_BLOCK

Presenter Notes

Exercice

Donner l'entier pour lequel la somme de tous les entiers avant lui (y compris cet entier) devient plus grande que 123456 en utilisant une sortie de boucle.

Presenter Notes

Les fonctions

Nées du besoin d'organiser notre code pour ne pas se répéter.

En mathématiques, une fonction est une relation entre un ensemble d’entrées (variable) et un ensemble de sorties (image), avec la propriété que chaque entrée est liée au plus à une unique sortie. Un exemple de fonction est la fonction qui à tout nombre noté x associe son carré.

Presenter Notes

Voila, maintenant, nous savons mettre des valeurs dans des variables, faire en sorte d’exécuter un bloc de code en fonction d'une condition, et même faire des boucles pour itérer sur les éléments d'une liste, etc.

En informatique, c'est quasiment semblable (à l'exception de l'unicité de la valeurs de sortie, surtout avec des nombres aléatoires ;) ). Une fonction est un bloc de code qui prend des arguments en entrée et qui retourne une (ou des) valeur(s) en sortie. Une fonction a un nom qui permet de l'appeler, comme en mathématiques, et comme une variable. D'ailleurs, en Python, une fonction est une variable de type function.

Définition d'une fonction

Pour définir une fonction on fait comme ça :

def name_of_function():
    CODE_BLOCK

Presenter Notes

Ceci défini une fonction qui ne prend pas de paramètre (oui c'est possible), et qui ne retourne rien. Une telle fonction pourrait très bien allumer une lampe, ou l'éteindre.

Fonction avec arguments

Si on veut rajouter des argument on rajoute leur nom entre les parenthèses, et séparés par des virgules :

def set_temperatur(wanted_temperature):
    CODE_BLOCK

def show_color(red_intensity, red_intensity, red_intensity):
    CODE_BLOCK

Presenter Notes

Dans le premier cas, dans tout le bloc de code, on a accès à une variable wanted_temperature, et dans le second exemple, on a accès aux trois variables pour le rouge, le vert et le bleu.

Valeur de retour d'une fonction

Pour retourner une valeur, on utilise le mot clé return, comme ceci :

def pi():
    return 3.14159

Presenter Notes

Appel d'une fonction

Tout simplement en utilisant son nom avec les parenthèses :

>>> def pi():
...     return 3.14156
...
>>> print pi()
3.14159

Presenter Notes

Appel d'une fonction avec paramètres

Si la fonction prend des paramètres, on les passe dans les parenthèses :

>>> def echo(valeurs):
...     print valeurs
...
>>> echo(1)
1
>>> echo("ABC")
'ABC'
>>> echo([1,2])
[1,2]

Presenter Notes

Type d'une fonction

Comme je le disais, une fonction en Python est aussi une variable :

>>> print echo
<function echo at 0x7f7ad7bf4668>
>>> type(echo)
<type 'function'>

Presenter Notes

En fait dans ce cas, echo est une variable qui pointe vers une fonction qui est stockée en mémoire à l'adresse 0x7f7ad7bf4668 (ce chiffre sera différent à chaque définition de fonction).

Exercice

  1. Écrire une fonction qui retourne la valeur absolue d'un nombre
  2. Utiliser cette fonction pour l'appliquer sur tous les chiffres d'une liste.

Presenter Notes

Documentation

  • Rebute les développeur mais est essentielle
  • Ce n'est pas parce que les gens rechignent à le faire que cela n'est pas à faire.
  • Pour les autres et pour soi-même
  • Pas à la dernière minute, pour ne rien oublier

En Python, la documentation fait partie prenante du langage, et peut même être recupérée avec l'introspection. help() retourne la documentation écrite par les développeurs.

Presenter Notes

La simple idée de relire un code qui n'est pas documenté n'est pas une chose qui m'attire. Quand bien même s'il s'agit de son propre code, quelques mois plus tard on ne sait plus forcement ce que l'on a fait, ni même à quoi sert un script, quelles sont ses options, ou à quoi sert telle ou telle fonction.

Documenter une fonction

Simplement en rajoutant un texte après sa définition (son nom).

Le plus commun est d'utiliser les triples doubles quotes :

def my_function():
    """This is the documentation of my_function."""
    CODE_BLOCK

print help(my_function)
# this will print 'This is the documentation of my_function.'

Presenter Notes

Excercice

Documentez les fonctions que vous aviez créées lors du point précédent.

Presenter Notes

Les modules

La notion de module fait de Python un langage à part.

Collection de variables et de fonctions qui permettent d'étendre le langage.

  • Modules développés par des développeurs externes,
  • Python est livré avec de nombreux modules :
    • Philosophie batteries included
    • Interagir avec l'OS (listing de fichiers, création et suppressions de fichiers)
    • Gérer le temps
    • Lire des fichiers CSV ou de faire du JSON
    • Multithreading, ou multiprocessing,
    • Dialoguer avec des bases de données
    • Faire du réseau, un server web, etc.

Pour connaître la liste des modules livrés de base avec Python, vous pourrez vous référer à la page suivante de la documentation de Python.

Presenter Notes

Importation d'un module

Afin de pouvoir utiliser un module il faut l'importer de cette façon :

import MODULE_NAME

Ensuite on peut utiliser la document ation officielle de ce module, mais aussi l'introspection (dir() ou bien help()), pour savoir quelles variables ou fonctions ce module met à disposition.

Presenter Notes

Utilisation d'un module

On utilise les variables et les fonctions en utilisant le nom du module, un point, ainsi que le nom de la variable/fonction, comme ceci :

import MODULE
MODULE.useful_function()

Presenter Notes

os

Ce module permet d'interagir avec le systeme d'opération de votre ordinateur.
os permet notemment de :

  • Connaitre et changer les variables d'environement,
  • Lancer des commandes du système,
  • Connaitre et changer le répértoire courant d'execution,
  • Connaitre le nom de l'utilisateur,
  • ...

Presenter Notes

os : exemple

Exemple :

>>> import os
>>> os.getlogin()
'fabien'

Presenter Notes

sys

Permet d'obtenir des informations sur l'état de l'interpreteur Python.

Par exemple quelle version de Python est utilisée :

>>> import sys
>>> print sys.version_info
sys.version_info(major=2, minor=7, micro=15, releaselevel='candidate', serial=1)

Presenter Notes

math

Besoin d'utiliser le module de mathématiques pour faire toutes sortes de calculs.

math propose tout un tas de fonctions comme copier le signe d'un nombre sur un autre, connaitre la valeur entière la plus proche d'un nombre, calculer un factoriel, des puissances de logarithmes, des sinus/cosinus, etc.

>>> import math
>>> math.sin(math.PI)
1.2246467991473532e-16

Presenter Notes

Et oui, les microprocesseurs ne sont pas hyper précis, mais bon 10^-16 c'est proche de 0 quand même.

time

Ce module met à disposition un certain nombre de fonctions relatives à la gestion du temps, mais aussi la gestion de l'heure.

Il permet notement de connaitre l'heure courante avec une précision generalement meilleure que la seconde, mais cela ne peut pas être garanti et dépends du système.

>>> import time
>>> time.time()
1547158168.292978

Presenter Notes

Ceci peut être très interressant pour faire de l'étude de performance grossière (à la seconde près), mais si on veut mieux, il faut plutot utiliser time.clock() qui est de l'ordre de la microseconde.

random

random, comme son nom l'indique, va permettre d'ajouter de l'aléatoire dans un script. Comme initialiser une variable avec un entier entre deux bornes, ou alors un nombre réél entre 0 et 1 :

>>> import random
>>> random.random()
0.9406027006427641
>>> random.randint(0, 30)
9

Presenter Notes

random est aussi capable de bien d'autres choses, par exemple mélanger une liste, ou alors retourner une sous-liste aléatoire à partir d'une liste de départ.

Autres

Il y a bien d'autres modules displonibles avec l'installation par défaut de Python.

  • Il y a aussi de très nombreux modules développés par des tiers (gratuits ou non)
  • Certains sont vite devenus incontournables pour leur domaine d'application :

Presenter Notes

Interaction avec l'utilisateur

Lors de l'écriture de scripts, on a parfois besoin de poser des questions à l'utilisatuer afin de rendre le script "interactif".

En Python 2.7 il faut passer par la fonction raw_input(). Elle prend en paramètre optionnel un texte à afficher avant de poser la question à l'utilisateur :

>>> s = raw_input('--> ')
--> Monty Python's Flying Circus
>>> s
"Monty Python's Flying Circus"

Presenter Notes

Exercice

  1. Écrire un script qui demande à l'utilisateur de deviner un chiffre entre 1 et 10. Il devra taper des chiffres jusqu'à ce qu'il trouve le bon résultat.
  2. Faire en sorte que le script résiste au fait que l'utilisateur écrive autre chose que des chiffres.

Presenter Notes

Donner des arguments à un script

Il existe une façon simple et (au moins) une façon avancé de gérer les paramètres d'un script. Je me contenterais ici de donner la façon simple, mais sachez que la version compliqué peut être trouvé sur cette page de la documentation officielle.

La façon simple est d'utiliser le module sys qui met à disposition une variable argv qui contient tous les éléments de la ligne de commande qui a été utilisée pour lancer Python.

>>> import sys
>>> sys.argv
['']

Presenter Notes

En mode interactif, ceci n'a que peu d'intérêt, mais si on écrit un script on peut se servir de cette liste pour connaitre les options qu'un utilisateur a ajouté en plus du script dans la ligne de commande.

Utiliser les arguments

Écrivons ce script :

import sys
print sys.argv

Maintenant, lançons le avec plusieurs options :

$ python argv_printer.py
['argv_printer']
$ python argv_printer.py argument_1
['argv_printer.py','argument_1']

Presenter Notes

Comme on peut le voir, argv est une liste remplie avec les options que l'utilisateur a ajouté dans sa ligne de commande quand il a lancé son script.

Amusons nous avec turtle

Presenter Notes

turtle est un module de dessin basé sur le 'jeu de la tortue'. La philosophie derrière est très simple : une tortue tiens un crayon, elle peut avancer d'une certaine distance, ou tourner a gauche/droite d'un certain angle. Il convient de faire le code suivant pour démarrer la tortue et lui faire dessiner une ligne droite, tourner à gauche, et dessiner une autre droite :

Exemple

>>> import turtle
>>> t = turtle.Turtle() # Create a new windows for turtle to move on
>>> t.forward(100)
>>> t.right(90)
>>> t.forward(100)

Presenter Notes

Dessiner un triangle

Un peu de maths : un triangle est un polygone à 3 cotés (ou 3 sommets). La somme des angles d'un triangle vaut 180°. On pourra donc finir de dessiner un triangle avec le code suivant :

>>> t.right(90+45)
>>> import math
>>> t.forward( math.sqrt( 100**2 + 100**2 ) )

Presenter Notes

Exercice

  1. Écrire une fonction qui permet de dessiner un triangle isocèle en fonction de son point de depart en bas à gauche, et de la longueur de ses cotés.
  2. Comment faire pour que l'on ne dessine pas entre deux triangles ?

Presenter Notes

Dessiner un carré

Exercice

Comme pour le triangle, écrire une fonction pour dessiner un carré.

Presenter Notes

Dessiner un cercle

Exercice

  1. Idem.
  2. Écrire une fonction pour dessiner une rosace.

Presenter Notes

Manipulations du système de fichiers

Presenter Notes

Création d'un fichier

  • La fonction open() permet de créer un fichier.
  • Elle prend deux paramètres :
    • un texte qui donne le nom ou le chemin (absolu ou relatif) du ficher à créer,
    • un texte qui donne le mode d'ouverture du fichier :
      • 'w' pour l'écriture, 'a' pour écrire à la fin du ficher, 'r' en mode lecture.

Créer le fichier toto.txt dans le répértoire courant :

>>> fd = open("toto.txt","w")
>>> fd.close() # Don't forget to close!

Presenter Notes

Nous avons ainsi ouvert le fichier toto.txt en écriture et nous l'avons fermé aussitôt. Si on ouvre ce fichier dans un éditeur, on verra qu'il s'agit d'un ficher vide.

with open

Pour faciliter l'ouverture et la fermeture de fichier, on peut utiliser with.

À la sortie du bloc, le fichier sera fermé automatiquement :

>>> with open("toto.txt", "w") as fd:
...     pass
...

Presenter Notes

Nous avons ainsi ouvert le fichier toto.txt en écriture et nous l'avons fermé aussitôt. Si on ouvre ce fichier dans un éditeur, on verra qu'il s'agit d'un ficher vide. Note : il est nécessaire de fermer le fichier afin que sont contenu ne soit réellement écrit et de pouvoir l'ouvrir dans un autre éditeur.

Python a introduit il y a peu la notation with, qui permet, notement, de gerer les fichiers plus facilement. Voila le même exemple, voyez comme il n'est plus nécessaire de fermer le fichier, la sortie du bloc de code de with entraine sa fermeture :

Écriture d'un fichier

Soit avec une forme spéciale de print

Soit en utilisant la méthode write du descripteur de fichiers.

>>> with open("toto.txt", "w") as fd:
...    print >>fd, "My first line"
...    fd.write("#My second line\n")
...

Presenter Notes

Voila, ce n'est pas plus compliqué que cela. Si on voulait ajouter des lignes au fichier toto.txt, il aurait juste suffit de l'ouvrir en mode "a" (comme append) et écrire dedans.

Lecture d'un fichier

Ouverture en mode lecture

Utiliser le descripteur de fichier dans une boucle pour itérer sur les lignes du fichier :

>>> with open("toto.txt", "r") as fd:
... for line in fd:
...     if line.startswith("#"):
...         print line
...
'#My second line'

Presenter Notes

Exercice

  1. Lire le fichier toto.txt et ne copier que les lignes qui ne commencent pas par # dans un fichier toto2.txt
  2. Lire le fichier toto.txt et le copier 3 fois de suite dans toto3.txt

Presenter Notes

Lister le contenu d'un répértoire

  • Utiliser des méthodes du module os :
    • os.listdir() : Retourne la liste des fichiers et répértoires qui sont contenus dans le répértoire donné en paramètre à la fonction.
    • os.path.join() : Concatène 2 chemins (ou plus) en utilisant le séparateur de chemin du système sur lequel le script tourne.
    • os.path.isdir() : Retourne True si, et seulement si, le chemin passé en paramètre correspond à un répértoire.
    • os.path.isfile() : Retourne True si, et seulement si, le chemin passé en paramètre correspond à un fichier.

Presenter Notes

Fonctions et os

def list_files_in_directory(path):
    """ Returns list of files only within given path."""
    result = list()
    for item in os.listdir(path):
        filepath = os.path.join(path, item)
        if os.path.isfile(filepath):
            result.append(filepath)
    return result

def list_dirs_in_directory(path):
    """ Returns list of directories only within given path."""
    result = list()
    for item in os.listdir(path):
        filepath = os.path.join(path, item)
        if os.path.isdir(filepath):
            result.append(filepath)
    return result

Presenter Notes

Exercice

Écrire un scripte qui prend un seul parametre, un chemin, et qui retourne tous les fichiers de manière récursive.

Presenter Notes

Supprimer, Déplacer ou Copier des fichier

Ici aussi il faudra utiliser le module os :

  • os.remove() : Supprime le fichier dont le chemin est passé en paramètre
  • os.rename(old, new) : Déplace un fichier passé en premier paramètre pour le placer et renommer à l'endroit pointé par le second paramètre.

MAIS, il n'y a pas de fonction de copie... Pour cela il faudra utiliser le module shutil qui continent plusieurs fonctions de copie :

  • shutil.copyfile(old, new) : Copie un fichier
  • shutil.copy(old, new) : Copie un fichier ainsi que les autorisations du fichier.
  • shutil.copy2(old, new) : Copie un fichier ainsi que ses méta-données.

Presenter Notes

Exercice

Écrire votre propre fonction de copie d'un fichier.

Presenter Notes

Array Slicing

Permet de traiter facilement des données d'une liste.

Quand on utilise les [], on peut faire beaucoup plus que de se limiter à donner un simple index.

>>> l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l[2,4]    # l[start:end] -> items from start through end-1
[2,3]

>>> l[7:]     # l[start:] -> items from start through the rest of the array
[7,8,9]

>>> l[:4]     # l[:end] -> items from the beginning through end-1
[0,1,2,3]

>>> l[:]      # l[:] -> a copy of the whole array
[0,1,2,3,4,5,6,7,8,9]

Presenter Notes

Array Slicing : incrément

On peut aussi utiliser un paramètre supplémentaire qui defini l'incrément :

# l[start:end:step] # start through not past end, by step
>>> l[2:9:3]
[2,5,8]

Presenter Notes

Ce qui est important a retenir c'est que la valeur de fin est la première valeur à ne pas être inclue. Ainsi, le nombre d'éléments dans le slice sera end-start (à moins de changer d'incrément).

Array Slicing : index négatifs

Le départ ou la fin peuvent être des nombres négatifs ! Donc :

>>> l[-2:]   # last two items in the array
[8,9]
>>> l[:-2]   # everything except the last two items
[0,1,2,3,4,5,6,7]

Presenter Notes

Array Slicing : incrément négatif

De la même manière, l'incrément aussi peut être négatif :

>>> l[::-1]    # all items in the array, reversed
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> l[1::-1]   # the first two items, reversed
[1,0]
>>> l[:-3:-1]  # the last two items, reversed
[9,8]
>>> l[-3::-1]  # everything except the last two items, reversed
[7,6,5,4,3,2,1,0]

Presenter Notes

Python est encore une fois du coté du développeur afin de lui simplifier la vie. Quand on demande plus d'éléments qu'il n'y en a dans la liste, Python retourne ce qu'il peut.

Array Slicing sur tuples et textes

Note : on peut faire la même chose avec des tuples, le résultat du slice sera un tuple.

Note 2 : on peut utiliser le slicing sur des textes aussi ! Ceci permet d'obtenir un sous texte de façon simple.

>>> t = "abcdefghij"
>>> t[-3::-1]
'hgfedcba'

Presenter Notes

doctest, quézako ?

Le module doctest permet de faire la documentation et les tests en même temps, ou quasiment.

  • Possible d'ajouter des tests en documentant :
    • Montrer des exemples d'utilisation
    • Montrer le résultat espéré, au sein même de la documentation.

Presenter Notes

doctest : Exemple

def absolute(x):
    """ Given a numeric input x, returns the value of x without sign.
    If x is not numeric, then return None
    >>> absolute(1)
    1
    >>> absolute(-1)
    1
    >>> absolute("a") is None
    True
    >>> absolute(0)
    0
    """
    if type(x) not in (type(1), type(1.5)):
        return None
    if x >= 0:
        return x
    else:
        return -x

Presenter Notes

Note : On peut se servir de cela pour faire du "Test Driven Developement"(TDD). On écrit alors le squelette de la fonction avec sa doc et ses tests !

doctest : Utilisation (1/2)

Mais alors, comment tourner les tests ? Très simple, il faut copier le code si-dessus dans un fichier TrainingPython/DocTests/first_doctests.py_ (doctest n'a d'utilité qu'avec des scripts), puis lancer la commande suivante :

$ python -m doctest Training_Python/DocTests/first_doctests.py

Presenter Notes

doctest : Utilisation (2/2)

L'affichage est vide : tous les tests passent ! Plus de détails avec l'option verbose (-v en abrégé) :

$ python -m doctest -v Training_Python/DocTests/first_doctests.py
Trying:
    absolute(1)
Expecting:
    1
ok
[...]
1 items had no tests:
    first_doctests
1 items passed all tests:
   4 tests in first_doctests.absolute
4 tests in 2 items.
4 passed and 0 failed.
Test passed.

Presenter Notes

Notre fonction à bel et bien passé ses 4 tests !

Exercice

Écrire une fonction en utilisant la méthode TDD avec doctest qui valide le cahier des charges suivant :

  • si l'entrée est un entier, retourne son opposé
  • si l'entrée est un flottant, retourne sa valeur absolue
  • si l'entrée est une liste, la fonction s'appelle elle même sur chacun des élements de la liste et retourne la liste resultante
  • si l'entrée est un texte, retourne un caractère sur 2 de ce texte

Presenter Notes

Exemple concret: soft timeouts

Implémentation de soft timeouts dans un but de tests de performances non bloquants.

Pour faire des benchmarks, on peut executer des commandes les unes après les autres en prenant le temps de chacune d'elles.

Presenter Notes