Introduction à la programmation – Premier semestre L1 Caen

TP12

Partie notée – MIASHS Groupe B

Le sujet de ce TP noté était la manipulation de grille vue en TP lors des deux dernières séances de TP. Une grille d’entiers de $n$ colonnes et $p$ lignes peut être représenté en python par un tableau à $n$ entrées dont les valeurs sont des tableaux de $p$ entiers. Par exemple, la grille à $2$ lignes et $3$ colonnes

4 5 6
1 9 7

est représenté par le tableau de tableaux suivant [[4,5,6],[1,9,7]].

Étant donnée une grille python stocké dans une variable ma_grille, on accède à la 2e valeur de la 1er ligne, en récupérant tout d’abord la 1er ligne ma_ligne = ma_grille[0]. Cette ligne étant également un tableau python, on récupère sa deuxième valeur comme tout tableau avec la notation ma_ligne[1]. Comme ma_grille[0] est un tableau, on n’a pas besoin d’utiliser la variable ma_ligne et directement accéder à l’élément désiré par ma_grille[0][1].

Avant de pouvoir manipuler une grille python, il faut être capable de la créer. Pour cela, on a vu qu’un code de la forme

ma_grille = [[0] * p]*n

n’est pas un code correct car chaque élément du tableau ma_grille fait référence au même tableau. Pour avoir $n$ lignes distinctes, il faut créer $n$ tableaux distincts. On a alors le code

def cree_grille(n, p):
    ma_grille = []
    for n in range(n):
        ma_grille.append([0] * p)
    return ma_grille

Question 1

Pour créer une grille une grille de valeurs aléatoires, on va utiliser la fonction randint. On souhaite obtenir des valeurs aléatoires paires entre $0$ et $9$. Seules les valeurs $0$, $2$, $4$, $6$, $8$ sont donc autorisées. Plutôt que de tirer un entier entre $0$ et $9$ et de le rejeter s’il est impair, on peut directement produire des nombres pairs en tirant des nombres entre $0$ et $4$ et en multipliant la valeur tirée par $2$.

from random import randint

def grille_alea(n, p):
    # On crée une grille de n lignes et p colonnes
    ma_grille = cree_grille(n, p)

    # On affecte ensuite à chaque case une valeur tirée aléatoirement
    for i in range(n):
        for j in range(p):
            ma_grille[i][j] = randint(0,4)*2

    return ma_grille

Question 2

Pour avoir un affichage plus humain d’une grille, plusieurs méthodes sont possibles. En voici deux. L’une en créant une chaine de caractères par ligne, on utilise ici l’accès aux éléments par leurs indices.

def afficher(grille):
    n = len(grille)
    p = len(grille[0])

    for i in range(n):
        # pour chaque ligne de la grille, on crée une chaine de caractères qui
        # contiendra ce que l'on souhaite afficher
        ma_ligne = ""
        for j in range(p):
            ma_ligne += str(grille[i][j]) + " "
        print(ma_ligne)

La seconde en exploitant l’argument end="" de la fonction print, on itère ici directement sur les éléments.

def afficher(grille):
    for ligne in grille:
        for valeur in ligne:
            print(valeur, "", end="")
        print()

Question 3

On désire calculer à partir d’une grille et d’un entier $k$ une nouvelle grille contenant les valeurs de la grille en entrée multipliées par $k$. On va donc parcourir chaque valeur de la grille en entrée, la multiplier par $k$ et affecter le résultat à la case de même position dans la grille à calculer.

def multiplication(grille, k):
    n = len(grille)
    p = len(grille[0])

    # On reprend le code de grille_alea
    ma_grille = cree_grille(n, p)

    # et on complète par la multiplication demandée
    for i in range(n):
        for j in range(p):
            ma_grille[i][j] = grille[i][j] * k

    return ma_grille

Question 4

La transposée d’une grille correspond à l’échange des colonnes et de lignes comme dans un miroir. Ainsi, la grille en introduction a pour transposée.

4 1
5 9
6 7

Lire les valeurs de la transposée colonne par colonne revient alors à lire les valeurs ligne par ligne de l’original.

Cette lecture se traduit directement sur les indices, la valeur en position $(j,i)$ de la transposée est la valeur de la grille initiale en position $(i,j)$.

