Dictionnaires
Chaque exercice est fourni avec un fichier Python à compléter et un énoncé « papier » distribué à l'élève et reproduit ci-dessous.
Remarques importantes
-
Les exercices de cette page ne sont pas classés par ordre de « difficulté », cette notion de difficulté étant subjective et dépendante de chaque élève.
-
Les solutions proposées ne sont que des propositions !
Il existe d'autres codes valables pour répondre à chaque problème que ceux proposés ici : il ne faut pas hésiter à les soumettre à votre enseignant pour qu'il vous donne son avis sur les idées mises en oeuvre.
Dictionnaire cyclique ?☘
On considère au plus 26 personnes A, B, C, D, E, F ... qui peuvent s'envoyer des messages avec deux règles à respecter :
- chaque personne ne peut envoyer des messages qu'à la même personne (éventuellement elle-même),
- chaque personne ne peut recevoir des messages qu'en provenance d'une seule personne (éventuellement elle-même).
Voici un exemple - avec 6 personnes - de « plan d'envoi des messages » qui respecte les règles ci-dessus, puisque chaque personne est présente une seule fois dans chaque colonne :
- A envoie ses messages à E
- E envoie ses messages à B
- B envoie ses messages à F
- F envoie ses messages à A
- C envoie ses messages à D
- D envoie ses messages à C
Et le dictionnaire correspondant à ce plan d'envoi est le suivant :
plan_a = {'A': 'E', 'B': 'F', 'C': 'D', 'D': 'C', 'E': 'B', 'F': 'A'}
plan_a
des messages ci-dessus, il y a deux cycles
distincts : un premier cycle avec A, E, B, F et un second cycle avec
C et D.
En revanche, le plan d’envoi plan_b
ci-dessous :
plan_b = {'A': 'C', 'B': 'F', 'C': 'E', 'D': 'A', 'E': 'B', 'F': 'D'}
Dans ce cas, lorsqu’un plan d’envoi comporte un unique cycle, on dit que le plan d’envoi est cyclique.
Pour savoir si un plan d'envoi de messages comportant N personnes est cyclique, on peut utiliser l'algorithme ci-dessous :
On part de la personne A et on inspecte les N–1 successeurs dans le plan d'envoi :
-
Si un de ces N–1 successeurs est A lui-même, on a trouvé un cycle de taille inférieure ou égale à N–1. Il y a donc au moins deux cycles et le plan d'envoi n'est pas cyclique.
-
Si on ne retombe pas sur A lors de cette inspection, on a un unique cycle qui passe par toutes les personnes : le plan d'envoi est cyclique.
La fonction est_cyclique()
doit prendre en paramètre un dictionnaire plan
correspondant à un plan d'envoi de messages entre N personnes A, B, C, D, E,
F ...(avec N <= 26). Elle renvoie Vrai si le plan d'envoi de messages est
cyclique et Faux sinon.
Exemples
>>> est_cyclique({'A':'E', 'F':'A', 'C':'D', 'E':'B', 'B':'F', 'D':'C'})
False
>>> est_cyclique({'A':'E', 'F':'C', 'C':'D', 'E':'B', 'B':'F', 'D':'A'})
True
-
Compléter la définition de la fonction
est_cyclique()
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
def est_cyclique(plan): """ plan - Sortie: >>> est_cyclique({'A':'E', 'F':'A', 'C':'D', 'E':'B', 'B':'F', 'D':'C'}) False >>> est_cyclique({'A':'E', 'F':'C', 'C':'D', 'E':'B', 'B':'F', 'D':'A'}) True """ pass if __name__ == '__main__': import doctest doctest.testmod()
-
Compléter le docstring de cette fonction.
- Ajouter au moins deux nouveaux tests avec affichage dans la partie principale
du programme (le
main
).
Une solution possible
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Occurrences des caractères d'une chaîne☘
L’occurrence d’un caractère dans un phrase est le nombre de fois où ce caractère est présent.
Exemples
- L’occurrence du caractère
'o'
dans'bonjour'
est 2 ; - L’occurrence du caractère
'b'
dans'Bébé'
est 1 ; - L’occurrence du caractère
'B'
dans'Bébé'
est 1 ; - L’occurrence du caractère
' '
dans'Hello world !'
est 2.
On cherche les occurrences des caractères dans une phrase. On souhaite stocker ces occurrences dans un dictionnaire dont les clefs seraient les caractères de la phrase et les valeurs associées l’occurrence de ces caractères.
La fonction occurrences_lettres()
prend comme paramètre phrase
, une chaîne de
caractères. Cette fonction doit renvoyer un dictionnaire dont les clefs sont
les caractères présents dans phrase
et dont les valeurs associées sont les
occurrences de ces caractères dans phrase
.
Exemple
>>> occurrences_lettres('Hello world !')
{'H': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 2, 'w': 1, 'r': 1, 'd': 1, '!': 1}
-
Compléter la définition de la fonction
occurrences_lettres()
.1 2 3 4 5 6 7 8 9 10 11 12 13 14
def occurrences_lettres(phrase): """ phrase - Sortie: >>> occurrences_lettres('Hello world !') {'H': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 2, 'w': 1, 'r': 1, 'd': 1, '!': 1} """ pass if __name__ == '__main__': import doctest doctest.testmod()
-
Compléter le docstring de cette fonction.
- Ajouter au moins deux nouveaux tests avec affichage dans la partie principale
du programme (le
main
).
Une solution possible
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Élections☘
Les résultats d'un vote sont stockés dans un tableau.
Exemple
Pour trois candidats A, B et C et 10 votants :
urne = ['A', 'A', 'A', 'B', 'C', 'B', 'C', 'B', 'C', 'B']
La fonction depouille()
doit permettre de compter le nombre de votes exprimés
pour chaque candidat. Elle prend en paramètre un tableau et renvoie le résultat
dans un dictionnaire dont les clés sont les noms des candidats et les valeurs
le nombre de votes en leur faveur.
La fonction vainqueur()
doit désigner le nom du ou des gagnants. Elle prend
en paramètre un dictionnaire dont la structure est celle du dictionnaire
renvoyé par la fonction depouille()
et renvoie un tableau. Ce tableau peut
donc contenir plusieurs éléments s’il y a des candidats ex-aequo.
Exemple
>>> urne = ['A', 'A', 'A', 'B', 'C', 'B', 'C', 'B', 'C', 'B']
>>> election = depouille(urne)
>>> election
{'A': 3, 'B': 4, 'C': 3}
>>> vainqueur(election)
['B']
-
Compléter la définition des fonctions
depouille()
etvainqueur()
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
def depouille(urne): """ urne - Sortie: >>> urne = ['A', 'A', 'A','B', 'C', 'B', 'C','B', 'C', 'B'] >>> depouille(urne) {'A': 3, 'B': 4, 'C': 3} """ pass def vainqueur(election): """ election - Sortie: >>> election = {'B': 4, 'A': 3, 'C': 3} >>> vainqueur(election) ['B'] """ pass if __name__ == '__main__': import doctest doctest.testmod()
-
Compléter les docstring de ces fonctions.
- Ajouter au moins deux nouveaux tests avec affichage dans la partie principale
du programme (le
main
).
Une solution possible
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
|
Minimum et maximum simultanés☘
Écrire une fonction rechercheMinMax()
qui prend en paramètre un tableau non
vide d'entiers non triés tab
, et qui renvoie la plus petite et la plus
grande valeur du tableau sous la forme d’un dictionnaire à deux clés 'min'
et 'max'
.
Exemple
>>> rechercheMinMax( [0, 1, 4, 2, -2, 9, 3, 1, 7, 1] )
{'min': -2, 'max': 9}
>>> rechercheMinMax( [] )
{'min': None, 'max': None}
-
Compléter la définition de la fonction
rechercheMinMax()
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
def rechercheMinMax(tab): """ tab - Sortie: >>> rechercheMinMax( [0, 1, 4, 2, -2, 9, 3, 1, 7, 1] ) {'min': -2, 'max': 9} >>> rechercheMinMax( [] ) {'min': None, 'max': None} """ pass if __name__ == '__main__': import doctest doctest.testmod()
-
Compléter le docstring de cette fonction.
- Ajouter au moins deux nouveaux tests avec affichage dans la partie principale
du programme (le
main
).
Une solution possible
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Plus grande valeur associée☘
Sur le réseau social TipTop, on s’intéresse au nombre de « like » des abonnés. Les données sont stockées dans des dictionnaires où les clés sont les pseudos et les valeurs correspondantes sont les nombres de « like » comme ci-dessous :
{'Bob': 102, 'Ada': 201, 'Alice': 103, 'Tim': 50}
Écrire une fonction max_dico()
qui :
- prend en paramètre un dictionnaire
dico
non vide dont les clés sont des chaînes de caractères et les valeurs associées sont des entiers ; - renvoie un tuple dont :
- la première valeur est la clé du dictionnaire associée à la valeur maximale ;
- la seconde valeur est la valeur maximale présente dans le dictionnaire.
Si le maximum apparaît plusieurs fois, le « plus petit » pseudo par ordre alphabétique est renvoyé.
Exemple
>>> max_dico({'Bob': 102, 'Ada': 201, 'Alice': 103, 'Tim': 50})
('Ada', 201)
>>> max_dico({'Alan': 201, 'Ada': 201, 'Alice': 103, 'Tim': 50})
('Ada', 201)
>>> max_dico({})
AssertionError: Le dictionnaire est vide !
-
Compléter la définition de la fonction
max_dico()
, sans oublier d'ajouter l'assertion signalée dans l'exemple précédent.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
def max_dico(dico): """ dico - Sortie: >>> max_dico({'Bob': 102, 'Ada': 201, 'Alice': 103, 'Tim': 50}) ('Ada', 201) >>> max_dico({'Alan': 201, 'Ada': 201, 'Alice': 103, 'Tim': 50}) ('Ada', 201) """ pass if __name__ == '__main__': import doctest doctest.testmod()
-
Compléter le docstring de cette fonction.
- Ajouter au moins deux nouveaux tests avec affichage dans la partie principale
du programme (le
main
).
Une solution possible
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
Plus grande occurrence☘
Écrire une fonction occurrence_max()
prenant en paramètres une chaîne de
caractères chaine
et qui renvoie le caractère le plus fréquent de la chaîne.
La chaine ne contient que des lettres en minuscules sans accent.
On pourra s’aider de la chaîne
alphabet = 'abcdefghijklmnopqrstuvwxyz'
occurrence
de 26 éléments où l’on mettra dans
occurrence[i]
le nombre d’apparitions de alphabet[i]
dans la chaine.
Puis on calculera l’indice k
d’un maximum du tableau occurrence
et on
affichera alphabet[k]
. Le caractère le « petit » sera renvoyé
en cas d'égalité d'occurrence.
Exemple
>>> ch = "je suis en premiere et je souhaite poursuivre des etudes pour devenir expert en informatique"
>>> occurrence_max(ch)
'e'
-
Compléter la définition de la fonction
occurrence_max()
, sans oublier d'ajouter l'assertion signalée dans l'exemple précédent.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
def occurrence_max(chaine): """ chaine - Sortie: >>> ch = "je suis en premiere et je souhaite poursuivre des etudes pour devenir expert en informatique" >>> occurrence_max(ch) 'e' """ alphabet = 'abcdefghijklmnopqrstuvwxyz' pass if __name__ == '__main__': import doctest doctest.testmod()
-
Compléter le docstring de cette fonction.
- Ajouter au moins deux nouveaux tests avec affichage dans la partie principale
du programme (le
main
).
Une solution possible avec un dictionnaire
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Une solution possible avec une fonction supplémentaire
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
Une solution possible avec les fonctions chr()
et ord()
On rappelle que ord('a')
vaut 97.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
Sélection dans une table de données☘
On considère des tables (des tableaux de dictionnaires) qui contiennent des
enregistrements relatifs à des animaux hébergés dans un refuge. Les attributs
des enregistrements sont 'nom'
, 'espece'
, 'age'
, 'enclos'
.
Voici un exemple d'une telle table :
animaux = [ {'nom':'Medor', 'espece':'chien', 'age':5, 'enclos':2},
{'nom':'Titine', 'espece':'chat', 'age':2, 'enclos':5},
{'nom':'Tom', 'espece':'chat', 'age':7, 'enclos':4},
{'nom':'Belle', 'espece':'chien', 'age':6, 'enclos':3},
{'nom':'Mirza', 'espece':'chat', 'age':6, 'enclos':5}]
Programmer une fonction selection_enclos()
qui :
- prend en paramètres :
- une table
table_animaux
contenant des enregistrements relatifs à des animaux (comme dans l'exemple ci-dessus), - un numéro d'enclos
num_enclos
;
- une table
- renvoie une table contenant les enregistrements de
table_animaux
dont l'attribut'enclos'
estnum_enclos
.
Exemples
Avec la table `animaux ci-dessus :
>>> selection_enclos(animaux, 5)
[{'nom': 'Titine', 'espece': 'chat', 'age': 2, 'enclos': 5},
{'nom': 'Mirza', 'espece': 'chat', 'age': 6, 'enclos': 5}]
>>> selection_enclos(animaux, 2)
[{'nom': 'Medor', 'espece': 'chien', 'age': 5, 'enclos': 2}]
>>> selection_enclos(animaux, 7)
[]
-
Compléter la définition de la fonction
selection_enclos()
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
def selection_enclos(table_animaux, num_enclos): """ table_animaux - num_enclos - Sortie: >>> selection_enclos(animaux, 5) [{'nom': 'Titine', 'espece': 'chat', 'age': 2, 'enclos': 5}, {'nom': 'Mirza', 'espece': 'chat', 'age': 6, 'enclos': 5}] >>> selection_enclos(animaux, 2) [{'nom': 'Medor', 'espece': 'chien', 'age': 5, 'enclos': 2}] >>> selection_enclos(animaux, 7) [] """ pass if __name__ == '__main__': import doctest doctest.testmod()
-
Compléter le docstring de cette fonction.
- Ajouter au moins deux nouveaux tests avec affichage dans la partie principale
du programme (le
main
).
Une solution possible
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Moyennes pondérées☘
Un professeur de NSI décide de gérer les résultats de sa classe sous la forme d’un dictionnaire :
- les clefs sont les noms des élèves ;
- les valeurs sont des dictionnaires dont les clefs sont les types d’épreuves et les valeurs sont les notes obtenues associées à leurs coefficients.
Exemple
Voici un exemple d'un tel dictionnaire, dans lequel L’élève de nom « Durand » a obtenu la note de 8 au DS2 dont le coefficient est 4.
resultats = {'Dupont': {'DS1' : [15.5, 4],
'DM1' : [14.5, 1],
'DS2' : [13, 4],
'PROJET1' : [16, 3],
'DS3' : [14, 4] },
'Durand': {'DS1' : [6 , 4],
'DM1' : [14.5, 1],
'DS2' : [8, 4],
'PROJET1' : [9, 3],
'IE1' : [7, 2],
'DS3' : [8, 4],
'DS4' : [15, 4]} }
Le professeur crée une fonction nommée moyennes()
qui prend en paramètre un
tel dictionnaire et qui renvoie un dictionnaire qui associe à chaque élève sa
moyenne arrondie au dixième.
Exemples
>>> moyennes(resultats)
{'Dupont': 14.5, 'Durand': 9.2}
Aide pour l'arrondi
La fonction pré-programmée round()
permet d'arrondir au nombre de
décimales suohaité, passé en paramètre :
>>> round(1.873, 1)
1.9
>>> round(1.873, 2)
1.87
-
Compléter la définition de la fonction
moyennes()
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
def moyennes(resultats): """ resultats - Sortie: >>> moyennes(resultats) {'Dupont': 14.5, 'Durand': 9.2} """ pass if __name__ == '__main__': resultats = {'Dupont':{'DS1' : [15.5, 4], 'DM1' : [14.5, 1], 'DS2' : [13, 4], 'PROJET1' : [16, 3], 'DS3' : [14, 4] }, 'Durand':{'DS1' : [6 , 4], 'DM1' : [14.5, 1], 'DS2' : [8, 4], 'PROJET1' : [9, 3], 'IE1' : [7, 2], 'DS3' : [8, 4], 'DS4' : [15, 4]}} import doctest doctest.testmod()
-
Compléter le docstring de cette fonction.
- Ajouter au moins un nouveau test avec affichage dans la partie principale
du programme (le
main
).
Une solution possible
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
|
Code alphabétique d'un mot☘
On affecte à chaque lettre de l’alphabet un code selon le tableau ci-dessous :
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
Pour un mot donné, on détermine d’une part son code alphabétique concaténé,
obtenu par la juxtaposition des codes de chacun de ses caractères, et d’autre
part, son code additionné, qui est la somme des codes de chacun de ses
caractères.
Par ailleurs, on dit que ce mot est « parfait » si le code additionné
divise le code concaténé.
Exemples :
-
Pour le mot
"PAUL"
, le code concaténé est la chaîne'1612112'
, soit l’entier 1 612 112.
Son code additionné est l’entier 50 car 16 + 1 + 21 + 12 = 50.
50 ne divise pas l’entier 1 612 112 ; par conséquent, le mot"PAUL"
n’est pas parfait. -
Pour le mot
"ALAIN"
, le code concaténé est la chaîne'1121914'
, soit l’entier 1 121 914.
Son code additionné est l’entier 37 car 1 + 12 + 1 + 9 + 14 = 37.
37 divise l’entier 1 121 914 ; par conséquent, le mot"ALAIN"
est parfait.
La fonction est_parfait
prend comme argument une chaîne de caractères mot
(en lettres majuscules) et renvoie un triplet constitué du code additionné
de mot
, du code alphabétique concaténé, ainsi qu’un booléen qui
indique si mot
est parfait ou pas.
Exemples
Attention aux types...
>>> est_parfait("PAUL")
(50, 1612112, False)
>>> est_parfait("ALAIN")
(37, 1121914, True)
-
Compléter la définition de la fonction
est_parfait()
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
def est_parfait(mot) : """ mot - Sortie: >>> est_parfait("PAUL") (50, 1612112, False) >>> est_parfait("ALAIN") (37, 1121914, True) """ pass if __name__ == '__main__': dico = {"A":1, "B":2, "C":3, "D":4, "E":5, "F":6, "G":7, "H":8, "I":9, "J":10, "K":11, "L":12, "M":13, "N":14, "O":15, "P":16, "Q":17, "R":18, "S":19, "T":20, "U":21,"V":22, "W":23, "X":24, "Y":25, "Z":26} import doctest doctest.testmod()
-
Compléter le docstring de cette fonction.
- Ajouter au moins deux nouveaux tests avec affichage dans la partie principale
du programme (le
main
).
Une solution possible
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|