0% ont trouvé ce document utile (0 vote)
5 vues11 pages

Gestion des exceptions en Python

Ce chapitre aborde la gestion des exceptions en Python, soulignant l'importance de spécifier le type d'exception dans les blocs 'except' pour éviter d'intercepter des erreurs inattendues. Il explique également comment lever des exceptions personnalisées et introduit les concepts de 'shebang' pour exécuter des scripts Python sur des systèmes Unix. Enfin, il traite du passage d'arguments à des fonctions à l'aide de *args et **kwargs, ainsi que du désempaquetage de tuples et de dictionnaires.

Transféré par

a.fabrici
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
5 vues11 pages

Gestion des exceptions en Python

Ce chapitre aborde la gestion des exceptions en Python, soulignant l'importance de spécifier le type d'exception dans les blocs 'except' pour éviter d'intercepter des erreurs inattendues. Il explique également comment lever des exceptions personnalisées et introduit les concepts de 'shebang' pour exécuter des scripts Python sur des systèmes Unix. Enfin, il traite du passage d'arguments à des fonctions à l'aide de *args et **kwargs, ainsi que du désempaquetage de tuples et de dictionnaires.

Transféré par

a.fabrici
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Chapitre 26. Remarques complémentaires 26.5.

Gestion des exceptions

Attention, si vous précisez le type d’exception comme ValueError, le except ValueError n’empêchera pas la
levée d’une autre exception.

1 >>> try:
2 ... nb = int(variable)
3 ... except ValueError:
4 ... print("Vous n'avez pas entré un nombre entier !")
5 ...
6 Traceback (most recent call last):
7 File "<stdin>", line 2, in <module>
8 NameError: name 'variable' is not defined. Did you mean: 'callable'?

Ici l’exception levée est de type NameError, car variable n’existe pas. Alors que si vous mettez except tout court,
cela intercepte n’importe quelle exception.

1 >>> try:
2 ... nb = int(variable)
3 ... except:
4 ... print("Vous n'avez pas entré un nombre entier !")
5 ...
6 Vous n'avez pas entré un nombre entier !
7 >>>

Vous voyez qu’ici cela pose un nouveau problème : le message d’erreur ne correspond pas à l’exception levée !

Conseil
• Nous vous conseillons vivement de toujours préciser le type d’exception dans vos except. Cela évite d’intercepter
une exception que vous n’aviez pas prévue. Il est possible d’intercepter plusieurs types d’exceptions en passant un
tuple à except, par exemple : except (Exception1, Exception2).
• Par ailleurs, ne mettez pas trop de lignes dans le bloc du try. Dans un tel cas, il peut être très pénible de trouver la
ligne qui a conduit à l’exécution du except. Pire encore, il se peut que des lignes que vous aviez prévues ne soient
pas exécutées ! Donc gardez des choses simples dans un premier temps, comme par exemple tester les conversions
de type ou vérifier qu’un fichier existe bien et que vous pouvez l’ouvrir.

Il existe de nombreux types d’exception comme RuntimeError, TypeError, NameError, IOError, etc. Vous pouvez
aller voir la liste complète 33 sur le site de Python. Nous avions déjà croisé des noms d’exception au chapitre 23 (Avoir
la classe avec les objets) en regardant ce que contient le module builtins.

1 >>> import builtins


2 >>> dir(builtins)
3 ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException',
4 [...]
5 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError'
6 [...]

Leur présence dans le module builtins signifie qu’elles font partie du langage lui même, au même titre que les
fonctions de base comme range(), list(), etc.
Avez-vous aussi remarqué que leur nom commence toujours par une majuscule et qu’il peut en contenir plusieurs à
la façon CamelCase ? Si vous avez bien lu le chapitre 16 Bonnes pratiques en programmation Python, avez-vous deviné
pourquoi ? Et bien, c’est parce que les exceptions sont des classes. C’est très intéressant car il est ainsi possible
d’utiliser l’héritage pour créer ses propres exceptions à partir d’exceptions pré-existantes. Nous ne développerons pas cet
aspect, mais en guise d’illustration, regardez ce que renvoit un help() de l’exception OverflowError.

33. [Link]

340 Cours de Python / Université Paris Cité / UFR Sciences du Vivant


