L'ennemi est con, il croit que c'est nous l'ennemi alors que c'est lui.
Pierre Desproges
Sans perdre de vue notre projet Cesar, je vous propose aujourd'hui cette petite application :
Code Python traduit en HTML:#variables globales
letexte=""
def ecrisfichier():
"""Cette fonction ecris dans le fichier texte.txt
le contenu de la variable globale letexte
Cette fonction n'attend pas de paramètre
et ne retourne auncune valeur
"""
fichier=open("texte.txt" ,"w" )
fichier.write(letexte)
fichier.close()
def lejob():
"""Cette fonction fait le travail
elle modifie le contenu de la variable globale letexte de la
façon suivante:
elle remplace les caractère eéèê par le chiffre 3
Cette fonction n'attend pas de paramètre
et ne retourne auncune valeur
"""
#variables locales
caracteres="eéèê" #variable locale
nouveau_texte=""
#important : le fonctionnement dela boucle:
for lettre in letexte:
#pour chacune des lettres de notre variable letexte
if lettre in caracteres:
#on ajoute un 3 dans nouveau_texte
nouveau_texte=nouveau_texte+"3"
else:
#on ajoute simplement cette lettre
nouveau_texte=nouveau_texte+lettre
#nouveau_texte contient le texte modifié
return nouveau_texte
#corps du programme
fichier=open("texte.txt" ,"r" )
letexte=fichier.read()
# Attention si le fichier n'existe pas il y a erreur !
fichier.close()
#letexte contient le texte original
letexte=lejob()
#letexte contient maintenant le texte modifié
ecrisfichier()
#le fichier de départ a été modifié
La documentation est abondante et rend le code facilement compréhensible.
Le but du programme est d'ouvrir un fichier nommé texte.txt, dans le même répertoire que le programme, et de remplacer dans ce programme les e (avec ou sans accent) par le chiffre 3.
Je l'ai testé avec la fable "Le corbeau et le renard" et j'ai obtenu :
Maîtr3 Corb3au, sur un arbr3 p3rch3, T3nait 3n son b3c un fromag3. Maîtr3 R3nard, par l'od3ur all3ch3, Lui tint à p3u pr3s c3 langag3 : Et bonjour, Monsi3ur du Corb3au. Qu3 vous 3t3s joli ! qu3 vous m3 s3mbl3z b3au ! Sans m3ntir, si votr3 ramag3 S3 rapport3 à votr3 plumag3, Vous 3t3s l3 Ph3nix d3s hôt3s d3 c3s bois. À c3s mots, l3 Corb3au n3 s3 s3nt pas d3 joi3 ; Et pour montr3r sa b3ll3 voix, Il ouvr3 un larg3 b3c, laiss3 tomb3r sa proi3. L3 R3nard s'3n saisit, 3t dit : Mon bon Monsi3ur, Appr3n3z qu3 tout flatt3ur Vit aux d3p3ns d3 c3lui qui l'3cout3. C3tt3 l3çon vaut bi3n un fromag3, sans dout3. L3 Corb3au hont3ux 3t confus Jura, mais un p3u tard, qu'on n3 l'y pr3ndrait plus.
Votre mission pour ce jour se décompose en 3 temps :
N'hésitez pas à relire les séquences précédentes !
Au cycle 4, les élèves s'initient à la programmation, en développant dans une démarche de projet quelques programmes simples, sans viser une connaissance experte et exhaustive d'un langage ou d'un logiciel particulier. En créant un programme, ils développent des méthodes de programmation, revisitent les notions de variables et de fonctions sous une forme différente, et s'entraînent au raisonnement.
Décomposer un problème en sous-problèmes afin de structurer un programme ; reconnaître des schémas. Écrire, mettre au point (tester, corriger) et exécuter un programme en réponse à un problème donné. Écrire un programme dans lequel des actions sont déclenchées par des événements extérieurs. Programmer des scripts se déroulant en parallèle. - Notions d'algorithme et de programme. - Notion de variable informatique. - Déclenchement d'une action par un événement, séquences d'instructions, boucles, instructions conditionnelles.
Jeux dans un labyrinthe, jeu de Pong, bataille navale, jeu de nim, tic tac toe. Réalisation de figure à l'aide d'un logiciel de programmation pour consolider les notions de longueur et d'angle. Initiation au chiffrement (Morse, chiffre de César, code ASCII...). Construction de tables de conjugaison, de pluriels, jeu du cadavre exquis... Calculs simples de calendrier. Calculs de répertoire (recherche, recherche inversée...). Calculs de fréquences d'apparition de chaque lettre dans un texte pour distinguer sa langue d'origine : français, anglais, italien, etc.
En 5e, les élèves s'initient à la programmation événementielle. Progressivement, ils développent de nouvelles compétences, en programmant des actions en parallèle, en utilisant la notion de variable informatique, en découvrant les boucles et les instructions conditionnelles qui complètent les structures de contrôle liées aux événements.

