Rappel : les programmes commencent par :
import numpy as np
import matplotlib.pyplot as plt
Entrées et sorties.
Pour permettre à l'utilisateur ou à l'utilisatrice d'entrer une valeur, nous utilisons la fonction codice_1 comme évoqué précédemment (chapitre "Premiers programmes"), avec la syntaxe codice_2. Notez que la valeur renvoyée par codice_1 est une chaîne de caractères. Si vous voulez autre chose, typiquement un nombre, il faut convertir cette chaîne.
Par exemple, nous demandons ici d'entrer une longueur sous la forme d'une valeur numérique :
longueurDefaut = 10.0
texteDemandeLongueur = f"Veuillez entrer la longueur en millimètres (valeur par défaut {longueurDefaut} mm) : "
longueur = input(texteDemandeLongueur)
if longueur=="":
 longueur=longueurDefaut
else:
 longueur=float(longueur)
print(longueur)
Pour afficher un texte, on utilise la fonction codice_4, également présentée dans le chapitre "Premiers programmes", avec la syntaxe codice_5. Le texte à afficher peut être de n'importe quel type (entier, réel en virgule flottante, booléen, chaîne de caractères…) mais si l'on veut « mélanger » les types, il faut tout convertir en chaînes de caractères, avec la fonction codice_6, et concaténer les chaînes avec codice_7.
Par exemple :
print("La longueur vaut : "+str(longueur)+" mm.")
Nous pouvons aussi utiliser une « chaîne “f” » "()" : on met un le codice_8 devant le guillemet ouvrant et dans la chaîne, on met un champ sous la forme codice_9. L'exemple ci-dessus devient alors :
print(f"La longueur vaut : {longueur} mm.")
Les chaînes « f » sont détaillées dans la section "Chaînes de caractères" ci-dessous.
Si l'on veut introduire un retour à la ligne dans la chaîne, on utilise les caractères codice_10 (contre-oblique suivie de la lettre N minuscule). Par exemple
print("Ceci est un texte\navec un retour à la ligne.")
Types de variables.
Généralités.
Python définit « tout seul » le type de la variable : « codice_11 » sera un entier "()", « codice_12 » sera un réel à virgule flottante "()", « codice_13 » sera une chaîne de caractères "()".
On peut connaître le type d'une variable avec la fonction codice_14.
On peut tester certaines valeurs, avec le module codice_15 :
On peut forcer un type :
Par exemple
type(3) # <class 'int'>
type(float(3)) # <class 'float'>
complex(1, 1) == 1 + 1j # True
list("blabla") # ['b', 'l', 'a', 'b', 'l', 'a']
Python distingue plusieurs genres de types :
Types numériques.
Entiers.
Nous pouvons définir les entiers au format octal ou hexadécimal : il faut débuter le nombre par respectivement codice_28 (le chiffre zéro et la lettre o) et codice_29 (le chiffre zéro et la lettre x). À l'inverse, la fonction codice_30 renvoie une chaîne correspondant à l'écriture d'un entier au format hexadécimal, et codice_31 renvoie la chaîne correspondant à l'éciture en octal. Par exemple :
print(0o10, ";", 0x10)
print(hex(20))
Réels.
Les réels disposent de fonctions spécifiques appelées « méthodes ».
Une méthode est un fonction spécifique à un type d'objets. Étant conçue "ad hoc", elle est souvent plus économe en ressource et en temps qu'une fonction générique. Pour appliquer la méthode codice_32 à la variable codice_33, on écrit : codice_34.
Nous avons déjà présenté la méthode codice_35 qui donne la fraction réduite égale à la valeur du nombre. Les réels disposent de plusieurs autres méthodes :
Par exemple :
a = 20.
print(a.hex())
print(10..hex())
Dans le deuxième exemple, nous appliquons la méthode codice_39 directement au nombre codice_41 ; le point est obligatoire car sinon, c'est un entier, pour lequel la méthode n'est pas définie.
Notez que la "méthode" codice_39 est différentes de la "fonction" codice_30 : la première concerne les réels, la seconde les entiers.
Complexes.
Nous avons déjà mentionné la méthode codice_44 qui donne le conjugué du nombre.
Un nombre complexe dispose de deux attributs :
Par exemple :
a = 5+2j
print(a.conjugate(), ";", a.real, ";", a.imag)
Chaînes de caractères.
Généralités.
Il existe en fait trois manières de définir une chaîne de caractères :
Une chaîne de caractères n'est pas modifiable. Si l'on veut remplacer un caractère, l'insérer ou le supprimer, il faut transformer la chaîne en liste, avec la commande codice_25, puis rassembler la liste en la joignant "()" à une chaîne vide :
chaine = "blabla"
chaineList = list(chaine)
chaineList[2] = "c"
chaine = "".join(chaineList)
print(chaine) # blcbla
Dans une chaîne simple codice_47 ou codice_48, on peut introduire un retour à la ligne avec codice_57.
Substitution de variables.
Lorsque l'on veut utiliser des variables, on fait précéder les guillemets d'un « f » et l'on écrit les noms de vrariables entre accolades. Par exemple :
monde = "world"
chaine = f"Hello {monde}!"
print(chaine) # Hello world!
On peut indiquer la taille de la chaîne générée à partir de la variable sous la forme codice_58, la taille étant un entier. Par exemple :
chiffre1 = 1
nom1 = "un"
chiffre2 = 2
nom2 = "deux"
chaine = f"{nom1:5} : {chiffre1:5d}\n{nom2:5} : {chiffre2:5d}"
print(chaine)
Vous remarquez que l'on ajoute un « d » pour les entiers décimaux, et que les nombres sont alignés à droite. Si le nombre est un nombre réal à virgule flottante "()", on peut indiquer le nombre de décimales sous la forme codice_59 :
chaine = f"{np.pi:.5f}"
print(chaine)
Avec la syntaxe codice_60, on indique également que la totalité du nombre doit occuper "m" caractères.
Pour convertir un nombre en caractère Unicode correspondant, on utilise la lettre c :
nompi = 0x03c0
chaine = f"{nompi:c} = {np.pi:.5f}"
print(chaine)
La classe "str" dispose également de la méthode codice_61. On indique un n-uplet de chaînes (ou de nombres) à la méthode et l'on met des accolades dans la chaîne principale ; les accolades sont remplacées dans l'ordre des chaînes de la méthode. On peut changer l'ordre en indiquant quelle valeur utiliser dans quelle accolade. Par exemple :
chaine1 = "On compte {} puis {}".format(1, 2)
chaine2 = "On compte {0} puis {1}. Mais à rebours, on compte {1} puis {0}.".format("un", "deux")
print(chaine1, "\n", chaine2)
L'utilisation du caractère pourcent « % » permet d'utiliser la mise en forme codice_62 du langage C :
chaine = "π = %.5f" % np.pi
print(chaine)
Méthodes des chaînes.
Le type "str" dispose d'un certain nombre de méthodes. Nous avons déjà vu les méthodes codice_63 et codice_64, en voici quelques autres :
Autres fonctions.
La fonction codice_81 transforme un code Unicode en caractère. Par exemple, codice_82 donne codice_83 et codice_84 donne codice_85.
Manipulation de listes.
Les listes sont une structure de données fondamentale en Python.
Copie d'une liste.
Contrairement à d'autres types, lorsque vos écrivez codice_86 avec des listes, vous ne créez pas une copie de la variable codice_87, vous créez un "alias" : l'objet codice_88 est un autre nom de l'objet codice_87. En particulier, si vous modifiez codice_88, vous modifiez en fait codice_87. Par exemple :
a = [1, 2, 3, 4]
b = a
b[2] = 5
print(a, b) # [1, 2, 5, 4] [1, 2, 5, 4]
Si l'on veut créer une copie de codice_87, il faut utiliser codice_93 ou bien codice_94 :
a = [1, 2, 3, 4]
b = a[:]
c = a.copy()
b[2] = 5
c[2] = 6
print(a, b, c) # [1, 2, 3, 4] [1, 2, 5, 4] [1, 2, 6, 4]
Méthodes de listes.
Pour modifier une liste, vous disposez des méthodes suivantes :
Pour supprimer l'élément à l'indice "i", au lieu d'utiliser codice_114, on peut aussi utiliser
del(a[i])
Pour trier une liste, on peut aussi utiliser la fonction codice_115, ce qui permet par exemple de conserver la liste originale, non triée : codice_116. La fonction codice_115 fonctionne avec tous les objets « itérables » comme par exemple une chaîne de caractères :
a = "ahjbfk"
print(sorted(a)) # ['a', 'b', 'f', 'h', 'j', 'k']
Pour mettre en évidence la performance de la méthode codice_118 par rapport à la fonction générique codice_115 :
import numpy as np
import time
a = np.random.rand(int(1e7))
t1 = time.perf_counter()
b = sorted(a) # Fonction générique
t2 = time.perf_counter()
a.sort() # Méthode spécifique
t3 = time.perf_counter()
print("Sorted :", t2-t1, " s ; .sort :", t3-t2, "s ; rapport :", (t2-t1)/(t3-t2))
Par rapport à une valeur donnée :
Définition en compréhension.
La définition en compréhension "()" est une méthode permettant de construire des listes en indiquant simplement des axiomes, des consignes de filtrage. Cette méthode est élégante car proche de la notation mathématique et compacte, mais c'est une méthode itérative donc lente par rapport à une méthode vectorisée fournie par le module NumPy.
Par exemple, pour créer la liste des carrés des nombres entiers entre 0 et 9, il suffit d'écrire
carre = [x**2 for x in range(10)]
ce qui se rapproche de la notation d'ensemble formula_1.
Si l'on veut la liste des nombres strictement inférieurs à 20 dont le carré est supérieur à 10, on peut écrire :
X = [x for x in range(20) if x**2 > 10]
ce qui se rapproche de la notation d'ensemble formula_2.
Pour mettre en évidence la performance du calcul vectorisé par rapport à la méthode itérative :
import time
import numpy as np
n = int(1e7) # taille de la liste
t1 = time.perf_counter()
carre = [x**2 for x in range(n)] # Définition en compréhension
t2 = time.perf_counter()
carre2 = np.arange(n)**2 # Calcul vectorisé
t3 = time.perf_counter()
print("En compréhension : ", t2-t1, "s ; vectorisé :", t3-t2, "s ; rapport :", (t2-t1)/(t3-t2))
Structure d'un programme.
Un programme est simplement une suite d'instructions.
Dans les environnements Unix BSD, un programme Python peut être considéré comme un script c'est-à-dire qu'il suffit de taper son nom dans l'invite de commande "()" sans avoir à invoquer codice_128. Le programme doit alors commencer par un en-tête normalisé surnommé " :
Ce " est inutile avec Jupyter.
L'en-tête peut également contenir la description de l'encodage du fichier texte, typiquement :
Le codage UTF-8 est le codage par défaut pour Python 3, il est donc inutile de l'indiquer.
Les commentaires sont introduits par le croisillon codice_129.
On peut grouper une suite d'instructions dans un bloc. Un bloc d'instructions commence par deux-points « codice_130 » et est identé, c'est-à-dire qu'il a une marge constituée de quatre espaces — on peut aussi utiliser une tabulation mais il ne faut pas mélanger les deux méthodes ; les tabulations sont déconseillées, il vaut mieux utiliser quatre espaces. Pour terminer le bloc, il suffit simplement de revenir en début de ligne ; contrairement à d'autres langages, il n'y a pas de commende de fin "()", c'est l'indentation qui définit le bloc.
 : # début du bloc
 "instruction 1"
 "instruction 2"
 "dernière instruction du bloc"
 "instruction hors bloc"
