Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Showing
with 745 additions and 180 deletions
---
jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.15.2
kernelspec:
display_name: C++17
language: C++17
name: xcpp17
---
### Objectif pédagogique : différence entre accumulateur et simple affectation
```{code-cell}
:editable: false
:tags: [hide-cell]
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
CONST I1 = RANDOM_INT(5, 17);
```
```{code-cell}
int x, y;
x = 0;
y = 0;
while ( x < I1 ) {
x = x + 1;
y = 1;
}
```
:::{admonition} Consigne
Quelle est la valeur attendue de x et y?
:::
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
int resultx = INPUT(
/// BEGIN SOLUTION
I1
/// END SOLUTION
);
```
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
int resulty = INPUT(
/// BEGIN SOLUTION
1
/// END SOLUTION
);
```
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( resultx == x );
CHECK( resulty == y );
```
---
jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.15.2
kernelspec:
display_name: C++17
language: C++17
name: xcpp17
---
### Objectif pédagogique : boucle while avec compteur (ici calcul du quotient)
```{code-cell}
:editable: 'false'
:tags: [hide-cell]
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
CONST I1 = RANDOM_INT(20, 37);
CONST I2 = RANDOM_INT(5, 10);
```
```{code-cell}
int n = I1;
int i = 0;
while (n > I2) {
n = n - I2;
i = i + 1;
}
```
:::{admonition} Consigne
Quelle est la valeur attendue de i et n?
:::
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
int resulti = INPUT(
/// BEGIN SOLUTION
i
/// END SOLUTION
);
```
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
int resultn = INPUT(
/// BEGIN SOLUTION
n
/// END SOLUTION
);
```
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( resulti == i );
CHECK( resultn == n );
```
---
jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.15.2
kernelspec:
display_name: C++17
language: C++17
name: xcpp17
---
### Objectif pédagogique : boucle while (ici calcul de factorielle)
```{code-cell}
:editable: 'false'
:tags: [hide-cell]
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
CONST N0 = RANDOM_INT(3, 5);
```
```{code-cell}
int N, r;
N = N0;
r = 1;
while (N > 0) {
r = r * N;
N = N - 1;
}
```
:::{admonition} Consigne
Quelle est la valeur attendue de `r`?
:::
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
int result = INPUT(
/// BEGIN SOLUTION
r
/// END SOLUTION
);
```
+++
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( result == r );
```
---
jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.15.2
kernelspec:
display_name: C++17
language: C++17
name: xcpp17
---
### Objectif pédagogique : boucle while (ici calcul du reste)
```{code-cell}
:editable: 'false'
:tags: [hide-cell]
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
CONST I1 = RANDOM_INT(20, 37);
CONST I2 = RANDOM_INT(5, 10);
```
```{code-cell}
int r = I1;
while (r > I2) {
r = r - I2;
}
```
:::{admonition} Consigne
Quelle est la valeur attendue de `r`?
:::
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
int result = INPUT(
/// BEGIN SOLUTION
r
/// END SOLUTION
);
```
+++
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( result == r );
```
#ifndef RANDOMIZATION_H
#define RANDOMIZATION_H
#include <iostream>
#include <cstdlib>
#include <vector>
#include <functional>
/** Infrastructure minimale de test **/
#ifndef ASSERT
#define ASSERT(test) if (!(test)) { throw std::runtime_error("\\x1b[48;5;224mTest failed: "#test); }
#endif
#ifndef CHECK
#define CHECK(test) if ( !(test) ) { throw std::runtime_error("\\x1b[48;5;224mTest failed: "#test); }
#endif
// TODO: how to initialize the seed?
// TODO: randomize ???
#define PLUSOUMOINS +
#define CONST const auto
// TODO: randomize ???
#define X x
#define Y y
#define Z z
int RANDOM_INT(int min, int max) {
return min + (rand() % (max - min + 1));
}
template<typename T, typename ... Args>
T RANDOM_CHOICE(const T arg0, const Args... args) {
const std::vector<T> v({arg0, args...});
return v[rand() % v.size()];
}
template<typename ... Args>
auto RANDOM_CHOICE(const char * arg0, const Args... args) {
const std::vector<std::string> v({arg0, args...});
return v[rand() % v.size()];
}
class RANDOM_VECTOR_CLASS {
public:
template <typename F, typename ... Args>
auto operator ()(int N, F f, Args ... args) {
using invoke_result_t = typename std::invoke_result<F, Args ...>::type;
std::vector<invoke_result_t> v(N);
for (auto &value: v)
value = f(args...);
return v;
}
/*template<typename ... Args>
auto operator ()(int N, RANDOM_VECTOR_CLASS f, Args... args) {
std::vector<std::vector<int>> v(N);
for (auto &value: v)
value = f(args...);
return v;
}*/
};
RANDOM_VECTOR_CLASS RANDOM_VECTOR;
template<typename T>
std::ostream & operator << (std::ostream& o, const std::vector<T> &v) {
o << "{";
if ( v.size() >= 0 ) {
o << v[0];
for ( unsigned int i=1; i<v.size(); i++ )
o << ", " << v[i];
}
o << "}";
return o;
}
template<class T>
T INPUT(T t) {
return t;
}
#endif
from typing import Any
from random import randint, choice
CONST = Any
def INPUT(default: Any) -> Any:
return default
def RANDOM_INT(min: int, max: int):
return randint(min, max+1)
def RANDOM_CHOICE(*args):
r"""
Return a random element of `args`
>>> RANDOM_CHOICE("alice", "bob", "charlie") # doctest: +SKIP
'charlie'
>>> RANDOM_CHOICE("alice")
'alice'
"""
return choice(args)
......@@ -3,8 +3,7 @@ using namespace sf;
#include "primitives.hpp"
int main()
{
int main() {
// Crée une fenêtre de taille 640x480
RenderWindow window(VideoMode(640, 480), "Ma super fenêtre");
......@@ -23,4 +22,3 @@ int main()
return 0;
}
......@@ -4,8 +4,7 @@ using namespace sf;
#include "primitives.hpp"
int main()
{
int main() {
/// BEGIN
// Crée une fenêtre de taille 640x480
RenderWindow window(VideoMode(640, 480), "Ma super fenêtre");
......@@ -33,4 +32,3 @@ int main()
return 0;
}
......@@ -4,27 +4,27 @@ using namespace sf;
#include "primitives.hpp"
int main(){
// Créé et affiche la fenêtre
int main() {
// Créé et affiche la fenêtre
RenderWindow window(VideoMode(640, 480), "Ma super fenêtre");
window.clear(Color::White);
// Dessine des cercles, ellipses, rectangles, lignes et points
// Dessine des cercles, ellipses, rectangles, lignes et points
draw_circle(window, {20, 20}, 10, Color::Blue);
draw_circle(window, {50, 20}, 10, Color::Red);
draw_rectangle(window, {10, 50}, 40, 20, Color::Blue );
draw_rectangle(window, {10, 50}, 40, 20, Color::Blue );
draw_line(window, {120, 50}, {160, 90}, Color::Black);
draw_point(window, {10, 110}, Color::Red);
// Affiche du texte
// Affiche du texte
draw_text(window, {10, 120}, 14, "Voici un exemple de texte.", Color::Black);
// Met à jour l'affichage.
// Met à jour l'affichage.
window.display();
// Attend 10 secondes avant la fin du programme.
// Attend 10 secondes avant la fin du programme.
sleep(seconds(10));
return 0;
return 0;
}
......@@ -36,13 +36,13 @@ void fibonacciTest() {
CHECK( fibonacci(6) == 8 );
}
int main(){
int main() {
fibonacciTest();
int n;
cout << "Entrez un entier : " << endl;
cin >> n;
cout << "Fibonacci(" << n << ") vaut "<< fibonacci(n) << endl;
cout << "Fibonacci(" << n << ") vaut " << fibonacci(n) << endl;
return 0;
}
......
......@@ -38,9 +38,9 @@ en plusieurs fichiers. Puis nous étudierons quelques exemples de
programmes utilisant la bibliothèque SFML et nous en inspirerons pour
programmer des dessins et interagir avec l'utilisateur.
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "1944ac8026cc545a57bcc39a8d55fe63", "grade": false, "grade_id": "cell-6d952c4decd8c706", "locked": true, "schema_version": 3, "solution": false, "task": false}}
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "66602a703f36c2f7e318dabbea427a84", "grade": false, "grade_id": "cell-6d952c4decd8c706", "locked": true, "schema_version": 3, "solution": false, "task": false}}
## <a name=Cours>Cours</a>
## [Cours](cours.md)
- Cours : [Cycle de vie d'un programme](cours-cycle-de-vie-d-un-programme.md)
- Cours : [Modularité et compilation séparée](cours-modularite.md)
......@@ -55,9 +55,19 @@ programmer des dessins et interagir avec l'utilisateur.
## TP
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "b3fecc2d15e9c0ee06eddcefbb2ad19a", "grade": false, "grade_id": "cell-88edc2f254ba7294", "locked": true, "schema_version": 3, "solution": false}}
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "0b59002ac0b41ec5fe9db98882963c56", "grade": false, "grade_id": "cell-88edc2f254ba7293", "locked": true, "schema_version": 3, "solution": false}}
### Exercice : préliminaires : compilation séparée
### Exercice 0 : préliminaires : exercices d'entraînement
1. Effectuez quelques exercices sur les prototypes de fonction de la
feuille [entraîneur/entraîneur.md](entraîneur/entraîneur.md).
Vous pourrez, pour réviser, travailler les exercices sur les autres
thèmes à la maison, en fonction de vos besoins.
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "c14862eeb15c1d00c45129ecb04ba658", "grade": false, "grade_id": "cell-88edc2f254ba7294", "locked": true, "schema_version": 3, "solution": false}}
### Exercice 1 : préliminaires : compilation séparée
1. Consultez le contenu des fichiers suivants : [factorielle.hpp](factorielle.hpp),
[factorielle.cpp](factorielle.cpp), [factorielle-exemple.cpp](factorielle-exemple.cpp).
......@@ -106,9 +116,9 @@ programmer des dessins et interagir avec l'utilisateur.
% REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "f49d0ae7077b8d73d8bb2d37e0d9b548", "grade": false, "grade_id": "cell-41bec4fdd73fc56d", "locked": true, "schema_version": 3, "solution": false}}
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "08916a6087c9fab33a500eaeb42a3e19", "grade": false, "grade_id": "cell-41bec4fdd73fc56d", "locked": true, "schema_version": 3, "solution": false}}
### Exercice : compilation séparée
### Exercice 2 : compilation séparée
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "0aa22e643a0731f21a052d645349ad26", "grade": false, "grade_id": "cell-89f33130471fc08e", "locked": true, "schema_version": 3, "solution": false}}
......@@ -160,38 +170,86 @@ programmer des dessins et interagir avec l'utilisateur.
% REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "7c740bf5fd075394305a0f98d1dd0422", "grade": false, "grade_id": "cell-96bafcc3c30ace6e", "locked": true, "schema_version": 3, "solution": false}}
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "36737f42fbf6300e344e76a3b1301b30", "grade": false, "grade_id": "cell-96bafcc3c30ace6e", "locked": true, "schema_version": 3, "solution": false}}
### Exercice : Premiers graphiques avec Jupyter
### Exercice 3 : Premiers graphiques avec Jupyter
1. Refaites l'exercice 2 du [TD](TD.md) en complétant la feuille
[premier-dessin](premier-dessin.md). Implantez chacun des items
en vérifiant à chaque fois le résultat.
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "e883c664c0706a830228145c1004b74a", "grade": false, "grade_id": "cell-96bafcc3c30ace6f", "locked": true, "schema_version": 3, "solution": false}}
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "a57556751a58812ad6c4403b1ef85a5d", "grade": false, "grade_id": "cell-96bafcc3c30ace6f", "locked": true, "schema_version": 3, "solution": false}}
### Exercice 4 : Premiers graphiques avec SFML
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "f94f35a5a86a6a9bbfa70e9f2ec5274c", "grade": false, "grade_id": "cell-96bafcc3c30ace6g", "locked": true, "schema_version": 3, "solution": false}}
:::::{attention} SFML et sessions graphiques
Pour exécuter un programme utilisant la bibliothèque SFML, il est
nécessaire d'être dans une ***interface graphique***; sinon, vous
aurez une erreur comme :
```
./exemple-graphisme1
Failed to open X11 display; make sure the DISPLAY environment variable is set correctly
```
(X11 est le gestionnaire de session graphique sous UNIX).
::::{admonition} Option 1 : Sur les ordinateurs des salles de TP
Vous êtes automatiquement dans une session graphique. Vous n'avez donc
rien de particulier à faire.
### Exercice : Premiers graphiques avec SFML ♣
::::
:::{attention}
::::{admonition} Option 2 : Avec le service JupyterHub@Paris-Saclay, depuis tout autre ordinateur ou tablette connectée à Internet
:class: dropdown
Il n'est à l'heure actuelle pas encore possible d'utiliser le serveur
JupyterHub pour cet exercice. Il est donc à effectuer en local en
salle de TP (ou sur votre machine personnelle si vous avez les
logiciels requis). Si vous n'avez pas eu le temps de le faire en
séance de TP, ce n'est pas critique pour l'avancement de votre
projet. Aussi est-il marqué d'un ♣.
En parallèle de l'interface usuelle JupyterLab, vous pouvez lancer une
interface graphique (dite XFCE Desktop) sur le même serveur. Vous
pourrez ensuite basculer entre l'une et l'autre pour éditer et
compiler vos programmes d'une part, et les exécuter d'autre part.
:::
<figure>
Pour installer les logiciels requis sur votre machine personnelle,
voir les sections « Aide à l'installation » sur la [page logiciels du
site du cours](http://nicolas.thiery.name/Enseignement/Info111/logiciels/#aide-installation).
À noter que, pour utiliser la SFML sur CodeBlocks ou tout autre
environnement de développement intégré (IDE),
il faut configurer l'IDE. Plus encore que d'habitude, nous
recommandons de compiler en ligne de commande dans le terminal. Pour
l'instant, en salle de TP, il est nécessaire d'utiliser `info-111 compile`
pour compiler un programme utilisant SFML.
<video src="https://nicolas.thiery.name/Enseignement/Info111/media/screencast-sfml-on-jupyterhub.webm"
width="95%" controls
alt="Vidéo: lancer un programme graphique SFML avec JupyterHub"
/>
<figcaption>Vidéo : lancer un programme graphique SFML avec JupyterHub</figcaption>
</figure>
::::
::::{admonition} Sur votre machine personnelle
:class: dropdown
L'installation, la configuration et l'utilisation de la SFML peut être
un peu technique selon la configuration de votre ordinateur (système
d'exploitation, environnement de développement, ...). Nous donnons
ici quelques pointeurs, mais après c'est à vous de fouiller la
documentation, notamment sur le [site de la
SFML](https://www.sfml-dev.org/index-fr.php) et de vous
débrouiller. Dans le doute, utilisez plutôt une des deux options
ci-dessus.
La section « Salle de TP virtuelle » sur la [page logiciels du site du
cours](https://nicolas.thiery.name/Enseignement/Info111/ComputerLab/README.html)
donne des instructions pour installer JupyterLab, compilateur C++ et
SFML. Sous GNU/Linux (Ubuntu, ...) cela devrait être suffisant pour
travailler.
Si vous souhaitez utiliser CodeBlocks, Visual Studio, ou tout autre
environnement de développement intégré (IDE), il faudra configurer cet
IDE pour utiliser la SFML. Plus encore que d'habitude, nous
recommandons de compiler en ligne de commande dans le terminal.
::::
:::::
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "a0ff90a81efe68e4975687391da8ddc6", "grade": false, "grade_id": "cell-96bafcc3c30ace6h", "locked": true, "schema_version": 3, "solution": false}}
1. Ouvrez les fichiers [exemple-graphisme1.cpp](exemple-graphisme1.cpp)
et [primitives.hpp](primitives.hpp) et consultez le premier.
......@@ -223,9 +281,9 @@ pour compiler un programme utilisant SFML.
à changer la valeur de la variable `delai` pour voir le résultat
s'afficher plus longtemps.
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "851f78b272e43edba563532592fc2279", "grade": false, "grade_id": "cell-eaefcdbc75785adb", "locked": true, "schema_version": 3, "solution": false}}
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "cb4372b6a345f17e803ae8856124785f", "grade": false, "grade_id": "cell-eaefcdbc75785adb", "locked": true, "schema_version": 3, "solution": false}}
### Exercice : Souris et clavier
### Exercice 5 : Souris et clavier
1. Pour vous donner une idée de l'utilisation de la SFML et
de notre bibliothèque de primitives, lisez attentivement
......@@ -239,9 +297,9 @@ pour compiler un programme utilisant SFML.
<!-- Solutions dans le TD !-->
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "5917c7b9cfd1dcba875ca0c00faa1060", "grade": false, "grade_id": "cell-5858dbcffa05aed3", "locked": true, "schema_version": 3, "solution": false}}
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "6bb1aa5b00f1758bbd44d55f54bc3ea6", "grade": false, "grade_id": "cell-5858dbcffa05aed3", "locked": true, "schema_version": 3, "solution": false}}
### Exercice : Couche d'abstraction
### Exercice 6 : Couche d'abstraction
Pour vous approprier la couche d'abstraction, consultez son
implantation dans `primitives.cpp`. En vous inspirant de
......@@ -254,9 +312,9 @@ Vous pouvez vous aider de la
% REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "346c0470eb0efbaa0d4446698ec913d5", "grade": false, "grade_id": "cell-48f3d0b08106b27e", "locked": true, "schema_version": 3, "solution": false, "task": false}}
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "d07cbe5dd5f6b305779f0b8a6d1128f3", "grade": false, "grade_id": "cell-48f3d0b08106b27e", "locked": true, "schema_version": 3, "solution": false, "task": false}}
### Exercice: Jeu du Yams
### Exercice 7_: Jeu du Yams
Reprenez le jeu du Yams du TP 6 en ajoutant une interface graphique.
......@@ -269,4 +327,3 @@ de points sera ensuite affiché.
À vous de concevoir les fonctions à introduire pour décomposer le
problème.
......@@ -12,9 +12,9 @@ int monMax(int a, int b) {
}
void monMaxTest() {
CHECK( monMax(2,3) == 3 );
CHECK( monMax(5,2) == 5 );
CHECK( monMax(1,1) == 1 );
CHECK( monMax(2, 3) == 3 );
CHECK( monMax(5, 2) == 5 );
CHECK( monMax(1, 1) == 1 );
}
int main() {
......
......@@ -7,9 +7,9 @@ using namespace std;
#include "max.hpp"
void monMaxTest() {
CHECK( monMax(2,3) == 3 );
CHECK( monMax(5,2) == 5 );
CHECK( monMax(1,1) == 1 );
CHECK( monMax(2, 3) == 3 );
CHECK( monMax(5, 2) == 5 );
CHECK( monMax(1, 1) == 1 );
}
int main() {
......
......@@ -5,16 +5,15 @@
using namespace sf;
using namespace std; // Pour les exceptions dans la version distribuée
int main()
{
int main() {
int delai = 1;
RenderWindow window(VideoMode(900, 480), "Ma super fenêtre");
RenderWindow window(VideoMode(640, 480), "Ma super fenêtre");
window.clear(Color::Green);
// Dessine un point noir de coordonnées (418, 143)
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 17");
throw runtime_error("code non implanté ligne 16");
window.display();
......@@ -23,7 +22,7 @@ int main()
// Dessine un segment blanc entre les points (100,200) et (200,200)
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 25");
throw runtime_error("code non implanté ligne 24");
window.display();
......@@ -32,7 +31,7 @@ int main()
// Dessine un segment rouge entre les points (200,300) et (200,400)
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 33");
throw runtime_error("code non implanté ligne 32");
window.display();
......@@ -41,7 +40,7 @@ int main()
// Dessine un rectangle horizontal vide de sommets diagonaux (200,200) et (400,300) et de contour rouge
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 41");
throw runtime_error("code non implanté ligne 40");
window.display();
......@@ -50,7 +49,7 @@ int main()
// Dessine un rectangle horizontal plein noir de sommets diagonaux (400,150) et (500,200)
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 49");
throw runtime_error("code non implanté ligne 48");
window.display();
......@@ -59,29 +58,38 @@ int main()
// Dessine un segment rouge entre les points (400,300) et (500,400)
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 57");
throw runtime_error("code non implanté ligne 56");
window.display();
sleep(seconds(delai));
// Dessine un cercle noir de centre (415,145) et de rayon 10
// Dessine un triangle bleu entre les (0,0), (640,0) et (0,160)
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 65");
window.display();
sleep(seconds(delai));
// Dessine un cercle noir de centre (415,145) et de rayon 10
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 72");
window.display();
sleep(seconds(delai));
// Dessine un disque jaune de centre (700, 100) et de rayon 50
// Dessine un disque jaune de centre (550, 75) et de rayon 50
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 73");
throw runtime_error("code non implanté ligne 80");
window.display();
sleep(seconds(10*delai));
sleep(seconds(10 * delai));
return 0;
}
......@@ -14,6 +14,15 @@ kernelspec:
# Premiers graphiques avec Jupyter
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "f43a760bd6125e25df23a9ab2628c3e9", "grade": false, "grade_id": "cell-db040b06c5a92100", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Dans cette feuille, nous allons reprendre l'exercice 2 du TD et
effectuer un premier dessin.
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "f4cbf5563a6542f5c409f308fdca30a3", "grade": false, "grade_id": "cell-db040b06c5a92101", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Commençons par créer un canvas vert de taille 640 x 480 :
```{code-cell}
---
deletable: false
......@@ -37,35 +46,44 @@ deletable: false
editable: false
nbgrader:
cell_type: code
checksum: bca96fdfc7023d461b707c8ae74b0caa
checksum: 9d359d2bf83f09dfcd9eb723473a197f
grade: false
grade_id: cell-c2afd88f340f46f4
locked: true
schema_version: 3
solution: false
task: false
tags: []
---
RenderWindow window(VideoMode(900, 480), "Ma super fenêtre");
RenderWindow window(VideoMode(640, 480), "Ma super fenêtre");
window.canvas
```
<canvas id='primitives_canvas'></canvas>
```{code-cell}
window.clear(Color::Green);
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "7df12946868397e5fbe4bc994fb8d19c", "grade": false, "grade_id": "cell-db040b06c5a92102", "locked": true, "schema_version": 3, "solution": false, "task": false}}
puis dessinons un point noir de coordonnées (418, 143). Ce point est
tout petit, vous aurez peut-être un peu de mal à le distinguer :
```{code-cell}
// Dessine un point noir de coordonnées (418, 143)
draw_point(window, {418, 143}, Color::Black );
window.display();
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "cb08398efe05ecc0073912c50887ba17", "grade": false, "grade_id": "cell-db040b06c5a92103", "locked": true, "schema_version": 3, "solution": false, "task": false}}
1. Dessinez un segment blanc entre les points de coordonnées
respectives (100,200) et (200,200) :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: b956b1c98520d602fab742ceb67096ed
checksum: ce1d6a0deeef3221d1ea8d9afbd40bce
grade: true
grade_id: cell-e77db2d9ed7265ac
locked: false
......@@ -74,17 +92,32 @@ nbgrader:
solution: true
task: false
---
// Dessine un segment blanc entre les points (100,200) et (200,200)
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display();
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "5da5ff8010119a35e52e9ba76dc3237d", "grade": false, "grade_id": "cell-db040b06c5a92104", "locked": true, "schema_version": 3, "solution": false, "task": false}}
:::{tip} Astuce
Pour éviter de monter et descendre constamment dans cette feuille,
faites un clic droit sur le canvas et cliquez sur «Créer une nouvelle
vue pour la sortie» (ou «Create new view for output»). Puis disposez
la copie obtenue du canvas sur votre espace de travail de sorte à voir
simultanément votre code et le canvas.
:::
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "fea5730c56d940cd6a18b432d9069629", "grade": false, "grade_id": "cell-db040b06c5a92105", "locked": true, "schema_version": 3, "solution": false, "task": false}}
2. Dessinez un segment rouge entre les points (200,300) et (200,400) :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: 85bdbd533e19a61d9a8a460522c51477
checksum: 90954d14f326667b7a51643cd5d83bc0
grade: true
grade_id: cell-03b3d3f225c29d1d
locked: false
......@@ -93,17 +126,21 @@ nbgrader:
solution: true
task: false
---
// Dessine un segment rouge entre les points (200,300) et (200,400)
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display();
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "0791571f18f4df2c2bfecb5a3ba9c0ff", "grade": false, "grade_id": "cell-db040b06c5a92106", "locked": true, "schema_version": 3, "solution": false, "task": false}}
3. Dessinez un rectangle horizontal vide de sommets diagonaux
(200,200) et (400,300) et de contour rouge :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: dea1bd15783375ceace4d093b9200ec4
checksum: 4c65f8e4cec21af229e5a44dd7063a03
grade: true
grade_id: cell-3606e0158c83309d
locked: false
......@@ -112,17 +149,21 @@ nbgrader:
solution: true
task: false
---
// Dessine un rectangle horizontal vide de sommets diagonaux (200,200) et (400,300) et de contour rouge
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display()
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "4eda0a34767a781e0fd3c186999331e2", "grade": false, "grade_id": "cell-db040b06c5a92107", "locked": true, "schema_version": 3, "solution": false, "task": false}}
4. Dessinez un rectangle horizontal plein noir de sommets diagonaux
(400,150) et (500,200) :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: 8d1e034e1cda25ee20a1c154f6f26185
checksum: f66e8172c61aca3cb946861a95326520
grade: true
grade_id: cell-25abe8a7c6c8c617
locked: false
......@@ -131,17 +172,21 @@ nbgrader:
solution: true
task: false
---
// Dessine un rectangle horizontal plein noir de sommets diagonaux (400,150) et (500,200)
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display()
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "2f11cf73501e6fcc67b66d7ced218656", "grade": false, "grade_id": "cell-db040b06c5a92108", "locked": true, "schema_version": 3, "solution": false, "task": false}}
5. Dessinez un segment rouge entre les points (400,300) et
(500,400) :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: 196d46fbc53bc7393b523ace887864ab
checksum: 49650230393c3fc8d743c211525de50c
grade: true
grade_id: cell-c6d75131df2bea6d
locked: false
......@@ -150,17 +195,42 @@ nbgrader:
solution: true
task: false
---
// Dessine un segment rouge entre les points (400,300) et (500,400)
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display()
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "34955bd551a86d7f66e34edca2617cab", "grade": false, "grade_id": "cell-db040b06c5a92109", "locked": true, "schema_version": 3, "solution": false, "task": false}}
6. ♣ Dessinez un triangle bleu entre les (0,0), (640,0) et (0,160) :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: de3439e6f2af1c2ebadec5e92840b900
grade: true
grade_id: cell-c6d75131df2bea6e
locked: false
points: 1
schema_version: 3
solution: true
task: false
---
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display()
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "16aaa6f47064b571ba75a417797361e4", "grade": false, "grade_id": "cell-db040b06c5a92110", "locked": true, "schema_version": 3, "solution": false, "task": false}}
7. Dessinez un cercle noir de centre (415,145) et de rayon 10 :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: 783c0f2dd02e54533dd5243b34fe2ccd
checksum: e56a4a8d478945ff8d1ef1c4497dcf05
grade: true
grade_id: cell-63406c09d76b868b
locked: false
......@@ -169,17 +239,20 @@ nbgrader:
solution: true
task: false
---
// Dessine un cercle noir de centre (415,145) et de rayon 10
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display()
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "92e964b26520043007e0fe1972b38638", "grade": false, "grade_id": "cell-db040b06c5a92111", "locked": true, "schema_version": 3, "solution": false, "task": false}}
8. Dessinez un disque jaune de centre (550, 75) et de rayon 50 :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: cfc9ac790998bab53ad2de41b30f2f6d
checksum: 6419729d5f34a928308cdd11942a3f1a
grade: true
grade_id: cell-4f7332edb4646cbf
locked: false
......@@ -188,8 +261,25 @@ nbgrader:
solution: true
task: false
---
// Dessine un disque jaune de centre (700, 100) et de rayon 50
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display()
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "ef878f93df33be50d5262273cefbc00a", "grade": false, "grade_id": "cell-db040b06c5a92112", "locked": true, "schema_version": 3, "solution": false, "task": false}}
:::{attention}
Comme vous l'avez constaté, les performances sont lamentables. C'est
parce que nous avons abusé des canvas de HTML : alors que ceux-ci sont
conçus pour du dessin vectoriel, nous approximons les figures
vectorielles (lignes, triangles, ...) par des accumulations d'un très
grand nombre de pixels (combien pour le triangle bleu?), sachant que
chacun de ces pixels est en fait représenté en interne par un petit
rectangle.
En dehors de ce premier dessin -- dont l'objectif pédagogique était de
faire un peu d'algorithmique -- il faut au contraire utiliser les
primitives vectorielles fournies.
:::
......@@ -3,17 +3,17 @@
#include <cmath>
#include <iostream>
void draw_point(RenderWindow& w, Point pos, Color color) {
void draw_point(RenderWindow &w, Point pos, Color color) {
Vertex p[] = { Vertex(pos, color) };
w.draw(p, 1, sf::Points);
}
void draw_line(RenderWindow& w, Point pos1, Point pos2, Color color) {
void draw_line(RenderWindow &w, Point pos1, Point pos2, Color color) {
Vertex p[] = { Vertex(pos1, color), Vertex(pos2, color) };
w.draw(p, 2, sf::Lines);
}
void draw_circle(RenderWindow& w, Point center, int r, Color color) {
void draw_circle(RenderWindow &w, Point center, int r, Color color) {
CircleShape shape(r);
shape.setPosition(center);
shape.setOutlineThickness(1.f);
......@@ -23,7 +23,7 @@ void draw_circle(RenderWindow& w, Point center, int r, Color color) {
}
/// BEGIN draw_filled_circle
void draw_filled_circle(RenderWindow& w, Point center, int r, Color color) {
void draw_filled_circle(RenderWindow &w, Point center, int r, Color color) {
CircleShape shape(r);
shape.setPosition(center);
shape.setOutlineThickness(0.f);
......@@ -32,7 +32,8 @@ void draw_filled_circle(RenderWindow& w, Point center, int r, Color color) {
}
/// END draw_filled_circle
void draw_rectangle(RenderWindow& w, Point pos, int width, int height, Color color) {
void draw_rectangle(RenderWindow &w, Point pos, int width, int height,
Color color) {
RectangleShape shape(Vector2f(width, height));
shape.setPosition(pos); //Top-left position
shape.setOutlineThickness(1.f);
......@@ -41,10 +42,11 @@ void draw_rectangle(RenderWindow& w, Point pos, int width, int height, Color col
w.draw(shape);
}
void draw_filled_rectangle(RenderWindow& w, Point pos, int width, int height, Color color) {
void draw_filled_rectangle(RenderWindow &w, Point pos, int width, int height,
Color color) {
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 47");
throw runtime_error("code non implanté ligne 49");
}
......@@ -69,7 +71,7 @@ bool font_is_available() {
return available;
}
void draw_text(RenderWindow& w, Point pos, int size, string str, Color co) {
void draw_text(RenderWindow &w, Point pos, int size, string str, Color co) {
if ( font_is_available() ) {
sf::Text text;
text.setFont(minipax);
......@@ -81,18 +83,18 @@ void draw_text(RenderWindow& w, Point pos, int size, string str, Color co) {
}
}
Point wait_mouse(RenderWindow& w) {
Point wait_mouse(RenderWindow &w) {
Event e;
do w.waitEvent(e);
while(e.type != Event::MouseButtonPressed or
e.mouseButton.button != Mouse::Button::Left);
while (e.type != Event::MouseButtonPressed or
e.mouseButton.button != Mouse::Button::Left);
return Point(e.mouseButton.x, e.mouseButton.y);
}
Event::KeyEvent wait_keyboard(RenderWindow& w) {
Event::KeyEvent wait_keyboard(RenderWindow &w) {
Event e;
do w.waitEvent(e);
while(e.type != Event::KeyPressed);
while (e.type != Event::KeyPressed);
return e.key;
}
......@@ -57,7 +57,7 @@ using Point = Vector2f;
* @param pos les coordonnées du point
* @param color la couleur du point
*/
void draw_point (RenderWindow& w, Point pos, Color color);
void draw_point (RenderWindow &w, Point pos, Color color);
/** Affiche une ligne de couleur entre deux positions données
* @param w une fenêtre ouverte dans laquelle dessiner
......@@ -65,7 +65,8 @@ void draw_point (RenderWindow& w, Point pos, Color color);
* @param pos1 les coordonnées du dernier point de la ligne
* @param color la couleur de la ligne
*/
void draw_line (RenderWindow& w, Point pos1, Point pos2, Color color);
void draw_line (RenderWindow &w, Point pos1, Point pos2,
Color color);
/** Affiche un rectangle coloré vide
* @param w une fenêtre ouverte dans laquelle dessiner
......@@ -74,7 +75,8 @@ void draw_line (RenderWindow& w, Point pos1, Point pos2, Color color)
* @param height la hauteur du rectangle
* @param color la couleur du trait
*/
void draw_rectangle (RenderWindow& w, Point pos, int width, int height, Color color);
void draw_rectangle (RenderWindow &w, Point pos, int width, int height,
Color color);
/** Affiche un rectangle coloré plein
* @param w une fenêtre ouverte dans laquelle dessiner
......@@ -83,7 +85,8 @@ void draw_rectangle (RenderWindow& w, Point pos, int width, int height, Co
* @param height la hauteur du rectangle
* @param color la couleur du trait et du remplissage
*/
void draw_filled_rectangle(RenderWindow& w, Point pos, int width, int height, Color color);
void draw_filled_rectangle(RenderWindow &w, Point pos, int width, int height,
Color color);
/** Affiche un cercle coloré vide
* @param w une fenêtre ouverte dans laquelle dessiner
......@@ -91,15 +94,15 @@ void draw_filled_rectangle(RenderWindow& w, Point pos, int width, int height, Co
* @param r le rayon du cercle
* @param color la couleur du trait
*/
void draw_circle (RenderWindow& w, Point center, int r, Color color);
void draw_circle (RenderWindow &w, Point center, int r, Color color);
/** Affiche un cercle coloré plein
/** Affiche un cercle coloré plein
* @param w une fenêtre ouverte dans laquelle dessiner
* @param center la position du centre du cercle
* @param r le rayon du cercle
* @param color la couleur du trait et du remplissage
*/
void draw_filled_circle (RenderWindow& w, Point center, int r, Color color);
void draw_filled_circle (RenderWindow &w, Point center, int r, Color color);
/** Affiche du texte coloré à une position donnée
* @param w une fenêtre ouverte dans laquelle dessiner
......@@ -108,13 +111,14 @@ void draw_filled_circle (RenderWindow& w, Point center, int r, Color color);
* @param str la chaîne de caractères à afficher
* @param color la couleur du texte
*/
void draw_text (RenderWindow& w, Point pos, int size, string str, Color color);
void draw_text (RenderWindow &w, Point pos, int size, string str,
Color color);
/** Attend que l'utilisateur appuie sur le clic gauche de la souris
* @param w la fenêtre dans laquelle l'utilisateur doit cliquer
* @return la position dans la fenêtre où l'utilisateur a cliqué
*/
Point wait_mouse(RenderWindow& w);
Point wait_mouse(RenderWindow &w);
/** Attend que l'utilisateur appuie sur une touche du clavier
* @param w la fenêtre concernée
......@@ -122,6 +126,6 @@ Point wait_mouse(RenderWindow& w);
* La liste des codes de touches est accessibles ici:
* https://huit.re/sfml_key_codes
*/
Event::KeyEvent wait_keyboard(RenderWindow& w);
Event::KeyEvent wait_keyboard(RenderWindow &w);
#endif
#ifndef PRIMITIVES_JUPYTER_H
#define PRIMITIVES_JUPYTER_H
/**
Variante de primitives.h pour dessiner dans Jupyter, sans la SFML
......@@ -11,48 +14,16 @@
NE PRENNEZ PAS EXEMPLE DESSUS!
**/
#include <iostream>
#include <sstream>
#include <xwidgets/xhtml.hpp>
/** Execute javascript code in the Jupyter window
**/
void execute_javascript(std::string js) {
nl::json mime_bundle;
mime_bundle["application/javascript"] = js;
::xeus::get_interpreter().display_data(mime_bundle,
nl::json::object(),
nl::json::object());
}
void load_javascript_library() {
execute_javascript(R"js(
document.primitives_get_context = function() {
return document.primitives_canvas.getContext('2d');
}
document.primitives_draw_rectangle = function(x, y, width, height, color) {
var ctx = document.primitives_get_context();
ctx.strokeStyle = color;
ctx.strokeRect(x, y, width, height);
}
document.primitives_draw_filled_rectangle = function(x, y, width, height, color) {
var ctx = document.primitives_get_context();
ctx.fillStyle = color;
ctx.fillRect(x, y, width, height);
}
document.primitives_draw_point = function(x, y, color) {
document.primitives_draw_rectangle(x, y, 1, 1, color);
}
)js");
}
#include <xcanvas/xcanvas.hpp>
namespace Color {
using Color = std::string;
Color White = "white";
Color Red = "red";
Color Yellow = "yellow";
Color Green = "#00FF00";
Color Black = "black";
Color White = "White";
Color Blue = "Blue";
Color Red = "Red";
Color Yellow = "Yellow";
Color Green = "#00CC00";
Color Black = "Black";
}
class Point {
......@@ -70,49 +41,43 @@ class VideoMode {
VideoMode(int w, int h): width(w), height(h) {}
};
using Canvas = xw::xmaterialize<xc::xcanvas>;
class RenderWindow {
xw::html html;
VideoMode vm;
public:
// A buffer of javascript commands to execute
std::ostringstream buffer;
Canvas canvas;
RenderWindow(VideoMode _vm, std::string s) : vm(_vm) {
std::ostringstream canvas;
// canvas << "<canvas id='primitives_canvas'"
// << " width=" << vm.width << " height=" << vm.height
// << " style='border:1px solid #000000;'></canvas>";
load_javascript_library();
buffer << "document.primitives_canvas = document.getElementById('primitives_canvas');";
buffer << "document.primitives_canvas.height = " << vm.height << ";";
buffer << "document.primitives_canvas.width = " << vm.width << ";";
buffer << "document.primitives_canvas.style = 'border:1px solid #000000';";
display();
// Disabled until xwidgets is functional again
// For now, the canvas needs to be created in a markdown cell of the notebook
// html.value = canvas.str();
// html.display();
vm = _vm;
canvas = xc::canvas().initialize()
.width(vm.width)
.height(vm.height)
.finalize();
canvas.cache();
}
// Update the canvas by executing all javascript commands in the buffer
void display() {
execute_javascript(buffer.str());
buffer = std::ostringstream();
Canvas& get_canvas() {
return canvas;
}
// Clear the canvas with the given color
void clear(Color::Color color) {
buffer << "document.primitives_draw_filled_rectangle(0, 0, "
<< vm.width << ", "
<< vm.height << ", '"
<< color << "');";
display();
canvas.fill_style = color;
canvas.fill_rect(0, 0, vm.width, vm.height);
display();
}
void display() {
canvas.flush();
canvas.cache();
}
};
void draw_point(RenderWindow &window, Point p, Color::Color color) {
window.buffer << "document.primitives_draw_point("
<< p.x << ", "
<< p.y << ", '"
<< color << "');";
window.canvas.fill_style = color;
window.canvas.fill_rect(p.x, p.y, 1, 1);
}
#endif