--- title: Decouvrir le langage author: Steve Kossouho --- # Bases du langage ---- ## Le langage Python Le langage Python peut être découpé en deux grands types d'instructions : - Les déclarations - Les expressions Les déclarations sont en général des instructions pour créer des variables ou des structures de données. Les expressions sont des instructions pour effectuer des calculs ou récupérer des données. ---- ## Hello World ```python {.numberLines} print("Hello world!") ``` ---- ## Commentaires En Python, un commentaire est un élément textuel dans votre code qui sera ignoré à l'exécution. Il ne pourra pas causer d'erreur de syntaxe, mais encore faut-il l'utiliser correctement : ```python {.numberLines} # Commentaire sur sa propre ligne print("Bonjour") # Commentaire à la fin d'une ligne de code ``` ---- ## Variables Une variable est une boîte en mémoire à laquelle on donne un nom, et dans cette boîte, on place une valeur. Cette valeur peut être un peu n'importe quoi en Python, mais notamment : - Un nombre (entier ou flottant) - Une chaîne de caractères (texte) - D'autres types avancés (collection, date, heure, classes, etc.) ---- ## Exemple d'assignation de variables ```python {.numberLines} a = 15 # Python comprend qu'il s'agit d'un entier c = 3.14159265358979323 # Python comprend qu'il s'agit d'un flottant b = "Bonjour" # Python reconnaît du texte d = input("Entrez du texte") del c # Détruit la variable, qui devient invalide ``` **Note** : une chaîne de caractères peut aussi être marquée par le caractère `'` : ```python {.numberLines} b = 'Bonjour' # Python reconnaît du texte ``` ---- ## Changer la valeur associée à une variable Une variable a, comme son nom l'indique, la capacité de changer de valeur dans le temps. En Python, on utilise exactement la même syntaxe pour déclarer une nouvelle variable ou encore changer la valeur qui lui est associée : ```python {.numberLines} a = 15 print(a) # Affiche 15 a = 99 print(a) # Affiche 99 a = a + 1 # ou a += 1 print(a) # Affiche 100 a = "Bonjour" # On associe une valeur d'un type différent print(a) # Affiche le texte "Bonjour" ``` ---- ## Typographie des variables Typographie conventionnelle des noms de variables : - Tout en minuscules (ex. `texte`, `tour_eiffel`) - Commence par une lettre (obligatoire, ex. `saisie`) - Contient des underscores entre les mots (ex. `user_name`) - Pas d'accent ni d'espace ni de tiret - Peut contenir un chiffre, mais pas en premier caractère (ex. `mambo_number_5`) ---- ## Expressions Une expression correspond toujours à une valeur que l'on pourrait mettre dans une variable. ```python {.numberLines} a = 15 chaine = "bonjour" nombre = 15 print(a) # `a` existe et peut être utilisée comme expression beau_temps = True # Valeur spécifique *vrai* sale_temps = False # Valeur spécifique *faux* non_defini = None # valeur spéciale considérée comme "pas de valeur". ``` ---- ## Types de données En programmation, les types de données ont des noms, et en Python ce sont les suivants : - `int`{.python} : (integer) nombres entiers - `float`{.python} : (floating point numbers) nombres à virgule flottante - `str`{.python} : (string) chaînes de caractères - `bool`{.python} : (boolean) c'est vrai / c'est faux ```python {.numberLines} print(type(15)) # Affiche print(type(15.0)) # Affiche print(type("Bonjour")) # Affiche ``` ---- ## Expressions et opérateurs Il est pratique de pouvoir écrire des expressions simples, mais c'est mieux de pouvoir faire des calculs avec. Il existe des opérateurs mathématiques, mais aussi de comparaison etc. ```python {.numberLines} a = 15 chaine = "bonjour " + "les amis" # intuitif produit = 15 * 60 # intuitif aussi a_double = a * 2 # ça aussi ``` Exemples d'opérateurs : `+`{.python}, `>`{.python}, `**`{.python}, `%`{.python}, `and`{.python}, `&`{.python}, `|`{.python}, `^`{.python}, `is`{.python}, `in`{.python}... ---- ### Opérateurs arithmétiques - Arithmétiques : `+`{.python}, `-`{.python}, `*`{.python}, `/`{.python} - Modulo : `%`{.python} (reste de la division entière) - Division entière : `//`{.python} - Exposant : `**`{.python} (ex. `2 ** 3 == 8`{.python}) ---- ### Opérateurs de comparaison - `>`{.python}, `<`{.python}, `>=`{.python}, `<=`{.python} - `==`{.python} (équivalent), `!=`{.python} (non équivalent) ---- ### Opérateurs booléens en langage naturel - `a and b`{.python} : Vaut `True`{.python} si `a` **et** `b` valent `True`{.python}, sinon `False`. - `a or b`{.python} : Vaut `True`{.python} si `a` **ou** `b` vaut `True`{.python}, sinon `False`. - `a in b`{.python} : `True`{.python} si `a` fait partie de la collection ou séquence `b`. - `a not in b`{.python} : `True`{.python} si `a` ne fait pas partie de la collection ou séquence `b` . - `a is b`{.python} : `True`{.python} si `a` est la même référence que `b`. Utilisé avec les booléens et `None`{.python} notamment. - `a is not b`{.python} : `True`{.python} si `a` n'est pas la même référence que `b`. - `not a`{.python} : Convertit `a` en booléen, et renvoie la valeur opposée. ---- #### Opérateurs booléens (avancé) Si `a`{.python} et `b`{.python} ne sont pas des booléens, la règle plus générale pour l'évaluation des expressions utilisant des opérateurs booléens est la suivante : - `a and b`{.python} : Vaut `a` si `a` est équivalent à la valeur fausse, sinon vaut b. - `a or b`{.python} : Vaut `a` si `a` est équivalent à la valeur vraie, sinon vaut `b`. ---- ### Opérateurs booléens (avancé, exemples) Toutes les instructions suivantes affichent `True`{.python} : ```python {.numberLines} print(("hello" and 0) == 0) print((0 and "hello") == 0) print(("hello" and 2) == 2) print(("hello" or False) == "hello") print((False or "") == "") print("hello" is not False) ``` Ici, on teste en premier que `"hello" and 0`{.python} vaut bien `0`{.python}, et ainsi de suite… ---- ### Exemple avec quelques opérateurs ```python {.numberLines} distance = 17543 # 17543 mètres kilometers = distance // 1000 # division entière par lots de 1000 mètres remaining_meters = distance % 1000 # reste après la division entière print(kilometers, "kilomètres et", remaining_meters, "mètres") print(2 ** 3) # affiche `8` print(2 <= 3) # affiche `True` ``` Petit exemple de code avec conversion d'ordres de grandeur proportionnels (ex. mètres), et usage d'autres opérateurs pour des opérations plus classiques. ---- `a += b`{.python} est équivalent à → `a = a + b`{.python} Des opérateurs similaires sont disponibles pour les autres opérations arithmétiques : `-=`{.python}, `*=`{.python}, `/=`{.python}, `**=`{.python}, `//=`{.python} et `%=`{.python} (_dans la pratique, on n'utilisera que très rarement autre chose que les opérations de base, mais le principe est là_) ---- ### Priorité des opérateurs en Python | Opérateurs | Signification | |------------------------------------------------------------------|---------------------------------------------------| | `()` | Parenthèses | | `**` | Exposant | | `+x`, `-x`, `~x` | Plus unaire, Moins unaire, NOT binaire | | `*`, `/`, `//`, `%` | Multiplication, Division, Division entière, Modulo | | `+`, `-` | Addition, Soustraction | | `<<`, `>>` | Opérateurs de décalage binaire | | `&` | AND binaire | | `^` | XOR binaire | | `\|` | OR binaire | | `==`, `!=`, `>`, `>=`, `<`, `<=`, `is`, `is not`, `in`, `not in` | Comparaisons, Identité, Opérateurs d'appartenance | | `not` | NOT logique | | `and` | AND logique | | `or` | OR logique | | `:=` | Expression d'assignation | ---- # Structures de contrôle ---- ## Conditions Dans tous les langages impératifs, on peut choisir de n'exécuter un bout de code que lorsque certaines conditions sont vérifiées. En Python comme ailleurs, on utilise le mot-clé `if`{.python} pour faire ce choix. Le mot-clé `if`{.python} est suivi d'une expression booléenne (`True`{.python} ou `False`{.python} ou équivalent) qui permet de savoir si on exécute du code ou pas. ```python {.numberLines} a = 15 if a > 10: # l'expression de comparaison renvoie un booléen True print("A est bien supérieur à 10.") print("Le bloc de la condition a bien été exécuté.") print("Exécuté quoi qu'il arrive") ``` . . . Ce qui est exécuté pour cette condition est indenté de 4 espaces (on parle de bloc). Grâce à l'indentation, Python sait où le code en question commence et où il s'arrête. ---- ## Syntaxe : blocs vides En Python, un bloc ne peut pas être vide (erreur de syntaxe), même si vous ne souhaitez rien y faire. Si vous souhaitez écrire un bloc syntax(ct)iquement valide sans rien y faire, Python propose un mot-clé spécifique à cet effet : `pass`{.python}. (Un commentaire ne suffit pas à former un bloc valide car il est ignoré dans la grammaire Python) ```python {.numberLines} if True: pass # utiliser une ellipse (...) fonctionne aussi mais peu utilisé ``` ---- ## Conditions : `if…else` Variante `if`…`else` : On peut exécuter du code si une condition est vraie, mais on peut aussi exécuter du code si cette condition ne s'est pas produite ! Le mot-clé `else`{.python} est au même niveau d'indentation que le `if`{.python}, et apparaît **une seule fois au maximum** pour le `if`{.python} auquel il est associé. ```python {.numberLines} a = 50 if a > 75: print("A est supérieur à 75") else: print("A est inférieur ou égal à 75") ``` ---- ## Conditions : `if…elif…else` On peut exécuter du code si une condition est vraie (`if`). Si elle est fausse, on peut exécuter du code si une autre condition est vraie (`elif`), et ainsi de suite. La première condition vraie voit son bloc exécuté, et l'interpréteur quitte ensuite la structure `if`{.python}. Si un bloc `else`{.python} existe, il est toujours en dernier, et sera exécuté si toutes les conditions le précédant ont été fausses. ```python {.numberLines} vote = 3 # Valeurs entre 1, 2 et 3 if vote == 1: print("Vous avez voté pour Andre") elif vote == 2: # Le vote n'est pas 1, mais 2 print("Vous avez voté pour Beverly") elif vote == 3: # Le vote n'est ni 1 ni 2, mais 3 print("Vous avez voté pour Carlos") else: # Aucun des cas de figure du dessus print("Vote incorrect") ``` ---- ## Faire des boucles : `for … in liste` En programmation, une boucle consiste à répéter un bloc de code. En Python, le bloc est répété à chaque fois qu'on parcourt un élément dans une liste. Par exemple, si on veut afficher les 10 premiers nombres, de 0 à 9, on utilise le mot-clé `for`{.python} avec la fonction `range`{.python} : ```python {.numberLines} nombres = range(10) # une liste de 10 entiers de 0 à 9 inclus for i in nombres: # Le bloc sera exécuté 10 fois # La variable nommée i que nous avons déclarée sera modifiée par Python à chaque itération print(i) # `i` contient tour à tour les nombres de 0 à 9 ``` **À noter** : la variable `i` reste disponible après l'exécution de la boucle et contient la dernière valeur assignée lors de la boucle. ---- ### La fonction `range()`{.python} La fonction `range()`{.python} fournie par Python permet de générer des suites arithmétiques de nombres entiers. Elle fonctionne avec un, deux ou trois arguments selon l'objectif. ```python {.numberLines} zero_to_nine = range(10) # stop (non inclus) one_to_eight = range(1, 9) # start, stop every_other_one = range(0, 10, 2) # start, stop, step no_number_generated = range(10, 0, 2) # start, stop, step ``` ---- ## Faire des boucles : `while condition` Python propose un autre type de boucle `while`{.python} dont le bloc est exécuté tant qu'une condition est vraie (une expression convertie en booléen). Dès qu'elle devient fausse au début d'une itération, Python quitte la boucle et passe à la suite. ```python {.numberLines} nombre = 12 while nombre > 10: print(nombre) nombre = nombre - 1 ``` **Attention** : Une boucle peut ne jamais se lancer, ou tourner indéfiniment ! Dans un terminal normal, (au clavier) `⌨️ Ctrl + C` interrompt le script. Dans un lancement de script avec PyCharm, seul le bouton `⏹ Stop` peut l'interrompre. ---- ## Exemple d'algorithme : Suite de Fibonacci **Suite de Fibonacci** : Une suite commençant par les nombres 0 et 1. On peut générer itérativement les éléments successifs de la suite simplement; chaque nouveau nombre de la suite est la somme des deux qui le précèdent. Cela donne dans l'ordre : `0 1 1 2 3 5 8 13 21 34 55 89 144 …` Pour le résoudre, au choix, on utilise : - Deux variables (avec ou sans _unpacking_), ou trois avec une variable temporaire. - Une boucle `while`{.python} (pour définir quand on s'arrête d'afficher un nouvel élément) ---- ### Fibonacci : unpacking En Python, le "dépaquetage" (**unpacking**) est une forme d'assignation de variables où, lorsque l'expression à droite du signe `=` est une séquence à `n` éléments (avec `n > 1`), vous pouvez assigner la séquence à `n` variables : ```python {.numberLines} a, b, c = (1, 2, 3) # a = 1, b = 2 et c = 3 a, b = (1, 2, 3) # erreur, trop d'éléments à dépaqueter a = (1, 2, 3) # aucun problème, a est une séquence de 3 éléments ``` . . . **Rappel** : si vous assignez la séquence à `1` variable, ça fonctionnera à nouveau, et votre variable sera une séquence de `n` éléments. ---- ## Interrompre des boucles On peut interrompre une boucle `for`{.python} ou `while`{.python} avec deux mots-clés : - `break`{.python}, - `continue`{.python}. ---- ### Interruption : `break`{.python} Lorsque l'on se trouve dans le bloc d'une boucle (seule la boucle directement englobante est concernée), l'exécution d'une instruction `break`{.python} interrompt immédiatement la boucle en cours, qu'il s'agisse d'un `for`{.python} ou d'un `while`{.python}. L'utilisation classique du mot-clé `break` s'applique aux traitements où vous exécutez une boucle (potentiellement avec un nombre d'itérations que vous ne contrôlez pas) à la recherche d'une information. Dans ce cas précis, si vous trouvez l'information qui vous intéresse avant la fin naturelle de la boucle, il n'est alors plus nécessaire de la laisser se poursuivre; typiquement, si vous trouvez votre information à la ligne 10 d'un fichier de 900 000 lignes, _pourquoi parcourir les 899 990 lignes restantes_ ? ---- ### `break`{.python} : Exemple Que fait cet exemple-ci ? ```python {.numberLines} for number in range(10 ** 9): if number == 23: print("Valeur trouvée") break else: print("Itération...") ``` ---- ### Interruption : `continue`{.python} Lorsque l'on se trouve dans le bloc d'une boucle, l'exécution d'une instruction `continue`{.python} revient immédiatement à la première ligne de l'itération suivante, ou autrement dit, ignore le reste du code de l'itération en cours. L'utilisation d'un mot-clé `continue`{.python} peut **toujours** être remplacée par un `if`{.python}, plus lisible. Cependant, ce mot-clé peut servir à réduire le niveau d'indentation d'un bloc complexe : ---- #### `continue`{.python} : Exemple ```python {.numberLines} for x, y in zip(a, b): if x > y: z = process_z(x, y) if y - z < x: y = min(y, z) other_actions() ``` . . . Deviendrait comme suit. ```python for x, y in zip(a, b): if x <= y: continue z = process_z(x, y) if y - z >= x: continue y = min(y, z) other_actions() ``` Très peu de développeurs s'en servent car le gain est minime à part pour ces raisons d'indentation. Les cas d'indentation extrême doivent pouvoir être simplifiés d'une autre manière. ---- ## Bonus : Opérateur morse (walrus) Sans rentrer dans le détail, on peut, depuis Python 3.8 (fin 2019), simplifier des boucles `while`{.python} avec un opérateur `:=`{.python}. C'est un opérateur qui permet d'assigner une valeur à une variable, mais contrairement au mot-clé `=`{.python}, l'opérateur forme une expression dont la valeur est l'opérande de droite. On peut ainsi écrire : ```python {.numberLines} while (saisie := input("Saisissez oui :")) != "oui": print("Saisie incorrecte") ``` . . . au lieu d'écrire : ```python {.numberLines} saisie = input("Saisissez oui :") # afficher l'invite et récupérer la saisie while saisie != "oui": print("Saisie incorrecte !") saisie = input("Saisissez oui :") ``` ---- ## Opérateur morse : considérations Attention toutefois, l'opérateur possède la priorité la plus basse de tous les opérateurs Python, et dans certains cas, l'expression l'utilisant **doit** employer des parenthèses pour ne pas provoquer d'erreur de syntaxe. **Dans le doute, utilisez toujours des parenthèses.** ```python {.numberLines} a := 1 # Erreur de syntaxe ``` . . . ```python {.numberLines} (a := 1) # Ça fonctionne, mais ça n'a aucun intérêt ``` . . . ```python {.numberLines} print(a := 1 < 9) # Affiche True, et a == True ``` . . . ```python {.numberLines} print((a := 1) < 9) # Affiche True, et a == 1, ce qu'on voulait ``` ---- ### Petit plus : expression ternaire En Python, il est possible de décrire une expression qui vaut une valeur `a` si une condition est vraie, et `b` sinon. Sans cet opérateur, on écrit : ```python {.numberLines} if condition: variable = a else: variable = b ``` . . . Avec cet opérateur, on écrira plutôt : ```python {.numberLines} variable = a if condition else b ```