En Mathématiques, “choisir” sans tenir compte de l’ordre, c’est la combinaison. En Python, c’est exactement ce que fait itertools.combinations : il énumère toutes les sélections possibles de taille k parmi une liste, sans doublon, et sans permutation inutile. Résultat : du code plus clair, plus sûr… et souvent plus rapide que des boucles bricolées.
Une combinaison de taille p parmi n objets, c’est un choix sans ordre.
[katex]C_n^p[/katex] [katex]C_n^p[/katex], souvent écrit [katex]\binom{n}{p}[/katex] dans la littérature anglo-saxonne et en informatique.
[katex]C_n^p[/katex] se lit : « p parmi n »
Cela désigne le nombre de combinaisons de p éléments choisis parmi n, sans tenir compte de l’ordre.
itertools.combinations ne renvoie pas une liste : c’est un itérateurLorsque l’on utilise itertools.combinations, il est tentant de penser que la fonction renvoie immédiatement une liste contenant toutes les combinaisons possibles. Ce n’est pas le cas. L’appel :
from itertools import combinations comb = combinations([1, 2, 3, 4], 2)
ne construit pas en mémoire toutes les paires possibles. Il renvoie un objet itérateur, c’est-à-dire un objet capable de produire les combinaisons au fur et à mesure, uniquement lorsqu’elles sont demandées.
Si l’on affiche directement l’objet :
print(comb)
Python renvoie quelque chose comme :
>>> # script executed <itertools.combinations object at 0x1164f90> >>>
Tester dans le Bac à sable Python!
Cela signifie que l’on dispose d’un générateur de combinaisons, et non d’une collection déjà matérialisée.
Ce choix n’est pas anodin. Il est directement lié à la nature combinatoire du problème.
Le nombre de combinaisons de p éléments parmi n est donné par
[katex]C_n^p[/katex].
Or cette quantité peut devenir extrêmement grande lorsque n augmente. Générer toutes les combinaisons et les stocker en mémoire pourrait devenir coûteux, voire impossible.
Un itérateur adopte une stratégie dite lazy (évaluation paresseuse) :
Ainsi, la mémoire utilisée reste minimale.
L’utilisation naturelle d’un objet combinations se fait dans une boucle :

