Adloun

Écrire une fonction min max(t) renvoyant le couple (plus petit…

Exercice de TD · niveau 2 · NSI (première), chapitre 4 — Les types construits · P-uplets, déballage et affectation multiple

Énoncé

Écrire une fonction min_max(t) renvoyant le couple (plus petit élément, plus grand élément) de t, en un seul parcours. Donner précondition et postcondition.

Corrigé


def min_max(t):
    """Couple (plus petit, plus grand) des elements de t, en un seul parcours.

    Precondition  : t est un tableau non vide de nombres.
    Postcondition : mini <= x <= maxi pour tout x de t, et mini comme maxi
                    sont des elements de t.
    """
    assert len(t) > 0, "tableau vide"
    mini = t[0]
    maxi = t[0]
    for x in t:
        if x < mini:
            mini = x
        if x > maxi:
            maxi = x
    assert mini in t and maxi in t
    assert all(mini <= x <= maxi for x in t)
    return mini, maxi

Pourquoi l'initialisation est t[0] et non . C'est exactement l'erreur de maximum_faux au chapitre 3 : partir de donnerait comme minimum sur un tableau de nombres tous positifs. Initialiser avec un élément du tableau garantit la seconde moitié de la postcondition — le résultat appartient à t — et c'est aussi ce qui impose la précondition « non vide » : sans élément, pas d'initialisation possible.

La postcondition en deux parties. L'encadrement seul ne suffirait pas : la fonction qui rendrait (-10<strong>9, 10</strong>9) le vérifierait. C'est mini in t and maxi in t qui interdit cette tricherie.

Un seul parcours. Le corps contient deux if indépendants, et non un if/else : un même élément peut être à la fois le minimum et le maximum courants — c'est le cas au premier tour, et sur [2, 2, 2]. Le coût est de comparaisons pour éléments, contre également si l'on appelait min(t) puis max(t) — mais en deux parcours de la mémoire au lieu d'un.

Vérification.


assert min_max([3, 1, 4, 1, 5]) == (1, 5)
assert min_max([7]) == (7, 7)
assert min_max([-3, -1, -7]) == (-7, -1)
assert min_max([2, 2, 2]) == (2, 2)

for _ in range(3000):
    t = [random.randint(-60, 60) for _ in range(random.randint(1, 15))]
    assert min_max(t) == (min(t), max(t))

Les quatre cas nommés et les tableaux aléatoires passent. Le cas [-3, -1, -7] est celui qui démasquerait une initialisation à .

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.