NSI 1ère

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 :

  1. x=2
  2. nom="boa"
  3. 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 :

  1. print("Bonjour tout le monde ! ")
  2. print(4*3)
  3. v=50
  4. 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 :

  1. reponse=input("Quel jour sommes-nous? ")
  2. 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:
  1. reponse=input("Ecrire une valeur numérique :")
  2. valeur=float(reponse)#convertit la variable 'reponse'en un nombre à virgule et l'affecte à la variable 'valeur'
  3. print("reponse:",reponse,"valeur:",valeur)#'reponse' et 'valeur' s'affichent de la même façon
  4. print("type de reponse:",type(reponse))#mais 'reponse'est une chaine de caractères (str)
  5. 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 :
  1. 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
  1. 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

  1. x=2+2==5
  2. 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:

  1. mot="anticonstitutionnellement"
  2. print(len(mot))
  3. 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:

  1. mot=input("écrire un mot d'au moins 5 lettres : ")
  2. if len(mot)<5:
  3.     print("le mot",mot,"est trop court") # cette ligne et la suivante sont exécutées si le mot a moins de 5 lettres
  4.     mot=mot*5 # le mot est remplacé par 5 copies de lui-même mises bout à bout
  5. 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:

  1. mot=input("écrire un mot d'au moins 5 lettres : ")
  2. if len(mot)<5:
  3.     print("le mot",mot,"est trop court")#exécuté si le mot a moins de 5 lettres
  4. else:
  5.     print("le mot",mot,"est assez long")#exécuté sinon
  6. 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:

  1. mot=input("écrire un mot de 5 lettres : ")
  2. if len(mot)<5:
  3.     print("le mot",mot,"est trop court")#exécuté si le mot a moins de 5 lettres
  4. elif len(mot)>5:
  5.     print("le mot",mot,"est trop long")#exécuté si le mot a plus de 5 lettres
  6. else:
  7.     print("le mot",mot,"a bien 5 lettres")#exécuté dans les cas restants (donc si le mot a 5 lettres)
  8. 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

  1. valeur=1 #  initialisation
  2. while valeur<10000: #  condition d'exécution de la boucle
  3.      print(valeur)   #instruction du corps de la boucle
  4.      valeur=valeur*4  #instruction du corps de la boucle

Ce programme cherche le premier multiple de 7 supérieur ou égal à 5555 :
  1. n=5555 #initialisation
  2. while n%7!=0:#condition d'exécution de la boucle
  3.     print(n,"n'est pas un multiple de 7")  #instruction du corps de la boucle
  4.     n=n+1 #instruction du corps de la boucle
  5. 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 :
  1. mot='' #initialisation avec un mot de longueur inférieure à 5, pour que la boucle démarre
  2. while len(mot)<5: #condition d'exécution de la boucle
  3.     mot=input("Ecrire un mot d'au moins 5 lettres : ")
  4. 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:
  1. compteur=0
  2. while compteur<10:
  3.     [instructions...]
  4.     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
  1. for i in range(10):
  2.     [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 :

  1. chaine="abracadabra"
  2. for c in chaine:
  3.     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

  1. for i in range(3):
  2.     i=i+3
  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:
  1. def logo():
  2.     print('@    @    @@@@@     @')
  3.     print('@@   @   @          @')
  4.     print('@ @  @    @@@@@     @')
  5.     print('@  @ @         @    @')
  6.     print('@   @@         @    @')
  7.     print('@    @    @@@@@     @\n')
  8. for i in range(3):
  9.     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:
  1. def repete(texte,nombre):
  2.     for i in range(nombre):
  3.         print(texte)
  4. 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:

  1. def factorielle(nombre):
  2.     resultat=1
  3.     while nombre>1:
  4.         resultat=resultat*nombre
  5.         nombre=nombre-1
  6.     return resultat
  7. x=factorielle(4)
  8. print(x)
  9. print(factorielle(6))
  10. 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 :

  1. def factorielle(nombre):
  2.     resultat=1
  3.     while nombre>1:
  4.         resultat=resultat*nombre
  5.         nombre=nombre-1
  6.     return resultat
  7. resultat=50
  8. print(factorielle(6))
  9. 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.