Skip to content

Using NBVAL as validation for jupyter notebooks #359

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Aug 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f12c212
implement nbval as a test
danielfeismann Aug 5, 2025
dc525f4
changelog
danielfeismann Aug 5, 2025
f8327ad
fmt
danielfeismann Aug 5, 2025
0eef611
add input_models.ipynb to validation
danielfeismann Aug 5, 2025
bc9dd4a
skip or exclude some cells
danielfeismann Aug 5, 2025
098e1e2
fix path in tests
danielfeismann Aug 5, 2025
b0bc7ad
restructure tests
danielfeismann Aug 6, 2025
746960b
remove empty cell
danielfeismann Aug 6, 2025
45c9588
Merge branch 'main' into df/#351-nbval
danielfeismann Aug 8, 2025
9f379c5
Merge branch 'main' into df/#351-nbval
danielfeismann Aug 11, 2025
d92e566
poetry
danielfeismann Aug 11, 2025
32b27e0
Merge branch 'main' into df/#351-nbval
danielfeismann Aug 11, 2025
bd8f319
poetry
danielfeismann Aug 11, 2025
9936ac9
Merge branch 'main' into df/#351-nbval
danielfeismann Aug 12, 2025
c2752de
poetry
danielfeismann Aug 12, 2025
f4111b8
reset input_models.ipynb
danielfeismann Aug 12, 2025
ff04512
input_models with outputs
danielfeismann Aug 12, 2025
3c33b2e
reset result_models with outputs
danielfeismann Aug 12, 2025
4fd4597
fmt
danielfeismann Aug 12, 2025
436414b
more fixes
danielfeismann Aug 12, 2025
10d3850
Merge branch 'main' into df/#351-nbval
danielfeismann Aug 19, 2025
8606eed
fix notebooks
danielfeismann Aug 19, 2025
09f1e1f
remove input_models.ipynb
danielfeismann Aug 19, 2025
05470a4
add input_models.ipynb
danielfeismann Aug 19, 2025
33d2f75
remove result_models.ipynb
danielfeismann Aug 19, 2025
674f669
add result_models.ipynb
danielfeismann Aug 19, 2025
515edab
adapt input_models.ipynb
danielfeismann Aug 19, 2025
8b76040
poetry
danielfeismann Aug 19, 2025
daaf5bb
remove result_models.ipynb
danielfeismann Aug 19, 2025
875bb9d
add result_models.ipynb
danielfeismann Aug 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- Add project-level `CLAUDE.md` file [#329](https://github.com/ie3-institute/pypsdm/issues/329)
- Adding congestion result handling [#198](https://github.com/ie3-institute/pypsdm/issues/198)
- Add pre-commit hook for removing metadata from jupyter notebooks [#363](https://github.com/ie3-institute/pypsdm/issues/363)
- Using `NBVAL` as validation for jupyter notebooks [#351](https://github.com/ie3-institute/pypsdm/issues/351)

### Changed

Expand Down
124 changes: 66 additions & 58 deletions docs/nbs/input_models.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,34 @@
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-08-12T17:17:12.341315Z",
"start_time": "2025-08-12T17:17:12.309989Z"
"end_time": "2025-08-19T16:40:01.862229Z",
"start_time": "2025-08-19T16:40:01.820265Z"
}
},
"source": [
"# NBVAL_IGNORE_OUTPUT\n",
"# Some jupyter notebook magic to reload modules automatically when they change\n",
"# not necessary for this specific notebook but useful in general\n",
"%load_ext autoreload\n",
"%autoreload 2"
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The autoreload extension is already loaded. To reload it, use:\n",
" %reload_ext autoreload\n"
]
}
],
"execution_count": 19
"outputs": [],
"execution_count": 1
},
{
"cell_type": "code",
"metadata": {
"ExecuteTime": {
"end_time": "2025-08-12T17:17:12.485196Z",
"start_time": "2025-08-12T17:17:12.359095Z"
"end_time": "2025-08-19T16:40:03.565588Z",
"start_time": "2025-08-19T16:40:01.872411Z"
}
},
"cell_type": "code",
"source": [
"# NBVAL_IGNORE_OUTPUT\n",
"from definitions import ROOT_DIR\n",
"import os\n",
"\n",
Expand All @@ -51,32 +46,35 @@
"# You can also load a `GridWithResults` container which additionally contains the result\n",
"# data. For more details see the `result_models.ipynb` notebook"
],
"id": "3d08b4fd2b690ca",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\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"
"\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"
]
}
],
"execution_count": 20
"execution_count": 2
},
{
"cell_type": "code",
"metadata": {
"ExecuteTime": {
"end_time": "2025-08-12T17:17:12.538077Z",
"start_time": "2025-08-12T17:17:12.491016Z"
"end_time": "2025-08-19T16:40:05.421736Z",
"start_time": "2025-08-19T16:40:03.726177Z"
}
},
"cell_type": "code",
"source": [
"# NBVAL_SKIP\n",
"from pypsdm.plots.grid import grid_plot\n",
"\n",
"# Use the grid_plot method to visualize the grid model\n",
"# only works if the underlying node input files have associated coordinates\n",
"grid_plot(grid)"
],
"id": "38b94c0e439ba698",
"outputs": [
{
"data": {
Expand Down Expand Up @@ -1015,24 +1013,26 @@
"output_type": "display_data"
}
],
"execution_count": 21
"execution_count": 3
},
{
"cell_type": "code",
"metadata": {
"ExecuteTime": {
"end_time": "2025-08-12T17:17:12.575596Z",
"start_time": "2025-08-12T17:17:12.542626Z"
"end_time": "2025-08-19T16:40:05.565587Z",
"start_time": "2025-08-19T16:40:05.534817Z"
}
},
"cell_type": "code",
"source": [
"# NBVAL_IGNORE_OUTPUT\n",
"# You can get a graph representation of the grid\n",
"graph = grid.raw_grid.build_networkx_graph()\n",
"# And a list of all the branches in the grid\n",
"branches_list = grid.raw_grid.get_branches()\n",
"branches_subgraphs = grid.raw_grid.get_branches(as_graphs=True)\n",
"branches_list, branches_subgraphs"
],
"id": "3bef89c519ea7a2e",
"outputs": [
{
"data": {
Expand All @@ -1041,25 +1041,26 @@
" 'b7a5be0d-2662-41b2-99c6-3b8121a75e9e',\n",
" '1dcddd06-f41a-405b-9686-7f7942852196',\n",
" 'e3c3c6a3-c383-4dbb-9b3f-a14125615386']],\n",
" [<networkx.classes.graph.Graph at 0x793323fdd790>])"
" [<networkx.classes.graph.Graph at 0x7e0971a5a960>])"
]
},
"execution_count": 22,
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 22
"execution_count": 4
},
{
"cell_type": "code",
"metadata": {
"ExecuteTime": {
"end_time": "2025-08-12T17:17:12.618855Z",
"start_time": "2025-08-12T17:17:12.589209Z"
"end_time": "2025-08-19T16:40:05.612777Z",
"start_time": "2025-08-19T16:40:05.585043Z"
}
},
"cell_type": "code",
"source": [
"# NBVAL_IGNORE_OUTPUT\n",
"# A grid container consists of a raw grid container\n",
"raw_grid = grid.raw_grid\n",
"# consisting of lines, transformers and so on\n",
Expand All @@ -1075,6 +1076,7 @@
"# The base data structure of all input model is a pandas DataFrame accessible via .data\n",
"pvs.data"
],
"id": "57731ebb07b93950",
"outputs": [
{
"data": {
Expand Down Expand Up @@ -1246,25 +1248,26 @@
"</div>"
]
},
"execution_count": 23,
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 23
"execution_count": 5
},
{
"cell_type": "code",
"metadata": {
"ExecuteTime": {
"end_time": "2025-08-12T17:17:12.661689Z",
"start_time": "2025-08-12T17:17:12.639427Z"
"end_time": "2025-08-19T16:40:05.663342Z",
"start_time": "2025-08-19T16:40:05.642882Z"
}
},
"cell_type": "code",
"source": [
"# You can access the columns via the data frame\n",
"pvs.data[\"s_rated\"]"
],
"id": "f588fa60db607ebf",
"outputs": [
{
"data": {
Expand All @@ -1276,25 +1279,26 @@
"Name: s_rated, dtype: int64"
]
},
"execution_count": 24,
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 24
"execution_count": 6
},
{
"cell_type": "code",
"metadata": {
"ExecuteTime": {
"end_time": "2025-08-12T17:17:12.715348Z",
"start_time": "2025-08-12T17:17:12.686303Z"
"end_time": "2025-08-19T16:40:05.723379Z",
"start_time": "2025-08-19T16:40:05.693807Z"
}
},
"cell_type": "code",
"source": [
"# or directly via the property attribute of the class\n",
"pvs.s_rated"
],
"id": "ccdd8fd0a1d60968",
"outputs": [
{
"data": {
Expand All @@ -1306,28 +1310,30 @@
"Name: s_rated, dtype: int64"
]
},
"execution_count": 25,
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 25
"execution_count": 7
},
{
"cell_type": "code",
"metadata": {
"ExecuteTime": {
"end_time": "2025-08-12T17:17:12.787361Z",
"start_time": "2025-08-12T17:17:12.735393Z"
"end_time": "2025-08-19T16:40:05.792223Z",
"start_time": "2025-08-19T16:40:05.743618Z"
}
},
"cell_type": "code",
"source": [
"# NBVAL_IGNORE_OUTPUT\n",
"# The respective classes implement some useful methods for dealing with the data\n",
"# e.g. retrieve all elements connected to one or multiple specified nodes\n",
"# (Please check out the classes to see all the implemented methods)\n",
"nodal_participants = participants.filter_by_nodes(grid.nodes.uuid.to_list()[::2])\n",
"nodal_participants.pvs.data"
],
"id": "be125965fbe013b2",
"outputs": [
{
"data": {
Expand Down Expand Up @@ -1472,22 +1478,23 @@
"</div>"
]
},
"execution_count": 26,
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 26
"execution_count": 8
},
{
"cell_type": "code",
"metadata": {
"ExecuteTime": {
"end_time": "2025-08-12T17:17:13.058337Z",
"start_time": "2025-08-12T17:17:12.794784Z"
"end_time": "2025-08-19T16:40:06.074600Z",
"start_time": "2025-08-19T16:40:05.801528Z"
}
},
"cell_type": "code",
"source": [
"# NBVAL_IGNORE_OUTPUT\n",
"from tempfile import TemporaryDirectory\n",
"\n",
"# You can write data models with their respective to_csv method\n",
Expand All @@ -1501,37 +1508,38 @@
" # the == operator is overloaded to compare the underlying dataframes\n",
" assert grid == grid_from_csv"
],
"id": "f0d62146d59403f9",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\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"
"\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"
]
}
],
"execution_count": 27
"execution_count": 9
}
],
"metadata": {
"kernelspec": {
"display_name": "pypsdm-sJkpnJQv-py3.11",
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
"nbformat_minor": 5
}
Loading
Loading