Programmation - notions de base
Conseils préalables :
Recopier et exécuter les morceaux de code donnés en exemple, ne pas hésiter ensuite à faire des essais en les modifiant. Pendant la phase d'apprentissage d'un langage, enregistrer tous les programmes réalisés, cela peut faire gagner du temps plus tard. Eviter d'effacer du code qui marche, créer plutôt une nouvelle version du programme.
Variables, affectations, types
L'information traitée par les programmes informatiques est mémorisée sous forme de variables . Une variable est constituée d'un nom (choisi par le programmeur) et d'une valeur associée.
En Python les noms de variable peuvent contenir des lettres (majuscules ou minuscules) de 'a' à 'z', des chiffres (mais jamais en première position), et le caractère _ (underscore, "tiret du 8"). Il est évidemment interdit d'utiliser comme nom de variable un des mots-clés du langage.
Il est préférable de ne pas commencer un nom de variable par une majuscule.
L'affectation d'une valeur à une variable se fait à l'aide du signe =
Exemples :
- x=2
- nom="boa"
- nombre=2.6
Ces trois variables sont de types différents.
La variable
x contient une valeur numérique entière : elle est de type
int (pour "integer").
La variable
nom contient du texte (à écrire entre guillemets doubles ou simples, au choix) : elle est de type
str (pour "string", chaîne de caractères)
La variable
nombre est une valeur numérique qui s'écrit avec une virgule: elle est de type
float (pour 'nombre codé en virgule flottante', en abrégé 'flottant').
Certains langages de programmation obligent le programmeur à déclarer lui-même le type de chaque variable. En Python cependant, le type d'une variable est attribué automatiquement pendant l'exécution du programme en fonction du type de la valeur affectée à cette variable. On parle de typage dynamique . Au cours de l'exécution d'un même programme, un même nom de variable peut être utilisé successivement pour des types différents.
L'instruction type() permet si nécessaire de déterminer le type d'une variable.
Exemple (en mode interactif):
Ecrire dans la console
>> x=4
puis
>>> type(x)
La réponse est < class 'int'> : l'attribution d'une valeur entière à la variable
x en a fait un int.
Ecrire maintenant :
>>> x=8/2
>>> type(x)
La réponse est maintenant < class 'float'> : le type float a été attribué à
x pour lui permettre de contenir le résultat d'une division, qui pourrait ne pas être un entier.
Entrées/Sorties
Les processus d'entrée et de sortie permettent l'échange d'information entre d'une part la machine et le programme qui tourne dessus, et d'autre part le monde extérieur, au sens large : utilisateur, fichiers, périphériques. Le point de vue adopté est celui de la machine : on parle d'
entrée quand l'information circule de l'extérieur vers la machine (exemple : l'utilisateur saisit un mot à l'aide du clavier) et de
sortie quand elle circule dans l'autre sens.
Dans un premier temps nous nous limiterons aux échanges d'information entre le programme et l'utilisateur via la
console d'entrée/sortie de l'environnement de développement intégré.
Sortie
L'instruction print() permet d'afficher un résultat sur la console. Les parenthèses peuvent contenir une valeur (nombre ou texte), un nom de variable,une opération.... ou plusieurs de ces éléments, séparés par des virgules (ils apparaîtront alors les uns à la suite des autres, séparés par des espaces).
Exemple :
- print("Bonjour tout le monde ! ")
- print(4*3)
- v=50
- print("la valeur de la variable v est",v)
Entrée
L'instruction input() permet de récupérer une valeur écrite par l'utilisateur sur la console. Les parenthèses peuvent contenir un message pour l'utilisateur (facultatif mais conseillé!).
Lors de l'exécution de la commande input , le message pour l'utilisateur est affiché dans la console et le programme s'arrête jusqu'à ce que l'utilisateur ait donné sa réponse dans la console, en la validant à l'aide de la touche Entrée
Exemple à tester :
- reponse=input("Quel jour sommes-nous? ")
- print("Nous sommes",reponse)
Attention: la valeur renvoyée par input est toujours de type chaîne de caractère (str) même si l'utilisateur a écrit un nombre dans la console.
Si on souhaite obtenir une valeur numérique de l'utilisateur, il faudra convertir le résultat de input en utilisant soit float() pour obtenir un nombre en virgule flottante, ou int() pour obtenir un entier.
Exemple:
- reponse=input("Ecrire une valeur numérique :")
- valeur=float(reponse)#convertit la variable 'reponse'en un nombre à virgule et l'affecte à la variable 'valeur'
- print("reponse:",reponse,"valeur:",valeur)#'reponse' et 'valeur' s'affichent de la même façon
- print("type de reponse:",type(reponse))#mais 'reponse'est une chaine de caractères (str)
- print("type de valeur:",type(valeur))#tandis que 'valeur' est un nombre à virgule (float)
Il est possible, et même recommandé, d'enchaîner les instructions :
- valeur=float(input("Ecrire une valeur numérique :"))#pour obtenir une valeur numérique de type float
On évite ainsi la création d'une variable intermédiaire de type str, souvent inutile.
Opérateurs arithmétiques
Opérations usuelles :
- + addition
- - soustraction
- * multiplication
- / division
- // valeur entière arrondie par défaut du résultat de la division (entre des naturels, équivaut à la division euclidienne)
- % (modulo) : reste de la division //
- ** élévation à la puissance (x ** y donne xy)
Opérateurs de comparaison
- égalité == et inégalité !=
- strictement inférieur < , inférieur ou égal <=
- strictement supérieur > , supérieur ou égal >=
- identité is
Les opérateurs
== et
is sont souvent équivalents, mais pas toujours.
Variables et opérateurs logiques
Valeurs et variables logique
L'écriture de comparaisons amène naturellement à se poser la question "Est-elle vraie ou fausse?", ce qui conduit à la notion de valeur logique
Tester par exemple le code
- print(3 < 4)
Le résultat affiché est True , avec une majuscule. C'est le mot-clé Python pour désigner la valeur logique de 3 < 4 : en effet cette expression est vraie (true).
Il n'existe que deux valeurs logiques : True et False.
Une valeur logique peut tout à fait être affectée à une variable, que l'on qualifie alors de variable logique, ou booléenne (type Python bool ) .
Exemple
- x=2+2==5
- print("le type de x est",type(x),"et sa valeur est",x)
Dans cet exemple la ligne 1 affecte à la variable
x la valeur de l'expression
2+2==5 , qui est une valeur logique valant
False (c'est faux). Le type de
x est donc
bool(booléen) et sa valeur
False.
Opérateurs logiques
Python propose trois opérateurs logiques:
- l'inverseur not qui inverse la valeur logique ( not True donne False et not False donne True )
- l'opérateur binaire and qui donne un résultat vrai (True) ssi ses opérandes sont tous deux vrais
- l'opérateur binaire or qui donne un résultat vrai (True) si l'un au moins de ses opérandes est vrai.
Les valeurs (et les variables) logiques peuvent également être comparées entre elles. Sans surprise,
True==False vaut
False . Python considère aussi que
True > False vaut
True
Opérations sur chaînes
Les chaînes de caractères supportent un certain nombre des opérateurs décrits ci-dessus
L'opérateur + entre deux chaînes, met leurs contenus bout à bout dans une nouvelle chaîne.
On peut également multiplier une chaîne c par un entier n (type int): n*c produit une nouvelle chaîne contenant n répétitions de la chaîne c .
Des chaînes peuvent être comparées entre elles avec les opérateurs de comparaison vu ci-dessus. La comparaison s'effectue caractère par caractère à partir du premier, par ordre lexicographique :
- les lettres sont comparées par ordre alphabétique, avec les majuscules avant les minuscules.
- les chiffres sont comparés par ordre croissant, et précèdent les lettres.
Il est également possible d'obtenir le nombre de caractères dans une chaîne avec l'instruction len() et de déterminer si la chaîne contient une sous-chaîne donnée en utilisant l'opérateur in , qui renvoie une valeur logique.
Exemple:
- mot="anticonstitutionnellement"
- print(len(mot))
- print("tuti" in mot)
Branchements conditionnels
Un branchement conditionnel permet qu'une série d'instructions, regroupées dans un bloc d'instructions, ne soit exécutée que sous certaines conditions. Les instructions Python qui permettent les branchements conditionnels sont if , if..else et if..elif.. ou if...elif...else
Une condition n'est autre qu'une variable logique, puisqu'elle doit pouvoir être vraie, ou fausse.
Blocs d'instructions
En Python un bloc d'instructions est signalé par
indentation: Les lignes qui composent un bloc d'instructionq doivent toutes être décalées vers la droite par le même nombre d'espaces (de préférence, 4 espaces).
Des blocs peuvent être imbriqués les uns dans les autres.
La ligne d'instruction qui précède un bloc d'instructions se termine par :
.
Instruction if
La syntaxe de l'instruction if est de la forme:
if variable logique(condition) :
bloc d'instructions à exécuter
si la condition est vraie
....
suite du programme (exécutée dans tous les cas)
Remarquer les
: à ne pas oublier à la fin de la ligne du
if .
Par exemple:
- mot=input("écrire un mot d'au moins 5 lettres : ")
- if len(mot)<5:
- print("le mot",mot,"est trop court") # cette ligne et la suivante sont exécutées si le mot a moins de 5 lettres
- mot=mot*5 # le mot est remplacé par 5 copies de lui-même mises bout à bout
- print("le mot",mot,"est assez long")
Instruction if ... else...
Le mot-clé
else permet d'introduire un bloc d'instructions alternatives à exécuter si la condition est fausse.
La syntaxe de l'instruction if...else est de la forme:
if variable logique(condition) :
bloc d'instructions à exécuter
si la condition est vraie
....
else:
bloc d'instructions à exécuter
si la condition est fausse
....
suite du programme (exécutée dans tous les cas)
Attention :
else doit être suivi de
:
Par exemple:
- mot=input("écrire un mot d'au moins 5 lettres : ")
- if len(mot)<5:
- print("le mot",mot,"est trop court")#exécuté si le mot a moins de 5 lettres
- else:
- print("le mot",mot,"est assez long")#exécuté sinon
- print("et maintenant, la suite du programme")#exécuté dans tous les cas
Instruction if...elif...
Lorsqu'on souhaite tester successivement plusieurs conditions, on peut utiliser elif .
La syntaxe de l'instruction if...else est de la forme:
if condition 1 :
bloc d'instructions à exécuter
si la condition 1 est vraie
....
elif condition 2 :
bloc d'instructions à exécuter
si la condition 1 est fausse et la condition 2 vraie
....
suite du programme (exécutée dans tous les cas)
Il est tout à fait possible d'utiliser plusieurs elif...: à la suite, ainsi que de faire suivre un ou plusieurs elif...: un else
Par exemple:
- mot=input("écrire un mot de 5 lettres : ")
- if len(mot)<5:
- print("le mot",mot,"est trop court")#exécuté si le mot a moins de 5 lettres
- elif len(mot)>5:
- print("le mot",mot,"est trop long")#exécuté si le mot a plus de 5 lettres
- else:
- print("le mot",mot,"a bien 5 lettres")#exécuté dans les cas restants (donc si le mot a 5 lettres)
- print("et maintenant, la suite du programme")
Notion de boucle
En programmation impérative, les instructions contenues dans un programme sont effectuées dans l'ordre dans lequel elles sont rencontrées (flot d'exécution). Les instructions de branchement conditionnel (if...) rencontrées précédemment, offrent une première possibilité de contrôle de ce flot, en l'envoyant dans une direction ou une autre. Il est également possible de revenir en arrière dans le flot, pour répéter une séquence d'instructions. On parle alors de
boucles .
Il existe deux types de boucle, les boucles "non bornées" et les boucles "bornées". Elles sont plus couramment qualifiées de "boucle while" (boucle "tant que") pour les non-bornées, et "boucle for" pour les boucles bornées, "while" et "for" étant les mots-clés les plus utilisés pour programmer ces deux types de boucles dans la majorité des langages évolués.
Il est important lorsqu'on programme une boucle, de savoir quand le programme va en sortir... en effet une boucle qui tourne indéfiniment est un problème ! Les deux types de boucles, bornée ou non bornée, correspondent à deux manières différentes de déterminer le moment de sortir de la boucle. On parle de boucle "bornée" lorsque le nombre d'exécutions (nombre d'itérations) de la boucle est fixé avant même l'entrée dans la boucle, et "non bornée" dans le cas contraire.
Boucle non bornée (while)
Le mot-clé
while (tant que) doit être suivi d'une condition (variable logique) et du sugne
: . Le bloc d'instruction indenté qui suit sera exécuté tant que la condition est vraie.
Syntaxe :
while condition :
instructions à exécuter
tant que la condition est vraie
....
suite du programme (exécutée dans tous les cas)
Exemples:
Ce programme calcule et affiche toutes les puissances de 4 inférieures à 10000
- valeur=1 # initialisation
- while valeur<10000: # condition d'exécution de la boucle
- print(valeur) #instruction du corps de la boucle
- valeur=valeur*4 #instruction du corps de la boucle
Ce programme cherche le premier multiple de 7 supérieur ou égal à 5555 :
- n=5555 #initialisation
- while n%7!=0:#condition d'exécution de la boucle
- print(n,"n'est pas un multiple de 7") #instruction du corps de la boucle
- n=n+1 #instruction du corps de la boucle
- print(n,"est un multiple de 7") #la boucle est terminée : n est donc un multiple de 7
Ce programme demande un mot à l'utilisateur, tant que la longueur du mot est inférieure à 5 :
- mot='' #initialisation avec un mot de longueur inférieure à 5, pour que la boucle démarre
- while len(mot)<5: #condition d'exécution de la boucle
- mot=input("Ecrire un mot d'au moins 5 lettres : ")
- print("Enfin! Ce n'était pourtant pas si difficile ! "#le programme est sorti de la boucle, cela montre que l'utilisateur a donné un mot de plus de 5 lettres
Points importants pour écrire une boucle while :
- Bien formuler la condition d'exécution: elle doit pouvoir être vérifiée ou non (variable logique), elle doit permettre d'obtenir ce que l'on veut.
- S'assurer que la condition d'exécution est initialement vérifiée, pour que le programme puisse rentrer dans la boucle. Au besoin, effectuer une initialisation.
- S'assurer qu'au moins une des instruction de la boucle pourra permettre que la condition ne soit plus vérifiée... sinon, boucle infinie assurée!
Boucle bornée (for)
Une boucle est dite bornée quand le nombre d'itérations est déterminé, avant même la première itération. On peut obtenir une telle boucle en utilisant l'instruction while associée à une variable servant de compteur, selon l'exemple ci-dessous:
- compteur=0
- while compteur<10:
- [instructions...]
- compteur=compteur+1
Dans cet exemple le nombre d'itérations est prédéterminé (il est égal à 10).
Le même résultat peut être obtenu de manière plus compacte en utilisant une instruction for
En Python on obtiendra 10 itérations, avec l'instruction
for, en écrivant
- for i in range(10):
- [instructions...]
L'instruction
range crée une séquence de valeurs, que la variable de contrôle de la boucle(ici
i) va prendre successivement, chaque valeur correspondant à une itération de la boucle.
range(10) donne ainsi la série de valeurs, ou séquence, 0,1,2....9, soit 10 valeurs différentes (10 itérations de la boucle introduite par
for i in range(10))
Les différentes syntaxes possibles de range sont :
range(vmax) avec vmax > 0 produit toutes les valeurs de 0 inclus à vmax exclue, soit vmax valeurs.
range(vmin,vmax) avec vmax > vmin produit toutes les valeurs de vmin (inclus) à vmax(exclue), soit vmax-vmin valeurs.
range(vdebut,vfin,dv) produit toutes les valeurs de vdebut inclus à vfin exclu, par pas de dv. Il est possible d'avoir vfin < vdebut, si dv<0.
for...in peut être utilisé pour parcourir d'autres séquences de valeurs que celles créées par l'instruction range. Par exemple une chaîne de caractères peut être parcourue ainsi :
- chaine="abracadabra"
- for c in chaine:
- print(c)
La variable de contrôle de boucle peut être lue et même modifiée à l'intérieur de la boucle, sans que cela n'ait aucun effet sur la suite de valeurs prévue ni le nombre d'itérations. Par exemple
- for i in range(3):
- i=i+3
- print(i)
affiche les valeurs 3,4, et 5. Cela montre bien que, malgré la modification de la valeur de
i dans la boucle,
i prend bien, au début de chacune des itérations de la boucle, successivement chacune des valeurs (0,1, et 2) imposées par l'instruction
for i in range(3):.
Fonctions
Définition d'une fonction
Devoir faire appel plusieurs fois à la même série d'instructions est une situation fréquente en programmation. Créer un sous-programme revient à extraire un tel groupe d'instructions du flot normal et à lui donner un nom, ou une référence, de manière à pouvoir l'appeler en cas de besoin. Pour créer un sous-programme (appelé fonction) en Python, on utilise le mot clé def.
Exemple:
- def logo():
- print('@ @ @@@@@ @')
- print('@@ @ @ @')
- print('@ @ @ @@@@@ @')
- print('@ @ @ @ @')
- print('@ @@ @ @')
- print('@ @ @@@@@ @\n')
- for i in range(3):
- logo()
Cette exemple définit entre les lignes 1 à 7 une
fonction appelée ici "logo".
La fonction est ensuite "appelée' (c'est le terme consacré) à la ligne 10. Comme cet appel est à l'intérieur d'une boucle bornée qui effectue 3 itérations, la fonction (dont la mission est de dessiner les lettres "NSI" avec des arobases @) sera ici appelée, et ses instructions effectuées, 3 fois.
En Python la définition d'une fonction commence par le mot-clé def , qu'on fait suivre du nom de la fonction,de parenthèses et de : . Les instructions composant le corps de la fonction doivent être indentées.
Une fois définie, une fonction peut être "appelée", par son nom suivi de parenthèses, n'importe où dans le programme. Les instructions qui constituent le corps de la fonction sont exécutées à chaque appel de la fonction, et seulement à ce moment-là.
Passage de paramètres
Les parenthèses qui suivent le nom de la fonction ont pas un rôle décoratif: elles peuvent servir à fournir à la fonction des informations à utiliser lors de son exécution, sous la forme de "paramètres".
Exemple:
- def repete(texte,nombre):
- for i in range(nombre):
- print(texte)
- repete("hello ",4)
Cet exemple définit dans les lignes 1 à 3 une fonction appelée "répète" affichant plusieurs fois un texte.
Le texte à répéter ainsi que le nombre de répétitions sont indiquées à la fonction sous la forme de deux paramètres, appelés respectivement
texte et
nombre dans la définition de la fonction.
Lors de l'appel de la fonction, les valeurs ou les variables que l'on souhaite faire utiliser à la fonction en guise de "texte" et "nombre", sont indiquées dans les parenthèses, dans le même ordre que celui dans lequel ils figurent dans la définition de la fonction.
Remarque : l'instruction print() abondamment utilisée au cours de cette séquence, est une fonction prédéfinie de Python, prenant en paramètre une séquence de valeurs séparées par des virgules.
Valeur de retour
Une fonction peut non seulement recevoir de l'information du programme qui l'appelle, par l'intermédiaire de ses paramètres: elle peut aussi lui en renvoyer, sous forme d'une
valeur de retour. Par exemple, l'instruction
len() rencontrée précédemment est une fonction prenant un paramètre (par exemple une chaîne de caractères) et renvoyant un nombre entier si Python peut attribuer une longueur à ce paramètre.
Lors de l'appel de la fonction, après son exécution, la valeur retournée par la fonction prend la place de l'appel de la fonction.
Dans le corps de la fonction, une valeur de retour est annoncée par le mot-clé return.
Exemple:
- def factorielle(nombre):
- resultat=1
- while nombre>1:
- resultat=resultat*nombre
- nombre=nombre-1
- return resultat
- x=factorielle(4)
- print(x)
- print(factorielle(6))
- y=factorielle(2)+factorielle(3)
Cet exemple définit une fonction calculant et retournant la
factorielle de son paramètre. Le corps de la fonction se termine ligne 6 par l'instruction de retourner le résultat du calcul, contenu dans la variable
resultat.
Les lignes 8,10 et 11 montrent différentes façons de récupérer et d'utiliser la valeur de retour de la fonction, obtenue lors de son appel :
A la ligne 8, cette valeur de retour est affectée à une variable x (qui est ensuite affichée à la ligne 9).
A la ligne 10, la valeur de retour est directement passée en paramètre à la fonction print , ce qui a pour effet de l'afficher.
A la ligne 11, deux valeurs de retour sont utilisées comme opérandes dans un calcul.
Portée des variables
Après avoir relancé l'interpréteur Python pour réinitialiser les variables, copier l'exemple de la fonction factorielle donné ci-avant, et ajouter après la ligne 10 (
print(factorielle(6))) la ligne
print(resultat). Exécuter le programme. On obtient un message d'erreur indiquant que le nom 'resultat' est indéfini. Les lignes d'instructions de la fonction factorielle, où la variable résultat est définie, ont pourtant bien été exécutées sans problème lors de l'appel
factorielle(6). Mais les variables créées à l'intérieur d'une fonction sont inaccessibles depuis l'extérieur.
On dit que la portée de ces variables est limitée à la fonction, ou encore qu'elles sont locales à cette fonction. L'intérêt de cette notion est d'éviter les conflits ou les confusions dus à des identités de noms. Elle rend possible la réutilisation locale de noms déjà utilisés ailleurs dans le programme.
Exemple :
- def factorielle(nombre):
- resultat=1
- while nombre>1:
- resultat=resultat*nombre
- nombre=nombre-1
- return resultat
- resultat=50
- print(factorielle(6))
- print(resultat)
L'exécution de ce code n'entraîne cette fois pas d'erreur car une variable
resultat est définie à l'extérieur de la fonction (on dit qu'elle est définie
globalement). On constate que la valeur de cette variable n'a pas été modifiée lors de l'exécution de la fonction par l'appel
factorielle(6): elle vaut 50 avant et après l'appel de la fonction. La variable globale
resultat est donc différente de la variable
resultat locale à la fonction.