26.6. Shebang et /usr/bin/env python3 Chapitre 26. Remarques complémentaires

1 >>> help(OverflowError)
2 [...]
3 class OverflowError(ArithmeticError)
4 | Result too large to be represented.
5 |
6 | Method resolution order:
7 | OverflowError
8 | ArithmeticError
9 | Exception
10 | BaseException
11 | object

L’exception OverflowError hérite de ArithmeticError, c’est-à-dire qu’OverflowError a été conçue à partir de


ArithmeticError et en hérite de tous ses attributs.
Un autre aspect très important que nous avons croisé au chapitre 24 Avoir plus la classe avec les objets est la
possibilité de lever vous-même une exception avec le mot-clé raise. Nous avions vu le code suivant :
if valeur < 0:
raise ValueError("Z'avez déjà vu une masse négative ?")

La ligne 2 lève une exception ValueError lorsque la variable valeur est négative. L’instruction raise est bien
pratique lorsque vous souhaitez stopper l’exécution d’un programme si une variable ne se trouve pas dans le bon intervalle
ou ne contient pas la bonne valeur. Vous avez sans doute compris maintenant pourquoi on parlait de « levée » d’exception…
Enfin, on peut aussi être très précis dans le message d’erreur. Observez la fonction download_page() qui, avec le
module urllib, télécharge un fichier sur internet.
1 import [Link]
2
3 def download_page(address):
4 error = ""
5 page = ""
6 try:
7 data = [Link](address)
8 page = [Link]()
9 except IOError as e:
10 if hasattr(e, 'reason'):
11 error = "Cannot reach web server: " + str([Link])
12 if hasattr(e, 'code'):
13 error = f"Server failed {[Link]:d}"
14 return page, error
15
16 data, error = download_page("[Link]
17
18 if error:
19 print(f"Erreur rencontrée : {error}")
20 else:
21 with open("[Link]", "w") as prot:
22 [Link]([Link]("utf-8"))
23 print("Protéine enregistrée")

La variable e est une instance de l’exception IOError. Certains de ses attributs sont testés avec la fonction hasattr()
pour ainsi affiner le message renvoyé (ici contenu dans la variable error).
Si tout se passe bien, la page est téléchargée est stockée dans la variable data, puis enregistrée sur le disque dur.

26.6 Shebang et /usr/bin/env python3


Lorsque l’on programme sur un système Unix (Mac OS X ou Linux par exemple), on peut exécuter directement un
script Python, sans appeler explicitement la commande python.
Pour cela, deux opérations sont nécessaires :
Étape 1. Préciser la localisation de l’interpréteur Python en indiquant dans la première ligne du script :
1 #! /usr/bin/env python

Par exemple, si le script [Link] contenait :

Cours de Python / Université Paris Cité / UFR Sciences du Vivant 341


Chapitre 26. Remarques complémentaires 26.7. Passage d’arguments avec *args et **kwargs

1 print("Hello World !")

il va alors contenir :
1 #!/usr/bin/env python
2
3 print("Hello World !")

Étape 2.. Rendre le script Python exécutable en lançant l’instruction :


$ chmod +x [Link]

Remarque
La ligne #! /usr/bin/env python n’est pas considérée comme un commentaire par Python, ni comme une ins-
truction Python d’ailleurs . Cette ligne a une signification particulière pour le système d’exploitation Unix.

Pour exécuter le script, il suffit alors de taper son nom précédé des deux caractères ./ (afin de préciser au shell où se
trouve le script) :
$ ./[Link]
Hello World !

Définition
Le shebang 34 correspond aux caractères #! qui se trouvent au début de la première ligne du script test.
Le shebang est suivi du chemin complet du programme qui interprète le script ou du programme qui sait où se
trouve l’interpréteur Python. Dans l’exemple précédent, c’est le programme /usr/bin/env qui indique où se trouve
l’interpréteur Python.

26.7 Passage d’arguments avec *args et **kwargs


Avant de lire cette rubrique, nous vous conseillons de bien relire et maîtriser la rubrique Arguments positionnels et
arguments par mot-clé du chapitre 10 Fonctions.
Dans le chapitre 10, nous avons vu qu’il était nécessaire de passer à une fonction tous les arguments positionnels
définis dans celle-ci. Il existe toutefois une astuce permettant de passer un nombre arbitraire d’arguments positionnels :
1 >>> def fct(*args):
2 ... print(args)
3 ...
4 >>> fct()
5 ()
6 >>> fct(1)
7 (1,)
8 >>> fct(1, 2, 5, "Python")
9 (1, 2, 5, 'Python')
10 >>> fct(z=1)
11 Traceback (most recent call last):
12 File "<stdin>", line 1, in <module>
13 TypeError: fct() got an unexpected keyword argument 'z'

L’utilisation de la syntaxe *args permet d’empaqueter tous les arguments positionnels dans un tuple unique args
récupéré au sein de la fonction. L’avantage est que nous pouvons passer autant d’arguments positionnels que l’on veut.
Toutefois, on s’aperçoit en ligne 10 que cette syntaxe ne fonctionne pas avec les arguments par mot-clé.
Il existe un équivalent avec les arguments par mot-clé :

34. [Link]

342 Cours de Python / Université Paris Cité / UFR Sciences du Vivant


26.7. Passage d’arguments avec *args et **kwargs Chapitre 26. Remarques complémentaires

1 >>> def fct(**kwargs):


2 ... print(kwargs)
3 ...
4 >>> fct()
5 {}
6 >>> fct(z=1, gogo="toto")
7 {'gogo': 'toto', 'z': 1}
8 >>> fct(z=1, gogo="toto", y=-67)
9 {'y': -67, 'gogo': 'toto', 'z': 1}
10 >>> fct(1, 2)
11 Traceback (most recent call last):
12 File "<stdin>", line 1, in <module>
13 TypeError: fct() takes 0 positional arguments but 2 were given

La syntaxe **kwargs permet d’empaqueter l’ensemble des arguments par mot-clé, quel que soit leur nombre, dans
un dictionnaire unique kwargs récupéré dans la fonction. Les clés et valeurs de celui-ci sont les noms des arguments et les
valeurs passées à la fonction. Toutefois, on s’aperçoit en ligne 9 que cette syntaxe ne fonctionne pas avec les arguments
positionnels.
Si on attend un mélange d’arguments positionnels et par mot-clé, on peut utiliser *args et **kwargs en même
temps :
1 >>> def fct(*args, **kwargs):
2 ... print(args)
3 ... print(kwargs)
4 ...
5 >>> fct()
6 ()
7 {}
8 >>> fct(1, 2)
9 (1, 2)
10 {}
11 >>> fct(z=1, y=2)
12 ()
13 {'y': 2, 'z': 1}
14 >>> fct(1, 2, 3, z=1, y=2)
15 (1, 2, 3)
16 {'y': 2, 'z': 1}

Deux contraintes sont toutefois à respecter. Il faut toujours :


• mettre *args avant **kwargs dans la définition de la fonction ;
• passer les arguments positionnels avant ceux par mot-clé lors de l’appel de la fonction.
Il est possible de combiner des arguments positionnels avec *args et des arguments par mot-clé avec **kwargs, par
exemple :
def fct(a, b, *args, **kwargs):
Dans un tel cas, il faudra obligatoirement passer les deux arguments a et b à la fonction, ensuite on pourra mettre
un nombre arbitraire d’arguments positionnels (récupérés dans le tuple args), puis un nombre arbitraire d’arguments par
mot-clé (récupérés dans le dictionnaire kwargs).

Conseil
Les noms *args et **kwargs sont des conventions en Python, ils rappellent les mots arguments et keyword argu-
ments. Bien qu’on puisse mettre ce que l’on veut, nous vous conseillons de respecter ces conventions pour faciliter la
lecture de votre code par d’autres personnes.

L’utilisation de la syntaxe *args et **kwargs est très classique dans le module Fenêtres graphiques et Tkinter
présenté dans le chapitre 25 (en ligne).
Il est possible d’utiliser ce mécanisme d’empaquetage / désempaquetage (packing / unpacking) dans l’autre sens :

Cours de Python / Université Paris Cité / UFR Sciences du Vivant 343


Chapitre 26. Remarques complémentaires 26.8. Décorateurs

1 >>> def fct(a, b, c):


2 ... print(a,b,c)
3 ...
4 >>> t = (-5,6,7)
5 >>>
6 >>> fct(*t)
7 -5 6 7

Avec la syntaxe *t on désempaquette le tuple à la volée lors de l’appel à la fonction. Cela est aussi possible avec un
dictionnaire :
1 >>> def fct(x, y, z):
2 ... print(x, y, z)
3 ...
4 >>> dico = {'x': -1, 'y': -2, 'z': -3}
5 >>> fct(**dico)
6 -1 -2 -3

Attention toutefois à bien respecter deux choses :


• la concordance entre le nom des clés du dictionnaire et le nom des arguments dans la fonction (sinon cela renvoie
une erreur) ;
• l’utilisation d’une double étoile pour désempaqueter les valeurs du dictionnaire (si vous utilisez une seule étoile,
Python désempaquettera les clés !).
Ce mécanisme de désempaquetage est aussi utilisable avec les objets zip, on parle de zip unpacking. Souvenons-nous,
un objet zip permettait d’assembler plusieurs listes, éléments par éléments (voir Chapitre 12 Plus sur les listes) :
1 >>> animaux = ["poulain", "renard", "python"]
2 >>> couleurs = ["alezan", "roux", "vert"]
3 >>> zip(range(3), animaux, couleurs)
4 <zip object at 0x7f333febc880>
5 >>> triplets = list(zip(range(3), animaux, couleurs))
6 >>> triplets
7 [(0, 'poulain', 'alezan'), (1, 'renard', 'roux'), (2, 'python', 'vert')]

Lignes 1 à 4. On crée un objet zip avec trois objets de trois éléments.


Lignes 5 à 7. Cet objet zip en conjonction avec la fonction list() nous permet d’associer les éléments par ordre
d’apparition (tous les éléments à la position 1 se retrouve ensemble, idem pour les positions 2 et 3). Au final, l’objet
triplets est une liste de tuples de trois éléments.
L’opérateur * en combinaison avec la fonction zip va nous permettre de désempaqueter triplets pour récupérer
les listes initiales (range(3), animaux et couleurs) :
1 >>> zip(*triplets)
2 <zip object at 0x7f333fd44980>
3 >>> list(zip(*triplets))
4 [(0, 1, 2), ('poulain', 'renard', 'python'), ('alezan', 'roux', 'vert')]

Bien sûr, on peut l’utiliser l’affectation multiple :


1 >>> numéros2, animaux2, couleurs2 = zip(*triplets)
2 >>> numéros2
3 (0, 1, 2)
4 >>> animaux2
5 ('poulain', 'renard', 'python')
6 >>> couleurs2
7 ('alezan', 'roux', 'vert')

Au final, on récupère des tuples au lieu des listes initiales. Mais à ce stade, vous devriez être capable de les retransformer
en liste ;-).

