Présentation
Ce support vise à introduire des concepts de base en programmation, avec une forte invitation à la pratique et aux bonnes pratiques.
Python-1 intro
Python
Python est un langage inventé par le programmeur Guido van Rossum dans les années 90. C’est un projet open source et multi-plateformes.
Python est un langage interprété, contrairement à d’autres, comme le C qui nécessite une phase de compilation qui produit une version exécutable pour une plateforme cible, le code source d’un programme Python est directement portable (l’analyse et sa traduction en langage machine se fait au cours de son lancement par un interpréteur Python lié à l’OS hôte).
Vérification de votre système
Ouvrir une console système (un terminal), et lancer la commande : python3 --version
(ou python --version
)
Exemple de résultat attendu (vérifier que vous êtes en 3.x.x) :
$ python3 --version
Python 3.10.6
Python peut être lancé en mode interactif ou en mode script.
Python en mode interactif
Il suffit de lancer la commande python3
, dans ce cas l’interpréteur attend la saisie de code, qu’il interprétera à partir du moment où il reçoit une donnée de fin de saisie (touche Enter
)
Pour sortir de ce mode, lancer la commande CTRL + D
(ou CTRL + Z
sous windows).
$ python3 >>> print('Hello World') Hello World >>>
Python en mode script
Dans ce mode (usage courant) le code source est placé dans un fichier text, avec .py
comme extension.
Cette procédure peut être automatisée (la première instruction est équivalente aux étapes 1 à 3 de la procédure présentée). L’opérateur système
L’opérateur système ⇒ La redirection du flux standard vers un fichier est une technique bien connue des hackers. |
Documentation
-
Préférer le site officiel docs.python.org et stackoverflow.
-
Consulter la documentation technique des objets du langages
help()
(etdir()
).-
la fonction help() extrait des chaînes de documentation (modules, fonctions et méthodes). Exemples :
-
help(print)
-
help(sys.exit)
(le modulesys
doit être importé avant cette commande)
-
-
-
Consulter régulièrement le référentiel de bonnes pratiques de programmation en python :
-
Style Guide for Python Code - par Kenneth Reitz et Tanya Schlusser
-
Mode interactif
EXERCICE 1
-
Lancez l’interpréteur dans un terminal
-
Tester une à une les expressions suivantes et essayez d’expliquer ce qui se passe dans chacun des cas. N’hésitez pas à échanger entre vous et à chercher des explications en ligne. Le langage python est utilisé par une grande communauté internationale. Voir le tableau de correspondances opérateur-fonction : https://docs.python.org/fr/3/library/operator.html#mapping-operators-to-functions
Code | Résultat | Explications |
---|---|---|
|
|
La priorité des opérateurs arithmétiques suit les conventions usuelles. (voir priiorité des opérateurs) |
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
Concaténation de 2 chaînes de caractères |
|
|
||
|
||
Par la suite des questions suivantes
on considère que la variable |
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
Les opérations associées aux structures de données de type conteneur seront étudiées plus loin. Pour les curieux, voir : https://docs.python.org/fr/3/library/stdtypes.html#typesseq
Quel éditeur de code utiliser ?
Vous trouverez ici https://docs.python.org/3/using/editors.html un inventaire de nombreux éditeurs.
Voici une sélection :
-
vi
: l’éditeur incontournable, présent dans toutes les distributions linux. Il vous sauvera de situation délicate (intervention à distance sur un serveur) -
Visual Studio Code
et son plugin python : léger mais suffisament complet pour démarrer avec python (complétion, vérification de cohérence de type, débogueur intégré…), également utilisé pour le dev frontend. -
pyCharm, l’IDE à destination des professionnels (gain de productivité assuré)

