Skip to article frontmatterSkip to article content
import numpy as np

on va commencer par quelques rappels et astuces

broadcasting

un trait qui sera abordé en cours, mais qu’on peut mettre en évidence facilement

# un tableau en ligne
row = np.array([0, 1000, 2000, 3000])
# un tableau en colonne
col = np.array([[0], [10], [20]])
row
array([ 0, 1000, 2000, 3000])
col
array([[ 0], [10], [20]])

eh bien ces deux tableaux, bien que n’ayant pas la même forme, peuvent s’ajouter !

row + col
array([[ 0, 1000, 2000, 3000], [ 10, 1010, 2010, 3010], [ 20, 1020, 2020, 3020]])

reshaping

pour fabriquer le tableau col ci dessus, on aurait pu procéder de plein d’autres façons

# en partant des données 'à plat'
raw = np.array([0, 10, 20])
# on aurait pu produire la forme de `col` comme ceci
# dans un reshape, le -1 est calculé pour boucher le trou
col1 = raw.reshape((-1, 1))
col1
array([[ 0], [10], [20]])
# avec newaxis
col2 = raw[:, np.newaxis]
col2
array([[ 0], [10], [20]])

indices

la fonction np.indices est très pratique pour obtenir les rangs dans le tableau

# par exemple
I, J = np.indices((3, 4))
I, J
(array([[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2]]), array([[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]))

exercices

Voici maintenant de quoi mettre ces astuces en pratique

table de multiplication

Produisez le tableau de la table de multiplication des entiers entre 1 et n

On peut le faire de au moins 3 façons (cf les 3 premières sections ci-dessus)

N = 5

# à vous

échiquier

base - v1

On veut écrire une fonction qui produit un échiquier

ex. avec checkers(3, 4)

0101
1010
0101
# à vous

def checkers():
    """
    vous avez le droit d'écrire le docstring :)
    """
    ...
# ceci doit afficher True

np.all(checkers(3, 4) == np.array([[0,1,0,1],[1,0,1,0],[0,1,0,1]]))
Output
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[13], line 3
      1 # ceci doit afficher True
----> 3 np.all(checkers(3, 4) == np.array([[0,1,0,1],[1,0,1,0],[0,1,0,1]]))

TypeError: checkers() takes 0 positional arguments but 2 were given

v2 - pareil, mais doit retourner des booléens

# à vous

def checkers():
    ...
# ceci doit afficher True

np.all(checkers(3, 4) == np.array([[0,1,0,1],[1,0,1,0],[0,1,0,1]]))
Output
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[15], line 3
      1 # ceci doit afficher True
----> 3 np.all(checkers(3, 4) == np.array([[0,1,0,1],[1,0,1,0],[0,1,0,1]]))

TypeError: checkers() takes 0 positional arguments but 2 were given
# ceci doit afficher True

checkers(3, 4).dtype == bool
Output
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[16], line 3
      1 # ceci doit afficher True
----> 3 checkers(3, 4).dtype == bool

TypeError: checkers() takes 0 positional arguments but 2 were given

affichage

comment feriez-vous pour afficher le tableau comme un damier ?

[indice] voyez plt.imshow()

# à vous
...

paramètrer le coin

Pour corser un peu, on ajoute un paramètre optionnel qui indique, lorsqu’il est True, qu’on veut que l’échiquer est inversé

ex. avec checkers(3, 4, True)

1010
0101
1010

mais les appels avec seulement deux paramètres continuent à fonctionner comme avant

# à vous
# ceci doit afficher True

np.all(checkers(3, 4) == np.array([[0,1,0,1],[1,0,1,0],[0,1,0,1]]))
Output
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[19], line 3
      1 # ceci doit afficher True
----> 3 np.all(checkers(3, 4) == np.array([[0,1,0,1],[1,0,1,0],[0,1,0,1]]))

TypeError: checkers() takes 0 positional arguments but 2 were given
# ceci doit afficher True

np.all(checkers(3, 4, True) == ~(checkers(3, 4)))
Output
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[20], line 3
      1 # ceci doit afficher True
----> 3 np.all(checkers(3, 4, True) == ~(checkers(3, 4)))

TypeError: checkers() takes 0 positional arguments but 3 were given
# pour débugger
checkers(3, 4)
Output
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[21], line 2
      1 # pour débugger
----> 2 checkers(3, 4)

TypeError: checkers() takes 0 positional arguments but 2 were given
# pour débugger
checkers(3, 4, True)
Output
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[22], line 2
      1 # pour débugger
----> 2 checkers(3, 4, True)

TypeError: checkers() takes 0 positional arguments but 3 were given

tester

On veut maintenant tester que si on ajoute ces deux formes on n’obtient que des 1

# à vous d'écrire le code qui vous permettra de vous en assurer

escaliers

écrivez une fonction qui retourne une espèce de pyramide escalier comme ceci

si le paramètre est 2, on retourne un tableau de taille 2n+12*n+1

stairs(2)

01210
12321
23432
12321
01210

quelques indices

toujours pour le cas où n=2, voici quelques phrases que je vous laisse lire

I, J = np.indices((5, 5))
# si on décale, retourne, et applique abs()
abs(2-I), abs(2-J)
(array([[2, 2, 2, 2, 2], [1, 1, 1, 1, 1], [0, 0, 0, 0, 0], [1, 1, 1, 1, 1], [2, 2, 2, 2, 2]]), array([[2, 1, 0, 1, 2], [2, 1, 0, 1, 2], [2, 1, 0, 1, 2], [2, 1, 0, 1, 2], [2, 1, 0, 1, 2]]))
# si on les ajoute
abs(2-I) + abs(2-J)
array([[4, 3, 2, 3, 4], [3, 2, 1, 2, 3], [2, 1, 0, 1, 2], [3, 2, 1, 2, 3], [4, 3, 2, 3, 4]])
# on y est presque
4-(abs(2-I) + abs(2-J))
array([[0, 1, 2, 1, 0], [1, 2, 3, 2, 1], [2, 3, 4, 3, 2], [1, 2, 3, 2, 1], [0, 1, 2, 1, 0]])
# à vous de mettre tout cela ensemble

def stairs(n):
    ...
# comment feriez-vous pour afficher le résultat visuellement ?

# à vous