Python dispose de deux structures de boucle.
Des boucles while pour l'itération indéfinie (non comptée), et des boucles for pour l'itération définie (comptée).
Les mots-clés break, continue et else permettent de personnaliser le comportement des boucles.
range() et enumerate() facilitent le comptage des boucles et l'accès par indice.
Les boucles while continuent de s'exécuter tant que l'loop expression ou le « test » vaut True dans un boolean context, et s'arrêtent quand il vaut False :
# Lists are considered "truthy" in a boolean context if they
# contain one or more values, and "falsy" if they are empty.
>>> placeholders = ["spam", "ham", "eggs", "green_spam", "green_ham", "green_eggs"]
>>> while placeholders:
... print(placeholders.pop(0))
...
'spam'
'ham'
'eggs'
'green_spam'
'green_ham'
'green_eggs'
La for loop de base en Python se décrit mieux comme un for each qui parcourt les valeurs de n'importe quel objet itérable, et s'arrête quand l'appel à next() ne renvoie plus de valeur :
>>> word_list = ["bird", "chicken", "barrel", "bongo"]
>>> for word in word_list:
... if word.startswith("b"):
... print(f"{word.title()} starts with a B.")
... else:
... print(f"{word.title()} doesn't start with a B.")
...
'Bird starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel starts with a B.'
'Bongo starts with a B.'
Quand aucun iterable précis n'est fourni, la séquence spéciale range() sert de compteur de boucle.
range() exige un int devant lequel stop la séquence, et prend éventuellement des paramètres start et step.
Si aucun nombre start n'est fourni, la séquence commence par 0.
Les objets range() sont paresseux (les valeurs sont générées à la demande), prennent en charge toutes les opérations courantes sur les séquences et occupent une quantité fixe de mémoire, quelle que soit la longueur de la séquence spécifiée.
# Here we use range to produce some numbers, rather than creating a list of them in memory.
# The values will start with 1 and stop *before* 7
>>> for number in range(1, 7):
... if number % 2 == 0:
... print(f"{number} is even.")
... else:
... print(f"{number} is odd.")
'1 is odd.'
'2 is even.'
'3 is odd.'
'4 is even.'
'5 is odd.'
'6 is even.'
# range() can also take a *step* parameter.
# Here we use range to produce only the "odd" numbers, starting with 3 and stopping *before* 15.
>>> for number in range(3, 15, 2):
... if number % 2 == 0:
... print(f"{number} is even.")
... else:
... print(f"{number} is odd.")
...
'3 is odd.'
'5 is odd.'
'7 is odd.'
'9 is odd.'
'11 is odd.'
'13 is odd.'
Si tu as besoin à la fois des valeurs et de leurs indices, la fonction intégrée enumerate(<iterable>) renvoie des paires (index, value) :
>>> word_list = ["bird", "chicken", "barrel", "apple"]
# *index* and *word* are the loop variables.
# Loop variables can be any valid python name.
>>> for index, word in enumerate(word_list):
... if word.startswith("b"):
... print(f"{word.title()} (at index {index}) starts with a B.")
... else:
... print(f"{word.title()} (at index {index}) doesn't start with a B.")
...
'Bird (at index 0) starts with a B.'
'Chicken (at index 1) doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Apple (at index 3) doesn\'t start with a B.'
# The same method can be used as a "lookup" for pairing items between two lists.
# Of course, if the lengths or indexes don't line up, this doesn't work.
>>> word_list = ["cat", "chicken", "barrel", "apple", "spinach"]
>>> category_list = ["mammal", "bird", "thing", "fruit", "vegetable"]
>>> for index, word in enumerate(word_list):
... print(f"{word.title()} is in category: {category_list[index]}.")
...
'Cat is in category: mammal.'
'Chicken is in category: bird.'
'Barrel is in category: thing.'
'Apple is in category: fruit.'
'Spinach is in category: vegetable.'
Le mot-clé continue permet de passer directement à l'itération suivante :
word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple", "bear"]
# This will skip *bird*, at index 0
for index, word in enumerate(word_list):
if index == 0:
continue
if word.startswith("b"):
print(f"{word.title()} (at index {index}) starts with a b.")
'Barrel (at index 2) starts with a b.'
'Bongo (at index 3) starts with a b.'
'Bear (at index 6) starts with a b.'
Le mot-clé break (comme dans beaucoup de langages apparentés au C) permet d'arrêter l'itération et de « sortir » de la loop englobante la plus interne :
>>> word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple"]
>>> for index, word in enumerate(word_list):
... if word.startswith("b"):
... print(f"{word.title()} (at index {index}) starts with a B.")
... elif word == "sliver":
... break
... else:
... print(f"{word.title()} doesn't start with a B.")
... print("loop broken.")
...
'Bird (at index 0) starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Bongo (at index 3) starts with a B.'
'loop broken.'
Tu es assistant d'enseignement et tu corriges les examens des élèves. Suivre les résultats à la main devient à la fois fastidieux et propice aux erreurs. Tu décides de rendre la chose un peu plus intéressante en écrivant quelques fonctions pour compter et calculer les résultats de la classe.
Tu peux accorder des « points partiels » sur les questions d'examen, mais les notes globales doivent être des ints.
Donc, avant de pouvoir faire quoi que ce soit d'autre avec les notes de la classe, tu dois parcourir ces notes et convertir en ints toutes celles qui sont des float.
Heureusement pour toi, Python possède la fonction intégrée round() que tu peux utiliser.
Crée la fonction round_scores(student_scores) qui prend une list de student_scores.
Cette fonction doit consommer la list d'entrée et return un nouveau tableau contenant toutes les notes converties en ints.
L'ordre des notes dans la list obtenue n'a pas d'importance.
>>> student_scores = [90.33, 40.5, 55.44, 70.05, 30.55, 25.45, 80.45, 95.3, 38.7, 40.3]
>>> round_scores(student_scores)
...
[40, 39, 95, 80, 25, 31, 70, 55, 40, 90]
Pendant que tu corrigeais l'examen, tu as remarqué que certains élèves ne réussissaient pas aussi bien que tu l'espérais. Mais tu étais distrait, et tu as oublié de noter exactement combien d'élèves étaient dans ce cas.
Crée la fonction count_failed_students(student_scores) qui prend une list de student_scores.
Cette fonction doit compter le nombre d'élèves qui n'ont pas une note suffisante et renvoyer ce nombre sous forme d'entier.
Un élève doit obtenir une note supérieure à 40 pour réussir l'examen.
>>> count_failed_students(student_scores=[90,40,55,70,30,25,80,95,38,40])
5
L'enseignant que tu assistes veut trouver le groupe d'élèves qui ont été « les meilleurs » à cet examen. Ce que signifie « les meilleurs » varie, tu dois donc trouver les notes qui sont supérieures ou égales au seuil actuel.
Crée la fonction above_threshold(student_scores, threshold) qui prend en paramètres student_scores (une list de notes) et threshold (le seuil de la « meilleure note »).
Cette fonction doit renvoyer une list de toutes les notes qui sont >= à threshold.
>>> above_threshold(student_scores=[90,40,55,70,30,68,70,75,83,96], threshold=75)
[90,75,83,96]
L'enseignant que tu assistes aime attribuer des notes alphabétiques en plus des notes numériques. Comme les élèves obtiennent rarement 100 à un examen, les seuils inférieurs des « notes alphabétiques » sont calculés à partir de la meilleure note obtenue, et augmentent régulièrement entre cette meilleure note et le seuil d'échec de <= 40.
Crée la fonction letter_grades(highest) qui prend en argument la note « la plus haute » de l'examen et renvoie une list de seuils inférieurs pour chaque intervalle de notes « à l'américaine » : ["D", "C", "B", "A"].
"""Where the highest score is 100, and failing is <= 40.
"F" <= 40
41 <= "D" <= 55
56 <= "C" <= 70
71 <= "B" <= 85
86 <= "A" <= 100
"""
>>> letter_grades(highest=100)
[41, 56, 71, 86]
"""Where the highest score is 88, and failing is <= 40.
"F" <= 40
41 <= "D" <= 52
53 <= "C" <= 64
65 <= "B" <= 76
77 <= "A" <= 88
"""
>>> letter_grades(highest=88)
[41, 53, 65, 77]
Tu disposes d'un tableau de notes d'examen classées par ordre décroissant, et d'un autre tableau de noms d'élèves, lui aussi trié par ordre décroissant selon leurs notes d'examen. Tu aimerais associer chaque nom d'élève à sa note et afficher un classement général de la classe.
Crée la fonction student_ranking(student_scores, student_names) avec les paramètres student_scores et student_names.
Associe chaque nom d'élève de la list student_names à sa note de la list student_scores.
Tu peux supposer que chaque list passée en argument sera triée de la meilleure note (donc du meilleur élève) à la plus basse (donc au moins bon élève).
La fonction doit renvoyer une list de strings au format <rank>. <student name>: <student score>.
>>> student_scores = [100, 99, 90, 84, 66, 53, 47]
>>> student_names = ['Joci', 'Sara','Kora','Jan','John','Bern', 'Fred']
>>> student_ranking(student_scores, student_names)
...
['1. Joci: 100', '2. Sara: 99', '3. Kora: 90', '4. Jan: 84', '5. John: 66', '6. Bern: 53', '7. Fred: 47']
Même si une note « parfaite » de 100 est rare à un examen, il est intéressant de savoir si au moins un élève l'a obtenue.
Crée la fonction perfect_score(student_info) avec le paramètre student_info.
student_info est une list de tableaux contenant le nom et la note de chaque élève : [["Charles", 90], ["Tony", 80]].
La fonction doit return la première paire [<name>, <score>] de l'élève qui a obtenu 100 à l'examen.
Si aucune note de 100 n'est trouvée dans student_info, un tableau vide [] doit être renvoyé.
>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80], ["Alex", 100]])
["Alex", 100]
>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80]])
[]
Inscris-toi sur Exercism pour apprendre et maîtriser Python avec 17 concepts146 exercices, et un vrai mentorat humain, le tout gratuitement.