Mini-cours de Python

Les bases (I) de Python

Les bases (II) de Python : Fonctions - String - Tableau - Fichier

Tous les langages de programmation traitent :

  1. du stockage des données en mémoire (les variables)
  2. des opérations avec les variables (les opérateurs)
  3. des structures décisionnelles (if)
  4. des structures répétitives (while, for)
  5. de l'appel d'un bloc d'instructions et du renvoi du résultat obtenu dans ce bloc (les fonctions)
  6. des variables contenant des variables (les tableaux)

Hormis JS, ils traitent aussi du stockage des données sur le disque dur (les fichiers).

Pour tester les codes présentés ci-dessous (et ainsi mieux comprendre), n'oubliez d'utiliser l'un des éditeurs présentés précédemment.

Le cours a été écrit pour que vous puissiez, ultérieurement, y retrouver une information rapidement.

Les informations de même nature sont donc regroupées. Toutefois, ce regroupement utilise parfois une notion ou un terme qui sera abordé ou défini un peu plus tard. Il est donc normal que vous ne compreniez pas tout avant d'avoir tout lu. Notez le passage difficile, puis continuez la lecture. Arrivé à la fin, recommencez la lecture, les passages difficiles deviendront plus clairs.

Notes préliminaires

Encodage

Le code (Python) est lui-même encodé ... en UTF-8, ANSI, ...

Quel est le meilleur format d'encodage pour du code écrit en Python ? UTF-8 ou ANSI ?
IA : Le meilleur format d'encodage pour du code Python dépend de vos besoins spécifiques.
Voici les différences entre ANSI (ou Windows-1252) et UTF-8 :

1. **ANSI (Windows-1252)** :
   - Utilise un seul octet (8 bits) pour représenter les caractères.
   - Restreint à un maximum de 256 caractères.
   - Principalement utilisé sur les systèmes Windows.
   - Vous pouvez essayer : `"\\x98".encode("cp1252")`.

2. **UTF-8** :
   - Système d'encodage multi-octets.
   - Peut utiliser de 1 à 6 octets pour représenter un caractère.
   - Capable de représenter une vaste gamme de caractères.
   - Recommandé pour la portabilité et la compatibilité internationale.

En résumé, si vous avez besoin de prendre en charge des caractères non latins
 ou si vous souhaitez une meilleure portabilité, optez pour UTF-8. Sinon, ANSI peut suffire¹².

Source : conversation avec Copilot, 21/06/2024
(1) encode - ANSI encoding in python - Stack Overflow. https://stackoverflow.com/questions/66911975/ansi-encoding-in-python.
(2) Différence entre ANSI et UTF-8 - Nicolas Housset. https://www.nicolas-housset.fr/difference-entre-ansi-et-utf-8/.
(3) Différence entre ANSI et UTF-8 - Les Idées Clis. https://www.ideeclis.fr/2581.html.
(4) character encoding - Unicode, UTF, ASCII, ANSI format differences .... https://stackoverflow.com/questions/700187/unicode-utf-ascii-ansi-format-differences.

L'encodage recommandé est UTF-8.

Surtout, si votre code Python vise à créer, lire ou modifier des fichiers encodés en UTF-8 ... Tels que des fichiers HTML ou JS (souvent codés en UTF-8).

Si votre code Python vise à modifier "massivement" plusieurs fichiers, il vaut mieux que tous les fichiers à modifier utilisent le même encodage ...

Mais, ... si vous codez sous Windows et si vous envisagez de publier votre code sur un site web, alors convertissez-le en ANSI, aussi appelé Windows-1252, (via l'éditeur NotePad++) car le visiteur préférera lire le code que le télécharger. D'autant plus qu'il sait que s'il peut le lire, il lui suffira de faire un copier/coller ...

En effet, si vos visiteurs sont d'Europe occidentale, leur navigateur web décodera un fichier texte avec l'encodage (présupposé) ISO-8859-1 (aussi appelé latin-1). Or, ANSI et ISO-8859-1 sont très proches ...

Différence entre ANSI et ISO-8859-1

Si votre logiciel d'édition est Visual Studio Code (VSC), vous pouvez coder directement en ISO-8859-1.

Seul un fichier au format HTML, dédié au navigateur, peut inclure une instruction indiquant l'exact encodage à utiliser pour décoder (et donc afficher correctement les caractères accentués, spéciaux, ... si l'encodage effectif est celui indiqué dans la balise ...).

En résumé, encodez en UTF-8.

Et, si vous publiez votre code Python,

Indentation et désindentation

Avec VSC, le bloc sélectionné peut être indenté via la touche de tabulation, TAB.
Et, désindenté, via les touches : SHIFT + TAB.

Les commentaires

Un programme peut contenir du texte qui sera ignoré par le programme : les commentaires.