26.8 Décorateurs
Dans le chapitre 24, nous avons rencontré la notion de décorateur pour déclarer des objets de type property. Cela
permettait de rendre des méthodes accessibles comme des attributs (décorateur @property), et plus généralement de

344 Cours de Python / Université Paris Cité / UFR Sciences du Vivant


26.8. Décorateurs Chapitre 26. Remarques complémentaires

contrôler l’accès, la modification et la destruction d’attributs (décorateurs @nom_attribut.setter et @nom_attribut


.deleter). Il existe d’autres décorateurs prédéfinis en Python (e.g. @staticmethod, @classmethod, etc.). Nous allons
voir dans cette section comment on crée ses propres décorateurs et les mécanismes sous-jacents. Nous vous conseillons
de bien relire commment fonctionne les fonctions de rappel, ou fonctions callback (chapitre 25 Tkinter).

Définition
Un décorateur est une fonction qui modifie le comportement d’une autre fonction.

Ceci étant dit, comme cela fonctionne-t-il ? Commençons par une fonction simple qui affiche de la nourriture :
1 def imprime_victuaille():
2 print("tomate / mozza")

On souhaite améliorer cette fonction et transformer cette victuaille en sandwich, en affichant une tranche de pain avant
et après. La stratégie va être de créer une fonction spéciale, qu’on appelle décorateur, modifiant imprime_victuaille
().
1 def transforme_en_sandwich(fonction_a_decorer):
2 def emballage():
3 print("Pain")
4 fonction_a_decorer()
5 print("Pain")
6 return emballage

