Pendant l’exécution d’un programme, les données que ce dernier manipule sont stockées en mémoire centrale.
En nommant ces données, on peut les manipuler beaucoup plus facilement. Les variables nous permettent donc
de manipuler ces données sans avoir à se préoccuper de l’adresse explicite qu’elles occuperont effectivement
en mémoire. Pour cela, il suffit de leur choisir un nom ou identificateur.
L’interpréteur est un programme qui traduit les lignes de code en langage Python en un langage directement
compréhensible par l'ordinateur : le langage machine.
L'interpréteur s’occupe d’attribuer une adresse à chaque variable et de superviser tous les éventuels futurs changements d’adresse.
Une variable peut-être assimilée à une boîte aux lettres portant un nom.
Par exemple, on veut stocker le nombre 5 dans une variable notée x. Nous avons noté en pseudo-code ceci :
Ceci signifie : « à l’adresse mémoire référencée par x - autrement dit, dans la boîte aux lettres dénommée x -, se trouve la valeur 5 ». Nous utilisons plus fréquemment l’abus de langage « la variable x vaut 5 ».
En langage Python, l'affectation sera notée à l'aide du symbole égal : =. On note ainsi l'affectation de 5 à x :
x = 5
L'instruction (en mode console) de cette affectation s'écrit donc :
>>>x = 5
Attention ! cette instruction n'a pas la même signification qu'en mathématiques. Il s'agit d'une affectation et non pas un symbole d'égalité. Ainsi, l'instruction
>>>x = x+1
est très fréquente en informatique en revanche,
elle est inacceptable en mathématiques.
Sous Python, on peut affecter une valeur à plusieurs variables simultanément :
>>>a=b=2
>>>a
2
>>>b
2
>>>
La fonction print
permet d'afficher dans la console les éléments mis entre parenthèses.
>>>print("Salut tout le monde !")
Salut tout le monde !
La fonction print peut prendre plusieurs arguments séparés par une virgule ,
.
>>>a=25
>>>print("Cette année, Noël sera le",a,"décembre 2020 !")
Cette année, Noël sera le 25 décembre 2020 !
Vous avez dû remarquer avec l'exemple prédécent qu'à l'exécution, un espace ' '
ou " "
est automatiquement ajouté entre chaque
argument de la fonction print.
Ce comportement peut être modifié par l'ajout d'un argument identifié par le nom sep
, de type chaîne de caractères (str
en Python),
de la façon suivante :
>>>val=3.14159
>>>print("Mots",'et','valeur',val,"à afficher.",sep="_")
Mots_et_valeur_3.14159_à afficher.
Le chaîne de caractères \n
sert à passer à la ligne lors de l'affichage.
Ainsi, dans l'utilisation suivante, les arguments affichés sont placés les uns en dessous des autres :
>>>val=3.14159
>>>print("Mots",'et','valeur',val,"à afficher.",sep="\n")
Mots
et
valeur
3.14159
à afficher.
La fonction input
permet d'obtenir une saisie depuis le clavier.
annee=input("Quelle année sommes-nous ?")
type(annee)
print("L'an 2050 est dans",2050-annee,"ans.")
Pourquoi cet affichage ?
Attention ! La fonction input
renvoie toujours une chaîne de caractères (son type est bien str
)
même si un nombre (entier ou réel) a été saisi. Pour pouvoir utiliser le renvoi dans un calcul, il est parfois nécessaire de changer son typage
à l'aide des fonctions int
ou float
qui permettent de transformer respectivement une chaîne de caractères correspondant à un nombre
en nombre entier ou nombre réel (un flottant pour être précis).
annee=int(input("Quelle année sommes-nous ?"))
type(annee)
print("L'an 2050 est dans",2050-annee,"ans.")
Pourquoi cet affichage ?
>>>input("Quelle année sommes-nous !")
Salut tout le monde !
En informatiques, les fonctions servent à mieux structurer votre code. Par exemple, elles permettent d'éviter de répéter plusieurs fois des portions de codes identiques. Ainsi, une fonction peut être vu comme un «petit» programme :
En Python, une fonction peut s'écrire en suivant toujours le même formalisme :
def
,:
return
suivi de ce que renvoie la fonction (ou None
si la fonction ne retourne rien).
Attention, cette ligne est indentée également et marque la fin de la fonction.Voici visuellement la structure d'une fonction en Python :
def nomFonction(liste des arguments):
blocs des instructions
return résultat
Voici la fonction carrée :
def carree(a: float) -> float:
return a**2 # renvoie l'image de a par la fonction carree
**
. Exemple : 5**2
correspond à 5^2.
#
apparaîtra à maintes reprises. Il marque le début d’un commentaire que la fin de la ligne termine.
Autrement dit, un commentaire est une information aidant à la compréhension du programme mais n’en faisant pas partie.Une fonction est utilisée comme une instruction quelconque. Un appel de fonction est constitué du nom de la fonction suivi entre parenthèses des valeurs des paramètres d'entrée. Cet appel peut être fait :
>>>carree(3)
9
def carree(a):
return a**2 # renvoie l'image de a par la fonction carree
a = carree(3) # a stocke la valeur 9
b = a - carree(2) # b stocke la valeur 5
La notion de fonction en informatique relève du même concept qu'une fonction mathématique, c'est-à-dire qu'on définit une fonction puis on l'applique à différentes valeurs.
Vous remarquerez le symbole :
très important en Python qui marque le début d'un bloc en dessous.
C'est l'indentation qui délimite le bloc d'instructions.
La fonction se termine avec une instruction return
. Ce qui suit le return
est l'image des entrées par la fonction.
Dès que la fonction rencontre un return
, elle renvoie ce qui suit le return
et stoppe son exécution.
Lorsqu'on définit la fonction carree()
, a
est appelé paramètre de la fonction.
Lorsqu'on appelle la fonction avec une valeur explicite pour a, comme dans carree(3)
, on dira plutôt que 3 est
un argument de
la fonction. Ainsi, en appelant la fonction carree()
d'argument 3, on obtient 9.
Le langage Python est plus aisé pour démarrer la programmation pour la concision des codes écrits et pour la gestion automatique du typage par l'interpréteur. Cependant, le but est que vous puissiez à terme être capable de faire basculer vos compétences acquises en NSI sur Python vers d'autres langages de programmation.
Comme la plupart des langages de programmation nécessitent la spécification du typage des variables, à terme, on vous demandera d'écrire en Python, une fonction en précisant le type de chaque antrée et sortie en suivant le même formalisme ci-dessous :
def nomFonction(liste des arguments: type) -> typeRetour:
blocs des instructions
return résultat
La convention PEP8 donne l'habitude de nommer les fonctions (comme les variables) avec des lettres minuscules et des tirets bas (celui du "8") _
.
Pour clarifier la fonction, il est conseillé d'utiliser un verbe dans son nom (obtenir, donner, get, set, ...).
Il est important de documenter vos fonctions, c'est-à-dire de décrire en quelques phrases le rôle de la fonction, de donner des informations sur la fonction, le lien entre les entrées et la sortie.
Pour cela, juste en dessous de la première ligne définissant la fonction, il suffit de mettre ses informations entre """
et """
;
c'est ce que l'on appelle en franglais le docstring de la fonction). En reprenant l'exemple précédent (sans le typage),
on peut écrire :
def carree(a):
"""
Fonction permettant de renvoyer le carré du nombre a qui est en paramètre
"""
return a**2 # renvoie l'image de a par la fonction carree
L'intérêt de l'auto-documentation d'une fonction par un texte est double :
help(nom de la fonction)
,
Python affiche le docstring de la fonction ce qui nous permet d'avoir des informations sur la fonction en cas d'oubli.
>>> help(carree)
Help on function carree in module __main__:
carree(a: float) -> float
Fonction permettant de renvoyer le carré du nombre a qui est en paramètre
>>>
Il faut faire la différence entre les variables utilisé dans le programme (variables globales) et les variables utilisées dans une fonction (variables locales).
Vous allez comprendre cela à l'aide des exemples de l'exercice suivant :
Ecrire les trois fonctions suivantes puis faire des appels avec différentes valeurs de x pour observer les différences entre ces codes :
Ici, ni les types ni la documentation n'ont été écrites afin de faciliter la vision de la différence entre variable locale et variable globale.
x=-101
def carre(x):
x=x**2
return x
x=-101
def carre_2():
x=x**2
return x
x=-101
def carre_3():
global x
x=x**2
return x
Normalement vous avez dû détecter un problème : il y a une fonction qui ne peut pas être interprétée !
Il faut privilégier les variables locales. La première écriture, celle de carre
est la définition à privilégier.
Vous pouvez utiliser des variables globales, comme mais dans carre3
, des cas qu'il faudra bien définir en amont.
En résumé, pour l'instant, pas de variables globales.
Voici le code en Python d'une fonction nommée get_unite
qui prend comme paramètre un nombre entier et qui renvoie son chiffre des unités.
def get_unite(n: int) -> int:
"""
renvoie le chiffre des unités d'un entier n
"""
while n>=10 : # répétition tant que n est supérieur ou égal à 10
n = n-10
return n
Une documentation a été donnée afin d'expliciter le bon usage de la fonction. Mais on ne pas être certain qu'un utilisateur de la fonction respectera les contraintes implicites ou explicites de la documentation et du typage. Voici quelques exemples d'appel de la fonction :
>>> get_unite(4567)
7
>>> get_unite(45.67)
5.670000000000002
>>> get_unite(-6)
-6
On voit que l'appel conduit à une réponse à chaque fois, mais que celle-ci ne correspond pas toujours à ce qui est attendu. Pour rendre "robuste" la fonction précédente, on doit vérifier au début de celle-ci certaines contraintes de bon usage que l'on appelle précondition.
Dans l'exemple précédent, ces préconditions sont :
n
est de type entier (par exemple, le programme buggera si une chaîne de caractères est saisie come argument),n
est positif (sinon le résultat renvoyé est la valeur négative saisie).
Pour cela, le langage Python possède l'instruction assert
qui permet un mécanisme d'assertion.
Les deux préconditions précédentes s'ajoutent à la fonction précédente ainsi :
def get_unite(n: int) -> int:
"""
renvoie le chiffre des unités d'un entier n
"""
assert type(n)==int, "vous devez entrer un nombre entier." # "Précondition 1"
assert n>=0, "le nombre étudié doit être positif ou nul." # "Précondition 2"
while n>=10 : # répétition tant que n est supérieur ou égal à 10
n = n-10
return n
Quelques explications :
a==b
renvoie True
si l'égalité "a=b" est vraie (même type et même contenu) et False
sinon,int
est le type "entier". Il existe les types float
pour les flottants, str
pour les chaînes de cractères, ...assert
est suivie :
True
ou False
),,
et d'une phrase en langue naturelle, sous forme d'une chaine de caractères.assert
teste si sa condition. Deux cas possibles :
Voici un fonction nommée diviser
réalisation la division du premier argument par le second.
def diviser(a: float,b: float) ->float:
"""
renvoie le résultat décimal de la division de a par b.
"""
return a/b
Quelle précondition, écrite en langage Python, doit-on rajouter afin d'assurer le bon fonctionnement de la fonction ?
Souvent les fonctions sont appelées au cours de programme ; le type et la qualité du résultat renvoyé est important pour ne pas conduire à un plantage. Des contraintes sur la variable renvoyée sont souvent nécessaires : on les appellent les postconditions.
Reprenons l'exemple précédent :
def get_unite(n: int) -> int:
"""
renvoie le chiffre des unités d'un entier n
"""
while n>=10 : # répétition tant que n est supérieur ou égal à 10
n = n-10
return n
Voici le résultat de quelques appels effectués :
>>> get_unite(4567)
7
>>> get_unite(45.67)
5.670000000000002
>>> get_unite(-6)
-6
Comme le résultat renvoyé doit être un nombre entier compris entre 0 et 9, on va rajouter les postconditions suivantes :
n
est un entier naturel. n
est positif. n
est strictement inférieur à 10
On utilise encore l'instruction assert
, juste avant le return
pour écrire ces postconditions comme montré ci-dessous :
def get_unite(n: int) -> int:
"""
renvoie le chiffre des unités d'un entier n
"""
while n>=10 : # répétition tant que n est supérieur ou égal à 10
n = n-10
assert type(n)==int, "Le nombre renvoyé devrait être un entier." # "Postcondition 1"
assert n>=0, "le nombre renvoyé doit être positif ou nul." # "Postcondition 2"
assert n<10, "le nombre renvoyé doit être inférieur à 10." # "Postcondition 3"
return n
L'indice de Masse Corporel est un nombre réel utilisé en médecine. Sa formule est pour une masse en kilos et une taille en mètres : IMC = masse/taille^2.
Écrire en langage Python un programme qui :
dire_bonjour
ayant comme paramètre un mot qui affiche bonjour suivi du mot. dire_bonjour("Paul")
affiche "Bonjour Paul !"
.
Écrire une fonction appelée echanger
qui échange les valeurs de deux arguments a et b.
Par exemple, echanger("mot",12)
renvoie (12,"mot")
.
La possibilité de stocker un entier dans une variable stockant initialement une chaîne de caractères est possible en Python car c'est un langage non typé : l'interpréteur gère automatiquement le typage. Attention ! Dans beaucoup d'autres langages de programmation, cela n'est pas possible.
Documenter la fonction suivante en ajoutant un docstring.
def examen(x,y,z,t):
m=(2*x+2*y+z+t)/6
if m>=10:
print("Le candidat est reçu")
else :
print("le candidat est refusé")
return None
Proposer des préconditions écrites sur les variables x
, y
, z
et t
en utilisant l'instruction assert
qui assurent le bon usage de cette fonction examen
.
Voici une fonction cherche_lettre
qui affiche si le caractère lettre
est présent ou non dans le nom saisi nom
,
tout deux entrés comme paramètre de la fonction :
def cherche_lettre(nom,lettre):
if lettre in nom:
print(lettre," est dans le nom ",nom)
else:
print(lettre,"n' est pas dans le nom ",nom)
return None
nom
et lettre
en utilisant l'instruction assert
qui assurent le bon usage de cette fonction cherche_lettre
.
La longueur d'une chaîne de caractères (c'est-à-dire le nomnbre de caractères) nommée chaine
en Python
s'obtient avec la commande len(chaine)
.
if
, for
ou while
ainsi que des listes.
Écrire une fonction get_max
qui prend en paramètre une liste et renvoie le max des éléments de celle-ci.
Indications :
[ ]
chaque élément étant séparée d'une virgule ,
.liste
en Python s'obtient avec la commande len(liste)
.
Écrire une fonction div_euclidienne
qui prend en paramètre deux nombres entiers a
et b
,
qui effectue la division euclidienne de a
par b
et qui renvoie le couple (a,i)
, respectivement le reste et le quotient de cette division euclidienne.
Un tel couple est appelé tuple.
a
et b
afin d'assurer le bon usage de la fonction
div_euclidienne
. a
et i
) afin d'assurer le bon usage de la fonction
div_euclidienne
.Réécriture de l'algorithme obtenu à l'exercice 17 du chapitre A1 sous forme d'une fonction
Écrire une fonction get_max_position
qui prend en paramètre une liste
et qui renvoie le couple (le tuple) (PG,IG)
, respectivement la plus grande valeur de la liste
et la position de cette valeur maximale dans la liste.
Indications :
[ ]
chaque élément étant séparée d'une virgule.liste
en Python s'obtient avec la commande len(liste)
len(liste)-1
.liste
positionné à l'index i
est obtenu avec : liste[i]
.IG
afin d'assurer le bon usage de la fonction
get_max_position
.
print
input
assert
assert
À retenir !
def nomFonction(liste des arguments):
blocs des instructions
return résultat
return
qui doit être unique.À maîtriser à terme
""" """
.