Par exemple, une exécution conditionnelle codice_131 ou une boucle codice_132 exécute un bloc d'instruction. Si l'on a besoin d'un bloc d'instruction qui « ne fait rien », on utilise l'instruction codice_133.
Structures de contrôle.
Boucle itérative
La boucle itérative s'écrit :
 for <variable> in <itérable>:
 <bloc d'instructions>
Si l'on veut que la variable prenne "n" valeurs de 0 à "n" – 1, on utilise l'instruction codice_134 :
for i in range(5):
 print(i)
print("Fin de la boucle")
codice_135
 0
 1
 2
 3
 4
 Fin de la boucle
En fait, la commande codice_134 extrait des valeurs de l'ensemble des nombres entiers ; on peut ainsi utiliser le découpage en tranches, par exemple codice_137pour avoir la « liste » codice_138. Notez que codice_134 ne crée pas à proprement parler une liste, cela crée un objet de type "«  »" (plage, intervalle) ; pour avoir une liste, il faut écrire codice_140.
Dans une boucle, la commande codice_141 saute la fin du bloc d'instruction et passe à la valeur suivante de la boucle. La commande codice_142 interrompt la boucle et passe à la suite.
Exécution conditionnelle
L'exécution conditionnelle s'écrit :
 if <booléen>:
 <bloc d'instructions>
