Skip to content

Commit 0d0b6cb

Browse files
Merge pull request #62 from easyscience/patch
Update dependencies, workflows, and plotting defaults; replace pip uncomment command with Python script
2 parents d51f565 + f029bba commit 0d0b6cb

21 files changed

+278
-150
lines changed

.github/workflows/build-docs.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
# Trigger the workflow on push
55
push:
66
# Selected branches
7-
branches: [develop, master, docs]
7+
branches: [develop, master, docs, patch]
88
# Allows you to run this workflow manually from the Actions tab
99
workflow_dispatch:
1010

@@ -104,7 +104,7 @@ jobs:
104104
cp ../assets-branding/easyscience-org/icons/eso-icon_bw.svg overrides/.icons/easyscience.svg
105105
106106
# Convert python scripts in the notebooks directory to Jupyter notebooks
107-
# Strip output from the notebooks and simpify cell ids
107+
# Strip output from the notebooks, simpify cell ids and replace '# !pip' with '!pip'
108108
# The notebooks are used to generate the documentation
109109
- name:
110110
Convert ${{ env.NOTEBOOKS_DIR }}/*.py to docs/${{env.NOTEBOOKS_DIR
@@ -113,6 +113,7 @@ jobs:
113113
cp -R ${{ env.NOTEBOOKS_DIR }}/data docs/${{ env.NOTEBOOKS_DIR }}/
114114
jupytext ${{ env.NOTEBOOKS_DIR }}/*.py --from py:percent --to ipynb
115115
nbstripout ${{ env.NOTEBOOKS_DIR }}/*.ipynb
116+
python tools/nb_uncomment_pip.py ${{ env.NOTEBOOKS_DIR }}/
116117
mv ${{ env.NOTEBOOKS_DIR }}/*.ipynb docs/${{ env.NOTEBOOKS_DIR }}/
117118
118119
# The following step is needed to avoid the following message during the build:

.github/workflows/publish-pypi.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ jobs:
2929
- name: Upgrade package installer for Python
3030
run: pip install --upgrade pip
3131

32-
- name: Install Python dependencies
33-
run: pip install '.[dev]'
34-
3532
- name: Create Python package
3633
run: python -m build
3734

.github/workflows/test-tutorials-colab.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Testing tutorials on Colab
1+
name: Test tutorials on Colab
22

33
on:
44
# Trigger the workflow on push
@@ -49,8 +49,8 @@ jobs:
4949

5050
- name: Install Python dependencies
5151
run:
52-
python -m pip install 'easydiffraction[charts]' nbconvert nbmake
53-
pytest pytest-xdist
52+
python -m pip install 'easydiffraction[visualization]' nbconvert
53+
nbmake pytest pytest-xdist
5454

5555
- name: Check if Jupyter Notebooks run without errors
5656
run: >

.github/workflows/test-tutorials.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ jobs:
142142
# Check if tutorials as Jupyter Notebooks run without errors
143143
# Convert all Python scripts in the folder tutorials/ to Jupyter Notebooks
144144
# Strip output from Jupyter Notebooks and rename cell ids
145+
# Replace '# !pip' with '!pip' in Jupyter Notebooks
145146
# Run all Jupyter Notebooks in the folder tutorials/ in parallel
146147
# -n auto: run as many in parallel as you have cores (auto mode)
147148
# --nbmake-timeout=600: set timeout to 600 seconds
@@ -150,6 +151,7 @@ jobs:
150151
run: |
151152
jupytext ${{ env.NOTEBOOKS_DIR }}/*.py --from py:percent --to ipynb
152153
nbstripout ${{ env.NOTEBOOKS_DIR }}/*.ipynb
154+
python tools/nb_uncomment_pip.py ${{ env.NOTEBOOKS_DIR }}/
153155
154156
- name: Run tutorials as Jupyter Notebooks (using src/ as the source dir)
155157
shell: bash

docs/installation-and-setup/index.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ installed using `pip`. We strongly recommend installing it within a virtual
8383
environment, as described in the [Environment Setup](#environment-setup)
8484
section.
8585

86-
We recommend installing the latest release of EasyDiffraction with the `charts`
87-
extras, which include optional dependencies used for simplified visualization of
88-
charts and tables. This can be especially useful for running the Jupyter
89-
Notebook examples. To do so, use the following command:
86+
We recommend installing the latest release of EasyDiffraction with the
87+
`visualization` extras, which include optional dependencies used for simplified
88+
visualization of charts and tables. This can be especially useful for running
89+
the Jupyter Notebook examples. To do so, use the following command:
9090

9191
```console
92-
pip install 'easydiffraction[charts]'
92+
pip install 'easydiffraction[visualization]'
9393
```
9494

9595
If only the core functionality is needed, the library can be installed simply
@@ -128,10 +128,10 @@ To install EasyDiffraction from, e.g., the `develop` branch of GitHub:
128128
pip install git+https://github.com/easyscience/diffraction-lib@develop
129129
```
130130

131-
To include extra dependencies (e.g., charts):
131+
To include extra dependencies (e.g., visualization):
132132

133133
```console
134-
pip install 'easydiffraction[charts] @ git+https://github.com/easyscience/diffraction-lib@develop'
134+
pip install 'easydiffraction[visualization] @ git+https://github.com/easyscience/diffraction-lib@develop'
135135
```
136136

137137
## How to Run Tutorials

docs/mkdocs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
# Project information
66
site_name: EasyDiffraction Library
7-
site_url: https://docs.easydiffraction.org/lib
7+
site_url: https://docs.easydiffraction.org/lib/
88

99
# Repository
10-
repo_url: https://github.com/easyscience/diffraction-lib
10+
repo_url: https://github.com/easyscience/diffraction-lib/
1111
edit_uri: edit/develop/docs/
1212

1313
# Copyright

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ classifiers = [
1616
'Operating System :: OS Independent',
1717
'Programming Language :: Python :: 3 :: Only',
1818
'Programming Language :: Python :: 3',
19-
"Programming Language :: Python :: 3.10",
2019
"Programming Language :: Python :: 3.11",
2120
"Programming Language :: Python :: 3.12",
2221
"Programming Language :: Python :: 3.13",
@@ -74,7 +73,7 @@ visualization = [
7473

7574
[project.urls]
7675
homepage = 'https://easydiffraction.org'
77-
documentation = 'https://easyscience.github.io/diffraction-lib'
76+
documentation = 'https://docs.easydiffraction.org/lib'
7877
source = 'https://github.com/easyscience/diffraction-lib'
7978
tracker = 'https://github.com/easyscience/diffraction-lib/issues'
8079

tools/nb_uncomment_pip.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
"""
2+
Uncomment `# !pip ...` lines in Jupyter notebooks so they become `!pip ...`.
3+
4+
- Operates only on code cells (does not touch outputs/metadata/markdown).
5+
- Matches lines that start with optional whitespace, then `# !pip` (e.g., " # !pip install ...").
6+
- Rewrites to keep the original indentation and replace the leading "# !pip" with "!pip".
7+
- Processes one or more paths (files or directories) given as CLI args, recursively for directories.
8+
"""
9+
10+
from __future__ import annotations
11+
12+
import argparse
13+
import re
14+
import sys
15+
from pathlib import Path
16+
17+
import nbformat
18+
19+
# Regex: beginning-of-line, capture leading whitespace, then "#", spaces, then "!pip"
20+
_PATTERN = re.compile(r'^(\s*)#\s*!pip\b')
21+
22+
23+
def fix_cell_source(src: str) -> tuple[str, int]:
24+
"""
25+
Replace lines starting with optional whitespace + '# !pip' with '!pip'.
26+
Returns the updated source and number of replacements performed.
27+
"""
28+
changed = 0
29+
new_lines: list[str] = []
30+
for line in src.splitlines(keepends=False):
31+
m = _PATTERN.match(line)
32+
if m:
33+
# Replace only the first '# !pip' at the beginning, preserve the rest of the line
34+
# e.g., " # !pip install foo" -> " !pip install foo"
35+
new_line = _PATTERN.sub(r'\1!pip', line, count=1)
36+
if new_line != line:
37+
changed += 1
38+
new_lines.append(new_line)
39+
else:
40+
new_lines.append(line)
41+
return ('\n'.join(new_lines), changed)
42+
43+
44+
def process_notebook(path: Path) -> int:
45+
"""
46+
Process a single .ipynb file. Returns number of lines changed.
47+
"""
48+
nb = nbformat.read(path, as_version=4)
49+
total_changes = 0
50+
for cell in nb.cells:
51+
if cell.cell_type != 'code':
52+
continue
53+
new_src, changes = fix_cell_source(cell.source or '')
54+
if changes:
55+
cell.source = new_src
56+
total_changes += changes
57+
if total_changes:
58+
nbformat.write(nb, path)
59+
return total_changes
60+
61+
62+
def iter_notebooks(paths: list[Path]):
63+
for p in paths:
64+
if p.is_dir():
65+
yield from (q for q in p.rglob('*.ipynb') if q.is_file())
66+
elif p.is_file() and p.suffix == '.ipynb':
67+
yield p
68+
69+
70+
def main(argv: list[str]) -> int:
71+
ap = argparse.ArgumentParser(description="Uncomment '# !pip ...' to '!pip ...' in code cells of .ipynb notebooks.")
72+
ap.add_argument('paths', nargs='+', help='Notebook files or directories to process')
73+
ap.add_argument('--dry-run', action='store_true', help='Report changes without writing files')
74+
args = ap.parse_args(argv)
75+
76+
targets = list(iter_notebooks([Path(p) for p in args.paths]))
77+
if not targets:
78+
print('No .ipynb files found.', file=sys.stderr)
79+
return 1
80+
81+
total_files = 0
82+
total_changes = 0
83+
for nb_path in targets:
84+
changes = process_notebook(nb_path) if not args.dry_run else 0
85+
if args.dry_run:
86+
# For dry-run, compute changes without writing
87+
nb = nbformat.read(nb_path, as_version=4)
88+
changes = 0
89+
for cell in nb.cells:
90+
if cell.cell_type != 'code':
91+
continue
92+
_, c = fix_cell_source(cell.source or '')
93+
changes += c
94+
if changes:
95+
action = 'UPDATED' if not args.dry_run else 'WOULD UPDATE'
96+
print(f'{action}: {nb_path} ({changes} line(s))')
97+
total_files += 1
98+
total_changes += changes
99+
100+
if total_files == 0:
101+
print('No changes needed.')
102+
else:
103+
print(f'Done. Files changed: {total_files}, lines changed: {total_changes}')
104+
return 0
105+
106+
107+
if __name__ == '__main__':
108+
raise SystemExit(main(sys.argv[1:]))

tutorials/advanced_joint-fit_pd-neut-xray-cwl_PbSO4.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"if hasattr(builtins, '__IPYTHON__'):\n",
4646
" if importlib.util.find_spec('easydiffraction') is None:\n",
4747
" print('Installing the easydiffraction library...')\n",
48-
" # !pip install 'easydiffraction[visualization]'"
48+
" !pip install 'easydiffraction[visualization]'"
4949
]
5050
},
5151
{

tutorials/basic_single-fit_pd-neut-cwl_LBCO-HRPT.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"if hasattr(builtins, '__IPYTHON__'):\n",
5252
" if importlib.util.find_spec('easydiffraction') is None:\n",
5353
" print('Installing the easydiffraction library...')\n",
54-
" # !pip install 'easydiffraction[visualization]'"
54+
" !pip install 'easydiffraction[visualization]'"
5555
]
5656
},
5757
{

0 commit comments

Comments
 (0)