Skip to content

Commit 09f1ac0

Browse files
authored
Merge pull request #359 from ie3-institute/df/#351-nbval
Using `NBVAL` as validation for jupyter notebooks
2 parents f6726b0 + 875bb9d commit 09f1ac0

File tree

8 files changed

+390
-6246
lines changed

8 files changed

+390
-6246
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
88
- Add project-level `CLAUDE.md` file [#329](https://github.com/ie3-institute/pypsdm/issues/329)
99
- Adding congestion result handling [#198](https://github.com/ie3-institute/pypsdm/issues/198)
1010
- Add pre-commit hook for removing metadata from jupyter notebooks [#363](https://github.com/ie3-institute/pypsdm/issues/363)
11+
- Using `NBVAL` as validation for jupyter notebooks [#351](https://github.com/ie3-institute/pypsdm/issues/351)
1112

1213
### Changed
1314

docs/nbs/input_models.ipynb

Lines changed: 66 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,34 @@
22
"cells": [
33
{
44
"cell_type": "code",
5+
"id": "initial_id",
56
"metadata": {
7+
"collapsed": true,
68
"ExecuteTime": {
7-
"end_time": "2025-08-12T17:17:12.341315Z",
8-
"start_time": "2025-08-12T17:17:12.309989Z"
9+
"end_time": "2025-08-19T16:40:01.862229Z",
10+
"start_time": "2025-08-19T16:40:01.820265Z"
911
}
1012
},
1113
"source": [
14+
"# NBVAL_IGNORE_OUTPUT\n",
1215
"# Some jupyter notebook magic to reload modules automatically when they change\n",
1316
"# not necessary for this specific notebook but useful in general\n",
1417
"%load_ext autoreload\n",
1518
"%autoreload 2"
1619
],
17-
"outputs": [
18-
{
19-
"name": "stdout",
20-
"output_type": "stream",
21-
"text": [
22-
"The autoreload extension is already loaded. To reload it, use:\n",
23-
" %reload_ext autoreload\n"
24-
]
25-
}
26-
],
27-
"execution_count": 19
20+
"outputs": [],
21+
"execution_count": 1
2822
},
2923
{
30-
"cell_type": "code",
3124
"metadata": {
3225
"ExecuteTime": {
33-
"end_time": "2025-08-12T17:17:12.485196Z",
34-
"start_time": "2025-08-12T17:17:12.359095Z"
26+
"end_time": "2025-08-19T16:40:03.565588Z",
27+
"start_time": "2025-08-19T16:40:01.872411Z"
3528
}
3629
},
30+
"cell_type": "code",
3731
"source": [
32+
"# NBVAL_IGNORE_OUTPUT\n",
3833
"from definitions import ROOT_DIR\n",
3934
"import os\n",
4035
"\n",
@@ -51,32 +46,35 @@
5146
"# You can also load a `GridWithResults` container which additionally contains the result\n",
5247
"# data. For more details see the `result_models.ipynb` notebook"
5348
],
49+
"id": "3d08b4fd2b690ca",
5450
"outputs": [
5551
{
5652
"name": "stderr",
5753
"output_type": "stream",
5854
"text": [
59-
"\u001B[32m2025-08-12 19:17:12.481\u001B[0m | \u001B[34m\u001B[1mDEBUG \u001B[0m | \u001B[36mpypsdm.models.primary_data\u001B[0m:\u001B[36mfrom_csv\u001B[0m:\u001B[36m273\u001B[0m - \u001B[34m\u001B[1mNo primary data in path /home/smdafeis/github/pypsdm/tests/resources/simple_grid/input\u001B[0m\n"
55+
"\u001B[32m2025-08-19 18:40:03.551\u001B[0m | \u001B[34m\u001B[1mDEBUG \u001B[0m | \u001B[36mpypsdm.models.primary_data\u001B[0m:\u001B[36mfrom_csv\u001B[0m:\u001B[36m273\u001B[0m - \u001B[34m\u001B[1mNo primary data in path /home/smdafeis/github/pypsdm/tests/resources/simple_grid/input\u001B[0m\n"
6056
]
6157
}
6258
],
63-
"execution_count": 20
59+
"execution_count": 2
6460
},
6561
{
66-
"cell_type": "code",
6762
"metadata": {
6863
"ExecuteTime": {
69-
"end_time": "2025-08-12T17:17:12.538077Z",
70-
"start_time": "2025-08-12T17:17:12.491016Z"
64+
"end_time": "2025-08-19T16:40:05.421736Z",
65+
"start_time": "2025-08-19T16:40:03.726177Z"
7166
}
7267
},
68+
"cell_type": "code",
7369
"source": [
70+
"# NBVAL_SKIP\n",
7471
"from pypsdm.plots.grid import grid_plot\n",
7572
"\n",
7673
"# Use the grid_plot method to visualize the grid model\n",
7774
"# only works if the underlying node input files have associated coordinates\n",
7875
"grid_plot(grid)"
7976
],
77+
"id": "38b94c0e439ba698",
8078
"outputs": [
8179
{
8280
"data": {
@@ -1015,24 +1013,26 @@
10151013
"output_type": "display_data"
10161014
}
10171015
],
1018-
"execution_count": 21
1016+
"execution_count": 3
10191017
},
10201018
{
1021-
"cell_type": "code",
10221019
"metadata": {
10231020
"ExecuteTime": {
1024-
"end_time": "2025-08-12T17:17:12.575596Z",
1025-
"start_time": "2025-08-12T17:17:12.542626Z"
1021+
"end_time": "2025-08-19T16:40:05.565587Z",
1022+
"start_time": "2025-08-19T16:40:05.534817Z"
10261023
}
10271024
},
1025+
"cell_type": "code",
10281026
"source": [
1027+
"# NBVAL_IGNORE_OUTPUT\n",
10291028
"# You can get a graph representation of the grid\n",
10301029
"graph = grid.raw_grid.build_networkx_graph()\n",
10311030
"# And a list of all the branches in the grid\n",
10321031
"branches_list = grid.raw_grid.get_branches()\n",
10331032
"branches_subgraphs = grid.raw_grid.get_branches(as_graphs=True)\n",
10341033
"branches_list, branches_subgraphs"
10351034
],
1035+
"id": "3bef89c519ea7a2e",
10361036
"outputs": [
10371037
{
10381038
"data": {
@@ -1041,25 +1041,26 @@
10411041
" 'b7a5be0d-2662-41b2-99c6-3b8121a75e9e',\n",
10421042
" '1dcddd06-f41a-405b-9686-7f7942852196',\n",
10431043
" 'e3c3c6a3-c383-4dbb-9b3f-a14125615386']],\n",
1044-
" [<networkx.classes.graph.Graph at 0x793323fdd790>])"
1044+
" [<networkx.classes.graph.Graph at 0x7e0971a5a960>])"
10451045
]
10461046
},
1047-
"execution_count": 22,
1047+
"execution_count": 4,
10481048
"metadata": {},
10491049
"output_type": "execute_result"
10501050
}
10511051
],
1052-
"execution_count": 22
1052+
"execution_count": 4
10531053
},
10541054
{
1055-
"cell_type": "code",
10561055
"metadata": {
10571056
"ExecuteTime": {
1058-
"end_time": "2025-08-12T17:17:12.618855Z",
1059-
"start_time": "2025-08-12T17:17:12.589209Z"
1057+
"end_time": "2025-08-19T16:40:05.612777Z",
1058+
"start_time": "2025-08-19T16:40:05.585043Z"
10601059
}
10611060
},
1061+
"cell_type": "code",
10621062
"source": [
1063+
"# NBVAL_IGNORE_OUTPUT\n",
10631064
"# A grid container consists of a raw grid container\n",
10641065
"raw_grid = grid.raw_grid\n",
10651066
"# consisting of lines, transformers and so on\n",
@@ -1075,6 +1076,7 @@
10751076
"# The base data structure of all input model is a pandas DataFrame accessible via .data\n",
10761077
"pvs.data"
10771078
],
1079+
"id": "57731ebb07b93950",
10781080
"outputs": [
10791081
{
10801082
"data": {
@@ -1246,25 +1248,26 @@
12461248
"</div>"
12471249
]
12481250
},
1249-
"execution_count": 23,
1251+
"execution_count": 5,
12501252
"metadata": {},
12511253
"output_type": "execute_result"
12521254
}
12531255
],
1254-
"execution_count": 23
1256+
"execution_count": 5
12551257
},
12561258
{
1257-
"cell_type": "code",
12581259
"metadata": {
12591260
"ExecuteTime": {
1260-
"end_time": "2025-08-12T17:17:12.661689Z",
1261-
"start_time": "2025-08-12T17:17:12.639427Z"
1261+
"end_time": "2025-08-19T16:40:05.663342Z",
1262+
"start_time": "2025-08-19T16:40:05.642882Z"
12621263
}
12631264
},
1265+
"cell_type": "code",
12641266
"source": [
12651267
"# You can access the columns via the data frame\n",
12661268
"pvs.data[\"s_rated\"]"
12671269
],
1270+
"id": "f588fa60db607ebf",
12681271
"outputs": [
12691272
{
12701273
"data": {
@@ -1276,25 +1279,26 @@
12761279
"Name: s_rated, dtype: int64"
12771280
]
12781281
},
1279-
"execution_count": 24,
1282+
"execution_count": 6,
12801283
"metadata": {},
12811284
"output_type": "execute_result"
12821285
}
12831286
],
1284-
"execution_count": 24
1287+
"execution_count": 6
12851288
},
12861289
{
1287-
"cell_type": "code",
12881290
"metadata": {
12891291
"ExecuteTime": {
1290-
"end_time": "2025-08-12T17:17:12.715348Z",
1291-
"start_time": "2025-08-12T17:17:12.686303Z"
1292+
"end_time": "2025-08-19T16:40:05.723379Z",
1293+
"start_time": "2025-08-19T16:40:05.693807Z"
12921294
}
12931295
},
1296+
"cell_type": "code",
12941297
"source": [
12951298
"# or directly via the property attribute of the class\n",
12961299
"pvs.s_rated"
12971300
],
1301+
"id": "ccdd8fd0a1d60968",
12981302
"outputs": [
12991303
{
13001304
"data": {
@@ -1306,28 +1310,30 @@
13061310
"Name: s_rated, dtype: int64"
13071311
]
13081312
},
1309-
"execution_count": 25,
1313+
"execution_count": 7,
13101314
"metadata": {},
13111315
"output_type": "execute_result"
13121316
}
13131317
],
1314-
"execution_count": 25
1318+
"execution_count": 7
13151319
},
13161320
{
1317-
"cell_type": "code",
13181321
"metadata": {
13191322
"ExecuteTime": {
1320-
"end_time": "2025-08-12T17:17:12.787361Z",
1321-
"start_time": "2025-08-12T17:17:12.735393Z"
1323+
"end_time": "2025-08-19T16:40:05.792223Z",
1324+
"start_time": "2025-08-19T16:40:05.743618Z"
13221325
}
13231326
},
1327+
"cell_type": "code",
13241328
"source": [
1329+
"# NBVAL_IGNORE_OUTPUT\n",
13251330
"# The respective classes implement some useful methods for dealing with the data\n",
13261331
"# e.g. retrieve all elements connected to one or multiple specified nodes\n",
13271332
"# (Please check out the classes to see all the implemented methods)\n",
13281333
"nodal_participants = participants.filter_by_nodes(grid.nodes.uuid.to_list()[::2])\n",
13291334
"nodal_participants.pvs.data"
13301335
],
1336+
"id": "be125965fbe013b2",
13311337
"outputs": [
13321338
{
13331339
"data": {
@@ -1472,22 +1478,23 @@
14721478
"</div>"
14731479
]
14741480
},
1475-
"execution_count": 26,
1481+
"execution_count": 8,
14761482
"metadata": {},
14771483
"output_type": "execute_result"
14781484
}
14791485
],
1480-
"execution_count": 26
1486+
"execution_count": 8
14811487
},
14821488
{
1483-
"cell_type": "code",
14841489
"metadata": {
14851490
"ExecuteTime": {
1486-
"end_time": "2025-08-12T17:17:13.058337Z",
1487-
"start_time": "2025-08-12T17:17:12.794784Z"
1491+
"end_time": "2025-08-19T16:40:06.074600Z",
1492+
"start_time": "2025-08-19T16:40:05.801528Z"
14881493
}
14891494
},
1495+
"cell_type": "code",
14901496
"source": [
1497+
"# NBVAL_IGNORE_OUTPUT\n",
14911498
"from tempfile import TemporaryDirectory\n",
14921499
"\n",
14931500
"# You can write data models with their respective to_csv method\n",
@@ -1501,37 +1508,38 @@
15011508
" # the == operator is overloaded to compare the underlying dataframes\n",
15021509
" assert grid == grid_from_csv"
15031510
],
1511+
"id": "f0d62146d59403f9",
15041512
"outputs": [
15051513
{
15061514
"name": "stderr",
15071515
"output_type": "stream",
15081516
"text": [
1509-
"\u001B[32m2025-08-12 19:17:12.954\u001B[0m | \u001B[34m\u001B[1mDEBUG \u001B[0m | \u001B[36mpypsdm.models.primary_data\u001B[0m:\u001B[36mfrom_csv\u001B[0m:\u001B[36m273\u001B[0m - \u001B[34m\u001B[1mNo primary data in path /tmp/tmplnxfgc6t\u001B[0m\n"
1517+
"\u001B[32m2025-08-19 18:40:05.968\u001B[0m | \u001B[34m\u001B[1mDEBUG \u001B[0m | \u001B[36mpypsdm.models.primary_data\u001B[0m:\u001B[36mfrom_csv\u001B[0m:\u001B[36m273\u001B[0m - \u001B[34m\u001B[1mNo primary data in path /tmp/tmp97ev7h7m\u001B[0m\n"
15101518
]
15111519
}
15121520
],
1513-
"execution_count": 27
1521+
"execution_count": 9
15141522
}
15151523
],
15161524
"metadata": {
15171525
"kernelspec": {
1518-
"display_name": "pypsdm-sJkpnJQv-py3.11",
1526+
"display_name": "Python 3",
15191527
"language": "python",
15201528
"name": "python3"
15211529
},
15221530
"language_info": {
15231531
"codemirror_mode": {
15241532
"name": "ipython",
1525-
"version": 3
1533+
"version": 2
15261534
},
15271535
"file_extension": ".py",
15281536
"mimetype": "text/x-python",
15291537
"name": "python",
15301538
"nbconvert_exporter": "python",
1531-
"pygments_lexer": "ipython3",
1532-
"version": "3.11.5"
1539+
"pygments_lexer": "ipython2",
1540+
"version": "2.7.6"
15331541
}
15341542
},
15351543
"nbformat": 4,
1536-
"nbformat_minor": 2
1544+
"nbformat_minor": 5
15371545
}

0 commit comments

Comments
 (0)