Système de fichiers

On s'intéresse dans cet exercice au système de fichiers sur un ordinateur. On considère dans ce cadre les deux éléments suivants :

  • des fichiers, représentés en machine par des tuples au format (nom_du fichier, None). nom_du_fichier est une chaîne de caractères ;

  • des dossiers, représentés en machine par des tuples au format (nom_du_dossier, liste_des_enfants). nom_du_dossier est une chaîne de caractères, liste_des_enfants est une liste contenant de nouveaux éléments (fichiers ou dossiers).

L'exemple ci-dessous est constitué d'un dossier nommé racine contenant un fichier (un.py) et un sous-dossier (nommé sous_dossier) contenant lui-même deux fichiers (deux.pdf et trois.jpg) :

Système de fichier
racine
├───un.py
└───sous_dossier
    ├───deux.pdf
    └───trois_jpg

Ce dossier est représenté en machine par le tuple :

Représentation en Python
("racine", [("un.py", None), ("sous_dossier", [("deux.pdf", None), ("trois.jpg", None)])])

On fournit deux fonctions, est_fichier et est_dossier, indiquant, pour un élément quelconque, s'il s'agit d'un fichier ou d'un dossier :

🐍 Console Python
>>> elt = ("un.py", None)
>>> est_fichier(elt)
True
>>> est_dossier(elt)
False
>>> elt = ("dossier_vide", [])
>>> est_fichier(elt)
False
>>> est_dossier(elt)
True
Code des deux fonctions
🐍 Script Python
def est_fichier(elt):
    return elt[1] is None

def est_dossier(elt):
    return type(elt[1]) is list

On cherche dans cet exercice, étant donné un dossier, à calculer le nombre de dossiers et de fichiers qu'il contient ainsi que sa profondeur et le contenu d'un de ses sous-dossiers descendant.

1. Nombre de dossiers

Écrire la fonction nb_dossiers qui prend en paramètre un tuple représentant un dossier et renvoie le nombre de dossiers que celui-ci contient au total : lui-même et ses sous-dossiers ainsi que les sous-dossiers de ceux-ci...

Exemples
>>> dossier_nsi = ("nsi", [("tp1.py", None), ("tp1.pdf", None)])
>>> nb_dossiers(dossier_nsi)
1
>>> dossier_doc = ("documents", [("photo.jpg", None), dossier_nsi])
>>> nb_dossiers(dossier_doc)
2

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10

.128013ben4vi[3mo5_tPhklpwf(: cga=ryS6]u/2)s1+d050O0c0n0A0g0r0L0x0y0r0A0L0L0B010n0g0s010406050L0H0j0j0A0C0D040E0k0r0H0)0k0d050I0:0=0@0_0.0s040519121c0I190.0O0g0f0X0Z0#0%0p0g0z0p0r1q0p0n0,050S0b0r0c1l0!0$011p1r1t1r0n1z1B1x0n0C1a0n0p0X0|0L0s0A0d0%0J011D1n010u0U0c0d0A0j0c1x1W1Y1%1F1*1B1-1/0,0a0x0o0C0k0s0k0L0g0 0d0x0Q1U0C0C0c0y27121=0d1a0I1S2k1P1R1Q1y0O1@0%1t0d1,241x1i1k0Y1E2u0g2w0d0k2A1x0s2d1a2i2k2O0/1X282C1(2H0C0?0r0,0M2h2S0-2R1?2U1F2W2Y0,0J2$1Y2(2i2t012-0A2Z040i2;2j0.2@2+0%2`2|0e2 2?2S2^350,0l38313a332_0k2X2{0,0F381d2M122A2n0O1R2s3i0y2I1:1a3t1b3r2Q132%053z0Q2N3h1m1F0q0,0Q0u3p323O0%0t0,0x3U3N2D2_0u0,0d0b0m0O24250c0C0L3#2*3W010+040v3@2T3_0d3R3/0g3;3~2^3{0K0w3f0x4c3!3V3%41040n384e3$1(0k0,0B4k2)3 3%0j0g2!4b4d4s2^3Q040u3k4r4f2V0,0c0r4j3H2=4l3^3%0k3Y042F4G4m2,420#440C463i3{0h4%3_4v4x4N2j4A4(0,0G4a4/0-4d4{4P4t1(4C0g3T4_4}3b4J0L0n3-43454_4;3_3{3}5c4H4Y044K4M2Q5i0%484^2O064|5u543i4h5m2%5w3_4o040N4q535d4g3*3,3.4!3;3?5h4X5p0,5g5n5R2_4J4L4+3%484y4c5I4 0,2d0n0H0C115H5o5X4i3f123K0c2k2L5{3s1j3u2n2q2l0A1A5~0I3t0.680R0T0V04.
2. Nombre de fichiers

Écrire la fonction nb_fichiers qui prend en paramètre un tuple représentant un dossier et renvoie le nombre de fichiers que celui-ci contient au total : ses fichiers mais aussi ceux présents dans ses sous-dossiers et les sous-dossiers de ceux-ci...