La fonction transforme_en_sandwich() est notre décorateur, elle prend en argument la fonction que l’on sou-
haite décorer sous forme de callback (donc sans les parenthèses). On voit qu’à l’intérieur, on définit une sous-fonction
emballage() qui va littéralement « emballer » (wrap) notre fonction à décorer, c’est-à-dire, effectuer une action avant
et après l’appel de la fonction à décorer. Enfin, le décorateur renvoie cette sous-fonction emballage sous forme de
callback. Pour que le décorateur soit actif, il faudra « transformer » la fonction à décorer avec notre fonction décoratrice :
1 imprime_victuaille = transforme_en_sandwich(imprime_victuaille)

Voici le code complet implémentant la fonction imprime_victuaille() décorée :


1 def transforme_en_sandwich(fonction_a_decorer):
2 def emballage():
3 print("Pain")
4 fonction_a_decorer()
5 print("Pain")
6 return emballage
7
8 def imprime_victuaille():
9 print("tomate/ mozza")
10
11 if __name__ == "__main__":
12 print("Fonction non décorée:")
13 imprime_victuaille()
14 print()
15 print("Fonction décorée:")
16 imprime_victuaille = transforme_en_sandwich(imprime_victuaille)
17 imprime_victuaille()

Au final l’idée est d’appeler la fonction décoratrice plutôt que la fonction imprime_victuaille() elle-même.
Regardons ce que donne l’exécution de la fonction avant et après décoration :
Fonction non décorée:
tomate/ mozza

