Accès rapide :
La vidéo
Contenu détaillé
Fonction factorielle récursive
Un exemple appliqué au parcours récursif d'un système de fichiers
Travaux pratiques
Les énoncés
Les corrections
Cette vidéo vous montre comment coder des fonctions récursives en Python. Un exemple appliqué à la manipulation du système de fichiers y est proposé.
L'exemple de code proposé ci-dessous vous montre comment coder une fonction factorielle récursive.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
def fact_rec(value): if not isinstance(value, int): raise TypeError("factorial is only defined for integers") if value < 0: raise ValueError("fact_rec() not defined for negative values") def unsafe_fact_rec(n): if n == 0: return 1 else: return n * unsafe_fact_rec(n - 1) # return 1 if n == 0 else n * unsafe_fact_rec(n - 1) return unsafe_fact_rec(value) print(fact_rec(3)) print(fact_rec(4)) print(fact_rec(5)) print(fact_rec(6)) |
L'exemple proposé ci-dessous permet d'afficher le contenu d'un dossier. S'il contient des sous-dossiers, le programme doit récursivement afficher le contenu
des sous dossiers. Pour réaliser ce programme, les modules os
et
sys
sont utilisés.
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 |
import sys import os def scan(path, level=""): short_name = path.split(os.sep)[-1] print(f"{level}{short_name}") try: files = os.listdir(path) for file in files: sub_path = path + os.sep + file sub_level = level + " " if os.path.isdir(sub_path): scan(sub_path, sub_level) else: short_name = sub_path.split(os.sep)[-1] print(f"{sub_level}{short_name}") except OSError: print(level + " Access is denied !!!") if len(sys.argv) == 2: folder = sys.argv[1] else: folder = os.getcwd() folder = os.path.abspath(folder) if not os.path.isdir(folder): print("Not a folder: " + folder) exit() scan(folder) |
Exercice 1 : considérons la définition récursive de la « puissance », proposée ci-dessous. Durant l'exercice, nous considérerons
que x
et p
sont des entiers positifs (nous ne traiterons pas du cas de la puissance sur des valeurs flottantes).
Veuillez coder une fonction power
, qui permet d'élever une valeur à une puissance donnée en implémentant cet algorithme.
x0 = 1 xp = x * xp-1
**
permet de calculer une puissance. Mais le but est de s'entraîner à coder une fonction récursive.
Donc au boulot ! ;-)
Exercice 2 : en vous basant sur l'exemple de listing récursif de dossiers, proposé plus haut, veuillez écrire une fonction qui compte
récursivement le nombre de fichiers et le nombre de sous-dossiers contenu dans un dossier donné. Les résultats devront être renvoyés sous forme
d'un tuple
.
os
qui fournit les primitives de manipulation du système de fichiers et notamment sur la fonction
listdir
.
Comme toujours, essayez de faire ces exercices sans regarder directement la correction ci-dessous. ;-)
Exercice 1 : voici comment coder une fonction power
récursive.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
def power(value, pow_value): # On fait les tests de cohérence une fois pour toute. if not isinstance(value, int) or not isinstance(pow_value, int): raise TypeError("My power function accept only two positive integers.") if value < 0 or pow_value < 0: raise ValueError("My power function accept only two positive integers.") # La fonction récursive qui implémente l'algorithme demandé def unsafe_power(v, p): result = 1 while p > 0: result *= v p -= 1 return result # Les paramètres étant vérifié, on lance le calcul. return unsafe_power(value, pow_value) for i in range(11): print(f"2 ** {i} => {power(2, i)}") |
Et voici le résultat produit par cet exemple.
2 ** 0 => 1 2 ** 1 => 2 2 ** 2 => 4 2 ** 3 => 8 2 ** 4 => 16 2 ** 5 => 32 2 ** 6 => 64 2 ** 7 => 128 2 ** 8 => 256 2 ** 9 => 512 2 ** 10 => 1024
Exercice 2 : voici comment compter, récursivement, le nombre de fichiers et le nombre de sous-dossiers contenus dans dossier donné.
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 |
import sys import os def scan(path): try: folder_count = 0 file_count = 0 files = os.listdir(path) for file in files: sub_path = path + os.sep + file if os.path.isdir(sub_path): folder_count += 1 res = scan(sub_path) folder_count += res[0] file_count += res[1] else: file_count += 1 return folder_count, file_count except PermissionError: print(f"{path}: Access is denied !!!") except OSError: print(f"{path}: Unknown error :-(") if len(sys.argv) == 2: folder = sys.argv[1] else: folder = os.getcwd() folder = os.path.abspath(folder) if not os.path.isdir(folder): print("Not a folder: " + folder) exit() results = scan(folder) print(f"Le dossier {folder} contient :") print(f"\t{results[0]} sous-dossiers") print(f"\t{results[1]} fichiers") |
Et voici le résultat produit par cet exemple.
Le dossier /home/dominique/Desktop/TutoPython contient : 164 sous-dossier(s) 1106 fichier(s)
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :