Skip to content

Commit f92ca3a

Browse files
committed
Move all top-level notebooks under notebooks/ (folder restructure)
Complete the folder restructure discussed with Peter Norvig: the importable code lives in aima/, the tests in tests/, and now every notebook lives under notebooks/ (alongside the existing notebooks/chapterNN/ chapter demos). - git mv all 40 top-level *.ipynb into notebooks/ (history preserved as renames). - Prepend a small bootstrap cell to each moved notebook: when run from the notebooks/ folder it chdirs to the repo root, so 'from aima import ...' and the cwd-relative aima-data/ and images/ paths resolve unchanged (works on Binder too, without needing an editable install). - README: document the aima/ + notebooks/ + tests/ layout; mark the 3e/4e convergence as done (single version per module, no *4e.py files remain). - CONTRIBUTING: fix the example notebook link to its new notebooks/ path. The GitHub Action to generate a .py from each .ipynb (making the notebook the source of truth) is intentionally left out -- it inverts the current direct-.py workflow and Peter wanted a contributor survey first.
1 parent 43170d8 commit f92ca3a

42 files changed

Lines changed: 642 additions & 43 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CONTRIBUTING.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ In this project we use Jupyter/IPython Notebooks to showcase the algorithms in t
4343
- Proofread the notebooks for grammar mistakes, typos, or general errors.
4444
- Move visualization and unrelated to the algorithm code from notebooks to `notebook_utils.py` (a file used to store code for the notebooks, like visualization and other miscellaneous stuff). Make sure the notebooks still work and have their outputs showing!
4545
- Replace the `%psource` magic notebook command with the function `psource` from `notebook_utils.py` where needed. Examples where this is useful are a) when we want to show code for algorithm implementation and b) when we have consecutive cells with the magic keyword (in this case, if the code is large, it's best to leave the output hidden).
46-
- Add the function `pseudocode(algorithm_name)` in algorithm sections. The function prints the pseudocode of the algorithm. You can see some example usage in [`knowledge.ipynb`](https://github.com/aimacode/aima-python/blob/master/knowledge.ipynb).
46+
- Add the function `pseudocode(algorithm_name)` in algorithm sections. The function prints the pseudocode of the algorithm. You can see some example usage in [`knowledge_current_best.ipynb`](https://github.com/aimacode/aima-python/blob/master/notebooks/knowledge_current_best.ipynb).
4747
- Edit existing sections for algorithms to add more information and/or examples.
4848
- Add visualizations for algorithms. The visualization code should go in `notebook_utils.py` to keep things clean.
4949
- Add new sections for algorithms not yet covered. The general format we use in the notebooks is the following: First start with an overview of the algorithm, printing the pseudocode and explaining how it works. Then, add some implementation details, including showing the code (using `psource`). Finally, add examples for the implementations, showing how the algorithms work. Don't fret with adding complex, real-world examples; the project is meant for educational purposes. You can of course choose another format if something better suits an algorithm.

‎README.md‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,17 @@ The 4th edition of the book is out now in 2020, and thus we are updating the cod
1616
**Edition policy (3rd vs 4th).** As [Peter Norvig stated](https://github.com/aimacode/aima-python/issues/1188#issuecomment-641669882), we are *not* maintaining two parallel editions — all new work should move toward the 4th edition. Concretely:
1717

1818
- The **4th edition is canonical**: new algorithms, fixes and pseudocode references should follow the 4e numbering and content.
19-
- Some modules still come in pairs (e.g. `agents.py` / `agents4e.py`). The unsuffixed modules are the primary, fully-tested base that the notebooks and tests use today; the `*4e.py` modules carry 4e-specific ports and algorithms not present in the 3e files. We are **converging on a single version per module**; until that migration is complete, prefer adding 4e content over extending the 3e-only versions.
20-
- New 4th-edition-only material (e.g. `deep_learning4e.py`, `game_theory4e.py`, `perception4e.py`) lives directly in its 4e module.
19+
- The 3e/4e split is **done**: there is now a **single version per module** (no `*4e.py` files remain). The old 3e/4e pairs have been merged — the canonical implementation was kept and any genuinely-new 4e algorithms were folded in — and the 4e-only modules (`deep_learning.py`, `game_theory.py`, `making_simple_decisions.py`, `perception.py`) were de-suffixed. Add new 4e content directly to the relevant module.
2120

2221

2322

2423
# Structure of the Project
2524

26-
When complete, this project will have Python implementations for all the pseudocode algorithms in the book, as well as tests and examples of use. For each major topic, such as `search`, we provide the following files:
25+
When complete, this project will have Python implementations for all the pseudocode algorithms in the book, as well as tests and examples of use. The code is organised into three top-level folders:
2726

28-
- `search.ipynb` and `search.py`: Implementations of all the pseudocode algorithms, and necessary support functions/classes/data. The `.py` file is generated automatically from the `.ipynb` file; the idea is that it is easier to read the documentation in the `.ipynb` file.
29-
- `search_XX.ipynb`: Notebooks that show how to use the code, broken out into various topics (the `XX`).
30-
- `tests/test_search.py`: A lightweight test suite, using `assert` statements, designed for use with [`py.test`](http://pytest.org/latest/), but also usable on their own.
27+
- **`aima/`** — the importable Python package: one module per major topic (e.g. `aima/search.py`) with the implementations of the pseudocode algorithms and their support functions/classes/data.
28+
- **`notebooks/`** — the Jupyter notebooks that explain and demonstrate the code (e.g. `notebooks/search.ipynb`), plus the per-chapter `notebooks/chapterNN/` demos. Each notebook starts with a small bootstrap cell so it runs correctly from the `notebooks/` folder (it `chdir`s to the repo root so `from aima import ...` and the `aima-data/`/`images/` paths resolve).
29+
- **`tests/`** — a lightweight test suite (e.g. `tests/test_search.py`), using `assert` statements, designed for use with [`py.test`](http://pytest.org/latest/) but also usable on their own.
3130

3231
# Python 3.9 and up
3332

agents.ipynb renamed to notebooks/agents.ipynb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
{
22
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"# notebooks live under notebooks/; run from the repo root so that\n",
10+
"# `from aima import ...` and the cwd-relative aima-data/ and images/ paths resolve.\n",
11+
"import os, sys\n",
12+
"if os.path.basename(os.getcwd()) == 'notebooks':\n",
13+
" os.chdir('..')\n",
14+
"if os.getcwd() not in sys.path:\n",
15+
" sys.path.insert(0, os.getcwd())"
16+
]
17+
},
318
{
419
"cell_type": "markdown",
520
"metadata": {},

arc_consistency_heuristics.ipynb renamed to notebooks/arc_consistency_heuristics.ipynb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
{
22
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"# notebooks live under notebooks/; run from the repo root so that\n",
10+
"# `from aima import ...` and the cwd-relative aima-data/ and images/ paths resolve.\n",
11+
"import os, sys\n",
12+
"if os.path.basename(os.getcwd()) == 'notebooks':\n",
13+
" os.chdir('..')\n",
14+
"if os.getcwd() not in sys.path:\n",
15+
" sys.path.insert(0, os.getcwd())"
16+
]
17+
},
318
{
419
"cell_type": "markdown",
520
"metadata": {

classical_planning_approaches.ipynb renamed to notebooks/classical_planning_approaches.ipynb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
{
22
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"# notebooks live under notebooks/; run from the repo root so that\n",
10+
"# `from aima import ...` and the cwd-relative aima-data/ and images/ paths resolve.\n",
11+
"import os, sys\n",
12+
"if os.path.basename(os.getcwd()) == 'notebooks':\n",
13+
" os.chdir('..')\n",
14+
"if os.getcwd() not in sys.path:\n",
15+
" sys.path.insert(0, os.getcwd())"
16+
]
17+
},
318
{
419
"cell_type": "markdown",
520
"metadata": {},

csp.ipynb renamed to notebooks/csp.ipynb

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
{
22
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"# notebooks live under notebooks/; run from the repo root so that\n",
10+
"# `from aima import ...` and the cwd-relative aima-data/ and images/ paths resolve.\n",
11+
"import os, sys\n",
12+
"if os.path.basename(os.getcwd()) == 'notebooks':\n",
13+
" os.chdir('..')\n",
14+
"if os.getcwd() not in sys.path:\n",
15+
" sys.path.insert(0, os.getcwd())"
16+
]
17+
},
318
{
419
"cell_type": "markdown",
520
"metadata": {},
@@ -628,7 +643,7 @@
628643
"source": [
629644
"## N-QUEENS\n",
630645
"\n",
631-
"The N-queens puzzle is the problem of placing N chess queens on an N\u00d7N chessboard in a way such that no two queens threaten each other. Here N is a natural number. Like the graph coloring problem, NQueens is also implemented in the csp module. The **NQueensCSP** class inherits from the **CSP** class. It makes some modifications in the methods to suit this particular problem. The queens are assumed to be placed one per column, from left to right. That means position (x, y) represents (var, val) in the CSP. The constraint that needs to be passed to the CSP is defined in the **queen_constraint** function. The constraint is satisfied (true) if A, B are really the same variable, or if they are not in the same row, down diagonal, or up diagonal. "
646+
"The N-queens puzzle is the problem of placing N chess queens on an N×N chessboard in a way such that no two queens threaten each other. Here N is a natural number. Like the graph coloring problem, NQueens is also implemented in the csp module. The **NQueensCSP** class inherits from the **CSP** class. It makes some modifications in the methods to suit this particular problem. The queens are assumed to be placed one per column, from left to right. That means position (x, y) represents (var, val) in the CSP. The constraint that needs to be passed to the CSP is defined in the **queen_constraint** function. The constraint is satisfied (true) if A, B are really the same variable, or if they are not in the same row, down diagonal, or up diagonal. "
632647
]
633648
},
634649
{
@@ -2775,7 +2790,7 @@
27752790
"version_minor": 0
27762791
},
27772792
"text/plain": [
2778-
"interactive(children=(IntSlider(value=0, description='iteration', max=20), Output()), _dom_classes=('widget-in\u2026"
2793+
"interactive(children=(IntSlider(value=0, description='iteration', max=20), Output()), _dom_classes=('widget-in…"
27792794
]
27802795
},
27812796
"metadata": {},
@@ -2789,7 +2804,7 @@
27892804
"version_minor": 0
27902805
},
27912806
"text/plain": [
2792-
"interactive(children=(ToggleButton(value=False, description='Visualize'), ToggleButtons(description='Extra Del\u2026"
2807+
"interactive(children=(ToggleButton(value=False, description='Visualize'), ToggleButtons(description='Extra Del…"
27932808
]
27942809
},
27952810
"metadata": {},
@@ -2924,7 +2939,7 @@
29242939
"version_minor": 0
29252940
},
29262941
"text/plain": [
2927-
"interactive(children=(IntSlider(value=0, description='iteration', max=473, step=0), Output()), _dom_classes=('\u2026"
2942+
"interactive(children=(IntSlider(value=0, description='iteration', max=473, step=0), Output()), _dom_classes=('…"
29282943
]
29292944
},
29302945
"metadata": {},
@@ -2938,7 +2953,7 @@
29382953
"version_minor": 0
29392954
},
29402955
"text/plain": [
2941-
"interactive(children=(ToggleButton(value=False, description='Visualize'), ToggleButtons(description='Extra Del\u2026"
2956+
"interactive(children=(ToggleButton(value=False, description='Visualize'), ToggleButtons(description='Extra Del…"
29422957
]
29432958
},
29442959
"metadata": {},
@@ -3008,7 +3023,7 @@
30083023
"version_minor": 0
30093024
},
30103025
"text/plain": [
3011-
"interactive(children=(IntSlider(value=0, description='iteration', max=27, step=0), Output()), _dom_classes=('w\u2026"
3026+
"interactive(children=(IntSlider(value=0, description='iteration', max=27, step=0), Output()), _dom_classes=('w…"
30123027
]
30133028
},
30143029
"metadata": {},
@@ -3022,7 +3037,7 @@
30223037
"version_minor": 0
30233038
},
30243039
"text/plain": [
3025-
"interactive(children=(ToggleButton(value=False, description='Visualize'), ToggleButtons(description='Extra Del\u2026"
3040+
"interactive(children=(ToggleButton(value=False, description='Visualize'), ToggleButtons(description='Extra Del…"
30263041
]
30273042
},
30283043
"metadata": {},
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
{
22
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"# notebooks live under notebooks/; run from the repo root so that\n",
10+
"# `from aima import ...` and the cwd-relative aima-data/ and images/ paths resolve.\n",
11+
"import os, sys\n",
12+
"if os.path.basename(os.getcwd()) == 'notebooks':\n",
13+
" os.chdir('..')\n",
14+
"if os.getcwd() not in sys.path:\n",
15+
" sys.path.insert(0, os.getcwd())"
16+
]
17+
},
318
{
419
"cell_type": "markdown",
520
"id": "07e68a51",
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
{
22
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"# notebooks live under notebooks/; run from the repo root so that\n",
10+
"# `from aima import ...` and the cwd-relative aima-data/ and images/ paths resolve.\n",
11+
"import os, sys\n",
12+
"if os.path.basename(os.getcwd()) == 'notebooks':\n",
13+
" os.chdir('..')\n",
14+
"if os.getcwd() not in sys.path:\n",
15+
" sys.path.insert(0, os.getcwd())"
16+
]
17+
},
318
{
419
"cell_type": "markdown",
520
"id": "eec33447",
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
{
22
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"# notebooks live under notebooks/; run from the repo root so that\n",
10+
"# `from aima import ...` and the cwd-relative aima-data/ and images/ paths resolve.\n",
11+
"import os, sys\n",
12+
"if os.path.basename(os.getcwd()) == 'notebooks':\n",
13+
" os.chdir('..')\n",
14+
"if os.getcwd() not in sys.path:\n",
15+
" sys.path.insert(0, os.getcwd())"
16+
]
17+
},
318
{
419
"cell_type": "markdown",
520
"id": "172aa32c",

games.ipynb renamed to notebooks/games.ipynb

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
{
22
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"# notebooks live under notebooks/; run from the repo root so that\n",
10+
"# `from aima import ...` and the cwd-relative aima-data/ and images/ paths resolve.\n",
11+
"import os, sys\n",
12+
"if os.path.basename(os.getcwd()) == 'notebooks':\n",
13+
" os.chdir('..')\n",
14+
"if os.getcwd() not in sys.path:\n",
15+
" sys.path.insert(0, os.getcwd())"
16+
]
17+
},
318
{
419
"cell_type": "markdown",
520
"metadata": {},
@@ -1666,4 +1681,4 @@
16661681
},
16671682
"nbformat": 4,
16681683
"nbformat_minor": 1
1669-
}
1684+
}

0 commit comments

Comments
 (0)