Fonction décorée:
Pain
tomate/ mozza
Pain

Cours de Python / Université Paris Cité / UFR Sciences du Vivant 345


Chapitre 26. Remarques complémentaires 26.8. Décorateurs

Le premier appel en ligne 13 exécute la fonction simple, alors que le second en ligne 17 exécute la fonction décorée.
Cette construction peut sembler ardue et difficile à comprendre. Heureusement, Python a une notation en « sucre
syntaxique » (syntactic sugar) qui en facilite la lecture. Celle-ci utilise le symbole @ :
1 def transforme_en_sandwich(fonction_a_decorer):
2 def emballage():
3 print("Pain")
4 fonction_a_decorer()
5 print("Pain")
6 return emballage
7
8 @transforme_en_sandwich
9 def imprime_victuaille():
10 print("tomate / mozza")
11
12 if __name__ == "__main__":
13 imprime_victuaille()

La ligne 8 transforme irrémédiablement la fonction imprime_victuaille() en fonction décorée. Cela parait déjà
un peu plus lisible. L’exécution donnera bien sûr :
Pain
tomate / mozza
Pain

Au final, la notation :
1 @decorator
2 def fct():
3 [...]

est équivalente à :
1 fct = decorator(fct)

Cela fonctionne avec n’importe quelle fonction prenant en argument une autre fonction.

Conseil
Nous vous conseillons bien sûr d’utiliser systématiquement la notation @decorator qui est plus lisible et intuitive.

Si tout cela vous semble ardu (on vous comprend…), vous devez vous dire « pourquoi utiliser une construction aussi
complexe ? ». Et bien, c’est tout simplement parce qu’un décorateur est ré-utilisable dans n’importe quelle fonction. Si
on reprend la même fonction décoratrice que ci-dessus :
1 @transforme_en_sandwich
2 def imprime_victuaille1():
3 print("tomate / mozza")
4
5 @transforme_en_sandwich
6 def imprime_victuaille2():
7 print("jambon / fromage")
8
9 if __name__ == "__main__":
10 imprime_victuaille1()
11 print()
12 imprime_victuaille2()

On a donc un décorateur permettant de transformer en sandwich n’importe quelle fonction imprimant une victuaille !
Ceci renverra :

346 Cours de Python / Université Paris Cité / UFR Sciences du Vivant


26.9. Un peu de transformée de Fourier avec NumPy Chapitre 26. Remarques complémentaires

Pain
tomate / mozza
Pain

Pain
jambon / fromage
Pain

Un exemple plus concret de décorateur pourrait être la mesure du temps d’exécution d’une fonction :
import time

def mesure_temps(fonction_a_decorer):
def emballage():
temps1 = [Link]()
fonction_a_decorer()
temps2 = [Link]()
print(f"Le temps d'éxécution de {fonction_a_decorer.__name__} est "
f"{temps2 - temps1} s")
return emballage

