{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Types construits : les matrices, des listes de listes\n", "\n", "## 1- Définition et implémentation en Python\n", "\n", "En mathématiques, on définit une matrice m x n ou (m, n) comme étant un tableau constitué de m lignes et n colonnes. Chaque élément de ce tableau est repéré par deux indices i et j comme indiqué ci-dessous (source Wikipédia modifiée) :\n", "\n", "![image : matrice_wiki.png](images/matrice_wiki.png)\n", "\n", "Le nombre de lignes et de colonnes peut être différent.\n", "\n", "Lorsqu’il est identique on parle d’une **matrice carrée**, qui est alors de la forme m x m ou (m, m)\n", "\n", "**En Python, une liste de liste pourra permettre d’implémenter une matrice.**\n", "\n", "Exemple : la matrice (2,3) ![image : matrice1.png](images/matrice1.png)\n", "\n", "sera représentée en Python par la liste de liste : **m1 = \\[ \\[1, 2, 3], \\[4, 5, 6]]**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m1 = [[1, 2, 3], [4, 5, 6]]\n", "# écrire les lignes de code permettant de connaître :\n", "# - le nombre de lignes que contient la matrice :\n", "\n", "# - le nombre de colonnes :\n", "\n", "# Que renvoient les instructions suivantes : m1[0] ; m1[0][2] ; m1[1][0] ; m1[1][3] ?\n", "\n", "\n", "# Quel code faut-il écrire pour modifier la valeur 6 de cette matrice en 7 :\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2- Affichage d'une matrice :\n", "\n", "La représentation en Python par une liste de liste : m1 = \\[ \\[1, 2, 3], \\[4, 5, 6]] est visuellement éloignée de l'écriture mathématique d'une matrice. Ecrire une fonction **aff_matrice(mat)** permettant d'afficher à l'écran une matrice comme ci-dessous :\n", "\n", "![title](images/matrice2.png)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def aff_matrice(mat):\n", " \"\"\" \n", " procédure qui affiche sous forme matricielle une liste de liste\n", " :param mat: (list) : la liste de liste à afficher\n", " \"\"\"\n", " # code de la fonction :\n", " for i in range(???):\n", " for j in range (???):\n", " print(mat[i][j], '\\t', end=' ')\n", " print('')\n", "# tester la fonction avec les deux matrices suivantes : \n", "m1 = [[1, 2, 3], [4, 5, 6]] # matrice (2,3) (donc constituée de 2 lignes et 3 colonnes)\n", "m2 = [[1,2], [3,4], [5,6]] # matrice (3,2) (donc constituée de 3 lignes et 2 colonnes)\n", "\n", "aff_matrice(m1)\n", "aff_matrice(m2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3- Créer une matrice par programmation :\n", "\n", "On souhaite créer la matrice m1 de deux façons différentes : à l'aide de deux boucles for imbriquées puis 'en compréhension'. Rédiger le code nécessaire dans les deux cellules ci-dessous et tester le résultat :" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\n", "m1 = [[0,0,0],[0,0,0]] # pour faire 'oublier' au notebook la liste m1\n", "# création de m1 = [[1, 2, 3], [4, 5, 6]] avec deux boucles for :\n", "for i in range(???):\n", " for j in range(???):\n", " m1[i][j] = 3*i+j+1\n", "\n", "# test :\n", "print(m1)\n", "aff_matrice(m1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m1 = [[0,0,0],[0,0,0]] # pour faire 'oublier' au notebook la liste m1\",\n", "#création de m1 = [[1, 2, 3], [4, 5, 6]] en compréhension :\n", "m1 = [[3*i+j+1 for j in range(???)] for i in range(???)]\n", "# test,\n", "print(m1)\n", "aff_matrice(m1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4- Quelques opérations avec les matrices :\n", "\n", "### 4.1 Multiplication d’une matrice par un nombre :\n", "\n", "Soit m une matrice, l’opération k.m renvoie une nouvelle matrice pour laquelle chacun de ses éléments est multiplié par k.\n", "\n", "Par exemple: l'opération **4.m1** donnera :\n", "\n", "![image : mult_matrice.png](images/mult_matrice.png)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def mult_matrice(k, mat):\n", " \"\"\" \n", " multiplie chaque élément de la matrice 'mat' par le réel 'k'\n", " :param k: (type int ou float)\n", " :param mat: (type list) : la matrice \n", " \n", " :return: (list) une nouvelle matrice\n", " \"\"\"\n", " # code de la fonction :\n", " return ???\n", "\n", " # test de la fonction sur la matrice m1 pour créer une matrice m2 = 4.m1 :\n", "m1 = [[1, 2, 3], [4, 5, 6]]\n", "m2 = mult_matrice(4,m1)\n", "aff_matrice(m2)\n", "print(m2)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.2 Somme (ou différence) de deux matrices :\n", "\n", "### 4.2.1- Somme\n", "\n", "La somme de deux matrices m1 et m2 renvoie une nouvelle matrice m3. Un élément de m3 est obtenu par la somme des éléments de m1 et m2 de mêmes indices : \n", "\n", "![image : somme_matrices.png](images/somme_matrices.png)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def add_matrices(mat1, mat2):\n", " \"\"\"\n", " réalise la somme de deux matrices 'mat1' et 'mat2'\n", " :param mat1: (list) \n", " :param mat2: (list) \n", " \n", " :return: (list) une nouvelle matrice égale à 'mat1' + 'mat2'\n", " \"\"\"\n", " # code de la fonction :\n", " return ???\n", " \n", "\n", "#test de la fonction sur les matrices m1 et m2 pour créer une matrice m3 = m1 + m2 :\n", "\n", "m1 = [[1, 2, 3], [4, 5, 6]]\n", "m2 =[[4, 8, 12], [16, 20, 24]]\n", "\n", "???\n", "...\n", "???" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.2- Différence\n", "\n", "La différence de deux matrices m1 et m2 renvoie une nouvelle matrice m3. Un élément de m3 est obtenu par la différence des éléments de m1 et m2 de mêmes indices \n", "\n", "![image : soust_matrice.png](images/soust_matrice.png)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def soust_matrices(mat1, mat2):\n", " \"\"\" \n", " réalise la différence de deux matrices 'mat1' et 'mat2'\n", " :param mat1: (list) \n", " :param mat2: (list) \n", " \n", " :return: (list) une nouvelle matrice égale à 'mat1' - 'mat2'\n", " \"\"\"\n", " # code de la fonction :\n", " return ???\n", " \n", "\n", "#test de la fonction sur les matrices m1 et m2 pour créer une matrice m3bis = m1 - m2 :\n", "m1 = [[1, 2, 3], [4, 5, 6]]\n", "m2 =[[4, 8, 12], [16, 20, 24]]\n", "\n", "m3bis = ???\n", "aff_matrice(m3bis)\n", "print(m3bis)\n", "\n", "# est-il identique de faire soust_matrices(m1, m2) ou soust_matrices(m2, m1) ?\n", "# non ce n'est pas identique, le résultat sera différent\n", "\n", "\n", "# est-il identique de faire soust_matrices(m1, m2) ou soust_matrices(m2, m1) ?\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.3- Transposée d’une matrice :\n", "La transposée d’une matrice est une nouvelle matrice obtenue par symétrie axiale par rapport à la diagonale de la matrice :\n", "\n", "![image : transposee_matrice.png](images/transposee_matrice.png)\n", "\n", "Ecrire une fonction **transpose_matrice(mat)** qui réalise cette opération :" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def transpose_matrice(mat):\n", " \"\"\" \n", " réalise la transposée de la matrice 'mat' \n", " :param mat: (list) : la matrice \n", " \n", " :return: (list) une nouvelle matrice, transposée de 'mat'\n", " \"\"\"\n", " # code de la fonction :\n", " return ???\n", "\n", "#test de la fonction sur la matrice m1 pour créer la matrice m4 qui est la transposée de m1\n", "m1 = [[1, 2, 3], [4, 5, 6]]\n", "m4 = transpose_matrice(m1)\n", "aff_matrice(m4)\n", "print(m4)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5- Applications à l’afficheur 5x5 Leds de la carte Micro:Bit\n", "\n", "## 5.1- Préparation d'images matricielles :\n", "On peut représenter mathématiquement l’afficheur de la carte Micro:Bit par une matrice carrée (5,5) pour laquelle chaque élément peut prendre une valeur entière comprise entre 0 et 9. Cette valeur représentant la luminosité de la Led correspondante. Par exemple, allumer les 25 Leds de l'afficheur avec la luminosité maximum peut-être représenté de la façon suivante : \n", "\n", "![image : matrice_led_9.png](images/matrice_led_9.png)\n", "\n", "\n", "On pourra préparer le travail de programmation dans ce notebook (ou dans Thonny) pour faciliter la mise au point puis transférer le travail sur le site https://create.withcode.uk/ pour le tester sur la carte Micro:Bit virtuelle\n", "\n", "*Pour pouvoir basculer le travail sur la carte Micro:Bit il faudra **faire une ré-écriture de la fonction d'affichage aff_matrice(mat)** de façon à l'adapter à l'écran 5x5 Leds (toutes les matrices que l'on écrira seront donc de type (5,5)*\n", "\n", "**Ce travail va nous montrer une fois de plus l'intérêt d'une programmation faisant usage de fonctions élémentaires réutilisables !**\n", "\n", "**En effet, hormis la fonction d'affichage, toutes les fonctions écrites pour gérer les matrices pourront être utilisées de la même façon pour gérer l'afficheur !**\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def aff_matrice(mat):\n", " \"\"\" \n", " procédure qui affiche sous forme matricielle une liste de liste\n", " :param mat: (list) : la liste de liste à afficher\n", " \"\"\"\n", " # code de la fonction :\n", " for i in range(len(mat)):\n", " for j in range (len(mat[0])):\n", " print(mat[i][j], '\\t', end=' ')\n", " print('')\n", "\n", "# Créer en compréhension une matrice pour représenter l'afficheur ayant toutes les Leds allumées \n", "# avec la valeur de luminosité la plus élevée :\n", "ecran_complet = [[ ??? for ??? in ???] for ??? in ???]\n", "\n", "print(ecran_complet)\n", "aff_matrice(ecran_complet)\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On veut obtenir l'écran suivant :\n", "\n", "![image : triangle_microbit.png](images/triangle_microbit.png)\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Créer en compréhension une matrice appelée 'triangle' pour représenter cette image, les Leds étant allumées \n", "# avec la valeur de luminosité la plus élevée :\n", "triangle = []" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5.2- Afficher une image matricielle :\n", "\n", "On rappelle qu’une led de l’afficheur peut être allumée par la méthode display.set_pixel(i, j, lum).\n", "\n", "Dans **Mu-editor**, **réécrire la fonction aff_matrice(mat)** pour l’adapter à un affichage sur la carte Microbit.\n", "\n", " La tester avec les matrices ecran_complet et triangle.\n", " \n", " \n", "## 5.3 Appliquer des transformations\n", "\n", "### 5.3.1 Transformer une image en ‘négatif’ :\n", " \n", "Réaliser une image en ‘négatif’ signifie que les zones lumineuses doivent devenir sombres et inversement :\n", " * une valeur 9 sera remplacée par un 0\n", " * une valeur 8 par un 1\n", " etc...\n", " \n", " ![image : negatif.png](images/negatif.png) \n", " \n", "Quelle opération mathématique faut-il réaliser sur la luminosité de chacune des Leds pour faire cette transformation ? \n", "\n", "Quelle opération matricielle peut-on alors mettre en oeuvre ?\n", "\n", "On propose de réaliser par exemple l'image d'un 1 puis d'en faire une image \"négative\".\n", "\n", "L'appui sur le bouton B affiche l'image inversée. L'appui sur le bouton A recharge l'image de départ :\n", "\n", "![image : inversion.png](images/inversion.png)\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Travail préparatoire :\n", "# 1- écrire la matrice permettant d'afficher ce 1 \n", "\n", "# 2- écrire le code pour en réaliser l'inversion :\n", "\n", "# 3- le vérifier ici à l'aide de la fonction aff_matrice()\n", "\n", "# on pourra ensuite basculer le code vers mu-editor pour\n", "# finaliser le code pour faire intervenir les boutons A et B)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5.3.2 Réaliser une autre transformation :\n", "\n", "On souhaite réaliser cette transformation par appui sur le bouton B. Un appui sur le bouton A réaffiche l'image initiale :\n", "![image : transposition.png](images/transposition.png)\n", "\n", "Quelle opération matricielle doit-on envisager ?\n", "\n", "Ecrire le code dans mu-editor.\n", "\n", "### 5.3.3 ... et pour les plus rapides :\n", "\n", "Ecrire une fonction miroir_vertical et une fonction miroir_horizontal pour réaliser une image symétrique par rapport à la verticale d'indice j = 2 ou par rapport à l'horizontale d'indice i = 2 \n", "\n", " **Miroir vertical :**\n", " \n", " ![image : miroirV.png](images/miroirV.png)\n", " \n", " \n", " **Miroir horizontal :**\n", " \n", " ![image : transform_miroirH.png](images/transform_miroirH.png)\n", " \n", " ### 5.3.4 ... et pour les très rapides :\n", " \n", " Modifier la fonction d'affichage **aff_matrice(mat)** en **aff_matrice(mat, i = 5, j = 5)** pour n'afficher qu'une partie de l'image matricielle si l'on décide de changer les paramètres i et j fixés par défaut à la valeur 5. \n", " \n", " Grâce à cette modification, il sera possible de faire des animations comme :\n", " - faire apparaître l'image en la faisant descendre vers le bas\n", " - faire apparaître l'image en la faisant arriver vers la droite" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3-final" } }, "nbformat": 4, "nbformat_minor": 2 }