Skip to content

Commit eec5165

Browse files
authored
MAINT Improve build of exercises to avoid duplicated 'Write your code here' cells (#788)
1 parent 449e220 commit eec5165

7 files changed

+40
-20
lines changed

build_tools/generate-exercise-from-solution.py

+25-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import jupytext
77

88

9+
WRITE_YOUR_CODE_COMMENT = "# Write your code here."
10+
11+
912
def replace_simple_text(input_py_str):
1013
result = input_py_str.replace("📃 Solution for", "📝")
1114
return result
@@ -44,7 +47,24 @@ def remove_solution(input_py_str):
4447
]
4548

4649
for c in cells_to_modify:
47-
c["source"] = pattern.sub("# Write your code here.", c["source"])
50+
c["source"] = pattern.sub(WRITE_YOUR_CODE_COMMENT, c["source"])
51+
52+
previous_cell_is_write_your_code = False
53+
all_cells_before_deduplication = nb.cells
54+
nb.cells = []
55+
for c in all_cells_before_deduplication:
56+
if c["cell_type"] == "code" and c["source"] == WRITE_YOUR_CODE_COMMENT:
57+
current_cell_is_write_your_code = True
58+
else:
59+
current_cell_is_write_your_code = False
60+
if (
61+
current_cell_is_write_your_code
62+
and previous_cell_is_write_your_code
63+
):
64+
# Drop duplicated "write your code here" cells.
65+
continue
66+
nb.cells.append(c)
67+
previous_cell_is_write_your_code = current_cell_is_write_your_code
4868

4969
# TODO: we could potentially try to avoid changing the input file jupytext
5070
# header since this info is rarely useful. Let's keep it simple for now.
@@ -53,6 +73,7 @@ def remove_solution(input_py_str):
5373

5474

5575
def write_exercise(solution_path, exercise_path):
76+
print(f"Writing exercise to {exercise_path} from solution {solution_path}")
5677
input_str = solution_path.read_text()
5778

5879
output_str = input_str
@@ -67,7 +88,9 @@ def write_all_exercises(python_scripts_folder):
6788
for solution_path in solution_paths:
6889
exercise_path = Path(str(solution_path).replace("_sol_", "_ex_"))
6990
if not exercise_path.exists():
70-
print(f"{exercise_path} does not exist")
91+
print(
92+
f"{exercise_path} does not exist, generating it from solution."
93+
)
7194

7295
write_exercise(solution_path, exercise_path)
7396

notebooks/cross_validation_ex_01.ipynb

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
"exercise.\n",
5353
"\n",
5454
"Also, this classifier can become more flexible/expressive by using a so-called\n",
55-
"kernel that makes the model become non-linear. Again, no undestanding regarding\n",
55+
"kernel that makes the model become non-linear. Again, no understanding regarding\n",
5656
"the mathematics is required to accomplish this exercise.\n",
5757
"\n",
5858
"We will use an RBF kernel where a parameter `gamma` allows to tune the\n",

notebooks/linear_models_ex_03.ipynb

-9
Original file line numberDiff line numberDiff line change
@@ -211,15 +211,6 @@
211211
"without interactions."
212212
]
213213
},
214-
{
215-
"cell_type": "code",
216-
"execution_count": null,
217-
"metadata": {},
218-
"outputs": [],
219-
"source": [
220-
"# Write your code here."
221-
]
222-
},
223214
{
224215
"cell_type": "code",
225216
"execution_count": null,

notebooks/metrics_ex_02.ipynb

+11-2
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@
8080
"cell_type": "markdown",
8181
"metadata": {},
8282
"source": [
83-
"Then, instead of using the $R^2$ score, use the mean absolute error. You need\n",
84-
"to refer to the documentation for the `scoring` parameter."
83+
"Then, instead of using the $R^2$ score, use the mean absolute error (MAE). You\n",
84+
"may need to refer to the documentation for the `scoring` parameter."
8585
]
8686
},
8787
{
@@ -102,6 +102,15 @@
102102
"compute the $R^2$ score and the mean absolute error for instance."
103103
]
104104
},
105+
{
106+
"cell_type": "code",
107+
"execution_count": null,
108+
"metadata": {},
109+
"outputs": [],
110+
"source": [
111+
"# Write your code here."
112+
]
113+
},
105114
{
106115
"cell_type": "code",
107116
"execution_count": null,

notebooks/parameter_tuning_ex_02.ipynb

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
"source": [
7777
"Use the previously defined model (called `model`) and using two nested `for`\n",
7878
"loops, make a search of the best combinations of the `learning_rate` and\n",
79-
"`max_leaf_nodes` parameters. In this regard, you have to train and test the\n",
79+
"`max_leaf_nodes` parameters. In this regard, you need to train and test the\n",
8080
"model by setting the parameters. The evaluation of the model should be\n",
8181
"performed using `cross_val_score` on the training set. Use the following\n",
8282
"parameters search:\n",

notebooks/parameter_tuning_ex_03.ipynb

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
"cell_type": "markdown",
3232
"metadata": {},
3333
"source": [
34-
"In this exercise, we progressively define the regression pipeline and\n",
35-
"later tune its hyperparameters.\n",
34+
"In this exercise, we progressively define the regression pipeline and later\n",
35+
"tune its hyperparameters.\n",
3636
"\n",
3737
"Start by defining a pipeline that:\n",
3838
"* uses a `StandardScaler` to normalize the numerical data;\n",

python_scripts/linear_models_ex_03.py

-3
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,3 @@
126126

127127
# %%
128128
# Write your code here.
129-
130-
# %%
131-
# Write your code here.

0 commit comments

Comments
 (0)