En ligne 8, l’attribut .__name__ renvoie le nom de la fonction sous forme de chaîne de caractères. Dans cet exemple,
le décorateur @mesure_temps mis devant n’importe quelle fonction affichera systématiquement le temps d’exécution de
celle-ci.
Pour finir, si on revient sur le décorateur @property vu dans le chapitre 24 Avoir plus la classe avec les objets, nous
avions vu également qu’il existait une fonction property(). Donc pour les décorateurs pré-existants que nous avons
abordés dans le chapitre 24, il existe des fonctions équivalentes. Comme dans notre exemple, la notation @decorateur
va finalement appeler la fonction décoratrice. Donc derrière une notation @quelquechose, il existe toujours une fonction
quelquechose() remplissant ce rôle de décorateur.

Pour aller plus loin


Pour aller plus loin, vous pouvez consulter ce très bon article 35 sur le site RealPython. Il y est expliqué en outre
comment on peut gérer le passage d’arguments quand on utilise des décorateurs, ainsi que l’utilisation de décorateurs
multiples.

26.9 Un peu de transformée de Fourier avec NumPy


La transformée de Fourier est très utilisée pour l’analyse de signaux, notamment lorsqu’on souhaite extraire des
périodicités au sein d’un signal bruité. Le module NumPy possède la fonction fft() (dans le sous-module fft) permettant
de calculer des transformées de Fourier.
Voici un petit exemple sur la fonction cosinus de laquelle on souhaite extraire la période à l’aide de la fonction fft() :
1 import numpy as np
2
3 debut = -2 * [Link]
4 fin = 2 * [Link]
5 pas = 0.1
6 x = [Link](debut,fin,pas)
7 y = [Link](x)
8
9 TF = [Link](y)
10 ABSTF = [Link](TF)
11 pas_xABSTF = 1/(fin-debut)
12 x_ABSTF = [Link](0,pas_xABSTF * len(ABSTF),pas_xABSTF)

Plusieurs commentaires sur cet exemple :


Ligne 1. On charge le module NumPy avec le nom raccourci np.
Lignes 3 à 6. On définit l’intervalle (de −2π à 2π radians) pour les valeurs en abscisse ainsi que le pas (0,1 radians).

35. [Link]

Cours de Python / Université Paris Cité / UFR Sciences du Vivant 347


Chapitre 26. Remarques complémentaires 26.10. Sauvegardez votre historique de commandes

Lignes 7. On calcule directement les valeurs en ordonnées avec la fonction cosinus du module NumPy. On constate
ici que NumPy redéfinit certaines fonctions ou constantes mathématiques de base, comme pi, cos() ou abs() (valeur
absolue, ou module d’un nombre complexe). Ces fonctions sont directement utilisables avec un objet array.
Ligne 9. On calcule la transformée de Fourier avec la fonction fft() qui renvoie un vecteur (objet array à une
dimension) de nombres complexes. Eh oui, le module NumPy gère aussi les nombres complexes !
Ligne 10. On extrait le module du résultat précédent avec la fonction abs().
Ligne 11. La variable x_ABSTFL représente l’abscisse du spectre (en radian−1 ).
Ligne 12. La variable ABSTF contient le spectre lui même. L’analyse de ce dernier nous donne un pic à 0,15 radian−1 ,
ce qui correspond bien à 2π (c’est plutôt bon signe de retrouver ce résultat).

26.10 Sauvegardez votre historique de commandes


Vous pouvez sauvegarder l’historique des commandes utilisées dans l’interpréteur Python avec le module readline.
1 >>> print("hello")
2 hello
3 >>> a = 22
4 >>> a = a + 11
5 >>> print(a)
6 33
7 >>> import readline
8 >>> readline.write_history_file()

Quittez Python. L’historique de toutes vos commandes est dans votre répertoire personnel, dans le fichier .history.
Relancez l’interpréteur Python.
1 >>> import readline
2 >>> readline.read_history_file()

Vous pouvez accéder aux commandes de la session précédente avec la flèche du haut de votre clavier. D’abord les
commandes readline.read_history_file() et import readline de la session actuelle, puis print(a), a = a +
11, a = 22…

348 Cours de Python / Université Paris Cité / UFR Sciences du Vivant


