Examen final: correction¶

Problème 1 : questions conceptuelles¶

  1. Permutation de variables :

Soit deux variables a et b:

In [1]:
a = 4
b = 5

Deux façons de réaliser une permutation en Python :

  • méthode 1 : en introduisant une variable temporaire
  • méthode 2 : en une ligne (l'algorithme est le même que pour la méthode 1)
In [2]:
# méthode 1
c = a  # temp
a = b
b = c
print(f"a = {a}\nb = {b}")
a = 5
b = 4
In [3]:
# méthode 2
a = 4
b = 5
a, b = b, a
print(f"a={a}\nb={b}")
a=5
b=4

Problème 2 : Double trouble!¶

  1. Comportement de la fonction : la fonction function prend en entrée une chaîne de caractère (text) et renvoie True si la chaîne de caractères contient deux voyelles consécutives, False sinon. Un nom plus adéquat serait has_double_vowel().
In [4]:
def has_double_vowel(text):
    vowels = "aeiouy"
    i = 0

    while i < len(text) - 1:
        if text[i] in vowels and text[i+1] in vowels:
            return True
        i += 1
        
    return False
In [5]:
print("2. Prédiction de résultats")
print("=====================")
print(f"Résultat pour snowflake: {has_double_vowel("snowflake")} (Pas de voyelles consécutives)")
print(f"Résultat pour tree: {has_double_vowel("tree")} (Voyelles consécutives: ee)")
print(f"Résultat pour oeuf: {has_double_vowel("oeuf")} (Voyelles consécutives: oe)")
2. Prédiction de résultats
=====================
Résultat pour snowflake: False (Pas de voyelles consécutives)
Résultat pour tree: True (Voyelles consécutives: ee)
Résultat pour oeuf: True (Voyelles consécutives: oe)
  1. Différence entre une boucle while et une boucle for : dans une boucle while, on itère sur une condition tandis que dans une boucle for, on itère sur les éléments d'une séquence (liste, chaîne de caractère...)
In [6]:
def has_double_vowel(text):
    vowels = "aeiouy"
    
    for i in range(len(text) - 1):  # cas limite
        if text[i] in vowels and text[i+1] in vowels:
            return True
    
    return False
In [7]:
print("Vérifications")
print("=====================")
print(f"Résultat pour snowflake: {has_double_vowel("snowflake")} (Pas de voyelles consécutives)")
print(f"Résultat pour tree: {has_double_vowel("tree")} (Voyelles consécutives: ee)")
print(f"Résultat pour oeuf: {has_double_vowel("oeuf")} (Voyelles consécutives: oe)")
Vérifications
=====================
Résultat pour snowflake: False (Pas de voyelles consécutives)
Résultat pour tree: True (Voyelles consécutives: ee)
Résultat pour oeuf: True (Voyelles consécutives: oe)

Problème 3 : Compter les suffixes¶

In [8]:
def has_string(l, s):
    c = 0  # counter
    for e in l:
        if s in e:
            c += 1
    return c
In [9]:
r = has_string(['chanter', 'danse', 'parler'], "er")
print(f"La chaîne 'er' apparaît dans {r} éléments de la liste ['chanter', 'danse', 'parler']")
La chaîne 'er' apparaît dans 2 éléments de la liste ['chanter', 'danse', 'parler']
In [10]:
def suffix_counter(l, s):
    c = 0  # counter
    b = len(s)  # suffix length
    for e in l:
        # check if the end of element e matches string s
        if e[len(e)-b:] == s: 
            c += 1

    return c
In [11]:
r = suffix_counter(['chanter', 'danse', 'parler'], "er")
print(f"Le suffixe 'er' apparaît dans {r} éléments de la liste ['chanter', 'danse', 'parler']")
Le suffixe 'er' apparaît dans 2 éléments de la liste ['chanter', 'danse', 'parler']
In [12]:
def suffix_counter(l, s):
    c = 0  # counter
    b = len(s)  # suffix length
    has_suffix = []  # will contain elements which have suffix s
    for e in l:
        if e[-b:] == s:
            c += 1
            has_suffix.append(e)

    return c, has_suffix
In [13]:
suffix_count, word_list = suffix_counter(['chanter', 'danse', 'parler'], "er")
print(f"Le suffixe 'er' apparaît dans {suffix_count} éléments de la liste ['chanter', 'danse', 'parler']:\n{word_list}")
Le suffixe 'er' apparaît dans 2 éléments de la liste ['chanter', 'danse', 'parler']:
['chanter', 'parler']

Problème 4 : Déboggage¶

  1. Erreurs :
  • long_words et first_letters : initialisés comme des dictionnaires (l.2, l.3). Pourtant, l.7 et l.8, la méthode .append() est utilisée (méthode propre aux objets de type list).
  • on itère sur un intervale range(len(words) - 1), ce qui empêche de vérifier le dernier élément de la liste words.
  • on vérifie len(word) > n or on souhaite extraireles mots de longueurs n.
  • l.7, on cherche à étendre long_words avec l'élément i. i correspond à l'index (intervale) et non à l'élément de words d'index i.
  • l.8, on chercher à étendre first_letters avec l'élément words[1]. Or, on souhaite extraire pour chaque élément de words de longueur n, le premier caractère (index 0).
  • l.9, finalement, la fonction ne renvoie que long_words (elle devrait renvoyer long_words ET first_letters)
In [14]:
def lists_of_words(words, n=7):
    long_words = []
    first_letters = []

    for i in range(len(words)):
        word = words[i]
        if len(word) == n:
            long_words.append(word)
            first_letters.append(word[0])
    
    return long_words, first_letters
In [15]:
l = ["ordinateur", "clé", "programme", "code"]
words, first_l = lists_of_words(l, n=5)
print(f"Sortie: {words}, {first_l}")
print("============")
print("Mots extraits:")
for i in range(len(words)):
    print(f"Mot: {words[i]}\tCaractère 0: {first_l[i]}")
# piège : aucun des mots de la liste n'était de longueur 5 ! ;)
Sortie: [], []
============
Mots extraits:
In [16]:
def lists_of_words(words, n=7, include_indices=False):
    long_words = []
    first_letters = []
    indices = []

    for i in range(len(words)):
        word = words[i]
        if len(word) == n:
            long_words.append(word)
            first_letters.append(word[0])
            
            if include_indices:
                indices.append(i)
        
    if include_indices:
        return long_words, first_letters, indices
    else:
        return long_words, first_letters
In [17]:
l = ["abeille", "programme", "code", "natures"]
words, first_l, index = lists_of_words(l, n=7, include_indices=True)
print(f"Sortie: {words}, {first_l}")
print("==============")
print("Mots extraits:")
for i in range(len(words)):
    print(f"Mot: {words[i]}\tCaractère 0: {first_l[i]}\tIndice: {index[i]}")
Sortie: ['abeille', 'natures'], ['a', 'n']
==============
Mots extraits:
Mot: abeille	Caractère 0: a	Indice: 0
Mot: natures	Caractère 0: n	Indice: 3

Problème 5 : Premier indice¶

In [18]:
def is_value(l, item):
    # version 1
    for e in l:
        if e == item:
            return True
    return False


def is_value(l, item):
    # version 2
    for i in range(len(l)):
        if l[i] == item:
            return True
    return False
In [19]:
def first_index(l, item):
    for i in range(len(l)):
        if l[i] == item:
            # on renvoie l'indice de la première occurrence de item dans l
            return i
    return -1  # si item n'est pas dans l
In [20]:
def first_index(l, item, start=0):
    for i in range(start, len(l)):
        if l[i] == item:
            # on renvoie l'indice de la première occurrence de item dans l
            # dans l'intervalle donné
            return i
    return -1  # si item n'est pas dans l
In [21]:
l = [3, 7, 2, 7, 9]
result_1 = first_index(l, item=7)  # start = 0 (default)
result_2 = first_index(l, item=7, start=2)
print("Test de la fonction first_index:")
print("=================================")
print(f"Première occurrence de 7 dans {l} : indice {result_1}")
print(f"Première occurrence de 7 dans {l} : indice {result_2} (start search at index 2)")
Test de la fonction first_index:
=================================
Première occurrence de 7 dans [3, 7, 2, 7, 9] : indice 1
Première occurrence de 7 dans [3, 7, 2, 7, 9] : indice 3 (start search at index 2)