def transpose(grille):
    n = len(grille)
    p = len(grille[0])

    # On reprend le code de grille_alea en échangeant n et p
    ma_grille = cree_grille(p, n)

    # on copie ensuite les données en échangeant les indices pour la transposée
    for i in range(n):
        for j in range(p):
            ma_grille[j][i] = grille[i][j]

    return grille

Question 5

La diagonale d’une grille carré est la suite des valeurs qui sont en position $(i,i)$. Pour récupérer cette suite, on doit donc créer une liste qui sera de taille $n$ pour une grille carré de côté $n$.

def diagonale(grille):
    n = len(grille)

    # la diagonale a n valeurs
    resultat = [0]*n
    for i in range(n):
        # les indices sur la diagonales sont égaux (i=j)
        resultat[i] = grille[i][i]

    return resultat

TP10

Partie notée – MIASHS Groupe B

Dans ce TP, il faut réaliser 4 fonctions, chacune prenant en argument une liste ou une chaine de caractères et renvoyant un résultat.

Ce résultat ne doit pas être affiché dans le code de la fonction. Il peut cependant être affiché à l’extérieur à des fins de test.

Question 1

On dispose une liste d’entiers et on souhaite savoir si celle-ci est triée. Pour cela, il suffit de vérifier si deux valeurs successives de la liste sont bien dans le bon ordre.

J’ai pris plusieurs fois en TP l’analogie d’un paquet de cartes. Imaginez que vous disposer d’un jeu de carte et vous vous demandez s’il est trié. Vous allez alors prendre les cartes une par une en vérifiant que chaque carte est plus petite que la suivante. Aussi, si vous rencontrez une carte plus grande que sa suivante, vous pouvez affirmer que le paquet n’est pas trié.

Ceci se traduit par le code suivant.

def est_croissante(l):
    # Pour chaque position de carte
    # (sauf la dernière qui n'a pas de suivante)
    for a in range(len(l)-1) :
        # Si elle n'est pas plus petite que la suivante
        if not l[a] <= l[a+1]:
            # alors on sait que la liste n'est pas croissante
            return False
    # Quand on arrive ici, on a bien vérifié que les cartes étaient dans l'ordre croissant
    return True

Question 2

On ne dispose plus d’une liste d’entiers, mais d’une liste de chaines de caractères. On souhaite maintenant obtenir la liste des longueurs de ces chaines.

Il faut donc calculer la longueur de chaque chaine de caractères dans la liste.

Comme il faut renvoyer la liste de ces longueurs, il nous faut également créer une liste pour les y placer.

def longueurs(l):
    # On crée la liste qui contiendra les longueurs
    resultat = []
    # Pour chaque chaine de caractères dans la liste `l`
    for a in l:
        # on calcule sa longueur et on rajoute la stocke
        resultat.append(len(a))
    return resultat

Question 3

Les questions précédentes nous donnent deux fonctions, l’une pour calculer les longueurs de chaines de caractères, et l’autre pour vérifier si une suite d’entiers est croissante.

Donc si on calcule la liste des longueurs des chaines de caractères et qu’on utilise la liste obtenu comme argument de la fonction est_croissante, on sait si la liste des longueurs des chaines de caractères est croissante.

C’est justement ce qu’il nous faut.

def longueurs_croissantes(l):
    return est_croissante(longueurs(l))

Question 4

La dernière question de ce sujet est un peu indépendante des autres. On travaille maintenant sur une seule chaine de caractères.

On veut isoler le premier mot d’une chaine de caractère, c’est à dire tout le début de la chaine jusqu’à la première espace. (On pourrait être plus précis, mais on va se satisfaire de cette définition).

Pour réaliser ceci, il faut une variable qui va contenir le premier mot. Et afin de s’arrêter à la première espace, on doit parcourir chaque caractère en construisant peu à peu le premier mot.

def premiet_mot(s):
    # On part d'une chaine de caractères vide
    mot = ''
    # Puis pour chaque caractère
    for c in s:
        # S'il est différent d'une espace, on l'ajoute à notre premier mot
        if c != ' ':
            mot += c
        # et sinon, on a trouvé notre premier mot, et on le renvoie
        else:
            return mot
    # il ne faut pas oublier le cas où il n'y a aucune espace
    return mot