CHAPITRE 27

Mini-projets

Dans ce chapitre, nous vous proposons quelques scénarios pour développer vos compétences en Python et mettre en
œuvre les concepts que vous avez rencontrés dans les chapitres précédents.

27.1 Description des projets


27.1.1 Mots anglais dans le protéome humain
L’objectif de ce premier projet est de découvrir si des mots anglais peuvent se retrouver dans les séquences du protéome
humain, c’est-à-dire dans les séquences de l’ensemble des protéines humaines.
Vous aurez à votre disposition :
• Le fichier [Link] 1 , qui contient les 3 000 mots anglais les plus fréquents, à raison d’1 mot
par ligne.
• Le fichier [Link] 2 qui contient le protéome humain sous la forme de séquences au format
FASTA. Attention, ce fichier est assez gros. Ce fichier provient de la banque de données UniProt à partir de cette
page 3 .

Conseil
Des explications sur le format FASTA et des exemples de code sont fournis dans l’annexe A Quelques formats de
données en biologie.

27.1.2 Genbank2fasta
Ce projet consiste à écrire un convertisseur de fichier, du format GenBank au format FASTA.
Pour cela, nous allons utiliser le fichier GenBank du chromosome I de la levure de boulanger Saccharomyces cerevisiae.
Vous pouvez télécharger ce fichier :
• soit via le lien sur le site du cours NC_001133.gbk 4 ;

1. [Link]
2. [Link]
3. [Link]
4. [Link]

349
Chapitre 27. Mini-projets 27.1. Description des projets

• soit directement sur la page de Saccharomyces cerevisiae S288c chromosome I, complete sequence 5 sur le site du
NCBI, puis en cliquant sur Send to, puis Complete Record, puis Choose Destination : File, puis Format : GenBank
(full) et enfin sur le bouton Create File.
Vous trouverez des explications sur les formats FASTA et GenBank ainsi que des exemples de code dans l’annexe A
Quelques formats de données en biologie.
Vous pouvez réaliser ce projet sans ou avec des expressions régulières (abordées dans le chapitre 17).

27.1.3 Simulation d’un pendule


On se propose de réaliser une simulation d’un pendule simple 6 en Tkinter. Un pendule simple est représenté par
une masse ponctuelle (la boule du pendule) reliée à un pivot immobile par une tige rigide et sans masse. On néglige les
effets de frottement et on considère le champ gravitationnel comme uniforme. Le mouvement du pendule sera calculé en
résolvant numériquement l’équation différentielle suivante :

d2θ g
aθ (t) = 2
(t) = − ∗ sin(θ (t))
dt l
où θ représente l’angle entre la verticale et la tige du pendule, aθ l’accélération angulaire, g la gravité, et l la longueur
de la tige (note : pour la dérivation d’une telle équation vous pouvez consulter la page wikipedia 7 ou l’accompagnement
pas à pas, cf. la rubrique suivante).
Pour trouver la valeur de θ en fonction du temps, on pourra utiliser la méthode semi-implicite d’Euler 8 de résolution
d’équation différentielle. La formule ci-dessus donne l’accélération angulaire au temps t : aθ (t) = − gl × sin(θ (t)). À
partir de celle-ci, la méthode propose le calcul de la vitesse angulaire au pas suivant : vθ (t + δ t) = vθ (t) + aθ (t) × δ t
(où δ t représente le pas de temps entre deux étapes successives de la simulation). Enfin, cette vitesse vθ (t + δ t) donne
l’angle θ au pas suivant : θ (t + δ t) = θ (t) + vθ (t + δ t) × δ t. On prendra un pas de temps δ t = 0.05 s, une accélération
gravitationnelle g = 9.8 m.s−2 et une longueur de tige de l = 1 m.

Figure 27.1 – Application pendule.

Pour la visualisation, vous pourrez utiliser le widget canvas du module Tkinter (voir le chapitre 25 Fenêtres graphiques
et Tkinter (en ligne), rubrique Un canvas animé dans une classe). On cherche à obtenir un résultat comme montré dans
la figure 27.1.
5. [Link]
6. [Link]
7. [Link]
8. [Link]

350 Cours de Python / Université Paris Cité / UFR Sciences du Vivant

Vous aimerez peut-être aussi