Dictionnaire modélisant le contenu d'un répertoire⚓︎
D'après 2022, Centres étrangers, J1, Ex. 3
Afin d'organiser les répertoires et les fichiers sur un disque dur, une structure arborescente est utilisée. Les fichiers sont dans des répertoires qui sont eux-mêmes dans d'autres répertoires, etc.
Dans une arborescence, chaque répertoire peut contenir des fichiers et des répertoires, qui sont identifiés par leur nom. Le contenu d'un répertoire est modélisé par la structure de données dictionnaire. Les clés de ce dictionnaire sont des chaines de caractères donnant le nom des fichiers et des répertoires contenus.
Un répertoire
Un répertoire est représenté par un dictionnaire dont chaque clé est :
- soit un nom de sous répertoire : la valeur associée est alors un dictionnaire représentant le contenu de ce sous répertoire.
- soit un nom de fichier : la valeur associée est alors un entier, représentant la taille du fichier en ko.
Un fichier est donc une clé d'un répertoire(dictionnaire) dont la valeur associée est un entier.
Exemple illustré
Le répertoire appelé Téléchargements
contient deux fichiers rapport.pdf
et jingle.mp3
ainsi qu'un répertoire Images
contenant simplement le fichier logo.png
.
Il est représenté ci-dessous.
%%{init: {'themeVariables': {'fontFamily': 'monospace'}}}%%
flowchart TB
n0[[Téléchargements]] --> n1[[Images]]
n1 --> n4(logo.png)
n0 --> n2(rapport.pdf)
n0 --> n3(jingle.mp3)
Ce répertoire Téléchargements
est modélisé en Python par le dictionnaire suivant :
{"Images": {"logo.png": 36}, "rapport.pdf": 450, "jingle.mp3": 4800}
Les valeurs numériques sont exprimées en ko (kilo-octets).
"logo.png": 36
signifie que le fichier logo.png
occupe un espace mémoire de 36 ko sur le disque dur.
On rappelle, ci-dessous, quelques commandes sur l'utilisation d'un dictionnaire :
dico = dict()
crée un dictionnaire vide appelédico
,dico[cle] = contenu
met la valeurcontenu
pour la clécle
dans le dictionnairedico
,dico[cle]
renvoie la valeur associée à la clécle
dans le dictionnairedico
,cle in dico
renvoie un booléen indiquant si la clécle
est présente dans le dictionnairedico
.for cle in dico:
permet d'itérer sur les clés d'un dictionnaire.len(dico)
renvoie le nombre de clés d'un dictionnaire.
L'adresse d'un fichier ou d'un répertoire correspond au nom de tous les répertoires à parcourir depuis la racine afin d'accéder au fichier ou au répertoire. Cette adresse est modélisée en Python par la liste des noms de répertoire à parcourir pour y accéder.
Exemple : L'adresse du répertoire : /home/pierre/Documents/
est modélisée par la liste ["home", "pierre", "Documents"]
.
1. Dessiner l'arbre donné par le dictionnaire docs
suivant, qui correspond au répertoire "Documents"
.
docs = {
"Administratif":{
"certificat_JDC.pdf": 1500,
"attestation_recensement.pdf": 850
},
"Cours": {
"NSI": {
"TP.html": 60,
"dm.odt": 345
},
"Philo": {
"Tractatus_logico-philosophicus.epub": 2600
}
},
"liste_de_courses.txt": 24
}
Réponse
%%{init: {'themeVariables': {'fontFamily': 'monospace'}}}%%
flowchart TB
doc[[Documents]] --> adm[[Administratif]]
adm --> certif(certificat_JDC.pdf)
adm --> attest(attestation_recensement.pdf)
doc --> cours[[Cours]]
cours --> nsi[[NSI]]
nsi --> tp(TP.html)
nsi --> dm(dm.odt)
cours --> philo[[Philo]]
philo --> tlp(Tractatus_logico-philosophicus.epub)
doc --> lst(liste_de_courses.txt)
2. On donne la fonction parcourt
suivante qui prend en paramètres un répertoire racine et une liste représentant une adresse, et qui renvoie le contenu du répertoire cible correspondant à l'adresse.
Exemple : Si la variable docs
contient le dictionnaire de l'exemple de la question 1 alors parcourt(docs, ["Cours", "Philo"])
renvoie le dictionnaire {"Tractatus_logico-philosophicus.epub": 2600}
.
2.a. Recopier et compléter la ligne 4
def parcourt(racine, adr):
repertoire = racine
for nom_repertoire in adr:
repertoire = ...
return repertoire
Réponse
def parcourt(racine, adr):
repertoire = racine
for nom_repertoire in adr:
repertoire = repertoire[nom_repertoire]
return repertoire
2.b. Soit la fonction suivante :
def affiche(racine, adr, nom_fichier):
repertoire = parcourt(racine, adr)
print(repertoire[nom_fichier])
Qu'affiche l'instruction affiche(docs, ["Cours", "NSI"], "TP.html")
sachant que la variable docs
contient le dictionnaire de la question 1 ?
Réponse
- La première instruction fait que
repertoire
correspond au dictionnaire"NSI"
qui vaut{"TP.html": 60, "dm.odt": 345}
. - La seconde affiche la valeur associée à la clé
"TP.html"
de ce dictionnaire, c'est-à-dire le poids en ko de ce fichier.
L'affichage est donc
>>> affiche(docs, ["Cours", "NSI"], "TP.html")
60
3.a. La fonction ajoute_fichier
suivante, de paramètres racine
, adr
, nom_fichier
et taille
, ajoute au dictionnaire racine
, à l'adresse adr
, la clé nom_fichier
associé à la valeur taille
.
Une ligne de la fonction donnée ci-dessous contient une erreur. Laquelle ? Proposer une correction.
def ajoute_fichier(racine, adr, nom_fichier, taille):
repertoire = parcourt(racine, adr)
taille = repertoire[nom_fichier]
Réponse
def ajoute_fichier(racine, adr, nom_fichier, taille):
repertoire = parcourt(racine, adr)
repertoire[nom_fichier] = taille
3.b. Écrire une fonction ajoute_repertoire
de paramètres racine
, adr
et nom_repertoire
qui crée un dictionnaire représentant un répertoire vide appelé nom_repertoire
dans le dictionnaire racine
à l'adresse adr
.
Réponse
def ajoute_repertoire(racine, adr, nom_repertoire):
repertoire = parcourt(racine, adr)
repertoire[nom_repertoire] = dict()
4.a.
isinstance
pour vérifier le type d'une variable
isinstance(variable, A)
renvoie True
si variable
est de type A
et False
sinon.
A
peut être le type int
, dict
ou tout autre type Python.
Écrire une fonction est_fichier
de paramètres repertoire
et cle
, où cle
est une clé du dictionnaire repertoire
, qui détermine si cle
correspond à un fichier ou non. Si cle
n'est pas une clé de repertoire
, la fonction doit provoquer une erreur.
On pourra compléter le code suivant ou en proposer un autre
def est_fichier(repertoire, cle):
return ...
Réponse
Une version simple est
def est_fichier(repertoire, cle):
return isinstance(repertoire[cle], int)
Pour choisir le message d'erreur, on peut écrire
def est_fichier(repertoire, cle):
if cle in repertoire:
return isinstance(repertoire[cle], int)
else:
raise KeyError("cle n'est pas une clé de repertoire")
4.b Écrire une fonction taille
de paramètre racine
qui prend en paramètre un dictionnaire racine
modélisant un répertoire et qui renvoie le total d'espace mémoire occupé par les fichiers contenus dans ce répertoire et ceux qu'il contient, de manière récursive.
Réponse
def taille(racine):
cumul = 0
for cle in racine:
if est_fichier(racine, cle):
cumul += racine[cle]
else:
cumul += taille(racine[cle])
return cumul