Exemples
>>> dossier_nsi = ("nsi", [("tp1.py", None), ("tp1.pdf", None)])
>>> nb_fichiers(dossier_nsi)
2
>>> dossier_doc = ("documents", [("photo.jpg", None), dossier_nsi])
>>> nb_fichiers(dossier_doc)
3

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10

.128013ben4vi[+3mo5_tPhklpwf(: cga=ry0S6]u/72)s18d050R0c0o0B0g0s0O0y0z0s0B0O0O0C010o0g0t010406050O0J0k0k0B0D0E040G0l0s0J0,0l0d050K0?0^0`0|0;0t04051c151f0K1c0;0R0g0f0!0$0(0*0q0g0A0q0s1t0q0o0/050V0b0s0c1o0%0)011s1u1w1u0o1C1E1A0o0D1d0o0q0!0 0O0t0B0d0*0M011G1q010v0X0c0d0B0k0c1A1Z1#1*1I1-1E1:1=0/0a0y0p0D0l0t0l0O0g120d0y0T1X0D0D0c0z2a151^0d1d0K1V2n1S1U1T1B0R1`0*1w0d1/271A1l1n0#1H2x0g2z0d0l2D1A0t2g1d2l2n2R0=1!2b2F1+2K0D0_0s0/0P2k2V0:2U1_2X1I2Z2#0/0M2)1#2+2l2w012:0B2$040j2@2m0;2`2.0*2}2 0e322_2V2{380/0m3b343d362|0l2!2~0/0H3i2,2W1p2/3n2;040L3s353v373x3p040Q3b1g2P152D2q0R1U2v3l0z2L1?1d3N1e3L2T162*053T0T2Q3k3D010r0/0T0v3J3C2G010u0/0y3=3+3@0d0v0/0d0b0n1-0z1s0c0D0O3|2-3,0.040w4b3u3~3/2728484h2{4e0N0x3i0y4u3{3?2Y0/0o3b4w3}1+0l0/0C4B3t2{0k0g0/0F4t4v4J3l3.040v3n4I4x2/0/0c0s4A3#2^4C4c3@0l3_042I4X4D4Z040R4l0g4n4(2m4R4d0/0h4o3l4L2%524 040I4s4|0:4v5d4*4i1+4T0g3;5b5f3e4!0O0o440g464`0D563@4e4g5b4~4j044#4%2T4Y0*4q5a2R065e5N5m3l0d4z4;4+4E0/0i4H5l5B1+54042(5b5M5O5!1I4T4#0O0c5w1+4e5K2*5*5O4Q5H2|5S5Z5}4F045X5T5g4?425r5t484a5A5}5y5=4?5E6g5I0/0N4P4u5,0*4T2g0o0J0D14604=375 5L153(0c2n2O6E3M1m3O2q2t2o0B1D6H0K3N0;6R0U0W0Y04.
3. Profondeur

On définit la profondeur d'un dossier comme la longueur maximale d'un chemin menant de ce dossier à un dossier ne contenant pas de sous-dossiers.

La profondeur d'un dossier vide ou ne contenant que des fichiers est donc égale à 0.

Écrire la fonction profondeur qui prend en paramètre un tuple représentant un dossier et renvoie la profondeur de celui-ci.

Exemples
>>> dossier_nsi = ("nsi", [("tp1.py", None), ("tp1.pdf", None)])
>>> profondeur(dossier_nsi)
0
>>> dossier_doc = ("documents", [("photo.jpg", None), dossier_nsi])
>>> profondeur(dossier_doc)
1

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10

.128013ben,4vi[3mo5_txPhklpwf(: cga=ry0S6]u/2)s1+d050R0c0o0C0h0t0O0z0A0t0C0O0O0D010o0h0u010406050O0K0k0k0C0E0F040H0l0t0K0,0l0d050L0?0^0`0|0;0u04051c151f0L1c0;0R0h0g0!0$0(0*0r0h0B0r0t1t0r0o0/050V0b0t0c1o0%0)011s1u1w1u0o1C1E1A0o0E1d0o0r0!0 0O0u0C0d0*0M011G1q010w0X0c0d0C0k0c1A1Z1#1*1I1-1E1:1=0/0a0z0q0E0l0u0l0O0h120d0z0T1X0E0E0c0A2a151^0d1d0L1V2n1S1U1T1B0R1`0*1w0d1/271A1l1n0#1H2x0h2z0d0l2D1A0u2g1d2l2n2R0=1!2b2F1+2K0E0_0t0/0P2k2V0:2U1_2X1I2Z2#0/0M2)1#2+2l2w012:0C2$040j2@2m0;2`2.0*2}2 0f322_2V2{380/0m3b343d362|0l2!2~0/0I3b1g2P152D2q0R1U2v3l0A2L1?1d3w1e3u2T162*053C0T2Q3k1p1I0s0/0T0w3s353R0*0v0/0z3X3Q2G2|0w0/2O0l0w130T0K0E3(2-3Z010.040x3^2W3`0d3U27280c3@3K2^2,403*3|0N0y3i0z4h3%3Y3*42040o3b4j3)1+0l0/0D4p4a2{0k0h0/0G4g4i4x3l3T043:472R4q3_4l0/0c0t4o482m4M4b4s3#042I4w4k2Y430(0h463 2{3|0i4,3l4z2%4:3`3|0J4f4T0:4i4~4V2{4H0h3W4|503l4m0c0O0o0n0R444*4K3L4$1I3|3~4|4F414P4R4@4c0/4e4D4 4 5n4O4n4#4r1I4t044v555y2Y0b0/0_0p5r1+5k5O2/0/4S2T5i0*3|0e5B4N1+4=042(5H5W015E0Q5!4W5S043.3:0d3=5g495+5Q5m5+585q5~5C5X5t0N5v563`4H2g0o3?145*632|5T3i153N0c2n2O6m3v1m3x2q2t2o0C1D6p0L3w0;6z0U0W0Y04.
4. Contenu

