1ère Générale NSI

 

Term. Générale NSI

 

Terminale STI2D SIN

Bts Ccst

Technico-commercial 3.0

[[{"title":"Python - Utilisation avancée des tableaux","posi":0},{"text":"
Dans cette séquence nous poursuivons la présentation des tableaux de Python avec des concepts plus  avancés.

"},{"text":""}],[{"text":"

Lorsque l’on veut répéter une opération pour chaque élément e d'un tableau t, il est possible d'utiliser l'instruction for directement sur le tableau lui-même, de la manière suivante :

t = [2,5,7,4,8,1]

for e in t:
print(e)

Tester le code ci-dessus.

Dans une telle forme, la boucle énumère les éléments du tableau : elle effectue un tour pour chaque élément de t et l'élément inspecté à un tour donné est associé à la variable e. 

Le programme précédent est équivalent à cet autre
programme que nous avons déjà écrit dans lequel la boucle énumère les indices i du tableau t, les éléments correspondants étant récupéré via l'expression t[i]. 


for i in range(len(t)):
e = t[i]
print(e)



Tester le code ci-dessus et conclure.



","title":"Itérer sur les éléments d’un tableau"},{"edit":"

Mettre ici les résultats.

"}],[{"text":"
On utilise parfois une boucle for en fournissant directement le tableau des éléments à traiter. Ainsi, le programe

print (\"Directions possibles :\")
for d in [\"Nord\", \"Sud\", \"Est\", \"Ouest\"]:
print(\"x\", d)



Tester le code ci-dessus et conclure.


L'itération directe sur les éléwebts d'un tableau correspond à une vision un peu plus abstraite. 
Le tableau y est ramené à une collection d'éléments dans laquelle on à effacé le fait que chaque élément était associé à un certain indice i d'un arrangement linéaire. 
En conséquence. cette forme est plus simple à lire comme à écrire. mais n'est applicable que lorsque nous n'avons pas besoin de connaitre l'indice de chaque élément e du tablean t.


","title":"Tableaux vus comme des collections"},{"edit":"

Mettre le résultat ici.

"}],[{"text":"
Supposons que l'on veuille construire un tableau de taille 100 contenant l’entier 3i + 1 dans sa case d'indice i. 
Bien sûr, on peut le construire explicitement, avec la définition en extension que nous connaissons déjà

t = [1, 4, 7, 10, ...]

mais c'est extrémement fastidieux. 

Une meilleure solution consiste a allouer le tableau dans un premier temps, avec une valeur arbitraire, pour le remplir ensuite avec une boucle.

t = [0] * 100
print(t)

for i in range(100):
t[i]= 3 * i + 1

print(t)


C'est déjà une bien meilleure solution. Comme c'est là une construction qui revient souvent, 

Python propose une syntaxe plus compacte encore pour combiner l'allocation d'un tableau et son remplissage par une boucle. 

La voici :


t = [ 3 * 1 + 1 for i in range(100)]
print(t)


Cette nouvelle construction mélange les crochets, qui explicitent que l'on construit un tableau, et les mots clés de la boucle for de Python, qui explicitent que l'on remplit ce tableau avec une boucle. 

On appelle cela la notation par compréhension.

Dans cette construction, le parcours de la variable i n’est pas limité à un intervalle d’entiers construit avec range. 

On peut ainsi parcourir un autre tableau déjà construit.

t = [3 * i + 1 for i in range(10)]
print(\"t=\",t)

print( [x * x for x in t] )


","title":" Construire un tableau par compréhension"},{"edit":"

Mettre le résultat ici.

"}],[{"text":"
Enfin, on peut ne conserver que certaines valeurs prises par la variable, en ajoutant une condition booléenne à la compréhension, avec le mot-clé if.

t = [i * i for i in range(30) if i % 4 == 1]
print(\"t=\",t)


Dans ce cas très particulier où l'on veut construire un tableau contenant les enticrs de i inclus à j exelu, on peut donc écrire

[v for v in range(i, j)]

print([v for v in range(10, 22,2)])


Il existe cependant une construction plus simple encore, à savoir

list (range(i, j))

print(list (range(10, 22,2)))


La fonction prédéfinie list transforme ici l'ensemble des éléments décrits par range(i, j) en un tableau.

","title":""},{"edit":"

Mettre le résultat ici (code et figure).

"}],[{"text":"
Les tableaux de Pythou peuvent contenir des valeurs arbitraires. En particulier, rien ne nous empêche de construire un tableau dont les éléments sont eux-mêmes des tableaux.

t = [[1, 0, 0, 0, 0], [1, 1, 0, 0, 0], [1, 2, 0 ,0, 0 ]]
print(t)


Pour accéder à un entier contenu dans ce tableau de tableaux, on commence par accéder à l'un des trois tableaux, par exemple le troisième avec t[2], puis on accède à l’un de ses éléments, par exemple le deuxième avec [1].

t = [[1, 0, 0, 0, 0], [1, 1, 0, 0, 0], [1, 2, 0 ,0, 0 ]]
print(\"t[2][1] = \", t[2][1])


La notation t[2][1] n’a rien de spécifique aux tableaux de tableaux. On le voit bien en isolant t[2] avec des parenthèses

print(\"t[2][1] = \", (t[2])[1])


Nous pouvons le faire aussi en deux étapes :

u = t[2]
print(u[1])


Sur l'exemple ci-dessus, il y a deux dimensions, la première ayant la taille 3 et la seconde la taille 5. 
print(len(t),\"x\",len(u))
print(len(t),\"x\",len(t[2]))


Pour un tel tableau, on dira que sa taille est 3 x 5, 

On peut se représenter graphiqueruent notre tableau à deux dimensions comme une grille.

01234
010000
111000
212000

Un tel tableau de tableaux est appelé un tableau à plusieurs dimensions.
  
Les indices de la première dimension sont indiqués verticalement, à gauche, et les indices de la seconde dimension sont indiqués horizontalement, en haut.

Pour modifier un élément, on utilise une affectation, exactement comme on le ferait avec un tableau à une dimension.

print(\"t = \", t)

t[1][3] = 7

print(\"t = \", t)


Là encore, cette affectation peut être décomposée, mentalement ou explicitement, comme un accès au tableau t[1] puis à l'affectation de son quatrième
élément.

Un tel tableau à deux dimensions, dont toutes les lignes ont la même taille, est parfois appelé une matrice (notamment dans un contexte mathématique). 

Le concept de tableau à plusieurs dimensions est cependant plus général, car il peut y avoir plus que deux dimensions (un tableau de tableaux de tableaux, par exemple). 

Par ailleurs. rien n'empêche les différents sous-tableaux d'avoir des tailles différentes, comme dans l'exemple suivant.

t1 = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
print(t1)

On s'éloigne alors du concept de matrice. On peut également rapprocher un tableau à deux dimensions de la notion familière de tableur (Excel, Google sheet).

","title":"Tableaux à plusieurs dimensions"},{"edit":"

Mettre le résultat ici (code et figure).

"}],[{"text":"
Pour construire un tableau de tableaux, on peut avantageusement se servir de la construction par compréhension introduite précédemment.

t = [[0] * 5 for i in range(3)]
print(t)

Il est important de bien comprendre qu'on a ici évalué trois fois l'expression [0] * 5, pour chaque valeur de i, en obtenant à chaque fois un nouveau tableau. 

Le tableau t est un tableau de taille 3, donc chaque valeur est un tableau (différent) de taille 5.


","title":"Construction de tableaux à plusieurs dimensions"},{"edit":"

Mettre le résultat ici (code et figure).

"}],[{"text":"
Erreurs. Il pourrait être tentant de construire le tableau t en écrivant simplement :

t = [[0] * 5] * 3
print(t)

 On à même l'impression que cela donne le bon résultat si on observe la valeur de t affichée par Python :

[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

Mais en réalité on à construit un tableau dont les trois éléments sont le même tableau à cinq éléments, ce que l'on peut visualiser ainsi :


\"\"

Si on modifie maintenant un élément de t, par exemple le deuxième élément de la première ligne avec l'affectation

t = [[0] * 5] * 3
print(t)

t[0][1] = 7
print(t)


on se retrouve avec la situation suivante 
 
[[0, 7, 0, 0, 0], [0, 7, 0, 0, 0], [0, 7, 0, 0, 0]]

c'est-à-dire que l'on à modifié simultanément le deuxième élément des trois lignes. 

Ce n'est probablement pas ce que l’on voulait faire.


","title":""},{"edit":"

Mettre le résultat ici (code et figure).

"}],[{"text":"
Pour parcourir tous les éléments d’un tableau à plusieurs dimensions, on va naturellement utiliser des boucles imbriquées, avec chaque boucle parcourant une dimension.

Si on reprend notre tableau  t de taille 3x5 et qu'on souhaite par exemple faire la somme de tous ses éléments.

On peut le faire avec deux boucle imbriquées.

t =[[0, 7, 0, 0, 0], [0, 7, 0, 0, 0], [0, 7, 0, 0, 0]]
s = 0
for i in range(3):
for j in range(5):
s += t[i][j]
print(s)


D'une façon équivalente, on peut utiliser également le parcours d'un tableau avec la méthode suivante :

t1 = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
print(t1)

s = 0
for l in t1:
for e in l:
s += e
print(s)




Ici, la variable l parcourt les lignes du tableau t à deux dimensions ct la variable e parcourt les éléments de chaque ligne. En particulier, les indices i
et j ont disparu (ils sont cachés derrière la construction for). 

Une autre différence, plus significative, est que nous n'avons plus besoin de connaître les différentes dimensions (3 et 5 dans cet exemple), même si on aurait pu remplacer 3 ot 5 par len(t) et len(t[i]), respectivement, dans le premier programme.
t =[[0, 7, 0, 0, 0], [0, 7, 0, 0, 0], [0, 7, 0, 0, 0]]
s = 0
for i in range(len(t)):
for j in range(len(t[i])):
s += t[i][j]
print(s)

","title":"Parcours d’un tableau à plusieurs dimensions"},{"edit":"

Mettre le résultat ici (code et figure).

"}],[{"text":"
Que construit l’expression [i % 3 for i in range(100)]?
(On rappelle que i % 3 est le reste de la division euclidienne de i par 3.)
","title":"Exercice"},{"edit":"

Mettre le résultat ici (code et figure).

"},{"solution":"
Un tableau de taille 100 répétant la sé-
quence 0, 1, 2:

[0, 1, 2, 0, 1, 2, 0, 1, 2, ...]
"}],[{"text":"
Écrire un programme qui construit un tableau t de taille 11 x 11, tel que t[i][j] contient i x j.
","title":"Exercice : Tables de multiplication"},{"edit":"

Mettre le résultat ici (code et figure).

"},{"solution":"
Il faut utiliser une double compréhension :

t = [[i * j for j in range(11)] for i in range(11)]
print(t)
"}],[{"text":"
Écrire un programme qui transforme un tableau t de 64 cases en un tableau m à deux dimensions, de taille 8 x 8, tel que :
m[i][j] =  t[i x 8 + j] pour tout 0 < i,j <8. 



","title":"Exercice"},{"edit":"

Mettre le résultat ici (code et figure).

"},{"solution":"
On peut le faire avec une double compréhension :

t = [i for i in range(64)]
print(t)

m = [[t[8 * i + j] for j in range(8)] for i in range(8)]
print(m)
"}],[{"text":"
Écrire un progrannne qui transforme un tableau m à deux dimensions, de taille 8 x 8, en un tableau t à une dimensions, de taille 64. tel que t[8 * i + j] = m[i][j] pour tout 0 < i,j < 8 .
   

Indication :
Commencer par créer le tableau t puis le remplir avec une double boucle.
","title":"Exercice"},{"edit":"

Mettre le résultat ici (code et figure).

"},{"solution":"
m = [[j + 8*i for j in range(8)] for i in range(8)]
print(m)

t = [0] * 64
for i in range(8):
for j in range(8):
t[8 * i + j] = m[i][j]

print(t)

"}],[{"text":"
Écrire un programme qui crée un tableau à deux dimensions de taille 30 x 30 contenant des entiers tirés au hasard entre 1 et 9999, puis l'affiche. 
","title":"Exercice"},{"edit":"

Mettre le résultat ici (code et figure).

"},{"solution":"
On peut le faire avec une double compréhension.
from random import randint

tab = [[randint(1, 9999) for _ in range(30)] \\
for _ in range(30)]

print(tab)
"}],[{"text":"
Compléter le programme précédent pour calculer et afficher l'élément maximum de ce tableau. 
","title":"Exercice"},{"edit":"

Mettre le résultat ici (code et figure).

"},{"solution":"
On initialise une variable maximum à tab[0][0]. Ensuite on parcourt chaque ligne et chaque élément de chaque ligne pour le comparer avec le maximum.

from random import randint

tab = [[randint(1, 9999) for _ in range(30)] \\

print(tab)


#cherche le maximum de tab
maximum = tab[0][0]
for i in range(30):
for j in range(30):
if tab[i][j] > maximum:
maximum = tab[i][j]
print (\"le maximum est\", maximum)

"}],[{"text":"
Écrire une fonction qui prend cu paramètre un tableau à deux dimensions de hauteur et de largeur non nulles et qui renvoie le maximum parmi les minima de chaque ligne. 

Indication : on pourra utiliser une fonction auxiliaire pour calculer le mininnun d'une ligne.

Tester avec le tableau suivant :
from random import randint

tab = [[randint(1, 9999) for _ in range(30)] \\

print(tab)

 
","title":"Exercice"},{"edit":"

Mettre le résultat ici (code et figure).

"},{"solution":"
Comme chaque ligne contient au moins un élément,
on peut prendre le premier élément pour initialiser la variable minimum dans
la fonction auxiliaire de calcul du minimum.

def minimum(ligne) :
minimum = ligne[0]
for e in ligne:
if e < minimum:
minimum = e
return minimum


De même, comme le tableau contient au moins une ligne, on peut prendre le minimum de la première ligne pour initialiser la variable maximum dans le calcul du maximum.

def maximin(tab):
maximum = minimum(tab[0])
for i in range(1, len(tab)):
min_i = minimum(tab[i])
if maximum < min_i:
maximum = min_i
return maximum

print(maximin(tab))
"}],[{"text":"
Le Puissance 4 est un jeu bien connu à deux joueurs qui se joue sur une grille verticale de six lignes et sept colonnes. 

À tour de rôle, chaque joueur fait tomber un pion de sa couleur dans une colonne de son choix non encore pleine. 

Le premier joueur qui aligne quatre pions de sa couleur, horizontalement, verticalement où en diagonal, gagne la partie. 

La partie est nulle si la grille ost totalement remplie sans qu'aucun joueur ne gagne. 

Pour représenter une grille de ce jeu, on utilise un tableau à deux dimensions de taille 6 x 7, la première dimension représentant les lignes et la seconde les colonnes. 
Une ligne est notée l et prend une valeur entre 0 et 5, la ligne 0 étant situéc en bas: une colonne est notée c et prend une valeur entre 0 et 6, la colonne 0 étant située à gauche. 

Un joueur est noté j et prend la valeur 1 ou 2. 

Dans une grille, notée g, la valeur 0 représente une
case vide et la valeur 1 ou 2 représente un pion du joueur correspondant, 

1. Écrire une fonction grille_vide() qui renvoie une grille vide.
Tester avec le code suivant :
gr = grille_vide()
print(gr)

Résultat :
[[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]

2. Ecrire une fonction affiche(g) qui affiche une grille, avec le caractère . pour une case vide, le caractère X pour le joueur 1 et le caractère O pour le joueur 2. On prendra soin de bien afficher les lignes de haut en  bas

Tester avec : 
affiche(gr)


Résultat :
.......
.......
.......
.......
.......

3. Ecrire une fonction coup_possible(g, c) qui renvoie un booléen indiquant s'il est possible de jouer dans la colonne c.

4. Écrire une fonction jouer(g, j, c) qui joue un coup du joueur j dans la colonne c, en supposant que la colonne c n'est pas pleine.

5. Écrire trois fonctions 
  - horiz(g, j, l, c) 
  - vert(g, j, l, c) 
  - et diag(g, j, l, c) 
qui déterminent respectivement s'il y à un alignement de quatre pions du joueur j à partir de la case (l, c).

6. Ecrire une fonction victoire(g, j) qui renvoie un booléen indiquant si le joueur j à gagné.

7. Ecrire une fonction match_nul(g) qui renvoie un booléen indiquant s'il y a match nul, c'est-à-dire si la grille est totalement remplie. 
Indication : on peut se contenter d'examiner la ligne du haut.

8. Ecrire une fonction coup_aleatoire(g, j) qui joue un coup aléatoire légal pour le joueur j, en supposant que la grille n'est pas pleine. On prendra soin de ne pas favoriser de colonne particulière.

9. Écrire une fonction jouer_auto(g) qui fait jouer deux adversaires aléatoirement à tour de rôle, en affichant la grille après chaque coup, et qui s'arrête dès qu'un joueur gagne ou que la partie est nulle.
 

10. Écrire enfin une fonction jouer_fonction(g) qui permet à l'utilisateur de jouer contre un adversaire qui joue aléatoirement, en affichant la grille après chaque coup et le résultat en fin de partie.
","title":"Exercice"},{"edit":"

Mettre le résultat ici (code et figure).

"},{"solution":"
def grille_vide():
return [[0] * 7 for _ in range(6)]

gr = grille_vide()
print(gr)

"},{"solution":"
def affiche(g):
for l in range(0, 6):
# on affiche de haut en bas
for c in range(0, 7):
if g[l][c] == 0:
print(\".\", end=\"\")
elif g[l][c] == 1:
print (\"X\", end=\"\")
else :
print(\"O\", end=\"\")
print()
print()

affiche(gr)

"},{"solution":"
bas = 0
haut = 5

def coup_possible(g, c):
return g[haut][c] == 0

"},{"solution":"
def jouer(g, j, c):
\"\"\"le joueur j joue dans La colonne c\"\"\"
l = haut
while l > bas and g[l - 1][c] == 0:
l=l-1
g[l][c] = j
"},{"solution":"5.
def horiz(g, j, l , c):
for i in range(4):
if g[l][c + i] != j: return False
return True

def vert(g, j, l, c):
for i in range(4):
if g[l + i][c] != j: return False
return True

def diag(g, j, l, c):
for i in range(4):
if g[l + i][c+i] != j: return False
return True

"},{"solution":"6.
def victoire(g, j):
for l in range(6):
for c in range(7):
if c < 4 and horiz(g, j, l, c) \\
or 1 < 3 and vert(g, j, l, c) \\
or c < 4 and 1 < 3 and diag(g, j, l, c):
return True
return False
"},{"solution":"7.
def match_nul(g):
\"\"\"détermine si la grille est pleine\"\"\"
for c in range(6):
if g[haut][c] == 0:
return False
return True
"},{"solution":"8.
def coup_aleatoire(g, j):
\"\"\"le joueur j joue un coup légal aléatoire\"\"\"
while True:
c = randint(0, 6)
if coup_possible(g, c):
jouer(g, j, c)
return


Dans cette dernière fonction, le return permet de terminer la fonction dès qu’un coup possible à été trouvé et joué. 
"},{"solution":"9.
def jouer_auto(g) :
joueur = 1
while not(match_nul(g)) :
coup_aleatoire(g, joueur)
affiche(g)
if victoire(g,joueur) :
print(joueur,\"a gagné!\")
#pour sortir de la boucle while
return
#change de joueur 1 coup sur 2
if joueur == 1 :
joueur = 2
else :
joueur = 1
sleep(0.1)
jouer_auto(gr)
"},{"solution":"
def coup_manu(g, j):
\"\"\"le joueur j joue un coup légal\"\"\"
while True:
c = int(input(\"colonne entre 0 et 5 :\"))
if coup_possible(g, c):
jouer(g, j, c)
return




def jouer_manu(g) :
joueur = 1
while not(match_nul(g)) :
if joueur == 1 :
coup_aleatoire(g, joueur)
else :
coup_manu(g, joueur)
affiche(g)
if victoire(g,joueur) :
print(joueur,\"a gagné!\")
#pour sortir de la boucle while
return
#change de joueur 1 coup sur 2
if joueur == 1 :
joueur = 2
else :
joueur = 1
sleep(0.1)
jouer_manu(gr)

"}],[{"text":"
Exercice 129 Écrire une fonction dessine qui prend en paramètre un tableau de 2 dimension contenant des booléens, et qui le dessine à l’aide de Turtle en représentant chaque occurrence dé True par un carré noir. Ainsi, le tableau t1 donnera le dessin ci-dessous.
t1 = [ [True, False, True],
[False, True, False],
[True, False, True] ]

dessine(t1)


\"\"i


","title":"Exercice"},{"edit":"

Mettre le résultat ici (code et figure).

"},{"solution":"
from turtle import *

def dessine(t):
for i in range(len(t)):
for j in range(len(t[i])):
if t[i][j]:
up()
goto(10 * j, -10 * i)
down()
begin_fill()
for _ in range(4):
forward(10)
left(90)
end_fill()

"}]]

En poursuivant votre navigation sur mon site, vous acceptez l’utilisation des Cookies et autres traceurs  pour réaliser des statistiques de visites et enregistrer sur votre machine vos activités pédagogiques. En savoir plus.