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

.128013nimwgyk2Po 56]u+al4t/sbr[vce3)fh:1S=_dp(050M0C0u0r0c0s0w0l0B0s0r0w0w0K010u0c0N010406050w0p0d0d0r0y0g040J0k0s0p0)0k0b050v0:0=0@0_0.0N041219051c0v1c1e190.0M0c0A0X0Z0#0%0G0c0f0G0s1s0G0u0,050S0x0s0C1n0!0$011r1t1v1t0u1B1D1z0u0x0k0M0_1A0y1a0u0G0X0|0w0N0r0b0%0i011F1p010F0U0C0b0r0d0C1z1%1)1.1H1;1D1@1_0,0a0l0j0y0k0N0k0w0c0 0b0l0Q1#0y0y0C0B2e121|0b1a0v1Z2r0u1X1W1Y0M1~0%1v0b1?2b1z1k1m0Y1G2B0c2D0b1T1l1z0N2k1a2p2r2V0/1(2f2J1/2O0y0?0s0,0I2o2Z0-2Y1}2#1H2%2)0,0i2-1)2/2p2A012@0r2*040D2{2q0.2~2=0%31330t362}2Z2 3c0,0m3f383h3a300k2(320,0n3f1b2T122H2u0M2y2 0B1T1`1a3A1d3y2X132.053F0Q2U3o1o1H0h0,0Q0F3w393U0%0e0,0l3!3T2K300F0,0b0x0L0M2b2c0C0y0w3+2;3$010+040O3}2!3 0b3X3^0c3`442 410E0H3m0l4i3*3#3-47040u3f4k3,1/0k0,0K4q2:453-0d0c2+4h4j4y2 3W040F3r4x4l2$0,0C0s4p3N2|4r3~3-0k3(042M4M4s2?480#4a0y4c3p410z4-3 4B4D4T2q4G4.0,0o4g4^0-4j514V4z1/4I0c3Z4 533i4P0w0u3?494b4 4`3 41435i4N4(044Q4S2X5o0%4e4~2V06525A5a3p4n5s2.5C3 4u040q4w595j4m3:3=3@4*3`3|5n4%5v0,5m5t5X304P4R4;3-4e4E4i5O550,2k0u0p0y115N5u5%4o3m123Q0C2r2S613z1l3B2u2w2s1S1U2u0r1C640v3A0.6h0R0T0V04.
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