On appelle contenu d'un dossier l'ensemble des sous-dossiers et des fichiers qu'il contient.

De même on appelle chemin entre deux dossiers, le nom des sous-dossiers traversés afin d'accéder du premier au dernier. Le nom du dossier de départ ne fait pas partie du chemin, par contre celui du dossier d'arrivée en fait partie.

Écrire la fonction contenu qui prend en paramètre un tuple représentant un dossier et un chemin menant de ce dossier à un de ses descendants. Cette fonction le contenu du sous-dossier visé par le chemin.

On garantit que le chemin passé en paramètre mène à un sous-dossier existant.

Exemples
>>> dossier_nsi = ("nsi", [("tp1.py", None), ("tp1.pdf", None)])
>>> contenu(dossier_nsi, [])
[("tp1.py", None), ("tp1.pdf", None)]
>>> dossier_doc = ("documents", [("photo.jpg", None), dossier_nsi])
>>> contenu(dossier_doc, ["nsi"])
[("tp1.py", None), ("tp1.pdf", None)]

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10

.128013ben,4vi[+3mo5tPhklpw!f(: cga=ry0S6]u/72)s18d050S0c0o0C0h0s0P0z0A0s0C0P0P0D010o0h0t010406050P0K0l0l0C0E0F040H0m0s0K0-0m0d050L0@0_0{0}0=0t04051d161g0L1d0=0S0h0g0#0%0)0+0q0h0B0q0s1u0q0o0:050W0b0s0c1p0(0*011t1v1x1v0o1D1F1B0o0E1e0o0q0#100P0t0C0d0+0N011H1r010w0Y0c0d0C0l0c1B1!1$1+1J1.1F1;1?0:0a0z0p0E0m0t0m0P0h130d0z0U1Y0E0E0c0A2b161_0d1e0L1W2o1T1V1U1C0S1{0+1x0d1:281B1m1o0$1I2y0h2A0d0m2E1B0t2h1e2m2o2S0?1#2c2G1,2L0E0`0s0:0Q2l2W0;2V1`2Y1J2!2$0:0N2*1$2,2m2x012;0C2%040k2^2n0=2{2/0+2~300f332`2W2|390:0n3c353e372}0m2#2 0:0I3j2-2X1q2:3o2=040M3t363w383y3q040R3c1h2Q162E2r0S1V2w3m0A2M1@1e3O1f3M2U172+053U0U2R3l3E010r0:0U0w3K3D2H010u0:0z3?3,3^0d0w0:3U0d0o1:0K3}2.3-0/040x483v3 3:28290c0E4e2|4b0e3c3|3@2Z420q0c0l2J4m3m4b0O0y3j0z4F4r3~4t041:0w1$0o0P4q3u2|0m0:0D4Q4s2:4h0)0h4k4z4a0:0i4%3^4x2(4+1,4b0J4E4G4R3m3/040w3o4W4I4Y4K0W0t0c4~493^0m3`044y3$2_4H564J0A4v4x155c2n4^4(044D5l0;4G5t5e4f4J0h555w1J4T044V5r5v2|4-040G4?5u5G4_0:0u1t1F5z3f0:4L4N4P5r5n3^4b4*5Z4X380:5y5(4 0+4;5%2U5)015I5K5-5f1J4;5T3m5C0v5E2S5N3-0d5V52545`5A5/0:5q2S065M5M5!5x5~3-5C0j622+644,0h4.5r6g6h6j505W445Y636y0+5C6p5d6E2}5V405X4/5|4)6O5*5a6R015:6U5I2)6a4n0:4=6v5t6J4`2h0o0K0E5k6D5?664K6M6B3t0L3)0c2o2P6}3N1n3P2r2u2p0C1E700L3O0=7a0V0X0Z04.