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 1605 additions and 0 deletions
---
jupyter:
jupytext:
text_representation:
extension: .md
format_name: myst
kernelspec:
display_name: C++17
language: C++17
name: xcpp17
---
### Objectif pédagogique : comprendre une boucle for et faire un calcul simple
```{code-cell} c++
---
editable: false
tags: [hide-cell]
---
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
```
+++
```{code-cell} c++
---
tags: [hide-cell, variable]
---
CONST RINIT = RANDOM_INT(1, 7);
RINIT
```
+++
```{code-cell} c++
---
tags: [hide-cell, variable]
---
CONST IMAX = RANDOM_INT(2, 4);
IMAX
```
+++
```{code-cell} c++
---
tags: [hide-output, substitution]
---
int r = RINIT;
int a = 2;
for ( int I = 1; I <= IMAX ; I = I + 1 ) {
r = r + a * I;
}
```
+++
:::{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 );
```
---
jupyter:
jupytext:
text_representation:
extension: .md
format_name: myst
kernelspec:
display_name: C++17
language: C++17
name: xcpp17
---
### Objectif pédagogique : comprendre une factorielle avec une boucle for
```{code-cell} c++
---
editable: false
tags: [hide-cell]
---
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
```
+++
```{code-cell} c++
---
tags: [hide-cell, variable]
---
CONST N0 = RANDOM_INT(3, 5);
// Ne pas randomiser le nom de variable pour l'indice k, sinon risque qu'on tombe sur n, qui existe déjà dans ce code.
// (Ou alors remplacer n par m, puis randomiser le nom de variable de l'indice k ?)
N0
```
+++
```{code-cell} c++
---
tags: [hide-output, substitution]
---
int n, r;
n = N0;
r = 1;
for ( int k = 1; k <= n; k++ ) {
r = r * k;
}
```
+++
:::{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 for avec accumulateur
```{code-cell}
:editable: false
:tags: [hide-cell]
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
```
```{code-cell}
:tags: [hide-cell, variable]
CONST I1 = RANDOM_INT(1, 6);
CONST I2 = I1 + RANDOM_INT(10,12);
```
:::{admonition} Consigne
Écrivez le code permettant de mettre dans la variable p
le produit des entiers compris entre I1 et I2 inclus.
:::
```{code-cell}
:editable: true
long int p;
```
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
/// BEGIN SOLUTION
p = 1;
for (int i = I1; i <= I2; i++)
p = p * i;
/// END SOLUTION
```
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
long int result = 1;
for (int i = I1; i <= I2; i++)
result = result * i;
CHECK( result == p );
```
---
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 for avec accumulateur
```{code-cell}
:editable: false
:tags: [hide-cell]
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
```
```{code-cell}
:tags: [hide-cell, variable]
CONST I1 = RANDOM_INT(0, 7);
CONST I2 = RANDOM_INT(18, 26);
```
:::{admonition} Consigne
Écrivez ici le code permettant de mettre dans la variable `s`
la somme des carrés des entiers compris entre I1 et I2 inclus.
:::
```{code-cell}
:editable: true
int s;
```
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
/// BEGIN SOLUTION
s = 0;
for (int i = I1; i <= I2; i++)
s = s + i*i;
/// END SOLUTION
```
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
int result = 0;
for (int i = I1; i <= I2; i++)
result = result + i * i;
CHECK( result == s );
```
#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)
---
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 : écriture d'entête de fonction
```{code-cell}
:editable: 'false'
:tags: [hide-cell]
#include <iostream>
#include <typeinfo>
#include <string>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
```
:::{admonition} Consigne
Écrivez ci-dessous l'entête de la fonction en n'oubliant pas de finir
par `{`. Regardez les appels dans les cellules suivantes pour voir le
nom de la fonction et son utilisation.
:::
```{code-cell}
/** Teste si a divise b
* @param un entier a et un entier b
* @return true si a divise b, false sinon
**/
```
```{code-cell}
---
editable: 'true'
nbgrader:
grade: 'false'
grade_id: init
locked: 'false'
schema_version: '3'
solution: 'true'
---
/// BEGIN SOLUTION
bool estDiviseur(int a, int b) {
/// END SOLUTION
return b % a == 0;
}
```
```{code-cell}
estDiviseur(2,8)
```
```{code-cell}
estDiviseur(3,8)
```
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( typeid(estDiviseur).name() == string("FbiiE") );
CHECK( estDiviseur(2,8) );
CHECK( !estDiviseur(3,8) );
```
---
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 : écriture d'entête de fonction
```{code-cell}
:editable: 'false'
:tags: [hide-cell]
#include <iostream>
#include <typeinfo>
#include <string>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
```
:::{admonition} Consigne
Écrivez ci-dessous l'entête de la fonction
en n'oubliant pas de finir par `{`.
Regarder les appels dans les cellules suivantes pour
voir le nom de la fonction et son utilisation.
:::
```{code-cell}
/** Multiplie un entier et un réel
* @param un entier a et un réel b
* @return le produit réel de a par b
**/
```
```{code-cell}
---
editable: 'true'
nbgrader:
grade: 'false'
grade_id: init
locked: 'false'
schema_version: '3'
solution: 'true'
---
/// BEGIN SOLUTION
float produit(int a, float b) {
/// END SOLUTION
return a * b;
}
```
```{code-cell}
produit(3, 2.5)
```
```{code-cell}
produit(2, 5.4)
```
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( typeid(produit).name() == string("FfifE") or typeid(produit).name() == string("FdidE" ))
CHECK( produit(3, 2.5) == 7.5f );
CHECK( produit(2, 5.4) == 10.8f );
```
---
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 : écriture d'entête de fonction
```{code-cell}
:editable: 'false'
:tags: [hide-cell]
#include <iostream>
#include <typeinfo>
#include <string>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
```
:::{admonition} Consigne
Écrivez ci-dessous l'entête de la fonction en n'oubliant pas de finir
par `{`. Regardez les appels dans les cellules suivantes pour voir le
nom de la fonction et son utilisation.
:::
```{code-cell}
/** Compte le nombre de caractères d'une chaîne de caractères
* @param une chaîne de caractères a
* @return le nombre de caractères de a
**/
```
```{code-cell}
---
editable: 'true'
nbgrader:
grade: 'false'
grade_id: init
locked: 'false'
schema_version: '3'
solution: 'true'
---
/// BEGIN SOLUTION
int nbCaracteres(string a) {
/// END SOLUTION
return a.size();
}
```
```{code-cell}
nbCaracteres("bonjour")
```
```{code-cell}
nbCaracteres("aujourd'hui")
```
+++
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( string(typeid(nbCaracteres).name()).find(string("FiNSt")) != string::npos )
CHECK( nbCaracteres("bonjour") == 7 );
CHECK( nbCaracteres("aujourd'hui") == 11 );
```
---
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 : écriture d'entête de fonction
```{code-cell}
:editable: 'false'
:tags: [hide-cell]
#include <iostream>
#include <typeinfo>
#include <string>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
```
:::{admonition} Consigne
Écrivez ci-dessous l'entête de la fonction en n'oubliant pas de finir
par `{`. Regardez les appels dans les cellules suivantes pour voir le
nom de la fonction et son utilisation.
:::
```{code-cell}
/** Affiche le contenu d'un tableau d'entiers
* @param tab un tableau d'entiers
**/
```
```{code-cell}
---
editable: 'true'
nbgrader:
grade: 'false'
grade_id: init
locked: 'false'
schema_version: '3'
solution: 'true'
---
/// BEGIN SOLUTION
void affiche(vector<int> tab) {
/// END SOLUTION
for (int i=0; i<tab.size(); i++) {
cout << tab[i]<<endl;
}
}
```
```{code-cell}
affiche( {3,2,5} )
```
```{code-cell}
affiche( {7,4} )
```
+++
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( string(typeid(affiche).name()).find(string("FvSt6vectorI")) != string::npos )
```
---
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 : écriture d'entête de fonction
```{code-cell}
:editable: 'false'
:tags: [hide-cell]
#include <iostream>
#include <typeinfo>
#include <string>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
```
:::{admonition} Consigne
Écrivez ci-dessous l'entête de la fonction en n'oubliant pas de finir
par `{`. Regardez les appels dans les cellules suivantes pour voir le
nom de la fonction et son utilisation.
:::
```{code-cell}
/** Affiche un compte à rebours commençant par l'entier pris en paramètre
* @param n un entier
**/
```
```{code-cell}
---
editable: 'true'
nbgrader:
grade: 'false'
grade_id: init
locked: 'false'
schema_version: '3'
solution: 'true'
---
/// BEGIN SOLUTION
void afficheCompteARebours(int n) {
/// END SOLUTION
for (int i=n; i>=0; i--) {
cout << i << endl;
}
}
```
```{code-cell}
afficheCompteARebours(5)
```
+++
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( typeid(afficheCompteARebours).name() == string("FviE") );
```
#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)
import copy
import IPython # type: ignore
from IPython.core.display_functions import display # type: ignore
import ipywidgets # type: ignore
import nbformat
import jupytext # type: ignore
import os
import random
import re
from typing import Any, List
from nbconvert.preprocessors import ExecutePreprocessor # type: ignore
from code_randomizer import Randomizer
Notebook = Any
class ExecutionError(RuntimeError):
pass
answer_regexp = re.compile(r"INPUT\(.*\)", re.DOTALL)
class Exercizer(ipywidgets.VBox):
def __init__(self, exercizes: List[str]):
self.exercizes = sorted(exercizes)
# View
border_layout = ipywidgets.Layout(border="solid", padding="1ex")
self.exercize_zone = ipywidgets.Output(layout=border_layout)
self.answer_zone = [ipywidgets.Textarea()]
self.run_button = ipywidgets.Button(
description="Valider", button_style="primary", icon="check"
)
self.name_label = ipywidgets.Label()
self.result_label = ipywidgets.Label()
self.randomize_button = ipywidgets.Button(
icon="dice",
description="Variante",
tooltip="Tire aléatoirement une autre variante du même exercice",
button_style="primary",
layout={"width": "fit-content"},
)
self.next_button = ipywidgets.Button(
icon="caret-right",
description="Exercice suivant",
button_style="primary",
layout={"width": "fit-content"},
)
self.previous_button = ipywidgets.Button(
icon="caret-left",
description="Exercice précédent",
button_style="primary",
layout={"width": "fit-content"},
)
self.random_button = ipywidgets.Button(
icon="dice",
description="Exercice aléatoire",
tooltip="Tire aléatoirement un exercice",
button_style="primary",
layout={"width": "fit-content"},
)
self.controler_zone = ipywidgets.VBox(
[
ipywidgets.HBox(
[
self.randomize_button,
self.run_button,
self.name_label,
self.result_label,
]
),
ipywidgets.HBox(
[self.previous_button, self.random_button, self.next_button]
),
]
)
# Controler
self.next_button.on_click(lambda event: self.next_exercize())
self.previous_button.on_click(lambda event: self.previous_exercize())
self.random_button.on_click(lambda event: self.random_exercize())
self.randomize_button.on_click(lambda event: self.randomize_exercize())
self.run_button.on_click(lambda event: self.run_exercize())
self.set_exercize(0)
super().__init__(
[self.exercize_zone, self.controler_zone], layout=border_layout
)
def set_exercize(self, i: int):
self.exercize_number = i
self.exercize_name = self.exercizes[self.exercize_number]
self.notebook = self.randomize_notebook(jupytext.read(self.exercize_name))
self.display_exercize(self.notebook)
language = self.notebook.metadata["kernelspec"]["language"]
self.name_label.value = f'{self.exercize_name} ({language})'
self.result_label.value = ""
def next_exercize(self):
self.set_exercize((self.exercize_number + 1) % len(self.exercizes))
def previous_exercize(self):
self.set_exercize((self.exercize_number - 1) % len(self.exercizes))
def random_exercize(self):
self.set_exercize(random.randint(0, len(self.exercizes) - 1))
def randomize_exercize(self):
self.set_exercize(self.exercize_number)
def run_exercize(self):
self.result_label.value = "🟡 Exécution en cours"
# self.result_label.style.background = "orange"
self.run_button.disabled = True
try:
success = self.run_notebook(
self.notebook,
answer=[answer_zone.value for answer_zone in self.answer_zone],
dir=os.path.dirname(self.exercize_name),
)
self.result_label.value = (
"✅ Bonne réponse" if success else "❌ Mauvaise réponse"
)
# self.result_label.style.background = "green" if success else "red"
except ExecutionError:
self.result_label.value = "❌ Erreur à l'exécution"
# self.result_label.style.background = "red"
finally:
self.run_button.disabled = False
def display_exercize(self, notebook):
with self.exercize_zone:
self.exercize_zone.clear_output(wait=True)
i_answer = 0
for cell in notebook.cells:
if cell["metadata"].get("nbgrader", {}).get("solution", False):
if i_answer > 0:
self.answer_zone.append(ipywidgets.Textarea())
code = cell["source"]
if re.search(answer_regexp, code):
self.answer_zone[i_answer].value = ""
else:
self.answer_zone[i_answer].value = code.split("/// END SOLUTION")[-1]
self.answer_zone[i_answer].rows = 3
display(self.answer_zone[i_answer])
i_answer = i_answer + 1
elif cell["cell_type"] == "markdown":
display(IPython.display.Markdown(cell["source"]))
else:
if "hide-cell" not in cell["metadata"].get("tags", []):
display(IPython.display.Code(cell["source"]))
def randomize_notebook(self, notebook: Notebook) -> Notebook:
notebook = copy.deepcopy(notebook)
language = notebook.metadata["kernelspec"]["language"]
randomizer = Randomizer(language=language)
for cell in notebook.cells:
cell["source"] = randomizer.randomize(
text=cell["source"], is_code=(cell["cell_type"] == "code")
)
return notebook
def run_notebook(self, notebook: Notebook, answer: list[str], dir: str) -> bool:
notebook = copy.deepcopy(notebook)
kernel_name = notebook["metadata"]["kernelspec"]["name"]
i_answer = 0
for i, cell in enumerate(notebook.cells):
# If Autograded code cell
if cell["cell_type"] == "code" and cell["metadata"].get("nbgrader", {}).get(
"solution", False
):
code = cell["source"]
if re.search(answer_regexp, code):
code = re.sub(answer_regexp, answer[i_answer], code)
else:
code = answer[i_answer]
notebook.cells[i] = nbformat.v4.new_code_cell(code)
i_answer = i_answer + 1
ep = ExecutePreprocessor(timeout=600, kernel_name=kernel_name, allow_errors=True)
owd = os.getcwd()
try:
os.chdir(dir)
result = ep.preprocess(notebook)
finally:
os.chdir(owd)
success = True
for cell in result[0]["cells"]:
# If this is a code cell and execution errored
if cell["cell_type"] == "code" and any(
output["output_type"] == "error" for output in cell["outputs"]
):
if cell["metadata"].get("nbgrader", {}).get("grade", False):
# If Autograded tests cell
success = False
# elif cell["metadata"].get("nbgrader", {}).get("solution", False):
# TODO: handle autograded answer cell failure
else:
# TODO: handle
raise ExecutionError("Execution failed")
return success
#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)
---
jupyter:
jupytext:
text_representation:
extension: .md
format_name: myst
kernelspec:
display_name: C++17
language: C++17
name: xcpp17
---
### Objectif pédagogique : comprendre la difference entre valeur et nom d'une variable de type string
```{code-cell} c++
---
editable: false
tags: [hide-cell]
---
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
```
+++
```{code-cell} c++
---
tags: [hide-cell, variable]
---
CONST NAMEstr = RANDOM_CHOICE("Bob", "Barbara", "Pierre", "Paul", "Jeanne", "Camille");
NAMEstr
```
+++
```{code-cell} c++
---
tags: [hide-output, substitution]
---
string NAME = NAMEstr;
string r = NAME;
```
+++
:::{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
---
string result = INPUT(
/// BEGIN SOLUTION
NAMEstr
/// 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 );
```
---
jupyter:
jupytext:
text_representation:
extension: .md
format_name: myst
kernelspec:
display_name: C++17
language: C++17
name: xcpp17
---
### Objectif pédagogique : échange de variable correct
```{code-cell} c++
---
editable: false
tags: [hide-cell]
---
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
```
+++
```{code-cell} c++
---
tags: [hide-cell, variable]
---
CONST I1 = RANDOM_INT(0, 7);
I1
```
+++
```{code-cell} c++
---
tags: [hide-cell, variable]
---
CONST I2 = RANDOM_INT(8, 15);
I2
```
+++
```{code-cell} c++
---
tags: [hide-output, substitution]
---
int X, Y, Z;
X = I1;
Y = I2;
Z = X;
X = Y;
Y = Z;
int r = Y;
```
+++
:::{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
Y
/// 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)