jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
kernelspec:
display_name: Python 3 (ipykernel)
language: python
name: python3
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "d6b46a0a95cd43ae80dbc181dc125671", "grade": false, "grade_id": "cell-10", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Semaine 8 : fichiers et flux de données
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "dc414efeceffd39f0262e39fbf550a1d", "grade": false, "grade_id": "cell-20", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Cours
- Cours : flux de données
- Cours : fichiers
- Cours : état d'un fichier
- Cours : lecture et écriture dans des chaînes de caractères
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "dbf5500bedb753c425b378e4748347d6", "grade": false, "grade_id": "cell-30", "locked": true, "schema_version": 3, "solution": false, "task": false}}
TD : fichiers et images numériques
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "bf4d86ed29ba34ce66bdbc753d794093", "grade": false, "grade_id": "cell-40", "locked": true, "schema_version": 3, "solution": false, "task": false}}
TP
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "6ff5819dcd18e689494acb0ba1af242e", "grade": false, "grade_id": "cell-49", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Exercice 0 : Jupyter : l'indentation
À faire chez vous!
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "9dd26fe469908352fac43de3f823d14a", "grade": false, "grade_id": "cell-50", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Exercice 1 : écrire dans un fichier - 20 minutes
+++
::::{hint} Rappels
-
Pour exécuter un programme, il faut d’abord avoir compilé le fichier
.cpp
avec la commandeclang++
puis lancer l’exécutable créé par la compilation. Consultez au besoin les instructions des TP précédents. -
Pensez à organiser votre espace de travail et à ajuster la taille des caractères (avec Ctrl-+ et Ctrl--) pour avoir une vue confortable simultanée de tous les éléments requis : consignes, code, terminal.
:::{figure} https://nicolas.thiery.name/Enseignement/Info111/media/screencast-espace-de-travail-compilation.gif Vidéo: organiser son espace de travail avec JupyterLab :::
::::
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "8124382c9ab91f1d2004315ed95e82c1", "grade": false, "grade_id": "cell-60", "locked": true, "schema_version": 3, "solution": false, "task": false}}
-
Consultez le fichier fichier-ecriture.cpp.
-
Essayez de deviner ce que fait ce programme.
-
Exécutez ce programme.
-
Trouvez le fichier
.txt
qui a été créé à l’exécution et l’ouvrir avec un éditeur de texte. Que contient-il? -
Copiez le contenu de fichier-ecriture.cpp dans fichier-ecriture-v2.cpp, et adaptez le pour qu’à l’exécution il écrive un fichier nommé
essai.txt
contenant le texte «17 fois 23 vaut» suivi de la valeur de ce nombre (valeur que le programme calcule par lui-même). -
Exécutez ce programme puis ouvrez le fichier
essai.txt
afin de vérifier son contenu. -
Lisez et essayez à nouveau dans le cours l'exemple de lecture depuis le clavier avec
cin
. -
En vous en inspirant, complétez le programme cin.cpp pour que, à l’exécution, il demande à l’utilisateur d’entrer deux entiers, puis qu’il écrive un fichier nommé
multiplication.txt
contenant un texte similaire au fichieressai.txt
de la question précédente, avec 17 et 23 remplacés respectivement par les deux entiers choisis par l’utilisateur.:::{note}
Pour faire des affichages à l’écran et pour faire saisir des données depuis le clavier, il faut inclure la bibliothèque
iostream
en écrivant#include <iostream>
. Pour lire et écrire dans un fichier de texte, il faut inclure la bibliothèquefstream
en écrivant#include <fstream>
:::
-
Exécutez le programme puis ouvrez le fichier
multiplication.txt
pour vérifier son contenu.
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "cb2c18e19c408b69d4d8589c8f7649cd", "grade": false, "grade_id": "cell-70", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Exercice 2 : ouvrir le smiley - 5 minutes
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "5f1d313afad6f51ebf42d10eb2ea7a42", "grade": false, "grade_id": "cell-80", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Le fichier media/smiley.pbm (dans le répertoire
media
donc!) contient l’image en noir et blanc du TD.
-
Ouvrez ce fichier d’abord avec un éditeur de texte. Depuis le navigateur de fichiers de JupyterLab: clic droit -> Ouvrir avec -> Éditeur.
-
Ouvrez ce même fichier avec un logiciel de vision d’images. Pour cela, depuis Jupyter, vous pouvez utiliser la cellule ci-dessous :
from open_ppm import open_ppm # importe la commande open_ppm fournie
im = open_ppm("media/smiley.pbm") # charge l'image
im.resize((256*im.width // im.height, 256)) # affiche l'image avec une taille donnée
:::{admonition} Pour les curieux :class: dropdown
Python et Jupyter ne savent pas manipuler nativement les fichiers aux
formats PBM, PGM ou PPM non compressés. La commande
open_ppm('xxx.ppm')
fournie dans le fichier
open_ppm.py commence par utiliser l'utilitaire
convert
de ImageMagick
avec convert xxx.ppm xxx.png
pour
convertir l'image en format PNG.
:::
Alternativement :
- Sous Windows, vous pouvez utiliser l’application
irfanview
. - Sous Linux, vous pouvez utiliser l’application
xviewer
: utilisez «Control +» et «Control -» pour zoomer / dezoomer. Vous remarquerez que l’image est lissée / floutée. Allez dans le menu «Edit -> Preferences» et décochez «Smooth images when zoomed in» pour mieux voir les pixels.
Exercice 3 : petit damier - 15 minutes
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "7a193c543e70cced08244a1a71520334", "grade": false, "grade_id": "cell-90", "locked": true, "schema_version": 3, "solution": false, "task": false}}
-
Utilisez un éditeur de texte pour écrire à la main un fichier texte
damier.pbm
contenant une image au format PBM (Portable Bit Map) de taille 10×10 représentant un damier ::::{image} media/damier_svg.png :width: 10% :alt: un damier :::
-
Visualisez le résultat, par exemple avec :
from open_ppm import open_ppm
im = open_ppm("damier.pbm")
im.resize((256*im.width // im.height, 256))
(indications_images)= :::{hint} Indications en cas d'erreur à la visualisation ou d'image incorrecte :class: dropdown
- Vérifiez que le fichier existe, dans le répertoire
Semaine8
, avec le bon nom et la bonne extension (.pbm
,.pgm
, ou.ppm
selon l'exercice). - Ouvrez le fichier avec un éditeur de texte.
- Vérifiez l'entête de l'image:
- la première ligne contient
P1
(format PBM),P2
(format PGM) ouP3
(format PPM); - la deuxième ligne (sans compter les lignes de commentaires
commençant par
#
) contient deux entiers: le nombre c de colonnes et le nombre l de lignes; - pour les fichiers
pbm
ouppm
: la troisième ligne contient un entier m.
- la première ligne contient
- Vérifiez que le reste du fichier consiste d'entiers séparés par des
espaces ou des sauts de ligne:
- format
pbm
: cl entiers 0 ou 1; - format
pgm
: cl entiers entre 0 et m; - format
ppm
: 3cl entiers entre 0 et m.
- format
- Vérifiez que les valeurs sont adéquates.
:::
Tests automatiques :
assert im.size == (10, 10), "l'image n'est pas de taille 10×10"
import numpy as np
M = np.array(im, dtype=int)
assert np.all(M[1:,:] + M[:-1,:] == 1), "l'image n'est pas un damier horizontalement"
assert np.all(M[:,1:] + M[:,:-1] == 1), "l'image n'est pas un damier verticalement"
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "65237cca3ba3cf9fb579a874a7f3f6b1", "grade": false, "grade_id": "cell-100", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Exercice 4 : grand damier
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "792992fb2ce3f4d9bf342c4bee84e65a", "grade": false, "grade_id": "cell-110", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Complétez le programme C++ damier.cpp qui, lorsqu’on
l’exécute, écrit un fichier image damier-automatique.pbm
comme le
précédent, mais cette fois pour un damier 100x100.
Visualisez et vérifiez au fur et à mesure le résultat avec :
im = open_ppm("damier-automatique.pbm")
im.resize((512*im.width // im.height, 512))
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "8b8ba5a75745c14276324532d144a1fe", "grade": false, "grade_id": "cell-120", "locked": true, "schema_version": 3, "solution": false, "task": false}}
:::{hint} Indications
- Vous pouvez vous inspirer de fichier-ecriture.cpp.
- Commencez par un programme pour un damier 10×10 avant de passer à 100×100.
- L'exécution de votre programme devrait être instantanée ou presque. Si ce n'est pas le cas, interrompez le avec Ctrl-C.
- Vérifiez la taille du fichier produit en tapant la commande suivante dans
le terminal :
ls -lh *.pbm
- Si le fichier produit ne donne pas l’image attendue, ou si vous n'arrivez pas à le visualiser: reportez vous aux indications de l'exercice précédent.
- Si cela vous aide, vous pouvez aussi dans un premier temps
afficher le texte produit à l’écran avec
cout
; puis écrivez le dans le fichier dans un deuxième temps.
:::
+++
Tests automatiques :
assert im.size == (100, 100), "l'image produite n'est pas de taille 100×100"
import numpy as np
M = np.array(im, dtype=int)
assert np.all(M[1:,:] + M[:-1,:] == 1), "l'image n'est pas un damier horizontalement"
assert np.all(M[:,1:] + M[:,:-1] == 1), "l'image n'est pas un damier verticalement"
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "fec81568499bca600d3cae6fb9dc41c0", "grade": false, "grade_id": "cell-130", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Exercice 5 : dégradé de gris
Pour créer une image avec des nuances de gris, il faut enregistrer un fichier de texte au format PGM (Portable Gray Map). Ce fichier doit contenir des nombres entre 0 et une valeur maximale (au choix) qui représenteront les différentes nuances de gris.
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "3175edfdcd2ba6f573443ce9504466dd", "grade": false, "grade_id": "cell-140", "locked": true, "schema_version": 3, "solution": false, "task": false}}
- Écrivez à la main, dans un éditeur de texte, un fichier
essai.pgm
représentant une image de taille 10×10 contenant différentes nuances de gris de votre choix. Vérifiez au fur et à mesure le résultat avec :
im = open_ppm("essai.pgm")
im.resize((256*im.width // im.height, 256))
Tests automatiques :
assert im.size == (10, 10), "l'image produite n'est pas de taille 10×10"
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "65f16b8b10337cf30c2a8273bd57ff79", "grade": false, "grade_id": "cell-150", "locked": true, "schema_version": 3, "solution": false, "task": false}}
-
Implantez un programme degrade.cpp qui écrit un fichier contenant une image
degrade.pgm
de taille 128x128, avec un dégradé de gris comme celui-ci ::::{image} media/degrade.png :width: 20% :alt: un dégradé de gris :::
im = open_ppm("degrade.pgm")
im.resize((256*im.width // im.height, 256))
Tests automatiques :
assert im.size == (128, 128), "l'image produite n'est pas de taille 128×128"
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "4f500798eefc2a87622c29ef17e57230", "grade": false, "grade_id": "cell-160", "locked": true, "schema_version": 3, "solution": false, "task": false}}
- Répétez, avec une image de taille 100×100
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "9c9224e94d136176282b95357c8edd88", "grade": false, "grade_id": "cell-170", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Exercice 6 : inversion d’image
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "f3fa5bea0ea3429d63f52fd66e7d3369", "grade": false, "grade_id": "cell-180", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Implantez un programme videoInverse.cpp
qui lit un fichier contenant une image au format
PGM (par exemple le fichier media/image.pgm
fourni), et écrit un fichier
contenant la même image en vidéo inverse (clair remplacé par sombre et
réciproquement).
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "2a4cc77ee0d0dcd169aad954bff7fd0a", "grade": false, "grade_id": "cell-190", "locked": true, "schema_version": 3, "solution": false, "task": false}}
:::{hint} Indication Implantez une fonction
/** Image en vidéo inverse
* @param image1: le nom du fichier contenant l'image à lire
* @param image2: le nom du fichier pour l'image à écrire
**/
void videoInverse(string image1, string image2);
:::
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "8e4c6932227912a0021029a54216d0ec", "grade": false, "grade_id": "cell-200", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Exercice 7 : dégradé circulaire de rouge ♣️
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "a4badd45d2e8d7c755437d2bcc49f9bc", "grade": false, "grade_id": "cell-210", "locked": true, "schema_version": 3, "solution": false, "task": false}}
-
Implantez un programme degrade-circulaire.cpp qui écrit un fichier contenant une image
degrade-circulaire.ppm
au format PPM de taille 255×255, avec un dégradé circulaire de rouge::::{image} media/degrade-circulaire.png :width: 20% :alt: un dégradé circulaire :::
-
Répétez, avec une image de taille 100×100.