Librement inspiré des supports de cours de Gaël Guibon
Librement inspiré des supports de cours de Julien PillaRetrouvez l'ensemble du cours sur 👉 github.com/alix-tz/enc-intro-algo👈
🏆 Connaître le vocabulaire de la programmation
🏆 Savoir lire et concevoir un algorithme
🏆 Se familiariser avec l'environnement de développement de Python
🏆 Connaître les bonnes pratiques de développement
🏆 Ecrire un programme simple avec Python
👉 Simulateur d'environnement Python en mode pseudo-IDE : https://repl.it/languages/python3
👉 Simulateur d'environnement Python en mode console : https://www.python.org/shell/
👉 Documentation officielle de Python : https://docs.python.org/3/
👉 Visualisateur d'exécution de code Python : http://pythontutor.com/
👉 "Automate the Boring Stuff with Python" (en
) : https://automatetheboringstuff.com/
👉 Leçons dédiées à Python sur Programming Historian (en
, fr
ou es
) : https://programminghistorian.org/en/lessons/introduction-and-installation
👉 "Apprendre à coder avec Python", MOOC de l'Université Libre de Bruxelles (fr
) : https://www.fun-mooc.fr/courses/course-v1:ulb+44013+session04/about
👉 "Apprenez à programmer en Python", cours en ligne sur OpenClassroom (fr
) : https://openclassrooms.com/fr/courses/235344-apprenez-a-programmer-en-python
👉 "Introduction à Python" pour le Master Ingénierie Multilingue de l'Inalco, Loïc Grobol et Yoann Dupont (fr
) : https://loicgrobol.github.io/python-im/m2-2018/
Comment faites-vous pour renommer 390 fichiers (ex: retirer "_copie" ou les renommer en ajoutant un numéro d'ordre) ? Combien de temps cela prend-il ? Quelles chances avez-vous de commettre des erreurs en faisant cela ?
Vous avez une base de données pleine de liens URL vers des ressources et vous voulez vérifier que ces liens sont corrects (toujours actifs et liés à la bonne ressource). Comment faites-vous ? Combien de temps cela va prendre ?
Dans un univers professionnel de plus en plus "numérique", avoir des bases en programmation est une compétence utile et valorisée.
Pour pouvoir mener à bien des projets numériques d'ampleur, il est nécessaire de démystifier le travail des développeur·ses avec qui vous collaborerez et de pouvoir comprendre les contraintes de la programmation.
Par algorithmique
(ou algorithmie), on désigne généralement les paradigmes qui guident la logique programmatique et qui existent quel que soit le langage de programmation utilisé. Construire un algorithme, c'est donc imaginer un scénario permettant d'obtenir un résultat étant donné un ensemble de contraintes formelles.
Un programme
est la mise en application d'un algorithme. C'est une suite d'instructions fournies à la machine pour qu'elle les exécute afin de produire un résultat (output
). Un programme peut en plus faire appel à des données extérieures (input
).
Ces instructions sont exécutées dans un ordre précis, un algorithme a donc un début et une fin.
Elles sont construites à partir d'éléments de base communs à tous les langages :
valeurs
fonctions
variables
opérateurs
structures conditionnelles
(si... alors)boucles
ou structures répétitives
commentaires
Il existe une multitude de langages pour exprimer ces instructions, par exemple :
C++ | Java | Python | R | php |
---|---|---|---|---|
💁 langages de haut niveau : Python, Java, etc.
🤖 langages de bas niveau : C, langage d'assemblage, code machine, etc.
Les langages de haut niveau ont besoin d'être compilés
avant d'être exécutés : ils sont traduits en un code binaire (suite de 0 et de 1) compréhensible par la machine.
Pas besoin d'être un robot 🤖, un-e magicien-ne 🧙 ou un-e geek 🤓 pour faire de l'algo !
Il faut simplement...
Le pseudo-code est une façon d'exprimer une suite d'instructions de manière abstraite, sans suivre la grammaire d'un langage en particulier.
En pseudo-code, 1 ligne = 1 instruction
!
DEBUT
Instruction 1
Instruction 2
Instruction 3
etc...
FIN
Instructions possibles :
- sélectionner le bloc
?
- déplacer de
?
vers?
Python est un langage de programmation de haut niveau sous licence libre. Il a été créé par Guido Van Rossum mais son développement est pris en charge depuis 2001 par la Python Software Foundation.
Le langage Python continue d'évoluer depuis par le biais des PEP
(Python Enhancement Proposals)
https://www.python.org/dev/peps/pep-0008/
One of Guido's key insights is that code is read much more often than it is written. The guidelines provided here are intended to improve the readability of code and make it consistent across the wide spectrum of Python code. As PEP 20 says, "Readability counts".
(à lire à tête reposée)
https://www.python.org/dev/peps/pep-0020/
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Entre 2008 et 2019, cohabitaient Python 2
et Python 3
, deux versions de Python dont la compatibilité n'est pas totale. Depuis le 31 décembre 2019, Python 2 est officiellement "abandonné" et seul règne Python 3.
👉 print()
est une fonction dite built-in
et qui affiche des valeurs qui lui sont fournies
👉 "hello, world"
est une chaîne de caractères
fournie à la fonction print()
👉 une fonction est un bloc d'instructions permettant d'obtenir un résultat précis
👉 anatomie d'une fonction : nom_de_la_fonction(argument, argument, etc.)
Les instructions sont exécutées dans l'ordre où elles sont écrites
print('hey') # première instruction
print('you') # deuxième instruction
print('!') # troisième instruction
hey you !
Un programme plante s'il contient des erreurs. Il affiche alors un message d'erreur
indiquant la raison pour laquelle il s'est interrompu.
Ce n'est pas grave de faire des erreurs. L'important c'est de savoir lire le message d'erreur pour trouver l'origine du problème et le résoudre.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
File "<stdin>", line 1
print("hello world)
^
SyntaxError: EOL while scanning string literal
txt
Traceback (most recent call last):
File "{nom du fichier contenant le script}", line {numéro de ligne}, in <module>:`
print("hello world) {<- citation de la ligne de code fautive}
^ {<- pointeur}
{type d'erreur}: {description}
numéro de ligne
: numéro de la ligne fautive dans le scriptpointeur
: indique non pas l'emplacement de l'erreur mais l'emplacement à partir duquel l'erreur fait planter le programme. Il faut parfois remonter quelques caractères ou quelques lignes plus haut pour trouver l'origine de l'erreur.{type d'erreur}
: NameError, SyntaxError, TypeError, ValueError, etc...description
: parfois suivi d'une suggestion de correction. Notez que dans certains cas une erreur dans le code conduit le programme à mal interpréter les instructions et donne une description de l'erreur inexacte.print(hello, world)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'hello' is not defined
On a fait référence à une variable qui n'existe pas.
- soit parce qu'on a oublié les " autour d'une chaine de caractères
- soit parce qu'on a fait une faute en tapant le nom de la variable
- soit parce qu'on fait référence à une variable trop tôt dans le script (avant qu'elle ne soit créée)
print "hello world"
File "<stdin>", line 1
print "hello world"
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print("hello world")?
Le code ne respecte pas la syntaxe de Python
- "EOL while scanning string literal" : on a oublié de fermer une chaîne de caractères (EOL : end of line)
- "Missing parentheses in ..." : on a mal refermé un bloc entre parenthèses
- "can't assign to literal" : on essaie d'assigner une valeur à un nombre
- "invalid syntax" : message générique
En programmation, lire la documentation est essentiel.
help()
help(print)
Help on built-in function print in module builtins: print(...) print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) Prints the values to a stream, or to sys.stdout by default. Optional keyword arguments: file: a file-like object (stream); defaults to the current sys.stdout. sep: string inserted between values, default a space. end: string appended after the last value, default a newline. flush: whether to forcibly flush the stream.
Il existe plusieurs types de valeurs possibles, les principales sont :
string
, str
(chaîne de caractères) : du texte écrit 'entre guillemets simples', "doubles" ou """triples""". Ex : "21"integer
, int
(entiers) : des nombres entiers. Ex : 21float
, fl
(décimaux) : des nombres décimaux, Attention les décimaux sont après un point .
et non une virgule (,
). Ex : 21.0boolean
, bool
(Booléen) : soit True, soit FalseAttention !
- "3" et 3 ne sont pas identiques !
- 4 et 4.0 sont identiques
- alors qu'on aura : 1, 14, 19, 40, 150
- on aura : "1", "14", "150", "19", "40"
Les variables sont des conteneurs permettant de sauvegarder temporairement des valeurs.
👉 une variable porte un nom
, contient une valeur
et possède un type
👉 la valeur et le type d'une variable peuvent changer mais pas son nom.
nom_de_variable = "valeur de la variable"
print("hello, world 1") # affichage sans variable
var = "hello, world 2" # création de la variable "var" contenant une chaine de caractères
print(var) # affichage de la valeur contenu dans la variable "var"
hello, world 1 hello, world 2
varA = "hello" # première assignation de valeur
varA = "world" # réassignation d'une nouvelle valeur
print(varA)
world
👉 le nom de variable doit respecter les règles suivantes :
mot réservé
(35 mots-clefs + noms de fonctions built-in)import keyword
print(keyword.kwlist)
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
# Pourquoi il ne faut pas utiliser le nom d'une fonction built-in pour créer une variable :
# On définit une variable nommée "help" contenant l'entier 666
help = 666
# résultat : le mot "help" renvoie désormais à la variable et non plus à la fonction help()
help(print)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-3-11b52f5eadb2> in <module> 3 help = 666 4 # résultat : le mot "help" renvoie désormais à la variable et non plus à la fonction help() ----> 5 help(print) TypeError: 'int' object is not callable
# On ne peut pas commencer le nom d'une variable par un chiffre
1_does_not_work = 'ça ne marche pas'
File "<ipython-input-4-6497af45ade4>", line 2 1_does_not_work = 'ça ne marche pas' ^ SyntaxError: invalid token
# Le nom d'une variable ne peut pas contenir de tiret (-)
ma-variable = "oups"
File "<ipython-input-4-47797ba742ac>", line 2 ma-variable = "oups" ^ SyntaxError: cannot assign to operator
# ne pas contenir d'espace
ma variable = "Toujours pas"
File "<ipython-input-5-53cd3fcbc277>", line 2 ma variable = "Toujours pas" ^ SyntaxError: invalid syntax
lambda = "ceci est un mot réservé"
File "<ipython-input-7-40194925f324>", line 1 lambda = "ceci est un mot réservé" ^ SyntaxError: invalid syntax
Il existe deux manières conventionnelles de former des noms de variables contenant plusieurs mots :
# le camelCase
maVariable = "Une bosse ou deux bosses ?"
# le snake_case
ma_variable = "DJ Snake"
La PEP 8
recommande d'utiliser
mon_document
plutôt que var1
)varl
et var1
se ressemblent)👉 https://www.python.org/dev/peps/pep-0008/#naming-conventions
Le type d'une variable fait référence au type d'objet / de valeur qu'elle contient. En Python, le typage
est dynamique
, contrairement à d'autres programmes, comme C ou Javascript, où on annonce le type d'une variable au moment de sa création.
// en c
int nombre_d_eleves = 20
# en python
nombdre_d_eleves = 20
En Python, si on change la valeur d'une variable par une valeur d'un type différent, le type de la variable change automatiquement.
mon_chiffre = 7 # variable de type "int"
mon_chiffre = "sept" # variable de type "str"
Pour connaître le type d'une variable, on utilise la fonction built-in type()
# notez qu'on peut donner plusieurs valeurs à print() en les séparant par une ,
mon_chiffre = 7
print(mon_chiffre, " = ", type(mon_chiffre))
mon_chiffre = "sept"
print(mon_chiffre, " = ", type(mon_chiffre))
7 = <class 'int'> sept = <class 'str'>
Les opérations arithmétiques sont l'une des premières manipulations qu'il est possible de faire avec des valeurs et des variables.
On peut additionner (+
) des valeurs, les soustraire (-
), les multiplier (*
), les diviser selon plusieurs méthodes (/
, //
) ou récupérer le reste d'une division entière (%
), etc.
a = 4
b = 2 + a
c = b * a
+
¶addition_int = 1 + 1 # addition de 2 entiers
addition_float = 1.0 + 2 # addition d'un décimal et d'un entier
addition_str = "a" + "b" # addition de deux chaines de caractères
print(addition_int, addition_float, addition_str, sep="\n")
2 3.0 ab
-
¶substraction_int = 2 - 4 # soustraction de 2 entiers
substraction_float = 12.6 - 8.4 # soustraction d'un décimal et d'un entier
print(substraction_int, substraction_float, sep="\n")
-2 4.199999999999999
substraction_str = "hello" - "world" # on ne peut pas soustraire deux chaines de caractères
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-7-d1c41d5bcf59> in <module> ----> 1 substraction_str = "hello" - "world" # on ne peut pas soustraire deux chaines de caractères TypeError: unsupported operand type(s) for -: 'str' and 'str'
*
¶multiplication = 2 * 10.0 # multiplication d'un entier et un décimal
multiplication_str = "multi" * 3 # multiplication d'une chaine de caractère et d'un entier
print(multiplication, multiplication_str, sep="\n")
20.0 multimultimulti
/
, %
et //
¶division = 36 / 7 # la division de 2 entiers produit toujours un décimal
division_tronquée = 36 // 7 # une division tronquée produit toujours un entier
reste_decimal = 36 % 7.0
reste_entier = 36 % 7
print(division, division_tronquée, reste_decimal, reste_entier, sep="\n")
5.142857142857143 5 1.0 1
division_string = "blabla" // 2 # on ne peut pas diviser une chaine de caractères
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-9-1efa55a5e3b6> in <module> ----> 1 division_string = "blabla" // 2 # on ne peut pas diviser une chaine de caractères TypeError: unsupported operand type(s) for //: 'str' and 'int'
**
¶10 ** 4 # 10^4
10000
Comme en mathématiques, les parenthèses ()
permettent de définir les priorités :
sans_parenthese = 36 / 2 * 3
avec_parenthese = 36 / (2 * 3)
print(sans_parenthese, avec_parenthese, sep="\n")
54.0 6.0
On ne peut pas concaténer
(additionner) certains types :
"hello" + 42
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-25-3baee1551631> in <module> ----> 1 "hello" + 42 TypeError: can only concatenate str (not "int") to str
Tandis que d'autres types de données sont plus souples :
15 + 3.21
18.21
Certaines fonctions permettent de changer le type d'un objet, à condition que la valeur de cet objet puisse être transférée vers un nouveau type. Ces fonctions sont : str()
, int()
, float()
, bool()
. Il en existe d'autres pour d'autres types de valeurs que nous verrons plus tard.
str(21)
donnera "21"
int(18.21)
donnera 18
bool(1)
donnera True
float("4")
donnera 4.0
int("ma chaine de caractères")
str()
¶# str() : transformer en chaîne de caractères
print(type(var_int), type(str(var_int)), sep = " ==> ")
print(type(var_bool), type(str(var_bool)), sep = " ==> ")
print(type(56.5), type(str(56.5)), sep = " ==> ")
<class 'int'> ==> <class 'str'> <class 'bool'> ==> <class 'str'> <class 'float'> ==> <class 'str'>
int()
¶# int() : transformer en entier
print(type(var_float), type(int(var_float)), sep = " ==> ")
print(type(56.5), type(int(56.5)), sep = " ==> ")
print(type("42"), type(int("42")), sep = " ==> ")
<class 'float'> ==> <class 'int'> <class 'float'> ==> <class 'int'> <class 'str'> ==> <class 'int'>
# spécificité quand on transforme un booléen en entier
print(type(var_bool), type(int(var_bool)), sep = " ==> ")
print(var_bool, int(var_bool), sep = " ==> ")
<class 'bool'> ==> <class 'int'> False ==> 0
# toutes les chaines de caractères ne sont pas convertibles en entiers
print(type(var_str), type(int(var_str)), sep = " ==> ")
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-15-3a384075590f> in <module> 1 # toutes les chaines de caractères ne sont pas convertibles en entiers ----> 2 print(type(var_str), type(int(var_str)), sep = " ==> ") ValueError: invalid literal for int() with base 10: 'soixante'
float()
¶# float() : transformer en décimal
print(type(var_int), type(float(var_int)), sep=" ==> ")
print(type("42"), type(float("42")), sep = " ==> ")
<class 'int'> ==> <class 'float'> <class 'str'> ==> <class 'float'>
# spécificité quand on transforme un booléen en décimal
print(type(var_bool), type(float(var_bool)), sep = " ==> ")
print(var_bool, float(var_bool), sep = " ==> ")
<class 'bool'> ==> <class 'float'> False ==> 0.0
print(type(var_str), type(float(var_str)), sep = " ==> ")
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-73-340baff32a83> in <module> ----> 1 print(type(var_str), type(float(var_str)), sep = " ==> ") ValueError: could not convert string to float: 'soixante'
bool()
¶# bool() : transformer en booléen
print(type(var_float), type(bool(var_float)), sep=" ==> ")
print(type(var_int), type(bool(var_int)), sep=" ==> ")
print(type(var_str), type(bool(var_str)), sep = " ==> ")
<class 'float'> ==> <class 'bool'> <class 'int'> ==> <class 'bool'> <class 'str'> ==> <class 'bool'>
# Mais quel booléen ?
print(type(var_float), type(bool(var_float)), sep=" ==> ")
print(var_float, bool(var_float), sep=" ==> ")
print(type(var_int), type(bool(var_int)), sep=" ==> ")
print(var_int, bool(var_int), sep=" ==> ")
print(type(var_str), type(bool(var_str)), sep = " ==> ")
print(var_str, bool(var_str), sep = " ==> ")
<class 'float'> ==> <class 'bool'> 18.21 ==> True <class 'int'> ==> <class 'bool'> 4 ==> True <class 'str'> ==> <class 'bool'> soixante ==> True
# A quel moments obtient-on "False"
print(type("False"), type(bool("False")), sep = " ==> ")
print("False", bool("False"), sep = " ==> ")
print(type(""), type(bool("")), sep = " ==> ")
print("", bool(""), sep = " ==> ")
print(type(0), type(bool(0)), sep = " ==> ")
print(0, bool(0), sep = " ==> ")
print(type(None), type(bool(None)), sep = " ==> ")
print(None, bool(None), sep = " ==> ")
<class 'str'> ==> <class 'bool'> False ==> True <class 'str'> ==> <class 'bool'> ==> False <class 'int'> ==> <class 'bool'> 0 ==> False <class 'NoneType'> ==> <class 'bool'> None ==> False
En utilisant des opérateurs arithmétiques et une variable, écrivez un algorithme permettant d'obtenir l'affichage suivant :
3 x 0 = 0
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
Ecrivez un script Python appliquant l'algorithme de l'exercice 1.
A. Ecrire un algorithme pour un programme permettant de créer automatiquement un pseudo à partir du nom, du prénom et de la longueur de ces deux éléments.
Vous pouvez également varier en utilisant la date de naissance de l'utilisateur-rice.
B. Rédigez ce programme en Python, étant donné que :
input()
permet de demander à l'utilisateur-rice d'entrer une valeurlen()
permet de connaître la taille d'une valeurRéaliser les 6 exercices du fichier variables.py