Aller au contenu

Du pseudocode vers python

Lorsqu'on crée un programme répondant à une spécification, on commence en général par penser le programme de façon "générique" en français et en pseudocode, par grandes étapes puis on précise petit à petit chaque étape en affinant le pseudocode.
Ce n'est qu'en dernière étape que l'on traduit le résultat dans un langage de programmation.

Les exercices qui suivent consistent à lire un pseudocode et à chercher à le traduire en python. Savoir traiter parfaitement ce type d'exercices est évidemment indispensable, une connaissance parfaite de la syntaxe python est incontournable.

Exercice

Traduire en python:

fonction f(n):
    """ 
    n est un entier naturel non nul
    renvoie le produit des entiers pairs compris entre 1 et n.
    """
    p ← 1
    Pour k de 1 à n:
        si k est pair:
            p ← p * k
    renvoyer p
Solution

Traduction directe du pseudocode donné:

def f(n):
    """
    n -- entier naturel > 1
    renvoie le produit des entiers pairs compris entre 1 et n.
    """
    p = 1
    for k in range(1, n+1):
        if k%2 == 0: 
            p = p*k
    return p

Mais on sera plus complet si on ajoute des tests afin de vérifier que notre traduction satisfait bien à la spécification annoncée.

def f(n):
    """
    n -- entier naturel > 1
    renvoie le produit des entiers pairs compris entre 1 et n.
    >>> f(2)
    2
    >>> f(3)
    2
    >>> f(4)
    8
    >>> f(5)
    8
    >>> f(6)
    48
    """
    p = 1
    for k in range(1, n+1):
        if k%2 == 0: 
            p = p*k
    return p

# les deux lignes suivantes permetttent de lancer les tests
# de la chaîne de documentation
import doctest
doctest.testmod(verbose=True)

Exercice

Traduire en python:

fonction g(debut, fin, pas):
    """ 
    debut, fin, pas sont des entiers avec fin >= debut et pas > 0.
    renvoie la somme des entiers 
    debut, debut + pas, debut + 2*pas, debut + 3*pas, ...., debut + k*pas
    la somme contenant tous les termes 
    de la forme debut + k*pas qui sont inférieurs ou égaux à fin.
    """
    s ← 0
    k ← 0
    tant que debut + k*pas <= fin:
        s ← s + (debut + k*pas)
        k ← k+1        
    renvoyer s
Solution

Une première traduction:

def g(debut, fin, pas):
    """
    debut, fin, pas: entiers
    contraintes: debut <= fin, pas > 0
    renvoie la somme des entiers 
    debut+k*pas pour k >= 0 et debut+k*pas <= fin.
    >>> g(1, 10, 2)
    25
    >>> g(1, 11, 2)
    36
    >>> g(1, 12, 2)
    36
    """
    somme = 0
    k = 0
    while debut + k*pas <= fin:
        somme += debut + k*pas
        k += 1
    return somme

# les deux lignes suivantes permetttent de lancer les tests
# de la chaîne de documentation
import doctest
doctest.testmod(verbose=True)

Le pseudocode proposé ici peut être traduit de façon "immédiate" en python, le pseudocode choisi étant déjà écrit sur un modèle très proche de python.
Mais une traduction aussi immédiate n'est pas toujours possible:

  • soit parce que le pseudocode donné n'est pas donné à une étape aussi avancée,
  • soit parce qu'on aura à le traduire dans un langage dont la syntaxe est plus éloignée des conventions choisies pour notre pseudocode que ne l'est python.

Il faut parfois ne pas hésiter à "s'éloigner du pseudocode" pourvu que les étapes en soient respectées.

Exemple de code python convenant pour la traduction du pseudocode précédent:

def g(debut, fin, pas):
    """
    debut, fin, pas: entiers
    contraintes: debut <= fin, pas > 0
    renvoie la somme des entiers debut+k*pas 
    pour k >= 0 et debut+k*pas <= fin.
    >>> g(1, 10, 2)
    25
    >>> g(1, 11, 2)
    36
    >>> g(1, 12, 2)
    36
    """
    somme = 0
    for k in range(0, (fin-debut)//pas + 1):
        somme += debut + k*pas
    return somme

# les deux lignes suivantes permetttent de lancer les tests
# de la chaîne de documentation
import doctest
doctest.testmod(verbose=True)

Voilà encore une autre version qui convient:

def g(debut, fin, pas):
    """
    debut, fin, pas: entiers
    contraintes: debut <= fin, pas > 0
    renvoie la somme des entiers debut+k*pas pour k >= 0 
    et debut+k*pas <= fin.
    >>> g(1, 10, 2)
    25
    >>> g(1, 11, 2)
    36
    >>> g(1, 12, 2)
    36
    """
    somme = 0
    k = 0
    while True:
        if debut + k*pas <= fin:
            somme += debut + k*pas
            k = k+1
        else:
            break # break fait sortir de la boucle
    return somme

# les deux lignes suivantes permetttent de lancer les tests
# de la chaîne de documentation
import doctest
doctest.testmod(verbose=True)

On pourrait aussi proposer la version suivante:

def g(debut, fin, pas):
    """
    debut, fin, pas: entiers
    contraintes: debut <= fin, pas > 0
    renvoie la somme des entiers debut+k*pas pour k >= 0 et debut+k*pas <= fin.
    >>> g(1, 10, 2)
    25
    >>> g(1, 11, 2)
    36
    >>> g(1, 12, 2)
    36
    >>> g(34, 40, 3)
    111
    """
    somme = 0
    for x in range(debut, fin+1):
        if (x-debut)%pas == 0:
            somme = somme + x
    return somme

# les deux lignes suivantes permetttent de lancer les tests
# de la chaîne de documentation
import doctest
doctest.testmod(verbose=True)

ou encore:

def g(debut, fin, pas):
    """
    debut, fin, pas: entiers
    contraintes: debut <= fin, pas > 0
    renvoie la somme des entiers debut+k*pas pour k >= 0 et debut+k*pas <= fin.
    >>> g(1, 10, 2)
    25
    >>> g(1, 11, 2)
    36
    >>> g(1, 12, 2)
    36
    >>> g(34, 40, 3)
    111
    """
    somme = 0
    for x in range(debut, fin+1, pas):
            somme = somme + x
    return somme

# les deux lignes suivantes permetttent de lancer les tests
# de la chaîne de documentation
import doctest
doctest.testmod(verbose=True)