Exercices en mode script
Un script python, appelé aussi "module", peut être utilisé directement, comme dans l’exemple python3 tp1.py
ou intégré dans un autre module (via l’instruction import
).
Python vient avec de nombreux modules préinstallés. Vous pouvez en consulter la liste avec : pip3 list -V
. Pour en utiliser d’autres, il faut préalablement les télécharger. Voir ici pour en savoir plus sur la gestion des modules : https://docs.python.org/fr/dev/installing/index.html
Dans un premier temps, placez-vous dans un dossier de votre espace personnel dédié aux exercices en python.
EXERCICE 2
Voici un code source d’un programme python respectant les conventions d’usage :
#!/usr/bin/env python3 (1)
def exo2() -> None : (2)
"""
exercice 2 du TP1
"""
nom = input("Entrez votre nom : ")
print("Bienvenue " + nom + " !")
# vos autres fonctions ici (exo3() exo4() etc.)
# le main (partie exécutée lors du lancement du programme)
if __name__ == "__main__": (3)
import sys (4)
exo2() (5)
sys.exit(0) (6)
1 | (optionnel) Shebang. Permet de rendre le script "directement" exécutable. voir https://stackoverflow.com/questions/6908143/should-i-put-shebang-in-python-scripts-and-what-form-should-it-take |
2 | Définition d’une fonction nommée exo2 , qui déclare ne "rien" retourner (None ), avec sa chaîne de documentation |
3 | Si le script est utilisé directement (en argument de l’interpréteur python), alors la valeur de la variable __main__ est "__main__", sinon il est utilisé en import dans un autre script et c’est le nom du script (module), sans son extension. Remarque : les noms de variables encadrés de 2 underscores (__ ) sont des variables système (pré)définies par l’interpréteur. |
4 | Importation du module sys (qui contient des fonctions système, dont exit utilisée plus loin) |
5 | Appel de la fonction exo2 . |
6 | Appel la fonction exit afin de demander la sortie du mode interpréteur de python avec transmission du code de retour. Voir https://docs.python.org/fr/3/library/sys.html#sys.exit, ou, en mode interactif, appeler l’aide sur cette fonction via la commande help(sys.exit) . Retourner zéro signifie que le programme se termine avec succès, toute autre valeur signale à l’appelant une anomalie à l’exécution. |
-
Si ce n’est pas déjà fait, créer un dossier
dev
-
Créer un sous-dossier
dev/TPS
et ouvrir ce dossier avec l’éditeur visual studio code -
Créer le fichier
tp1.py
-
Recopiez le code ci-dessus
-
(optionnel) Rendez-le exécutable (par exemple avec la commande
chmod +x tp1.py
) -
Exécutez-le (dans un terminal), éventuellement corrigez les erreurs de frappe.
-
Modifiez la fonction
exo2()
, afin qu’elle affiche le prénom et le nom. Elle devra pour cela inviter l’utilisateur à entrer son prénom.
EXERCICE 3
On vous présente un programme exprimé en pseudo-langage
ainsi qu’une traduction de ce programme en Python (exo3()
). Après avoir pris connaissance
de la version en pseudo-langage, recopier la traduction
proposée en Python (code source ci-dessous), à insérer à la suite de exo2()
et avant la partie main
, comme nouvelle fonction dans le script tp1.py
.
Afficher("Entrez un nombre entier svp :") lire un nombre au clavier et placer sa valeur dans une variable nomméee x (1) Si x est pair Alors Afficher("Ce nombre est pair") Sinon Afficher("Ce nombre est impair") FinSi
1 | ou plus simlement : x <-- lire un nombre au clavier |
def exo3() -> None :
x = int(input("Entrez un nombre entier svp : "))
if x % 2 == 0 : # le reste de division par 2 est-il zéro ?
print("Ce nombre est pair")
else :
print("Ce nombre est impair")
-
Intégrer, comme indiqué (avant la partie
main
), la nouvelle fonctionexo3
dans le moduletp1.py
. Respecter l’indentation. -
Appeler cette fonction dans la partie
main
detp1.py
. -
Tester différentes valeurs afin de vérifier la justesse du code. (Si l’utilisateur ne saisit pas un nombre, le programme s’arrête brutalement - c’est normal, la gestion des cas d’erreurs sera abordée ultérieurement)
EXERCICE 4
On souhaite proposer une variante de la fonction exo2
, sous la forme d’une nouvelle fonction nommée exo4
, de sorte que, si l’utilisateur ne fournit pas d’identité, le programme lui attribut d’office le nom "anonymous".
Voici une version en pseudo-code founit par un de vos collègues.
Afficher("Entrez votre nom svp :") nom <-- lire une chaîne de caractère au clavier Afficher("Entrez votre prenom svp :") prenom <-- lire une chaîne de caractère au clavier Si nom est vide Alors Afficher("Bonjour Anonymous !") Sinon Afficher("Bonjour " + prenom + " " + nom + " !") FinSi
-
Étudier la version en pseudo-langage ci-dessus puis proposer une traduction fidèle en Python.
-
Travaillez à partir d’une copie de la fonction
exo2
que vous nommerezexo4
, puis appelez cette fonction dans le main. -
Tester votre code
EXERCICE 5
L’algorithme proposé par votre collègue dans l’exercice précédent manque de logique. Avez-vous repéré ce qui cloche ?
Si l’utilisateur ne décline pas son identité à la demande de son nom, alors le programme ne devrait pas lui demander son prénom.
Proposez une amélioration de la fonction exo4
, que vous nommerez exo5
, qui respecte cette nouvelle logique.
-
Fournir d’abord une version en pseudo-langage
-
Faire valider votre version par un professeur
-
Traduire votre version en Python (une nouvelle fonction nommée
exo5
) -
Tester et mettre au point votre fonction
EXERCICE 6
Voici un programme écrit en pseudo-code : .Version pseudo-langage
n <- 60 m <- 7 afficher("Les entiers valent ", m , "et ", n) afficher("leur somme est ", m+n) afficher("leur différence est ", m-n) afficher("leur produit est ", m*n) afficher("leur quotient est ", m/n) afficher("le reste de la division entière m/n est ", m modulo n)
-
Transcrire ce programme en une fonction Python (nommée
exo6
). -
Puis améliorer la fonction
exo6
de sorte que l’utilisateur puisse lui-même fournir des valeurs pour les zones mémoire référencées par les identificateursm
etn
. Vérifier la justesse des sorties.
EXERCICE 7
Cet exercice introduit la notion de type. En effet, toute variable est associée, à un instant t, à un et un seul type. Le type de la variable est déterminé par l’interpréteur au moment de l’affectation et peut être consulté à l’exécution par un appel à la fonction type
.
>>> x = 42
>>> type(x)
<class 'int'> # <== le type de x est int
Commençons par définir une fonction qui réalise une somme de 2 entiers reçues en argument. Nous appellerons cette fonction somme
.
def somme(arg1: int, arg2: int) -> int :
"""
Return la somme des arguments
"""
# affecte à la var result le résultat de l'opération +
result = arg1 + arg2
return result (1)
1 | On remarquera que la fonction "n’affiche" rien. C’est très important. Le fait d’afficher ou non la valeur retournée est de la responsabilité de l’appelant, pas de l’appelé (voir Glossaire Appelant/Appelé) |
Voici un exemple de programme (une fonction) qui appelle la fonction somme
(ligne 25)
def exo7() -> None:
print("Bonjour, je suis un programme écrit en Python.")
# invite l'utilisateur à entrer un nombre entier
# l'information est stockée dans une zone mémoire
# référencée par 'str_n1'
str_n1 = input("Entrez un nombre entier : ")
# affiche une information sur le type de l'objet crée
print("Le type de l'objet crée est ", type(str_n1))
# n1 est l'image de str_n1 par la fonction int(). Le rôle de int()
# est de tenter de traduire son argument en une valeur
# numérique (un entier).
n1=int(str_n1)
# affiche une information sur le type de l'objet crée
print("Le type du nouvel objet crée est ", type(n1))
# idem
n2 = input("Entrez un second nombre entier : ")
# appel à la fonction somme, définie plus haut,
# en vue de réaliser une addition (normalement pb de type ici)
res = somme(arg1 = n1, arg2 = n2) (1)
# affichage du résultat
print("La somme des deux nombres est : ", res)
# dernière instruction pour une fin annoncée
print("bye, je meurs...")
if __name__ == "__main__":
import sys
exo7()
sys.exit(0)
1 | On remarquera l’usage des valeurs n1 et n2 comme valeurs d’arguments de la fonction somme . Une autre façon d’appeler la fonction est de passer les valeurs par position, par exemple : res = somme(n1, n2) , qui aura même effet. |
-
Adapter le script
tp1.py
(ajout de la fonctionsomme
etexo7
) -
Tester et comprendre pourquoi la fonction
exo7
bugue -
Corriger la fonction
exo7
-
Modifiez la fonction
exo7.py
afin qu’elle réalise la somme de 3 nombres. -
Faire évoluer la fonction
exo7.py
afin qu’elle réalise, en plus de la somme de 3 nombres, le produit de ces 3 nombres. Pour cela vous devrez créer, juste après la déclaration desomme()
, une nouvelle fonction nomméeproduit()
, inspirée desomme()
.
EXERCICE 8 (FINAL)
A l’issue de cette première séance de travaux pratiques, vous avez appris à programmer des fonctions simples en Python, à les appeler dans la partie main du script/module tp1.py
.
Votre mission : Au lancement de tp1.py
, permettre à l’utilisateur de choisir la fonction qu’il souhaite exécuter parmi les fonctions exo2()
, exo3()
, …, exo7()
du module.
-
Ajouter une fonction nommée
main
. Son rôle sera de répondre à cette demande. -
Faire en sorte que le code du main de
tp1.py
appelle cette nouvelle fonction. -
Tester le tout
Contrôler vos connaissances et contribuer aux QCMs
-
Contrôler vos connaissances sur quizbe.org. (choisir
PYTHON-LDV
, scopep-1-intro
) -
Enrichir la base de données QCM. Pour cela, proposer, pour le thème
PYTHON-LDV
(scopep-1-intro
), 2 questions QCM originales et personnelles, sur des thèmes couverts pas cette séquence d’exercices. Il est important d’associer un feedback à chacune des réponses proposées, qu’elles soient justes ou fausses.
Python-2 intro - type
Méta-modèle IPO
Nous avons vu que les exercices de programmation ont en commun le fait qu’ils traitent des informations et produisent un résultat en retour.
C’est en fait le schéma général qui est en action dans l’ensemble des systèmes.
ENTREE → TRAITEMENT → RESULTAT
Le résultat pouvant être une entrée vers un autre processus analogue.
En anglais, ce modèle est connu sous l’acronyme IPO :
INPUT → PROCESS → OUTPUT
Déterminisme
Lorsqu’il s’agit de programmation, le process du modèle IPO, c’est à dire la partie traitement, se doit d’être déterministe.
Par déterminisme, il faut comprendre qu’une fonction doit, pour un même ensemble de données d’entrée, toujours produire la même sortie.
Par exemple, définissons une fonction qui retourne le signe d’un nombre passé en argument :
def signe(x: int) -> str: (1)
""" (2)
Retourne le signe de son argument.
soit '+', '-' ou '' (chaine vide) si x==0
"""
result = '' # pas de signe
if (x < 0):
result = '-'
elif (x > 0): (3)
result = '+'
return result
1 | On précise ici le type du premier argument (premier paramètre) ainsi que le type de retour de la fonction (string). Cette possibilité a été introduite à partir de la version 3.5 de python. Cette information n’est pour l’heure pas exploitée par l’interpréteur. (voir https://docs.python.org/3/library/typing.html) |
2 | C’est une chaîne de documentation ("docstring"). Son but est de présenter le rôle de la fonction. C’est à destination des développeurs (pas de l’interpréteur). N’hésitez pas à mettre des exemples dans cette partie. |
3 | elif, une contraction de else if , c’est un des mots clés de python. |
On pourra appeler autant de fois notre fonction signe
avec la même valeur de donnée d’entrée, elle nous retournera toujours le même résultat.
Exemple :
print(signe(42)) # +
print(signe(42)) # +
print(signe(40+2)) # +
print(signe(2+2*20)) # +
...
print(signe(-42)) # -
...
print(signe(0)) #
Une fonction qui ne dépend que des valeurs de ses arguments pour réaliser son travail, sans impacter le système, est qualifiée de fonction pure. Une fonction pure a de nombreux avantages, dont celui de permettre la programmation parallèle. |
Type et opérations
Nous avons constaté (Exercice 7) que les opérations sont dépendantes du type de la donnée sur laquelle elles travaillent.
Il existe des types prédéfinis, dits natifs à l’interpréteur (Built-in). Ce sont les types numériques, les séquences, les dictionnaires, les classes, les instances et les exceptions.
Python manipule des objets (un concept qui sera approfondi dans une prochaine section) et certaines opérations sont prises en charge par plusieurs types d’objets ; en particulier, pratiquement tous les objets peuvent être comparés en égalité, testés en valeur de vérité (valeur booléenne) et convertis en une chaîne de caractères (avec la fonction repr()
ou la fonction légèrement différente str()
). Cette dernière est implicitement utilisée quand un objet est affiché par la fonction print()
.
Types numériques
Il existe trois types d’objets numériques : les entiers (integers), les nombres flottants (floating point numbers) et les nombres complexes (complex numbers). En outre, les booléens sont un sous-type des entiers. Les entiers ont une précision illimitée.
Exemples d’opérations courantes (source : documentation opérations)
Chaîne de caractères
Les données textuelles en Python sont manipulées avec des objets str
ou strings. Les chaînes sont des séquences immuables de points de code Unicode (une suite ordonnée d’indice dans la table UNICODE).
Une donnée immuable est une donnée qui ne peut pas être modifiée une fois créée. Les structures de type Collection seront abordées prochainement |
Les chaînes littérales peuvent être écrites de différentes manières :
-
entre quotes :
'cela autorise les "guillemets"'
; -
entre guillemets :
"cela autorise les 'simples quotes'"
; -
entre guillemets triples :
'''Trois simples quotes''', """Trois guillemets"""
.
Les chaînes entre guillemets triples peuvent couvrir plusieurs lignes, tous les caractères de type 'espace' sont alors inclus dans la chaîne littérale.
Travaux pratiques
En python
-
La fonction
ord()
permet de connaître le code (ou indice) d’un caractère UNICODE. Une valeur d’indice dans la table UNICODE allant de 0 à 1114111 (0x10FFFF en base 16) -
Inversement, la fonction
chr()
permet de connaître le caractère UNICODE associé à une valeur d’indice - voir documentation de la fonction chr
Exemple d’utilisation (d’appels) de ces fonctions :
ord('A') -> 65
chr(65) -> 'A'
La représentation du glyphe d’un caractère UNICODE est de la responsabilité du système d’affichage (dépend de la police et du contexte d’affichage) Voir plus en détail ici : python et l’unicode |
Le type caractère n’existe pas en Python. Un caractère est une chaîne de un seul caractère. Challenge : Proposez un POC (preuve de concept) de cette remarque ! |
EXERCICE 20
tp2.py
, réaliser, dans une fonction nommée exo20
, le scénario suivant et l’appeler dans le main :-
L’utilisateur est invité à saisir un caractère.
-
Le programme lui affiche successivement les informations suivantes
-
Le code du caractère
-
Le caractère précédent
-
Le caractère suivant
-
Entrez un caractère, svp : A # remarque : l'utilisateur choisit le caractère 'A' # le programme répond Le code du caractère est : 65 Le caractère précédent : @ Le caractère suivant : B
EXERCICE 21
Voici une spécification de la fonction pred()
fonction pred() : Caractère -> Caractère
# reçoit un caractère en argument
# rend, s'il existe, le caractère précédent dans la table UNICODE
# Sinon retourne None (une autre solution consiste à déclencher une exception)
tp2.py
-
Traduire la fonction
pred
en python. -
Concevoir la fonction
succ
(caractère suivant) en python. -
Tester ces 2 fonctions dans une fonction nommée
exo21
appelées dans le main -
Réécrire la fonction
exo20
enexo20bis
en conséquence.
(Pour les plus avancés) Comment déclencher une exception en python ? Dans le corps de la fonction, utiliser le mot clé
Vous pouvez consulter la discussion ici : https://stackoverflow.com/questions/2052390/manually-raising-throwing-an-exception-in-python Le déclenchement d’une exception provoque un arrêt brutal de l’interprétation du corps de la fonction dans lequel il est lancé, contrôlable par un gestionnaire |
EXERCICE 22
Concevoir une fonction nommée exo22
qui respecte le scénario suivant :
-
L’utilisateur est invité à saisir un code de caractère
-
Le programme affiche, dans un tableau, le caractère correspondant encadré
-
à droite des 5 caractères suivants
-
à gauche des 5 caractères précédents, à condition que leur code soit supérieur ou égal à celui du caractère
espace
.
-
EXERCICE 23
Concevoir une fonction nommée exo23
qui respecte le scénario suivant :
-
L’utilisateur est invité à choisir une 'langue' parmi 3 autres - à vous de les sélectionner parmi (url) block Unicode
-
Le programme affiche, dans un tableau, les 16 (ou plus ?) premiers caractères UNICODE correspondants.
Exemple de 'langue' : Hangul_Syllables Coréen. L’indice du block est U+AC00
. Testons le premier caractère en mode python interactif:
>>> ord('\uAC00')
44032
# saute les 2 premiers caractères de la chaine 'U+AC00'
>>> int('U+AC00'[2:], base=16)
44032
>>> chr(44032)
'가'
EXERCICE 23Bis
Concevoir une fonction qui attend en 2 paramètres : un indice de block UNICODE et un nombre de caractères à retourner, et qui retourne la chaîne de caractères correspondant à la demande.
Appeler cette fonction dans une nouvelle fonction nommée exo23bis
et tester cette nouvelle version dans le main.
Type booléen
Le type bool
est sous-type de int
, et définit 2 valeurs particulières : True
et False
, pour 1 et zéro respectivement.
Testons ces caractéristiques annoncées via une fonction native de Python nommée isinstance
qui prend 2 arguments : le premier est l’objet à tester, le second et un type (une classe). Elle rend vrai si le premier argument est du type du second.
Exemple : isinstance("42", int)
rendra False
car "42" est du type str
et non int
.
>>> isinstance(True, bool)
True
>>> isinstance(False, bool)
True
>>> isinstance(True, int)
True
>>> isinstance(False, int)
True
>>> isinstance(True, float)
False
>>> int(True)
1
>>> int(False)
0
Valeur de vérité
Toute valeur python peut être interprétée en valeur booléenne via la fonction bool()
>>> bool(1)
True
>>> bool(0)
False
>>> bool(True)
True
>>> bool('Hello World')
True
>>> bool(42)
True
En pratique, toute valeure différente de zéro ou 'vide' sera considérée comme True
.
Valeurs considérées comme False
Seules quelques valeurs sont considérées comme fausse :
-
Zéro de toute représentation et type numérique :
0, 0_000, 0.0, 0j, Decimal(0), Fraction(0, 1)
-
Les chaînes et collections vides :
'', (), [], {}, set(), range(0)
. -
None
etFalse
Affecter None à une variable est une façon de dire que cette variable n’a pas de valeur significative ou "n’a pas encore de valeur".
|
>>> bool(False)
False
>>> bool(None)
False
>>> bool('None')
True
Les opérations et fonctions natives dont le résultat est booléen renvoient toujours 0
ou False
pour faux et 1
ou True
pour vrai, sauf indication contraire (exception importante : les opérations booléennes or et and renvoient toujours l’une de leurs opérandes).
Opérations booléennes — and, or, not
Opération | Résultat | Note |
---|---|---|
|
si x est faux, alors |
|
|
si x est faux, alors x, sinon y |
C’est un opérateur court-circuit, il n’évalue le deuxième argument que si le premier est vrai. |
|
si x est vrai, alors x, sinon y |
C’est un opérateur court-circuit : il n’évalue le deuxième argument que si le premier est faux. |
Opérateurs de comparaison
Voir le tableau ici : https://docs.python.org/fr/3/library/stdtypes.html#comparisons
Travaux pratiques
EXERCICE 24
Opération | Résultat | Justification |
---|---|---|
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
Type chaîne de caractères (string)
En python les chaines de caractères sont instances du type str
, et sont des séquences ordonnées de valeurs de point de code UNICODE, pouvant être notées en hexadécimal.
>>> "\U00000394"
'Δ'
>>> ord("\U00000394")
916
Le terminal peut ne pas être en mesure de représenter le glyphe du caractère UTF-8. Dans ce cas, le système affiche le point de code.
>>> "\U00000394"
'\u0394'
Fort heureusement, le développeur utilise rarement les point de code directement, préférant les glyphes dès que permis.
>>> print('\u0394\u0395\u0394')
ΔΕΔ
>>> print('ΔΕΔ')
ΔΕΔ
>>> '\u0394\u0395\u0394'[1]
'Ε'
>>> len('\u0394\u0395\u0394')
3
>>> print("Hello World")
Hello World
EXERCICE 25 Opérations courantes sur les strings
Voici une liste à compléter, non exhaustive, d’opérations usuelles sur le type str
, à renseigner par vous-même à partir de ces ressources string-methods documentation et common-sequence-operations - il y a bien entendu d’autres ressources non officielles, comme sur wikibooks.org par exemple.
Opération | Python | Exemple |
---|---|---|
Extraire le "caractère" 'H' (chaîne de longueur 1) de |
Utilisation de la notation |
|
Extraction de la sous-chaîne 'Hello' |
||
Changement de casse (majuscule <-> minuscule) |
||
Suppression de "blancs" en queue et/ou en tête |
||
Recherche d’une occurrence d’une sous-chaîne dans la chaîne |
||
Compteur le nombre de 'l' dans x |
||
Quel est l’opérateur de concaténation ? (qui crée une nouvelle |
||
Peut-on comparer des chaines entre elles ? |
||
Comment tester qu’un chaîne est vide ? |
||
Comment obtenir la longueur d’une chaîne ? (nombre de points de code de la chaîne) |
||
Tentative de conversion : chaîne <-> numérique |
Travaux pratique
EXERCICE 26
On vous demande de programmer le scénario suivant (fonction nommée exo26
) :
L’utilisateur est invité à entrer deux lignes de texte respectant chacune le format suivant :
<public>;<code produit>;<qté vendue>;<mois>;<année>;<commentaire>
Le programme, après avoir vérifié le nombre de champs (6) de chacune de ces lignes, affiche le détail des informations (Mois, Année, Public, Code Produit, Qté vendue et Commentaire)
Il y a deux cas de figure :
-
Le code produit est le même, alors les informations ne seront affichées qu’une seule fois,
-
Le code produit est différent, les informations seront affichées en deux fois.
Exemples de scénarios à reproduire
Entrez une première ligne d'informations de ventes : F;a12;21;mars;2023; Attention, léger défaut... Entrez une deuxième ligne d'informations de ventes : F;a12;14;avril;2023; Attention, léger défaut... Voici la fiche produit : Date : MARS-2001, AVRIL-2023 Public : FEMME Code Produit : A12 Qté vendue : 35 Commentaire : Attention, léger défaut...
Entrez une première ligne d'informations de ventes : F;a12;21;mars;2023; Attention, léger défaut... Entrez une deuxième ligne d'informations de ventes : H;d45;11;mars;2023; Voici les fiches produit : Date : MARS-2023 Public : FEMME Code Produit : A12 Qté vendue : 21 Commentaire : Attention, léger défaut... Date : MARS-2023 Public : HOMME Code Produit : D45 Qté vendue : 11 Commentaire : AUCUN
Entrez une première ligne d'informations de ventes : F;a12;21;mars-2001; Attention, léger défaut... ERREUR de format !
Pour éviter de faire saisir les 2 lignes à l’utilisateur, vous pouvez lui demander de passer ces informations en argument du programme. Exemple :
où Le module
|
EXERCICE 27
On se place dans le scénario A. Nous appellerons A' (A prime) ce scénario étendu. Le voici :
Si le code produit est de nouveau saisi sur la deuxième ligne, alors on considère que l’utilisateur souhaite une mise à jour du produit. Seuls les champs renseignés (non vide) lors de cette seconde saisie seront mis à jour.
-
Donner un exemple de scénario A', avec des valeurs comme dans l’énoncé.
-
Implémenter et, bien entendu, tester le scénario A'
EXERCICE HACKING 28
Voici un programme python faisant usage de caractères unicode non conventionnels. Certains de ces caractères peuvent ne pas avoir un glyphe spécifique associé !!
C’est une technique d'obfuscation de code source, bien connue des hackers malveillants, cherchant à décourager les personnes souhaitant comprendre le code source (souvent encodé à la base)
On vous assure que ce code est sans risque ! n’hésitez pas à l’exécuter.
-
Votre mission consiste à déchiffrer ce code (le remettre en clair), en expliquant votre démarche.
import sys as Ꭓ𝑿
import random as X
X.seed('𝒙')
𝒙 = [print,"Hello World !",2,"Hello",__name__,1,"",len,"__main__","!"]
X.shuffle(𝒙)
def Ꭓ(𝑿):
if 𝑿:
𝒙[0](𝒙[1], 𝑿, 𝒙[2])
else:
𝒙[0](𝒙[3])
if (𝒙[4] == 𝒙[5]):
(Ꭓ(𝒙[8]) if (𝒙[6](Ꭓ𝑿.argv) < 𝒙[7]) else Ꭓ(Ꭓ𝑿.argv[𝒙[9]]))
Contrôler vos connaissances et contribuer aux QCMs
-
Contrôler vos connaissances sur quizbe.org. (choisir
PYTHON-1
, scopep-2-type
) -
Proposer, pour le thème
PYTHON-LDV
, scopep-2-type
, 2 questions QCM originales et personnelles, sur des thèmes couverts pas cette séquence d’exercices.
Python-3 Déboguer
Qu’est-ce que le débogage ?
-
Le débogage est un processus d’identification d’erreurs dans le code source d’un programme.
-
Les erreurs dans le code sont appelées des "bugs".
-
Les bugs peuvent provoquer des comportements indésirables ou un plantage du programme.
Pourquoi le débogage est-il important ?
-
Le débogage permet de comprendre plus rapidement la nature de certaines erreurs.
-
Le débogage aide à comprendre le fonctionnement du code, ce qui améliore les compétences en programmation.
Méthodes de débogage
Il existe plusieurs approches, complémentaires entre elles.
-
Analyser la logique du programme pour en détecter les failles.
-
Afficher des valeurs en cours d’exécution.
-
Interagir pas à pas avec le programme en cours d’exécution en utilisant un debogger
Afficher des valeurs
La technique consiste à utiliser provisoirement des instructions print afin d’obtenir des traces d’exécution sur la console de lancement du script.
print(f"Le prédécesseur de {chr(x)} est {chr(pred(x))}") (1)
1 | Cet exemple utilise la technique qui permet de formater des chaînes littérales incluant des expressions entre accolades {} . Attention à préfixer la chaîne avec 'f' ou 'F'. Ces chaînes sont appelées formatted string literal ou f-string |
Cette technique a ses limites. Elle s’avère fastidieuse lorsqu’il y a plusieurs variables à inspecter. De plus, le développeur ne doit pas oublier de supprimer (ou de commenter) ces instructions de débogage une fois le problème réglé.
Utiliser le débogueur (debugger) intégré
Analyser un code avec un débogueur c’est entreprendre une analyse du programme en cours d’exécution. |
Le débogage est une action qui consiste à interroger la mémoire vive d’un programme à l’exécution, à un instant t.
L’instant débogué est d’ordinaire celui du pointeur d’exécution [1].
L’idée est d'arrêter provisoirement l’exécution d’un programme afin d’interroger son contexte mémoire, une sorte d’instantané d’une partie de la mémoire vive. Le développeur peut alors consulter la valeur des variables exploitées à ce moment là par le programme et comparer ces valeurs avec ses prédictions afin d’y déceler d’éventuels anomalies.
Python dispose d’un débogueur intégré appelé pdb
, qui permet d’exécuter le code pas à pas et d’inspecter les variables à chaque étape.
Utilisez les commandes break
, continue
, step
, print
, etc., pour naviguer dans le code et examiner les valeurs.
En mode console
L’instruction breakpoint()
permet de mettre le programme en pause afin de consulter des valeurs à un instant t choisi par le développeur.
def exo3() -> None :
x=int(input("Entrez un nombre entier svp : "))
breakpoint() (1)
if x%2==0 : # la valeur de x est-elle divisible par 2 ?
print("Ce nombre est pair")
else :
print("Ce nombre est impair")
1 | L’exécution du programme s’arrêtera ici. Le développeur peut alors interroger la valeur de la variable x . |
$ ./test.py
Entrez un nombre entier svp : 2
> test.py(19)exo3() (1)
-> if x%2==0 : # la valeur de x est-elle divisible par 2 ?
(Pdb) x (2)
2 (3)
(Pdb) continue (4)
Ce nombre est pair (5)
$
1 | Le débogueur Pdb a mis en pause l’exécution du programme (ligne 19) |
2 | (mode interactif) Le développeur, en interaction avec le débogueur, demande la valeur de la variable x |
3 | Le débogueur retourne 2 (la valeur saisie par l’utilisateur) |
4 | Le développeur demande la poursuite du programme jusqu’au prochain point d’arrêt (sinon, pour avancer pas à pas, utiliser step ) |
5 | Le programme s’est terminé car il n’y a plus aucun autre point d’arrêt |
EXERCICE 30
Placer l’instruction breakpoint()
dans un de vos scripts, et tester le.
Débogueur piloté par l’IDE
C’est la façon la plus souple d’interagir avec un débogueur.
Nous utilisons code
(visual studio code) pour la démonstration.
Définition d’un point d’arrêt
Dans l’éditeur, une colonne (à gauche) est dédiée à la pause de point d’arrêt.
Exemple :
Avancement pas à pas
Dans l’éditeur, une colonne (à gauche) est dédiée à la pause de points d’arrêt.
Exemple pour entrer dans le code d’une fonction appelée
Exemple pour ne pas entrer dans le code d’une fonction appelée
Exemple de consultation des variables locales
N’hésitez pas à explorer les autres commandes de la bare de debug (continue
, restart
, stop
)
EXERCICE 31
Reprendre l’exemple ci-dessous, supprimer tous les points d’arrêt.
Ajouter un point d’arrêt conditionnel sur la ligne 6. Pour cela, une fois placé le point d’arrêt, faire un clic droit sur celui-ci , puis sélectionner Edit breakpoint…
. Comme valeur de l’expression, inscrire par exemple x == 42
.
Lancer le mode debug. Le programme se mettra en pause debug que si la valeur de x égalera 42.
Une technique fort pratique pour pister des erreurs !
Testez-la !
Les assertions pour se prémunir de certains bugs
Les assertions sont des instructions qui vérifient la cohérence de valeurs en cours d’exécution dans le code.
Elles peuvent être utilisées pour vérifier des résultats intermédiaires ou des conditions d’utilisation de fonctions (particulièrement dans le cas de langage de script non typés).
L’instruction assert
L’instruction assert
permet de vérifier qu’une condition est vraie à un point particulier du code. Si la condition n’est pas vérifié, une exception (AssertionError
) est alors déclenchée qui, si elle n’est pas traitée par l’appelant, entraînera l’arrêt non contrôlé du programme (bug)
assert
def extract_name(full_name : str) -> tuple : (1)
"""
Algorithme naïf, full_name de la forme "prénom nom"
Retourne une liste de 2 éléments
"""
assert isinstance(full_name, str), "Le nom complet doit être une chaîne de caractères."
names = full_name.split() # place les différentes partie de full_name dans une liste
assert len(names) >= 2, "Le nom complet doit contenir au moins un prénom et un nom de famille."
first_name = names[0]
last_name = names[-1]
return first_name, last_name
# Exemple d'utilisation
try:
full_name = "John Doe"
first_name, last_name = extract_name(full_name)
print(f"Prénom : {first_name}")
print(f"Nom de famille : {last_name}")
except AssertionError as e:
print(f"Erreur : {e}")
1 | La structure de données tuple (une liste de valeurs) sera étudiée dans la section suivante |
Dans cet exemple, nous avons une fonction extract_name()
qui extrait le prénom et le nom de famille d’une chaîne de caractères qui représente un nom complet.
L’instruction assert
est utilisée pour vérifier deux choses :
-
La variable full_name doit être une chaîne de caractères. Si ce n’est pas le cas, une exception
AssertionError
est levée avec le message : "Le nom complet doit être une chaîne de caractères." -
La chaîne de caractères full_name doit contenir au moins un prénom et un nom de famille. Si la chaîne ne contient pas au moins deux parties (prénom et nom de famille) séparées par un espace, une exception
AssertionError
est levée avec le message : "Le nom complet doit contenir au moins un prénom et un nom de famille."
Ces assertions nous permettent de nous assurer que la fonction extract_name()
est correctement utilisée avec une chaîne de caractères représentant un nom complet. Si un développeur utilise la fonction de manière incorrecte en passant un autre type de variable ou une chaîne de caractères mal formatée, les assertions lèveront une exception pour signaler le problème.
Les assertions sont particulièrement utiles pour valider les entrées de fonction, les préconditions et les invariants, permettant ainsi de s’assurer que le code est utilisé correctement et en accord avec les attentes du développeur concepteur de la fonction. |
EXERCICE 33
Tester la fonction extract_name
, en pas à pas avec le débogueur, avec au moins 3 scénarios :
-
un de réussite (à l’instar de celui fourni)
-
un avec une erreur de type
-
un avec une erreur de mauvais contenu de chaîne
Pour les plus avancés :
-
Modifier la fonction pour qu’elle considère que le nom de famille est toute la seconde partie après le prénom (premier mot). À tester avec
Guido van Rossum
.
Contrôler vos connaissances et contribuer aux QCMs
-
Contrôler vos connaissances sur quizbe.org. (choisir
PYTHON-1
, scopep-3-debug
) -
Proposer, pour le thème
PYTHON-1
, scopep-3-debug
, 2 questions QCM originales et personnelles, sur des thèmes couverts pas cette séquence d’exercices.
Python-4 Collections
Mise en condition
Nous avons vu qu’un programme manipule des valeurs. Ces dernières sont principalement référencées par des variables, ou constante définies directement dans le code source (constante littérale).
Nous avons alors une correspondance simple entre u identifiant et une valeur.
Une variable étant associée, à un instant t, à un type de donnée et à une et une seule valeur.
EXERCICE 42
Prenons un exemple simple d’un programme qui calculerait la note d’un joueur en fonction de ses différents scores aux compétitions, obtenus au cours de l’année en cours. Le calcul de la note d’un joueur est la moyenne de ses scores, mais est exclut de ce calcul un des scores correspondant à la valeur minimale des scores. Exemple, si les scores sont 0, 100, 100, 100
alors le 0
ne sera pas comptabilisé dans la moyenne, donc la note du joueur sera (100 + 100 + 100) / 3 = 100
.
Pour les besoins de l’exercice, on conçoit une fonction, nommée note
, qui prend 4 valeurs de scores, que l’on nommera score1
à score4
(valeurs supérieures ou égales 0) et qui calcule la note selon la règle précisée ci-dessus. Voici l’interface de la fonction à implémenter en python :
def note(score1, score2, score3, score4) -> int
Travail à faire
-
Implémenter la fonction
note
dans le respect de la logique du calcul présentée ci-dessus.
-
Vérifier que votre fonction retourne bien la valeur attendue. Pour cela nous vous communiquons la fonction de tests suivante :
def test_note() -> bool:
return (
note(0, 100, 100, 100) == 100
and note(0, 100, 100, 0) == 67
and note(100, 100, 100, 100) == 100
and note(0, 0, 0, 100) == 33
and note(0, 0, 100, 0) == 33
and note(0, 100, 0, 0) == 33
and note(100, 0, 0, 0) == 33
and note(0, 0, 0, 0) == 0
and note(100, 100, 100, 1000) == 400
)
Lancer votre fonction testNote()
à partir du main
de votre script.
if __name__ == "__main__":
print(test_note())
-
L’appel de la fonction
testNote()
doit rendreTrue
. Corrigez l’implémentation de votre fonctionnote
si nécessaire.
⇒ IMPORTANT : Aborder la suite qu’après avoir réussi à résoudre l’exercice 42. Faites-vous aider le cas échéant. On apprend par nos erreurs
Structure de données de type Collection
Nous avons défini une fonction note
, qui prend en argument 4 valeurs. S’il fallait prendre 5 ou plus de valeurs, il nous faudrait définir d’autres versions de cette fonction… Exemple.
def note(score1, score2, score3, score4) -> int
def note5(score1, score2, score3, score4, score5) -> int
def note6(score1, score2, score3, score4, score5, score6) -> int
etc.
Mais ce n’est pas la bonne solution !
Rappelez-vous de cela, si un jour vous êtes amené à penser de la sorte, alors votre analyse est certainement à revoir. |
Il y a mieux à faire. La bonne solution consiste à passer une liste - ou collection - de valeurs à la fonction note
.
Python propose plusieurs types prédéfinis de collections [2]. Pour l’heure nous nous intéressons aux principaux types natifs : list
, set
, dict
et tuple
.
-
list
est une structure de données de type séquentiel, au même titre questr
, mais muable. Une instance delist
dispose des mêmes opérations questr
. Donc vous êtes déjà familiarisé avec cette structure, sauf que les éléments delist
ne sont pas réduits à des chaînes. Particularité : type séquentiel, donc les index sont des entiers (commence à zéro) et la structure est muable, elle permet donc l’ajout, la suppression et le remplacement d’éléments (contrairement àstr
). -
set
est une structure de données muable de type ensemble, non organisée séquentiellement. Particularité : structure non indexée et n’accepte pas d’éléments en doublon. -
dict
est une structure de données muable de type dictionnaire, non organisée séquentiellement. Particularité : les index sont des objets, par exemple des index de type string, comme un dictionnaire (nom → définition), d’où son nom. -
tuple
est une structure de données immuable de type séquentiel. Particularité : type séquentiel, donc les index sont des entiers (comme string)
Une classification des principales collections natives :

À noter : Il existe également un type set
immuable : frozenset
.
Opérations courantes sur les structures séquentielles
Déclaration de variables Collection
Exemple de déclaration et initialisation de variables de type conteneur (autre nom pour collection)
def declare_collections() :
""" Exemple de syntaxe de déclaration et initialisation de collections """
une_liste : list = ['a', 'a', '123', 123] # crochets (bracket)
un_tuple : tuple = ('a', 'a', '123', 123) # parenthèses (optionnelles)
un_ensemble : set = {'a', 'a', '123', 123} # accolades (brace)
un_dico : dict = {1:'a', 3:'a', 5:'123', 7:123} # accolades avec couples clé:valeur comme éléments (key:value)
print(f"Nombre d'éléments de la liste : {len(une_liste)}") # 4
print(f"Nombre d'éléments du tuple : {len(un_tuple)}") # 4
print(f"Nombre d'éléments de l'ensemble : {len(un_ensemble)}") # 3 (pas de doublons)
print(f"Nombre d'éléments du dictionnaire : {len(un_dico)}") # 4
print('-------------------------------------------------------')
print(f"Premier élément de la liste (index 0) : {une_liste[0]}")
print(f"Premier élément du tuple (index 0) : {un_tuple[0]}")
print("Premier élément du set : Non Applicable ") # de plus l'ordre des éléments dans un `set` n'est pas garanti...
print(f"Élément du dico (ici clé = 1) : {un_dico[1]}")
Les structures de données natives ont leur propre syntaxe qu’il faut connaître. [] ⇒ list , {} ⇒ set et dict , {key:value} ⇒ dict , () ⇒ tuple .
|
Création d’instances de tuple
Les tuples peuvent être construits de différentes façons :
-
en utilisant une paire de parenthèses pour désigner le tuple vide :
()
; -
en utilisant une virgule, pour créer un tuple d’un élément :
a,
ou(a,)
; -
en séparant les éléments avec des virgules :
a, b, c
ou(a, b, c)
; (parenthèses optionnelles) -
en utilisant la fonction native
tuple()
:tuple()
outuple(iterable)
.
Création d’instances de set
Les ensembles peuvent être construits de différentes manières :
-
création d’un ensemble vide :
set()
({}
est réservé au dictionnaire) -
en utilisant une liste d’éléments séparés par des virgules entre accolades :
{'Bob', 'Alice'}
-
en utilisant un ensemble en compréhension :
{c for c in 'abracadabra' if c not in 'abc'}
(donne{'d', 'r'}
); -
en utilisant le constructeur du type :
set()
,set('foobar')
,set(['a', 'b', 'foo'])
.
Les Ces deux classes disposent des opérations sur les ensembles bien pratiques telles que : la différence, l'union et l'intersection de 2 ensembles. ![]() Voir ici https://docs.python.org/fr/3/library/stdtypes.html#set et là aussi par exemple python - notions avancées chez developpez.com |
Création d’instances de dict
Les dictionnaires peuvent être construits de différentes manières :
-
en utilisant une liste de paires clé: valeur séparées par des virgules entre accolades :
{'Bob': 13, 'Alice': 42}
ou, inversion clé/valeur,{13: 'Bob', 42: 'Alice'}
-
en utilisant un dictionnaire en compréhension :
{}
,{x: x ** 2 for x in range(10)}
; -
en utilisant le constructeur du type :
dict()
,dict([('foo', 100), ('bar', 200)])
,dict(foo=100, bar=200)
.
Choisir la bonne structure de données
Si la collection de type liste n’a pas à être modifiée une fois créée, préférer un type immuable. Ces structures de données sont plus efficaces. Donc tuple
au lieu de list
.
Si les index sont des valeurs métier, le dictionnaire s’impose, sinon une structure indexée par des entiers est plus efficace en générale.
Si la structure de données conteneur doit faire l’objet d’opérations ensembliste comme l’union, l’intersection etc. alors préférer le type set
.
Itérer sur tous les éléments d’une collection
Boucle for idiomatique :
fruits = ['tomates', 'bananes', 'kiwis'] (1)
for fruit in fruits : (2)
print(fruit) (3)
1 | (IMPORTANT) Il est d’usage d’utiliser le pluriel (fruits ) pour le noms de variables de type collection |
2 | La variable fruit (au singulier) est une variable de boucle (créée pour l’occasion), qui var prendre, successivement, la valeur de chacun des éléments de la liste. |
3 | Le corps de la boucle. Ici on affiche la valeur de l’élément courant (ne pas hésitez à pauser un point d’arrêt sur cette ligne pour comprendre l’itération ) |
Un exécution donnera :
tomates
bananes
kiwis
Attention, dans le cas des dictionnaires, cette structure retournera les clés, pas les valeurs.
Pour d’autres façons d’opérer, voir ici : https://stackoverflow.com/questions/3294889/iterating-over-dictionaries-using-for-loops |
Autres modèle d’itérations :
modèle idiomatique
C’est un modèle d’itération présenté dans le guide de l’auto-stoppeur python
fruits = ['tomates', 'bananes', 'kiwis']
for index, fruit in enumerate(fruits) : (1)
print(index, fruit) (2)
1 | utilise la fonction native enumerate (pour les listes, ou tuples) |
2 | affiche l’index en plus de la valeur de l’élément |
Qui donnera :
0 tomates
1 bananes
2 kiwis
Modèle "classique"
fruits = ['tomates', 'bananes', 'kiwis']
i = 0 (1)
while i < len(fruits) : (2)
print(i, fruits[i]) (3)
i += 1 (4)
print(i) (5)
1 | Les indices commencent à zéro |
2 | Tant que i est inférieur au nombre d’éléments |
3 | Affiche l’index et l’élément situé à cet index |
4 | Incrémente i |
5 | Affiche la valeur de i qui est len(fruits) (condition d’arrêt de l’itération) |
Qui donnera :
0 tomates
1 bananes
2 kiwis
3
Modèle non idiomatique
fruits = ['tomates', 'bananes', 'kiwis']
for index in range(len(fruits)):
print(index, fruits[index])
Bien qu’opérationnel, ce modèle appelle range
, qui crée inutilement une séquence (immuable) de nombres en guise d’indices.
Cette remarque se vaut dans la mesure où l’on souhaite itérer sur la totalité des éléments de la liste.
Approfondir le sujet sur stackoverflow : https://stackoverflow.com/questions/522563/accessing-the-index-in-for-loops
Avec un itérateur (iterator)
En fait, toutes les collections sont itérables. Python dispose de 2 fonctions iter
et next
qui permettent de boucler sur les éléments d’une collection (mais pas seulement)
iterateur = iter(fruits)
print(next(iterateur))
print(next(iterateur))
print(next(iterateur))
Qui donnera :
tomates
bananes
kiwis
La fonction next() donne l’élément suivant (le premier appel à next
donne le premier élément). Un appel à next() alors que le dernier élément a déjà été atteint déclenchera une exception de type StopIteration
.
Ainsi, peut-on reproduire ce que fait en réalité la structure de boucle for
:
iterateur = iter(fruits)
while(True) : (1)
try:
fruit = next(iterateur)
print(fruit)
except StopIteration :
break (2)
# equivalent à : for fruit in fruits : print(fruit) (3)
1 | Oh, boucle infinie ! |
2 | Ouf, fort heureusement l’instruction break provoquera l’arrêt de la boucle lorsque que l’exception StopIteration sera déclenchée. |
3 | Syntaxe à préférer ! |
EXERCICE 43
L’objectif est de réécrire la fonction note
(exercice 42) afin de lui passer en paramètre, non pas 4 valeurs, mais une collection de valeurs numériques (c’est plus souple).
Voici une nouvelle version de l’interface de la fonction note
:
def note(scores : tuple) -> int (1)
1 | Le paramètre est typé tuple plutôt que list car la fonction n’a pas vocation à modifier les éléments de la collection reçue en argument (voir Choisir la bonne structure de données) |
Une autre approche consiste à placer une étoile (`*`) en *préfixe du paramètre* (qui dénote un tuple) -- une double étoile (`**`) dénote un dictionnaire.
Dans ce cas, il faut omettre les parenthèses englobant les arguments. Exemple:
|
-
Implémenter cette nouvelle fonction
-
Proposer une nouvelle version de
test_note()
de l’exercice 42 afin de tester la nouvelle fonction -
Étendre les scénarios inclus dans
test_note()
qui passe ànote
un tuple de plus ou moins 4 éléments. Exemple.note((100, 100, 100, 1000, 100)) # 325 (5 éléments) note((100, 100)) # 100 (2 éléments)
Proposer au moins 4 autres scénarios. Revenir sur votre implémentation de la nouvelle fonction
note
si nécessaire.
-
Faire en sorte que la fonction ne puisse pas buguer lorsqu’on lui passe une liste de valeurs avec un nombre incorrect d’éléments (à identifier). (2 cas)
Indice : Utiliser
assert
(ref cours sur le debugger), et mettre à jour ladocstring
de la fonctionnote
.
EXERCICE 44
Voici une version d’une fonction qui prend 2 listes et retourne une liste des éléments communs.
def recherche_elements_communs(list1 : list, list2 : list) -> list :
common_elements = []
for item1 in list1:
for item2 in list2:
if item1 == item2:
common_elements.append(item1) # ajoute cet élément
return common_elements
Exemple
recherche_elements_communs(['a', 'b'], ['x', 'b', 'y', 'z']) # retourne ['b']
-
Déterminer le nombre de parcours de boucles de l’exemple ci-dessus. Utiliser le débogueur pour une exécution pas à pas de la fonction à fin de vérification. Inspecter les variables
item1
etitem2
à chaque itération de la boucle. -
Donner une formule générale qui donne le nombre d’itérations, quelque soit le nombre d’éléments des arguments
-
Définir une fonction nommée
test_recherche_elements_communs
qui teste plusieurs scénarios (inspirez-vous de l’exemple donnée et detest_note()
) -
Proposez une amélioration de l’implémentation de la fonction
test_recherche_elements_communs()
. Il y a plusieurs possibilités, l’idée est de faire confiance aux structures existantes du langage. Attention, l’interface de la fonction ne doit pas être modifiée !def recherche_elements_communs(list1 : list, list2 : list) → list
-
Tester la nouvelle version de votre fonction
EXERCICE 45
Concevoir et tester une fonction qui prend en argument une liste d’objets et qui retourne une liste des éléments en doublons. Voici son interface :
def doublons(liste : list) → list
doublons(['1','X','2','2','3','4','3','A','a','X']) # rend ['X', '2', '3']
-
Implémenter la fonction
doublons
-
Définir une fonction qui teste plusieurs scénarios d’utilisation de cette fonction.
-
Définir une deuxième implémentation de la fonction
doublons
-
Concevoir une nouvelle fonction qui prend en argument une liste et qui détermine si cette liste détient des doublons ou non.
-
Définir l’interface de cette fonction
-
Implémenter cette fonction
-
Définir une fonction de test pour cette fonction
-
Contrôler vos connaissances et contribuer aux QCMs
-
Contrôler vos connaissances sur quizbe.org. (choisir
PYTHON-1
, scopep-2-collection
) -
Proposer, pour le thème
PYTHON-LDV
, scopep-2-collection
, 2 questions QCM originales et personnelles, sur des thèmes couverts pas cette séquence d’exercices.
Python-Projet 1
Big Data et Web Scraping
Le web regorge de données exposées, le plus souvent, au format HTML.
Ces données peuvent être extraites des sites web. On parle alors de web scraping
Le web scraping est une technique d’extraction des données de sites Web par l’utilisation d’un script ou d’un programme dans le but de les transformer et les réutiliser dans un autre contexte comme l’enrichissement de bases de données, le référencement ou l’exploration de données. (source : Web_scraping Wikipedia) |
Les IA sont très gourmandes de ces données, mais pas que.
L’exploitation de données publiques ou privées est au coeur des systèmes décisionnels. C’est une branche à part entière de l’informatique.
Exemple de parcours : https://www.univ-paris8.fr/-Master-Big-Data-et-fouille-de-donnees-BD- : développement de solutions Big Data, à l’aide des techniques les plus récentes de l’intelligence artificielle, de l’apprentissage automatique et de la fouille de données, et à l’aide d’architectures distribuées. Ils seront capables de comprendre et maîtriser le traitement des données structurées ou non, numériques et textuelles, pour dialoguer avec les experts métier, ainsi que les mathématiques appliquées nécessaires au domaine. La place de l’alternance est importante dans ce parcours. Attention, pour pouvoir entrer dans ce parcours en M2 il faut avoir obtenu l’option BD en M1. |
BeautifulSoup
Beautiful Soup est un package Python pour parser (traiter) des documents HTML
et XML
(incluant des documents mal formés, i.e. balise non fermées par exemple, d’où le nom de tag soup). Une solution couramment utilisée pour du web scraping.
Beautiful Soup a été crée par Leonard Richardson, qui continue à contribuer à ce project.
TP préparatoire
À partir de l’exemple de code suivant, extrait de la document sur Wikipédia
#!/usr/bin/env python3
# Anchor extraction from HTML document
from bs4 import BeautifulSoup
from urllib.request import urlopen
with urlopen('https://en.wikipedia.org/wiki/Main_Page') as response:
soup = BeautifulSoup(response, 'html.parser')
for anchor in soup.find_all('a'):
print(anchor.get('href', '/'))
-
Concevoir un script qui extrait les liens en
https
de la ressource web suivante :sous la forme d’un document
HTML
bien formé.Attention : Pour faciliter la consultation du résultat de l’extraction des liens https, Le texte des liens devra être tronqué s’il dépasse une certaine longueur (75 caractères)
Exemple de lancement du script :
$ python3 tp-bs4-web-scraping.py > res.html
Exemple de résultat attendu
REAMRQUE : Dans cet exemple, 2 textes de lien sont tronqués (et donc terminés par 3 points de suspension, comme la coutume l’impose afin d’en informer l’utilisateur).
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=500, initial-scale=1" />
<style></style>
</head>
<body>
<h1>Exemple de web scraping</h1>
<ul><li><a href="https://github.com/kennethreitz/python-guide" target="_blank">https://github.com/kennethreitz/python-guide</a></li>
<li><a href="https://github.com/python-guide-fr/python-guide/issues" target="_blank">https://github.com/python-guide-fr/python-guide/issues</a></li>
<li><a href="https://www.transifex.com/python-guide-fr/python-guide-fr/" target="_blank">https://www.transifex.com/python-guide-fr/python-guide-fr/</a></li>
<li><a href="https://twitter.com/kennethreitz" target="_blank">https://twitter.com/kennethreitz</a></li>
<li><a href="https://www.amazon.com/Hitchhikers-Guide-Python-Practices-Development/dp/1491933178/ref=as_li_ss_il?ie=UTF8&linkCode=li2&tag=bookforkind-20&linkId=804806ebdacaf3b56567347f3afbdbca" target="_blank">https://www.amazon.com/Hitchhikers-Guide-Python-Practices-Development/dp/14...</a></li>
<li><a href="https://djangogirls.org" target="_blank">https://djangogirls.org</a></li>
<li><a href="https://github.com/kennethreitz/records" target="_blank">https://github.com/kennethreitz/records</a></li>
<li><a href="https://github.com/kennethreitz/python-guide/graphs/contributors" target="_blank">https://github.com/kennethreitz/python-guide/graphs/contributors</a></li>
<li><a href="https://media.readthedocs.org/pdf/python-guide-fr/latest/python-guide-fr.pdf" target="_blank">https://media.readthedocs.org/pdf/python-guide-fr/latest/python-guide-fr.pd...</a></li>
<li><a href="https://github.com/kennethreitz/python-guide" target="_blank">https://github.com/kennethreitz/python-guide</a></li>
</ul>
</body>
</html>
Conseil méthodologique. Allez-y progressivement, par étapes (c’est la méthode clé pour programmer). Exemple de décomposition :
|
Projet Web Scraping
À partir de l’expérience acquise au cours de ces moments passés à coder en Python, et en vous inspirant du travail réalisé à l’issu du dernier TP, proposez (analyser, coder, tester) une application Python (sous la forme d’un script) qui extrait et met en forme des données d’un ou plusieurs sites web de votre choix.
Vous placerez ce travail sous la forme d’un projet hébergé sur GitHub, en mode public, et rédigerez votre rapport sous la forme d’un README de votre projet (markdown ou asciidoc). Par conséquent ce rapport sera librement consultable par vos professeurs, et servira de base à l’évaluation de votre projet, et enrichira votre portfolio !
Date de rendu du projet : à déterminer
Glossaire
- variable
-
symbole dans le code, dont le nom témoigne de son rôle, qui désigne selon son utilisation soit un contenant (une adresse mémoire) soit une valeur de contenu (interprétée selon son type)
- type
-
Pour l’interpréteur, désigne comment utiliser et stocker la valeur d’une variable.
Pour l’utilisateur, limite l’exploitation de la variable aux opérations définies sur ce type.Listing 20. La fonction 'type' retourne le type de son argument>>> type(42) <class 'int'> >>> type(42) is int True >>> type(42) is str False >>> type("42") is str True >>>
Voir la discussion ici : https://stackoverflow.com/questions/4843173/how-to-check-if-type-of-a-variable-is-string
- valeur d’une variable
-
interprétation du contenu de (l’espace occupé par) la variable, selon son type.
Exemple :
x = "42"
ouy = 42
;La valeur de
x
est"42"
est son type est stringLa valeur de
y
est42
est sont type est intCes deux variables pointent vers des espaces mémoire peu comparables en terme de structure binaire et de taille.
- Constante littérale
-
Valeur inscrite dans le code source
Ces valeurs sont typées. Exemple :
'ANNEE' "ANNEE" """ANNEE"""
sont des constantes littérales de type string - Convention de nommage
-
Les conventions usuelles
nom | usage |
---|---|
UpperCamelCase |
nom de classe |
lowerCamelCase |
propriété, méthode, variable, paramètre… en Java, JS, PHP… |
lower_snake_case |
nom de variable et fonction en python |
SCREAMING_SNAKE_CASE |
constante |
kebab-case |
ressource web, identifiant, attribut html |
- return
-
Directive signifiant la fin de l’exécution du corps de la fonction où elle est présente. Peut être suivie d’une valeur qui sera retournée à l’appelant.
- Appelant
-
Instruction (un bout de code) qui appelle une fonction en se fiant à son entête. Exemple :
x = len(y)
est une instruction appelant l’exécution de la fonctionlen
. - Appelé
-
Un sous-programme identifié par un nom (nom d’une fonction par exemple) Exemple :
x = len(y)
,len
est la fonction appelée. Dans cet exemple, la valeur de retour de la fonction appelée est stockée, par l’appelant, dans une variable nomméex
. - Entête d’une fonction
-
Nommée également interface, définit le nom de la fonction, ses paramètres éventuels et son type de retour (ou
None
). Exemple (première ligne) :def bidon() -> None : pass
- Corps d’une fonction
-
Nommée également implementation, définit le travail de la fonction, et sa valeur de retour, si attendue. La séquence d’instructions est placée dans le bloc indenté qui suit l’entête de la fonction.
- Algorithme déterministe
-
(sensibilisation) Une fonction, pour une même donnée d’entrée, doit invariablement produire la même sortie.
- Muable
-
Une structure de données muable signifie que les variables de ce type peuvent sont susceptibles d’avoir leur valeur évoluée dans le temps. Exemple
list
, contre exemplestr
(ne peut pas être modifiée après création) - Immuable
-
Une structure de données immuable signifie que les variables de ce type ont une valeur qui ne peut être modifiée après leur création. Exemple
str
outuple
, ne permettent pas l’ajout d’éléments, et leurs éléments ne peuvent être ni modifiés ni supprimés. Contre exemplelist
(accepte l’ajout, et les éléments d’une instance delist
peuvent être modifier, supprimer)