Ils sont très utiles pour faciliter la compréhension du code.

Le commentaire de fin de ligne est indiqué par le caractère : #. Ce qui suit ce caractère ne sera pas exécuté. L'exécution des instructions ne reprendra qu'à la ligne de code suivante.

La première ligne de code devrait indiquer la version et l'encodage. Par exemple :

# Code Python 3.12, encod早 en UTF-8

Le caractère # peut être mis en début de ligne ou après une instruction.

a=1 # la variable a vaut 1
# Le caractère indiquant un commentaire de fin de ligne (#) peut être le premier de la ligne ...
# a=2 # L'instruction (a=2) a été commentée. Donc, la variable a vaut toujours 1 ...
print(a) # affiche 1 à l'écran

Pour le programme, c'est comme si nous avions écrit :

a=1


print(a)

Le commentaire multi-ligne est entouré par ''' ou par """.

r''' Ceci est un commentaire écrit sur plusieurs lignes de code.
Le nombre d'apostrophes ne peut pas être ni inférieur à 3, ni supérieur à 3.
Les trois apostrophes peuvent être précédées ou suivis
 sur la même ligne par une instruction. Bref, ils débutent ou terminent une ligne.'''

r"""
Pour faciliter la lecture du code,
- Des lignes de code peuvent être vides.
- Ce qui suit ou précède les trois apostrophes (ou guillemets) peut être vide.
"""

Depuis la version 3.12, mieux vaut écrire r""" ou r'''.
Pour éviter des SyntaxWarning (notamment si ce commentaire contient les caractères / ou \)

Pour le programme, c'est comme si nous avions écrit :











Commenter son code

Lorsque le code contient des centaines de lignes de code, il devient important de commenter son code pour pouvoir le comprendre des mois plus tard (et pour qu'il soit compréhensible par d'autres développeurs, si le code est publié).

Tant que c'est encore tout chaud dans votre tête, il est recommandé de commenter vos fonctions de la façon suivante :

La notion de "fonction" sera abordé ultérieurement. Lisez ce qui suit sans vous attarder et revenez ici lorsque vous commencerez à coder de nombreuses fonctions.


def getIntPositif(msg,a=1,b=99999999): #----------------------------------------
  
""" Cette fonction demande à l'utilisateur de taper un nombre entier
positif, jusqu'à ce que le nombre soit valide.

Elle est appelée par : ask2ID(), position() et openDB()

:param str msg: label du champ input() message précédant la réponse de l'utilisateur
:param int a: facultatif (vaut alors 1), = limite inférieure comprise
:param int b: facultatif (vaut alors quasi cent millions), = limite supérieure comprise

:return: un nombre entier positif (entre a compris et b compris)
:rtype: int

2021-12-12 16:44:04 """
    if(b<a): print("Erreur dans un appel de getIntPositif(). Passage de paramètres : b<a !")
    while(True):
      re=input(msg)
      if(not re.isdecimal()): continue
      n=int(re)
      if(n<a): continue
      if(n>b): continue
      return n
        

Le commentaire de la fonction, ici sur fond vert-clair, est plus long que le code de la fonction. Et, c'est souvent le cas !

Le commentaire commence sur la première ligne qui suit les deux-points, :, qui terminent la définition de la fonction. Il commence par """ et se termine par """.

Dans ce commentaire, des lignes débutent par  :

  • :param  suivi du nom d'un paramètre (formel), suivi par : (rôle du paramètre, sur une ou plusieurs lignes)
  • :type   suivi du nom d'un paramètre (formel), suivi par : (type du paramètre : <'int'>, <'float'>, <'str'>, <'lst'>, <'tup'>, ... )
  • :return: (ce que retourne la fonction, sur une ou plusieurs lignes)
  • :rtype: (type de retour : <'int'>, <'float'>, <'str'>, <'lst'>, <'tup'>, ... )

Un commentaire utilisant cette syntaxe, très simple, est appelé une docstring et il sera possible de documenter son code de manière professionnelle. Par exemple, sous la forme de pages web.

L'outil qui réalisera cette documentation est issu du projet Sphinx

Certaines "fonctions" ne retournent rien. Une telle fonction peut alors être appelée "procédure" (sub). :return: et :rtype: ne figurent alors pas dans le commentaire.

Certaines "fonctions" ne reçoivent rien. Une telle fonction utilise alors souvent des variables globales. :param et :type ne figurent alors pas dans le commentaire. Une telle façon de coder est toutefois déconseillée. Qui dit fonction, dit paramètre(s).

#---------------------------------------- qui termine la ligne qui commence par def  est facultatif. Cette ligne sert à améliorer la lisibilité du code. Éviter de dépasser 80 caractères sur une ligne de code pour éviter les retours de ligne lors d'une éventuelle impression. Le dernier caractère de cette ligne, -, est donc le 80ème caractère.

