Participer au site avec un Tip
Rechercher
 

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 :

Mise en oeuvre de fonctions récursives

Définition de fonctions Fonctions à nombre variable de paramètres


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

La vidéo

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é.


Mise en oeuvre de fonctions récursives.

Contenu détaillé

En cours d'écriture : prochainement disponible.

Fonction factorielle récursive

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))
fichier fact.py : exemple de définition d'une fonction récursive.

Un exemple appliqué au parcours récursif d'un système de fichiers

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)
Fichier my_ls.py : exemple de fonction récursive appliquée au parcours d'un système de fichiers.

Travaux pratiques

Les énoncés

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
Définition récursive de la fonction mathématique « puissance » appliquée à des valeurs entières.
oui, je sais, l'opérateur ** 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.

pour réaliser cet exercice, il peut être nécessaire de se documenter sur le module 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. ;-)

Les corrections

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)}")
Correction de l'exercice 1

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")
Correction de l'exercice 2

Et voici le résultat produit par cet exemple.

Le dossier /home/dominique/Desktop/TutoPython contient :
    164 sous-dossier(s)
    1106 fichier(s)


Définition de fonctions Fonctions à nombre variable de paramètres