On peut utiliser les commandes codice_143 "(else if") et codice_144 :
 if <booléen>:
 <bloc d'instructions>
 elif <booléen>:
 <bloc d'instructions>
 else:
 <bloc d'instructions>
Boucle antéconditionnée
La boucle antéconditionnée s'écrit :
 while <booléen>:
 <bloc d'instructions>
Cette boucle peut contenir des instructions codice_141 et codice_142.
Fonction.
La déclaration d'une fonction utilise la commande codice_147. La fonction est un bloc d'instructions. Si elle doit renvoyer des valeurs, on utilise la commande codice_148. Par exemple
def nombres(n):
 """Entrer plusieurs nombres""" # description de la fonction
 foo = [] # initialisation
 for i in range(n):
 foo = foo+[float(input("Entrez un nombre"))]
 return foo
a = nombres(3)
print(a)
La fonction commence par une chaîne de caractères qui la décrit. Cette chaîne peut être récupérée automatiquement par certains logiciels pour faire une documentation automatique. Si la description prend plusieurs lignes, elle commence et finit par trois double-guillemets codice_49 ; en fait, par convention, même si cela n'est pas obligatoire, les descriptions sont toutes encadrées de trois double-guillemets. Cette description est appelée '. Pour récupérer les ' :
def foo():
 """Cette fonction ne fait rien"""
 pass