Syhinx est le nom d'un programme qui analyse le code source (pour y trouver des docstrings et générer automatiquement une documentation)

D'autres programmes permettent de représenter graphiquement les relations entre les fonctions. Il est alors recommandé de n'écrire qu'un seul nom de fonction par ligne de code et que le nom de la première fonction appelée se nomme "main()".

Point d'entrée du programme

Le code source est lu, ligne par ligne.

Comme les importations, les déclarations de variables globales et de fonctions doivent être faites avant leur utilisation, ipso facto, la fonction main() est la dernière fonction déclarée. Son appel est donc la dernière ligne du code.

Noms

Le nom des variables, des fonctions, des mots-clés, ... sont composés des caractères [a-zA-Z0-9]. Attention, ils sont sensibles à la case, c.-à-d. que, dans un nom, une lettre minuscule ne vaut pas une lettre majuscule.

Toutefois, le premier caractère d'un nom ne peut pas être un chiffre.

Le nom de vos variables et de vos fonctions peut contenir le caractère underscore, _.

# Le nom de toutes les fonctions sont en minuscules : la fonction LEN() n'existe pas (=> erreur)
# Le nom de tous les mots-clés sont en minuscules : IN, NOT, FOR, ... n'existent pas (=> erreur)
# mavariable, MAVARIABLE, maVariable et MaVariable sont 4 noms différents (=> 4 variables différentes).