from itertools import combinations
for a, b in combinations([1, 2, 3, 4], 2):
print(a, b)
Les paires sont produites successivement. À aucun moment l’ensemble des combinaisons n’est stocké dans une liste complète.
Cette approche présente un avantage important : si l’on cherche une combinaison vérifiant une condition donnée, il est possible d’interrompre le parcours dès que le résultat est trouvé :
from itertools import combinations
nums = [2, 7, 11, 15, 3, 6]
for a, b in combinations(nums, 2):
if a + b == 9:
print(a, b)
break
Dans ce cas, seules les combinaisons nécessaires sont générées.
Un point essentiel doit être souligné : un itérateur ne peut être parcouru qu’une seule fois.
from itertools import combinations c = combinations([1, 2, 3, 4], 2) print(list(c)) # première conversion print(list(c)) # seconde conversion
La seconde conversion renverra une liste vide. L’itérateur a été “épuisé” lors du premier parcours.
Tester dans le Bac à sable Python!
Si plusieurs parcours sont nécessaires, il convient soit de recréer l’itérateur, soit de convertir explicitement le résultat en liste — à condition que le volume de données reste raisonnable :
pairs = list(combinations([1, 2, 3, 4], 2))
Il existe une cohérence profonde entre la notion mathématique de combinaison et l’implémentation choisie par Python.
Le coefficient combinatoire [katex]C_n^p[/katex] peut croître très rapidement. En conséquence, une approche “en flux” est souvent plus pertinente qu’une approche fondée sur le stockage intégral des résultats.
itertools.combinations ne fournit donc pas une liste prête à l’emploi, mais un mécanisme de génération contrôlée. Ce choix reflète une philosophie plus large de Python : privilégier l’efficacité mémoire et la modularité des traitements.
itertools (version lourde)Au Texas Hold'em No Limit, vous recevez 2 cartes privatives.
Supposons que l’on représente le paquet par les entiers de 0 à 51.
Sans itertools, on peut écrire deux boucles imbriquées pour représenter ces cartes privatives possibles :
deck = list(range(52))
hands = []
for i in range(len(deck)):
for j in range(i + 1, len(deck)):
hands.append((deck[i], deck[j]))
print(len(hands)) # 1326
Tester dans le Bac à sable Python!
Ici :
Ici :
hands,Cette méthode fonctionne, mais :
j = i + 1),
itertools.combinations (version légère)La même opération peut s’écrire :
from itertools import combinations
deck = range(52)
for hand in combinations(deck, 2):
print(hand)
Différence fondamentale :
Si l’on souhaite simplement connaître le nombre total :
count = 0
for _ in combinations(deck, 2):
count += 1
print(count) # 1326
Le résultat est identique, mais sans stockage massif.
Pour une main complète de 5 cartes :
[katex]C_{52}^5[/katex]
soit 2 598 960 combinaisons.
La version “lourde” devrait créer une liste contenant plus de 2,5 millions de tuples :
hands = list(combinations(range(52), 5))
Cela représente plusieurs dizaines de mégaoctets en mémoire.
En revanche, l’itérateur :
for hand in combinations(range(52), 5):
# analyse statistique
pass
ne conserve qu’une seule combinaison à la fois.
Sans itertools :
Avec itertools.combinations :
Dans un contexte combinatoire comme le poker, où les quantités passent rapidement de 1326 à plusieurs millions, cette différence n’est pas anecdotique : elle est structurelle.
La première fois que j’ai utilisé itertools.combinations — encore avec une certaine hésitation — c’était lors de la génération des mains pour l'a page'application Poker Training de site2wouf.fr.
À ce moment-là, l’objectif était simplement pratique : produire proprement toutes les mains possibles sans écrire des boucles imbriquées interminables. Ce n’est qu’ensuite que la portée conceptuelle est devenue évidente. Derrière une ligne de code concise se cachait une idée mathématique ancienne : la combinatoire.
Ce qui paraissait être un simple outil Python révélait en réalité une cohérence profonde entre la théorie et l’implémentation. Générer des mains de poker revient exactement à parcourir les [katex]C_{52}^2[/katex] combinaisons possibles. Python ne faisait que traduire, de manière élégante, une formule déjà connue.
Avec un peu de recul, cette première utilisation a marqué un déclic : combinations n’est pas seulement pratique, il incarne une manière plus rigoureuse de penser les problèmes. Plutôt que de “fabriquer des listes”, il invite à raisonner en termes de génération contrôlée, de flux, et d’efficacité.
C’est précisément là que les mathématiques et la programmation cessent d’être deux mondes distincts pour devenir deux expressions d’une même idée.
Imaginons que l’on souhaite former tous les groupes possibles de 3 élèves parmi une classe de 20.

students = [
"Alice", "Mohamed", "Sofia", "Lucas", "Yuki",
"Amina", "Ethan", "Fatou", "Mateo", "Inès",
"Noah", "Lina", "Arjun", "Chloé", "Ibrahim",
"Maya", "Diego", "Leïla", "Hugo", "Zara"
]
groups = []
for i in range(len(students)):
for j in range(i + 1, len(students)):
for k in range(j + 1, len(students)):
groups.append((students[i], students[j], students[k]))
print(len(groups))
Tester dans le Bac à sable Python!
Ce programme fonctionne.
Mais plusieurs éléments apparaissent immédiatement :
i, j, k) plutôt que d’élèves.Autrement dit, la mécanique de parcours prend le pas sur l’idée mathématique.
Et si l’on décide de former des groupes de 4 élèves, il faut ajouter une quatrième boucle.
La structure du code devient dépendante de la profondeur combinatoire.
Avec itertools.combinations, la même idée s’écrit :
from itertools import combinations
students = [
"Alice", "Mohamed", "Sofia", "Lucas", "Yuki",
"Amina", "Ethan", "Fatou", "Mateo", "Inès",
"Noah", "Lina", "Arjun", "Chloé", "Ibrahim",
"Maya", "Diego", "Leïla", "Hugo", "Zara"
]
groups = combinations(students, 3)
print(len(list(groups)))
Tester dans le Bac à sable Python!

Ici :
Mathématiquement, le nombre de groupes possibles est :
[katex]C_{20}^3[/katex]
soit 1140 combinaisons.
La structure du code ne change pas si l’on passe à 4 élèves :
groups = combinations(students, 4)
Seul le paramètre varie.
La mécanique reste identiqu...