1A.e - Correction de l’interrogation écrite du 6 novembre 2015

Links: notebook, html, PDF, python, slides, GitHub

listes et dictionnaires

from jyquickhelper import add_notebook_menu
add_notebook_menu()

Enoncé 1

Q1

Le programme suivant provoque une erreur de temps en temps, pourquoi ?

import random
l = [0, 1, 2, 3, 4]
i = random.randint(0, 5)
del l[i]  # déclenche une exception de temps en temps

Pour le faire planter de façon quasi systémtique, on l’insère dans une boucle :

import random
for i in range(0,100):
    l = [0, 1, 2, 3, 4]
    i = random.randint(0, 5)
    del l[i]  # déclenche une exception quasi sûrement
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-9-ced82ea8013e> in <module>()
      3     l = [0, 1, 2, 3, 4]
      4     i = random.randint(0, 5)
----> 5     del l[i]

IndexError: list assignment index out of range

L’erreur vient du faire que la fonction randint tire un nombre entre 0 et 5 inclus. La liste ne contient que 5 éléments. Le dernier a pour indice 4.

Q2

A votre avis, qu’a voulu dire l’auteur de ces lignes ? Corriger ce programme.

mat = {}
for i in range(0,3) and j in range(0,3): # déclenche une exception
    mat[i,j] = 0
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-10-b85136f11268> in <module>()
      1 mat = {}
----> 2 for i in range(0,3) and j in range(0,3):
      3     mat[i,j] = 0

NameError: name 'j' is not defined

C’est une erreur que je vois souvent chez ceux débutent en programmation. On souhaite ici faire une double boucle imbriquée pour remplir le dictionnaire mat de 0.

mat = {}
for i in range(0,3):
    for j in range(0,3):
        mat[i,j] = 0

Q3

Ecrire une fonction qui met en majuscule les voyelles d’un mot.

Exemple : python \rightarrow pYthOn

Il n’existe pas une seule solution pour faire ceci. En voici quelques unes.

def maj_voy(mot):
    l = []
    for c in mot:
        if c in "aeiouy":
            l.append(c.upper())
        else:
            l.append(c)
    return "".join(l)

maj_voy("python")
'pYthOn'
def maj_voy(mot):
    return "".join(map(lambda c: c.upper() if c in "aeiouy" else c, mot))

maj_voy("python")
'pYthOn'
def maj_voy(mot):
    return "".join( c.upper() if c in "aeiouy" else c for c in mot )

maj_voy("python")
'pYthOn'

Enoncé 2

Q1

La variable i est soit 1, soit 2. Que fait le code suivant et comment le simplifier en une ligne ?

i = 2
if i == 2:
    i = 1
else:
    i = 2

print(i)
1

L’énoncé était un peu ambigü mais il fallait que le code fonctionne dans les deux cas : i==1 et i==2

i = 3-i

print(i)
2
i = i%2 + 1

print(i)
1

Q2

Le programme suivant produit une erreur. Modifier le programme pour qu’il ne la produise plus.

l = {{}}  # déclenche une exception
for i,j in zip(range(0,3), range(0,3)):
    l[i,j] = 1
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-22-6b8ba89606bb> in <module>()
----> 1 l = {{}}
      2 for i,j in zip(range(0,3), range(0,3)):
      3     l[i,j] = 1

TypeError: unhashable type: 'dict'

La première ligne contient des doubles accolades sans raison.

l = {}
for i,j in zip(range(0,3), range(0,3)):
    l[i,j] = 1

Q3

Ecrire une fonction qui double toutes les voyelles.

Exemple : python \rightarrow pyythoon

def double_voy(mot):
    l = []
    for c in mot:
        if c in "aeiouy":
            l.append(c*2)
        else:
            l.append(c)
    return "".join(l)

double_voy("python")
'pyythoon'

Ou plus court encore :

def double_voy(mot):
    return "".join(map(lambda c: c*2 if c in "aeiouy" else c, mot))

double_voy("python")
'pyythoon'