.128013nimwgyk02Po 56]u+al84t/sbr[vce3)fh:1S=7_dp(050P0E0w0s0c0t0y0m0D0t0s0y0y0M010w0c0Q010406050y0q0d0d0s0A0g040L0l0t0q0,0l0b050x0?0^0`0|0;0Q04151c051f0x1f1h1c0;0P0c0C0!0$0(0*0I0c0f0I0t1v0I0w0/050V0z0t0E1q0%0)011u1w1y1w0w1E1G1C0w0z0l0P0|1D0A1d0w0I0!0 0y0Q0s0b0*0j011I1s010H0X0E0b0s0d0E1C1*1,1;1K1@1G1`1|0/0a0m0k0A0l0Q0l0y0c120b0m0T1(0A0A0E0D2h151 0b1d0x1$2u0w1!1Z1#0P210*1y0b1_2e1C1n1p0#1J2E0c2G0b1W1o1C0Q2n1d2s2u2Y0=1+2i2M1=2R0A0_0t0/0K2r2$0:2#202(1K2*2,0/0j2:1,2=2s2D012`0s2-040F2~2t0;312^0*34360v39302$323f0/0n3i3b3k3d330l2+350/0o3p2?2%1r2_3u2{040N3z3c3C3e3E3w040u3i1e2W152K2x0P2B320D1W1}1d3U1g3S2!162;053Z0T2X3r3K010h0/0T0H3Q3J2N010e0/0m3{3;3}0b0H0/0b0z0O1@0D1u0E0A0y422@3=0.040R4h3B443^2e2f4e4n324k0G0J3p0m4A413|2)0/0w3i4C431=0l0/0M4H3A320d0c0/0i4z4B4P3s3@040H3u4O4D2_0/0E0t4G3+2 4I4i3}0l3 042P4%4J4)040P4r0c4t4.2t4X4j0/0B4u3s4R2.5855040p4y520:4B5j4:4o1=4Z0c3`5h5l3l4*0y0w4a0c4c500A5c3}4k4m5h544p044+4-2!4(0*4w5g2Y065k5T5s3s0b4F4`4;4K0/0r4N5r5H1=5a042/5h5S5U5*1K4Z4+0y0E5C1=4k5Q2;5:5U4W5N335Y5)634L045%5Z5m4|485x5z4e4g5G635E5{4|5K6m5O0/0G4V4A5=0*4Z2n0w0q0A14664{3e655R153.0E2u2V6K3T1o3V2x2z2v1V1X2x0s1F6N0x3U0;6!0U0W0Y04.
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

.128013nximwgyk02Po, 56]u+al4t/sbr[vce3)fh:1S=_dp(050P0F0x0u0d0v0z0o0E0v0u0z0z0N010x0d0Q010406050z0s0e0e0u0B0h040M0m0v0s0,0m0b050y0?0^0`0|0;0Q04151c051f0y1f1h1c0;0P0d0D0!0$0(0*0J0d0g0J0v1v0J0x0/050V0A0v0F1q0%0)011u1w1y1w0x1E1G1C0x0A0m0P0|1D0B1d0x0J0!0 0z0Q0u0b0*0k011I1s010I0X0F0b0u0e0F1C1*1,1;1K1@1G1`1|0/0a0o0l0B0m0Q0m0z0d120b0o0T1(0B0B0F0E2h151 0b1d0y1$2u0x1!1Z1#0P210*1y0b1_2e1C1n1p0#1J2E0d2G0b1W1o1C0Q2n1d2s2u2Y0=1+2i2M1=2R0B0_0v0/0L2r2$0:2#202(1K2*2,0/0k2:1,2=2s2D012`0u2-040G2~2t0;312^0*34360w39302$323f0/0p3i3b3k3d330m2+350/0q3i1e2W152K2x0P2B320E1W1}1d3D1g3B2!162;053I0T2X3r1r1K0i0/0T0I3z3c3X0*0f0/0o3%3W2N330I0/2V0m0I130T0s0B3.2@3)010.040R3~2%400b3!2e2f0F3}3Q2 2?463:420H0K3p0o4n3-3(3:48040x3i4p3/1=0m0/0N4v4g320e0d0/0j4m4o4D3s3Z043_4d2Y4w3 4r0/0F0v4u4e2t4S4h4y3+042P4C4q2)490(0d4c4532420C4=3s4F2.4_40420r4l4Z0:4o544#324N0d3$52563s4s0F0z0x0O0P4a4:4Q3R4,1K4244524L474V4X4}4i0/4k4J55555t4U4t4+4x1K4z044B5b5E2)0A0/0_0c5x1=5q5U2_0/4Y2!5o0*420n5H4T1=4{042/5N5$015K0t5*4$5Y043@3_0b3{5m4f5;5W5s5;5e5w645I5%5z0H5B5c404N2n0x3|145:69335Z3p153T0F2u2V6s3C1o3E2x2z2v1V1X2x0u1F6v0y3D0;6I0U0W0Y04.
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

.128013nimwgyk02Po, 56]u+al84t/sbr[vce!3)fh:1S=7dp(050Q0F0x0t0c0u0z0n0E0u0t0z0z0O010x0c0R010406050z0r0d0d0t0B0g040N0l0u0r0-0l0b050y0@0_0{0}0=0R04161d051g0y1g1i1d0=0Q0c0D0#0%0)0+0K0c0f0K0u1w0K0x0:050W0A0u0F1r0(0*011v1x1z1x0x1F1H1D0x0A0l0Q0}1E0B1e0x0K0#100z0R0t0b0+0j011J1t010J0Y0F0b0t0d0F1D1+1-1=1L1^1H1{1}0:0a0n0k0B0l0R0l0z0c130b0n0U1)0B0B0F0E2i16200b1e0y1%2v0x1#1!1$0Q220+1z0b1`2f1D1o1q0$1K2F0c2H0b1X1p1D0R2o1e2t2v2Z0?1,2j2N1?2S0B0`0u0:0M2s2%0;2$212)1L2+2-0:0j2;1-2?2t2E012{0t2.040H2 2u0=322_0+35370w3a312%333g0:0o3j3c3l3e340l2,360:0p3q2@2(1s2`3v2|040P3A3d3D3f3F3x040v3j1f2X162L2y0Q2C330E1X1~1e3V1h3T2#172=053!0U2Y3s3L010h0:0U0J3R3K2O010e0:0n3|3=3~0b0J0:3!0b0x1`0r432^3?0/040S4e3C453_2f2g0F0B4k334h0m3j423}2*480K0F0d2Q4s3t4h0I0L3q0n4L4x444z041`0J1-0x0z4w3B330l0:0O4W4y2`4n0)0c4q4F4g0:0C4-3~4D2/4;1?4h0q4K4M4X3t3^040J3v4$4O4(4Q0W0R0F544f3~0l40044E3,304N5c4P0E4B4D155i2u4~4.044J5r0;4M5z5k4l4P0c5b5C1L4Z044#5x5B334?040i4|5A5M4 0:0e1v1H5F3m0:4R4T4V5x5t3~4h4:5)4%3f0:5E5.550+4`5-2#5/015O5Q5?5l1L4`5Z3t5I0G5K2Z5T3?0b5#585a605G5^0:5w2Z065S5S5*5D643?5I0s682=6a4=0c4@5x6m6n6p565$4a5(696E0+5I6v5j6K345#465%4^624/6U5:5g6X015_6!5O2:6g4t0:4{6B5z6P502o0x0r0B5q6J5|6c4Q6S6H3A0y3/0F2v2W733U1p3W2y2A2w1W1Y2y0t1G760y3V0=7j0V0X0Z04.