print(foo.__doc__)
L'instruction codice_150 permet à l'utilisateur de saisir une valeur. La valeur est retournée sous la forme d'une chaîne de caractères qui est ensuite convertie en nombre réel avec l'instruction codice_151.
On peut définir une valeur par défaut en l'indiquant dans l'en-tête de la définition de la fonction, de la manière suivante :
def nombres(n=1): # valeur par défaut : 1
 """Entrer plusieurs nombres"""
 foo = [] # initialisation
 for i in range(n):
 foo = foo+[float(input("Entrez un nombre"))]
 return foo
Si le paramètre à initialiser est de type modifiable "()", comme par exemple une liste, il faut procéder comme suit :
def fooFonction(fooListe=None): # valeur par défaut : n'existe pas
 """Description"""
 if fooListe = None:
 fooListe = [] # initialisation
 <suite des instructions>
Par défaut, les variables sont locales. On peut rendre une variable globale avec l'instruction codice_152 "à l'intérieur de la fonction", avant l'utilisation de la variable. Par exemple :
a = 1
b = 1
def toto():
 """Test de variable globale"""
 global a
 a = 2
 b = 2
toto()
print("a =", a, "; b =", b) # a = 2 ; b = 1
Pour être plus précis : si une variable n'est pas assignée dans une fonction, alors Python va chercher une variable du même nom à l'extérieur de la fonction. Mais à partir du moment où la variable est assignée dans la fonction, elle devient locale "sauf" si l'on a utilisé l'instruction codice_152.
Si l'on s'attend à un nombre indéfini d'arguments, on utilise la notion d'empaquetage/dépaquetage "()". L'empaquetage consiste à mettre les arguments dans un n-uplet, le dépaquetage consiste à développer un n-uplet en plusieurs variables. Cela se fait en mettant un astérisque "()" « codice_154 » devant le nom de la variable. Par convention, on utilise le nom de variable codice_155 mais cela n'est pas obligatoire.
def concatenation(*args):
 """Concatène des chaînes de caractères"""
 resultat = ""
 for i in args:
 resultat = resultat + i
 return resultat
concatenation("a", "foo", "toto") # 'afoototo'
À l'inverse, si une fonction doit recevoir plusieurs paramètres, on peut à la place lui transmettre une liste à dépaqueter :
def addition(a, b):
 """Ajoute deux nombres"""
 return a+b
arg = (1, 2)
addition(*arg) # 3
On peut aussi empaqueter/dépaqueter un dictionnaire, on utilise pour cela deux astérisques « codice_156 ». Par convention, on utilise le nom codice_157 sans que cela ne soit obligatoire.
L'instruction codice_158 permet de créer de petites fonctions ne contenant pas de boucle ni de branchement conditionnel. Cependant, si la déclaration est courte et compacte, le code n'est pas toujours facilement lisible ; l'utilisation de cette instruction n'est pas recommandé.
Par exemple l'expression
f = lambda x: 2*x
est la même chose que
def f(x):
 return 2*x
Gestion des erreurs.
Dans un bloc d'instructions, on peut utiliser la structure codice_159. Le bloc après codice_160 est exécuté ; si une erreur se déclare dans ce bloc, alors le bloc codice_161 s'exécute. Par exemple
try:
 1/0 # Génère une erreur
except:
 print("Division par zéro") # Cette instruction est donc exécutée
On peut compléter avec codice_162 et codice_163 :
try:
 codice_164 : le nom de variable n'existe pas ;
On peut aussi créer ses propres erreurs : si une situation erronée survient, on peut « lever » une exception avec codice_168. Par exemple
if a < 0:
 raise ValueError("La valeur doit être positive")
Exercices.
Calcul du PGCD et du PPCM par l'algorithme d'Euclide.
Écrire un programme Python qui demande deux nombres entiers et affiche leurs PGCD et PPCM. Le programme utilisera l'algorithme d'Euclide.
"""Programme : euclide.py
Auteur : User:cdang
date : 2019-02-19
dates de modification : 
version de Python : 3
module requis : aucun
Objectif : calcule le PGCD et le PPCM de deux nombres entiers.
Entrée
 au clavier, saisie de deux nombres entiers.
Sorties
 à l'écran, affichage du PGCD et du PPCM.
def euclide():
 """Calcule le PGCD et le PPCM avec l'algorithme d'Elclide
 Entrée
 Aucune, la saisie des paramètres fait partie de la fonction
 Sortie
 affichage du PGCD et du PPCM