Évidemment, le caractère qui précède ou suit ces noms ne peut être un caractère ou un chiffre, [a-zA-Z0-9]. Le caractère qui précède ou suit est souvent un espace (recommandé). Toutefois, dans un code condensé, ce caractère peut être =, (, :, [, [, +, -, ...

Le nom d'une variable ne peut plus être attribué ... à une fonction (et inversement).

Les variables

Une variable est une case dans la mémoire de l'ordinateur dont le contenu peut varier au cours de l'exécution du programme (d'où le nom de variable). Elles sont créées lorsqu'elles reçoivent une valeur. Cette opération s'appelle l'affectation. Le signe de l'affectation est le signe égal (=). x=1 se traduit par : "ce qui est à droite du signe d'affectation va dans la case-mémoire identifiée à gauche (appelée, ici, x).

On peut écrire : a=b=c=1. c vaudra 1, puis b vaudra ce que vaut c (c'est-à-dire 1), puis a vaudra ce que b vaut (c.-à-d. 1).

a=b=c=1; print(a);   # affiche 1

En Python, c'est la fin de ligne qui indique la fin de l'instruction. Le point virgule précédant # n'est donc pas nécessaire, mais c'est une bonne habitude de terminer chaque instruction par un point-virgule (comme dans d'autres langages).

L'espace après le point virgule n'est pas nécessaire, mais il ajoute de la lisibilité.

Une suite de caractères doit être entourée par des apostrophes (') ou des guillemets (").

a=b=c="BONJOUR"; print(a);   # affiche : BONJOUR

Une suite de caractères est appelée, en anglais : string. Cette appellation sera reprise dans le reste de ce mini-cours.

On peut affecter à une variable un texte avec son retour de ligne.

x = """Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua."""

Ce qui à gauche du signe d'affectation (=) est un nom de variable.

Le trait bas, appelé aussi trait de soulignement ou blanc souligné, est appelé, en anglais : underscore.
Le nom d'une variable ne peut pas commencer ni par un chiffre, ni par un caractère spécial, ni une lettre accentuée.

Les constantes

Parfois, une variable ne changera jamais de valeur. Elle est ... une constante. Pour mieux les identifier dans le code, par convention, leur nom est écrit en majuscules.

Exemple : PI=3.14159265358979

Affecter toutes les constantes au début du code est une bonne pratique.
Un nombre décimal contient un POINT DÉCIMAL (et non une virgule)

Les trois principaux types de variables

Le type list sera abordé ultérieurement.
Les autres types ne seront pas abordés dans le cadre de ce mini-cours.

Il est possible de connaître le type d'une variable, via la fonction type().

a=1;         print(type(a));   # affiche : <class 'int'>
a=1.0;       print(type(a));   # affiche : <class 'float'>
a="Bonjour"; print(type(a));   # affiche : <class 'str'>

Python est un langage de programmation "orienté-objet". Chaque type de variable correspond à une class. La notion de class n'entre pas dans le cadre de ce mini-cours.

int(), float() et str()

Le nom de chaque type de variable est le nom d'une fonction permettant de renvoyer une valeur (parfois approximative) dans le type souhaité.

Les fonctions int() et float() sont très utiles. En effet, lorsque l'utilisateur du programme introduit des données, via la fonction input() que nous aborderons plus tard, ce qui est tapé est toujours une string (une suite de caractères)

Ainsi, si à la question : "Quel est ton âge ?", l'utilisateur répond en tapant 14, sa réponse est composée de deux caractères : le caractère 1 suivi du caractère 4. La réponse n'est pas un nombre ! Pour que la réponse devienne un nombre entier, il faudra utiliser la fonction int(). Pour que la réponse devienne un nombre décimal, il faudra utiliser la fonction float().

Et, pour afficher une réponse numérique, par exemple le résultat d'une opération mathématique, il faudra convertir le nombre en une suite de caractères, via la fonction str(). Ce qui est affiché à l'écran est toujours une string.

# avec int() --------------------------------------
x = int(1);          # x vaudra 1
# La fonction int() ne fait rien puisque c'est déjà un nombre entier

y = int(2.8);        # y vaudra 2
# La fonction int() se contente d'enlever les décimales

z = int("3");        # z vaudra 3
a=z+z;               # a vaudra 6

""" Notez que :
z = int("3,1");      # => ValueError: invalid literal for int() with base 10: '3,1'
z = int("3.1");      # => ValueError: invalid literal for int() with base 10: '3.1'
Donc, si la string n'est pas un nombre entier => une erreur est générée

  # code (extrait d'une application graphique), compréhensible à la fin du cours
  watts = txt_watts.get()
  if not watts : watts = 120 # valeur par défaut
  try:
    watts = int(watts)
  except:
    messagebox.showwarning("Puissance moyenne !","Le nombre de watts doit être un nombre entier.")
    return
  if watts < 50 or watts > 400:
    messagebox.showwarning("Puissance moyenne !","La puissance moyenne doit être entre 50 et 400 watts.")
    return
  print("Puissance moyenne :", watts)

"""

# avec float() ------------------------------------
x = float(1);        # x vaudra 1.0
y = float(2.8);      # y vaudra 2.8
z = float("3");      # z vaudra 3.0
w = float("4.2");    # w vaudra 4.2

"""
  # code (extrait d'une application graphique), compréhensible à la fin du cours
  distance = txt_km.get()
  if not distance : distance = 1 # valeur par défaut
  try:
    distance = round(float(txt_km.get()),2)
  except:
    messagebox.showwarning("Distance !","La distance doit être 1 et 300 km.")
    return
  if distance < 1 or distance > 300:
    messagebox.showwarning("Distance !","La distance doit être 1 et 300 km.")
    return
  print("Distance (en km) :", str(distance))
"""

# avec str() --------------------------------------
x = str("bonjour");  # x vaudra 'bonjour'
# NB : La fonction str() ne fait rien puisque c'est déjà une string

y = str(2);          # y vaudra '2'
# Maintenant, y peut être concaténé avec une string
a=y+y;               # a vaudra '22'

z = str(3.0);        # z vaudra '3.0'
print(z+z);          # affiche : 3.03.0

L'opérateur + permet d'additionner deux nombres ou concaténer deux strings.

a=2;     b=3;      print(a+b);        # affiche : 5
a="2";   b=3;      print(a+b);        # affiche un message d'erreur
a="2";   b=3;      print(a+str(b));   # affiche : 23
a="bon"; b="jour"; print(a+b);        # affiche : bonjour

a=2;     print(a)                              # affiche : 2
b=3;     print(a+b)                            # affiche : 5
print("Le résultat de "+a+" + "+b+" = "+(a+b)) # affiche une erreur
print("Le résultat de "+str(a)+" + "+str(b)+" = "+str(a+b))
# affiche : Le résultat de 2 + 3 = 5

L'opérateur + ne peut pas être utilisé avec un nombre et une string

Un nombre (entier ou décimal) supporte la notation scientifique où "e" ou "E" indique une puissance de 10 :

x = 1e3;         # x vaudra 1000.0   = 1       x 1000
y = 12E4;        # x vaudra 12000.0  = 12      x 10000
z = -87.123e2;   # x vaudra -8712.3  = -87.123 x 100
a = 1e-2         # x vaudra 0.01     = 1       / 100

Dans le cadre de ce mini-cours, nous aborderons prochainement le type "bool" et "list".

Pour aller plus loin : Tous les types de variables

La variable booléenne

Il existe aussi des variables booléennes. Son utilisation est liée aux structures conditionnelles (que nous verrons prochainement)

Une variable peut être numérique (de type int ou float), une string (de type str) ou booléenne (de type bool).

a=1;     print(type(a))   # affiche : <class 'int'>
a=1.0;   print(type(a))   # affiche : <class 'float'>
a="1";   print(type(a))   # affiche : <class 'str'>

La particularité des variables booléennes est qu'elles ne peuvent contenir que deux valeurs : True ou False.

a=True;  print(type(a));  # affiche : <class 'bool'>
a=False; print(type(a));  # affiche : <class 'bool'>

Attention. true et True sont deux "valeurs" différentes.
Idem pour, false et False. Ainsi,

a=true;  print(type(a));  # affiche un message d'erreur
a=false; print(type(a));  # affiche un message d'erreur
en C/C++, JS et PHP

En C, il n'existe pas de type booléen. faux vaut 0, tout le reste est vrai (1, -1, 2, ...).

En C++, JS et PHP, faux s'écrit false et vrai, true (tout en minuscule)

Attention, en Python, la première lettre est en majuscule.

bool()

La fonction bool() retourne une valeur : True ou False.

La fonction bool() ne retourne False que si la valeur de son paramètre vaut : 0, 0.0, "", '' ou False.
Dans tous les autres cas, elle retourne True.

    print(bool(0));       # affiche : False
    print(bool(0.0));     # affiche : False
    print(bool(""));      # affiche : False
    print(bool(''));      # affiche : False
    print(bool(False));   # affiche : False
    print(bool([]));      # affiche : False (*)

    print(bool(1));       # affiche : True
    print(bool(2.0));     # affiche : True
    print(bool("x"));     # affiche : True
    print(bool(True));    # affiche : True
    print(bool([1,2]));   # affiche : True  (*)

    print(bool("false"))  # affiche True
    print(bool("False"))  # affiche True

    print(bool("true"))   # affiche True
    print(bool("True"))   # affiche True

(*) La notion de tableau sera abordée ultérieurement.

Les 7 types d'opérateurs

Un opérateur utilisent deux variables (ou littéraux ou expressions mises entre parenthèses); celle qui le précède et celle qui le suit.

Toutefois, certains opérateurs peuvent ne s'appliquer qu'à une seule variable, littéral ou expression, tel que l'opérateur not.

Un littéral est une valeur qui peut être le contenu d'une variable de type int, float ou str.

Une expression est composée de variables (ou de littéraux) et d'opérateurs..

Exemples :

Lorsqu'il existe plusieurs opérateurs, tel que 2 * 3 + 4, l'ordre des opérations peut être imposé via des parenthèses.

Priorités des opérateurs

Dans l'expression 2 * 3 + 4, le resultat sera 6 + 4 = 10 (et non 2 * 7 = 14). Le langage définit des priorités. Or, il est difficile de toutes les retenir. Pour éviter toute erreur, il est préférable de placer des parenthèses. Et, d'écrire soit (2 * 3) + 4, soit 2 * (3 + 4).

En Python, il existe 7 types d'opérateurs :

Les 7 opérateurs arithmétiques

Les 4 premiers opérateurs (+, -, *, /) n'appellent aucun commentaire. Exemple : 13 / 2 = 6.5.

En C/C++

L'opérateur / retourne le quotient entier. 13 / 2 = 6 et 13.0 / 2 = 6.5

Le cinquième opérateur (%) existe dans tous les grands langages, mais il est rarement utilisé par les débutants. Il retourne le reste de la division. Ce reste est un nombre entier. Exemples : 13 % 2 = 1, 23%3=2.

Lorsque le second opérande est 2, il permet de savoir si le nombre entier est pair ou impair.
Si x%n=0, alors x est un multiple de n.

Le sixième opérateur, **, est propre aux langages JS et Python.
** représente l'exposant. Exemples : 8 ** 2 = 64, 10**-2=0.01.

Le septième opérateur, //, est propre au langage Python.
// représente la division entière. Exemples : 13 // 2 = 6, 23//3=7.

Les opérateurs d'affection

Un opérateur d'affectation affecte une variable. Il place une valeur dans une variable.

Seul l'opérateur = est indispensable. Il place ce qui à droite (un littéral ou une variable) dans ce qui est à gauche (une variable).
Exemples : nombreEntier = 1, prenom = "Thibaut", PI=3.1415926535, ...

Les autres opérateurs ne sont que des simples raccourcis.

x += y équivaut à x = x + y
x -= y équivaut à x = x - y
x *= y équivaut à x = x * y
x /= y équivaut à x = x / y
x %= y équivaut à x = x % y
...

Ces raccourcis existent, mais ils sont rarement utilisés par les débutants.

Nous aborderons prochainement la notion de structures répétitives (aussi appelées boucles)

Dans une boucle, il est fréquent d'incrémenter un compteur (de boucles).
On utilise alors un raccourci. Exemples : compteur += 1, i+=1.

Il arrive qu'on décrémente un compteur. On utilise encore un raccourci. Exemples : compteur -= 1, i-=1.

En C/C++, JS et PHP

En C/C++ et JS, i+=1 peut s'écrire i++ (ou ++i)
i-=1 peut s'écrire i-- (ou --i)

En PHP, $i++ ou $i--

Les 2 opérateurs d'identité

x = ["apple", "banana"] est une variable-tableau appelée x qui contient deux variables simples de type string. En résumé, une variable-tableau est une variable qui en contient d'autres ...

La notion de variable-tableau sera développé ultérieurement

Les opérateurs is , is not retourne une valeur booléenne (True ou False).

Voir

La valeur retournée par is not est l'inverse de celle is

Les 2 opérateurs d'appartenance

x = ["apple", "banana"] est une variable-tableau appelée x qui contient deux variables simples de type string. En résumé, une variable-tableau est une variable qui en contient d'autres ...

La notion de variable-tableau sera développé ultérieurement

Les opérateurs in , not in retourne une valeur booléenne (True ou False).

Voir

La valeur retournée par not in est l'inverse de celle in

Les 6 opérateurs de comparaison

Les 6 opérateurs de comparaison sont : ==, !=, <, >, <=, >=. C'est-à-dire respectivement : égal, différent, inférieur, supérieur, inférieur ou égal, supérieur ou égal.

Rappel : = est le signe d'affectation (et non d'égalité).

print(10=10)      # affiche un message d'erreur (Un nombre ne peut pas recevoir une valeur)

print(10==10);    # affiche : True
print(10==9);     # affiche : False

print(10!=10);    # affiche : False
print(10!=9);     # affiche : True

print(10<10);     # affiche : False
print(10<9);      # affiche : False

print(10>10);     # affiche : False
print(10>9);      # affiche : True

print(10<=10);    # affiche : True
print(10<=9);     # affiche : False

print(10>=10);    # affiche : True
print(10>=9);     # affiche : True

Les 3 opérateurs logiques

L'opérateur  and , qui signifie "et", travaille avec des opérateurs de comparaison.

x = 5; print(x > 3  and  x < 10)
# retourne True car toutes les conditions sont vraies (5 plus grand que 3 ET plus petit que 10)
# retourne False, dans le cas contraire (les deux conditions ne sont pas toutes vraies)

L'opérateur  or , qui signifie "ou", travaille avec des opérateurs de comparaison.

x = 5; print(x > 3  or  x < 4)
# retourne True si au moins une des deux conditions est vraie (5 est plus grand que 3)
# retourne False, dans le cas contraire (les deux conditions sont fausses).

L'opérateur  not , qui signifie "pas", inverse la valeur booléenne. Cela peut sembler inutile. Mais, les programmeurs préfèrent parfois dire "pas vrai" au lieu de dire "faux" ...

print(not True)        # affiche : False
print(not(not True))   # affiche : True (double négation)
print(not 0)           # affiche : True (car 0 est évalué à False ...)
print(not 0.0)         # affiche : True
print(not "")          # affiche : True

Cette façon de penser s'avera très utile dans les structures conditionelles.

La structure conditionnelle

Contrairement aux langages de programmation tels que C, C++, JS, ..., le langage Python ne fournit pas l'instruction switch, car elle est, facilement, source d'erreur. Il suffit d'oublier un break ...

if ...

La comparaison se fait entre deux expressions.

Une expression est tout ce qui est évaluable : une variable, un nombre, une string, un booléen, un appel de fonction, ... En général, les deux termes de la comparaison sont des variables.

a = 1; b = 2
if a>b:
  print("a est plus grand que b.\n")
  print("Et, donc b n'est pas plus grand que a.")

La structure conditionnelle est composée de 2 parties obligatoires :

  1. Une ligne de code composée :
    • du mot-clé if
    • de la condition (à évaluer)
      Pour plus de lisibilité, la condition peut être mise entre parenthèses.

      La condition peut être un appel de fonction qui retourne une valeur booléenne.

      def myFunction():
        return True
      
      if myFunction():
        print("YES!")
      else:
        print("NO!")

      Si le retour de fonction vaut None, l'évaluation de la condition vaudra False.

      Codage à la C/C++. La condition peut être une variable (voire un littéral !)

      if True:     print("if True:")
      if 1:        print("if 1:           car 1     est évalué à True")
      if "abc":    print('if "abc":       car "abc" est évalué à True')
      print()
      if not 0:    print("if not 0:       car 0     est évalué à False")
      if not None: print("if not None:    car None  est évalué à False")
      if not "":   print('if not "":      car ""    est évalué à False')
    • du caractère :
  2. Le bloc de code (rappel)

Ce qui peut se traduire par : Si la condition est vraie, exécute les instructions situées dans le bloc de code.

Toutefois, si une seule instruction est à exécuter, elle peut être placée immédiatement après :
if(a>b):print("a est supérieur à b")

if ... else ...

Facultativement, la structure peut être complétée par else: suivi d'un bloc de code contenant les instructions à exécuter si la condition est fausse. else: doit alors avoir la même indentation que le if auquel else: se rapporte.

a = 1; b = 2
if a>b:
  print("a est plus grand que b.\n")
  print("Et, donc b n'est pas plus grand que a.")
else:
  print("a n'est pas plus grand que b")

if ... elif ... (else ...)

a=1

  if a<0:
    print("a est négatif")
  else:
    if a>0:
      print("a est positif")
    else:
      print("a vaut zéro")

  # équivalent au code ci-dessus
  if a<0:
    print("a est négatif")
  elif a>0:
    print("a est positif")
  else:
    print("a vaut zéro")

  # équivalent au "switch" de certains langages
  x="b"
  if x=="a": print("x ='a'")
  elif x=="b": print("x ='b'"); print("ligne2")
  elif x=="c": print("x ='c'")
  elif x=="d": print("x ='d'")
  elif x=="b": print("x vaut encore ='b'") # ne s'affichera jamais
  elif x=="e": print("x ='e'")

Pour une plus grande performance, il faut placer les elif par ordre de probabilité tel que la condition la plus souvent vraie soit la première de la liste.

Une structure (conditionnelle ou répétitive) peut être imbriquée dans une autre.

if x > 10:
  print("x est supérieur à 10,")
  if x > 20:
    print("et aussi supérieur à 20")
  else:
    print("mais inférieur ou égal à 20.")
Lisibilité et espaces

Pour plus de lisibilité, la condition peut être écrite entre des parenthèses.
Dans ce cas, la condition peut coller au mot-clé if. if(a>b):

Un ou plusieurs espaces peuvent précéder ou suivre un opérateur.
On peut donc écrire : if(a > b):

Un ou plusieurs espaces peuvent précéder ou suivre un nom de variable.
On peut donc écrire : if( a > b ):

Un ou plusieurs espaces peuvent précéder ou suivre un mot-clé.
On peut donc écrire : if ( a > b ) :

Supposons que l'on propose à l'utilisateur d'afficher le résultat d'une division (a/b). Pour ce faire, il doit donner deux nombres, a et b. Mais, on sait que la division par zéro est impossible. Avant d'afficher le programmeur doit tester b et n'afficher un résultat que si b est différent de zéro.

if (not (b == 0)): print(a/b)
else : print("b vaut zéro. Division impossible")

if (b != 0): print(a/b)
else : print("b vaut zéro. Division impossible")

if (b): print(a/b)
else : print("b vaut zéro. Division impossible")

# Différentes façons de coder ...

Une structure ne peut pas être vide. Après : du code doit être présent. Durant le développement du programme, on peut utiliser le mot-clé pass et revenir plus tard taper le bloc de code.

if b > a:
  pass

Opérateur ternaire

L'opérateur ternaire retourne une valeur en fonction de la condition.

value_if_true if condition else value_if_false

Cette valeur est souvent affectée à une variable ...

nombre = 7
message = 'est pair' if nombre % 2 == 0 else 'est impair'
print(str(nombre),message) # Affiche : 7 est impair

Après la condition et après le else, il ne faut pas :.

... ou toute l'expression ternaire est le paramètre d'une fonction.
nombre = 7
print(str(nombre), 'est pair' if nombre % 2 == 0 else 'est impair')

Les structures répétitives

La boucle (= répéter un bloc d'instructions) est le mécanisme le plus important en programmation car elle donne la "puissance" aux programmes.

Un tour = une répétition d'un bloc d'instructions.

Deux types de boucle existent - déterministe ou non - selon que le nombre de tours est connu avant d'entrer dans la boucle ou pas.

while ... (else ...)

La boucle while est utilisable dans tous les cas (qu'on connaisse ou non le nombre de tours avant d'entrer dans la boucle ou si le nombre de tours doit être modifié par une condition dans la boucle).

La boucle while est souvent utilisée dans l'analyse d'un fichier.

i = 1               # variable initialisée
while i<6:          # variable utilisée dans la condition
  print(i)
  i = i + 1         # modification de la valeur de la variable
                    # telle qu'elle va finir par rencontrer la limite fixée dans la condition (6)

La boucle while est composée de 2 parties obligatoires :

  1. une ligne composée :
    • du mot-clé while
    • de la condition (à évaluer)
      Pour plus de lisibilité, la condition peut être mise entre parenthèses.
    • du caractère :
  2. Le bloc de code (rappel)

Toutefois, il ne faut pas oublier d'utiliser une variable (souvent nommée i) :

  1. dont la valeur doit être initialisée avant d'entrer dans la boucle
  2. qui doit être évaluée dans la condition
  3. dont la valeur doit changer au niveau du bloc d'instructions
    de manière telle qu'une fois la condition soit fausse.

Contrairement à d'autres langages, Python permet d'exécuter des instructions si la condition est fausse.

i=-2
while i<0:
  print(i)
  i+=1
else:
  print("La condition est fausse.")

Ceci permet d'exécuter des instructions si la boucle n'a pas été utilisée ou en fin de boucle, si une instruction break n'est pas exécutée.

Une structure ne peut pas être vide. Après : du code doit être présent. Durant le développement du programme, on peut utiliser le mot-clé pass et revenir plus tard taper le bloc de code.

Sortir d'une boucle infinie via break

while True:
  # le cœur du programme

  folder  = filedialog.askdirectory(initialdir=gPath, title="Sélection d'un dossier")
  dossier = folder.replace("/",SEP)#;print(dossier)

  if not messagebox.askyesno("Encore ?","Faut-il traiter un autre dossier ?"): break

Ici, avec une interface graphique.

for ... [else ...]

[else ...] est une particularité de Python. Documentation officielle : for.

La boucle for est plus rapide que la boucle while, car la boucle for est déterministe. En interne, la taille de la mémoire nécessaire au résultat peut être déterminé. Il n'est alors pas nécessaire de réallouer de la mémoire au fur et à mesure. La boucle for est à privilégier.

La boucle for n'est utilisable que si le programme connaît le nombre de tours à faire avant de commencer (et, en Python, si le compteur ne doit pas être modifié (par une condition donnée dans la boucle)).

Le gros avantage de la boucle for est qu'elle n'est pas infinie.

La boucle for est souvent utilisée pour parcourir un tableau.

La boucle for est composée de 2 parties obligatoires :

  1. La définition de la boucle (située sur la même ligne de code) composé :
    • du mot-clé for
    • de "élément courant" in "ensemble de valeurs"
      • L'élément courant est une variable temporaire tel que x
      • in est un mot-clé
      • l'ensemble de valeurs est souvent une liste
    • du caractère :
  2. Le bloc de code (rappel)

Une string est une liste de caractères.

La fonction range() retourne un ensemble de nombres, commençant à 0 par défaut, et incrémentés de 1 par défaut, et se terminant au nombre indiqué (exclu)

for x in range(10): # stop=10 (exclu)
  print(x)

"""
0
1
2
3
4
5
6
7
8
9
"""

a=""; start=5; stop=10;
for i in range(start,stop): # en C, JS, ... : for(i=start;i<stop;i++){...}
  a=a+str(i)+",";
  print(a);

"""
5,
5,6,
5,6,7,
5,6,7,8,
5,6,7,8,9,
"""

start=6; stop=20; step=2
for x in range(start,stop,step):
  print(x)

"""
6
8
10
12
14
16
18
"""

start=26; stop=20            # ne provoque pas une boucle infinie. Ouf !
for x in range(start,stop):
  print(x)                   # rien n'est affiché. La boucle est ignorée
Le mot-clé break ordonne de quitter une boucle prématurément.

Le mot-clé continue ordonne de reboucler prématurément (= avant d'avoir atteint la fin du bloc).

fruits = ["apple", "banana", "cherry"]
for x in fruits:
  print(x)
  if x == "banana":
    break

# 'cherry' ne sera pas affiché.

fruits = ["apple", "banana", "cherry"]
for x in fruits:
  if x == "banana":
    break
  print(x)

# Seul 'apple' sera affiché.

fruits = ["apple", "banana", "cherry"]
for x in fruits:
  if x == "banana":
    continue
  print(x)

# Seul 'banana' se sera pas affiché

Attention. Contrairement à d'autres langages (C/C++, JS, PHP), il n'est pas possible de modifier le comportement de la boucle FOR en modifiant la valeur du compteur et/ou celle des bornes (inférieures et supérieures)

print("Boucle 'for'")
for i in range(10):
  if(i==3): i=7
  print(str(i))

"""
Boucle 'for'
0
1
2
7
4
5
6
7
8
9
"""

Si on veut modifier le comportement de la boucle, il faut utiliser la boucle while

print("\nBoucle 'while'")
i=0 # Ne pas oublier d'initialiser le compteur
    (pour s'assurer que la boucle démarre avec la bonne valeur
while(i<10):
  if(i==3): i=7
  print(str(i))
  i+=1 # Ne pas oublier d'incrémenter le compteur !

"""
Boucle 'while'
0
1
2
7
8
9
"""

Contrairement à d'autres langages, Python permet d'exécuter des instructions lorsque la boucle for est terminée, si une instruction break n'est pas exécutée.

Une structure (répétitive ou conditionnelle) peut être incluse dans une autre structure (répétitive ou conditionnelle)

Une structure ne peut pas être vide. Après : du code doit être présent. Durant le développement du programme, on peut utiliser le mot-clé pass et revenir plus tard taper le bloc de code.

Prêt pour la suite ?