Metadata-Version: 2.4
Name: pypad-notebook
Version: 0.1.0
Summary: Read, write and convert PyPad notebooks (.pypad.py) and Jupyter notebooks (.ipynb).
Author: Philip Lewis
License: MIT
Project-URL: Homepage, https://pypad.dev
Project-URL: Repository, https://github.com/pypad-dev/pypad
Keywords: notebook,jupyter,ipynb,pypad,moodle,education
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Education
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Education
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"
Dynamic: license-file

# pypad-notebook

Read, write and convert [PyPad](https://pypad.dev) notebooks (`.pypad.py`) and Jupyter notebooks (`.ipynb`). Standard library
only; Python 3.9+.

PyPad is a small in-browser Python notebook for teaching: it runs entirely in the learner's browser, fits in a Moodle quiz question, can be
shared as a link, and its files are plain, readable Python. This package is the file-format side of it, so a notebook is never trapped.

```bash
pip install pypad-notebook
```

## Command line

```bash
pypad convert lesson.pypad.py            # -> lesson.ipynb
pypad convert lesson.ipynb                # -> lesson.pypad.py
pypad convert lesson.ipynb --outputs text
pypad check lesson.pypad.py              # ok / changed / absent: is it still what PyPad wrote?  (exit 1 if changed)
pypad embed lesson.pypad.py > question.html     # the HTML block for a Moodle question or web page
pypad answers responses.csv --out answers/       # split a Moodle quiz "Responses" download into one file per student
pypad verify template.pypad.py answers/*.pypad.py   # re-check them against the template (exit 1 if any are not clean)
pypad embed lesson.pypad.py --answer-format base64 --loader https://pypad.dev/v1/pypad-mdl-quiz.js
```

`convert` never overwrites without `--force`. `check`, `convert` and `embed` also accept an HTML page that holds a notebook (an embed, or a
PyPad "web page" export).

## Marking

An assessment that matters should be checked where the student cannot touch it. The widget stops mistakes in the student's browser, but the browser is
the student's. `pypad verify` applies, on your side, the same rules the widget applies when it opens an answer (the template's `policy`, its locked cells,
its answer cells and sections), and tells you for each answer what the student changed, added or removed, and what the rules would have put back:

```
answers/Student_Sam.pypad.py: clean (check value ok) - changed a1
answers/Other_Oz.pypad.py: NOT CLEAN (check value ok) - changed a1
    cell "i1" cannot be edited, and its text was put back
```

`pypad answers` turns a Moodle quiz **Responses** download (CSV) into those files, decoding stored answers.

## In Python

```python
import pypad

result = pypad.parse(open("lesson.pypad.py", encoding="utf-8").read())
result.integrity            # 'ok', 'changed' or 'absent'
result.warnings             # problems found while reading; a damaged file still opens
nb = result.notebook        # nb.config, nb.cells[i].id / .type / .source / .settings / .outputs

text = pypad.dumps(nb)                          # .pypad.py text, with its check value
ipynb = pypad.to_ipynb_text(nb, save_outputs="text")
nb2 = pypad.from_ipynb_text(open("lesson.ipynb", encoding="utf-8").read())
html = pypad.build_embed(text, answer_format="plain")

report = pypad.verify_answer(template_nb, answer_nb, integrity)   # report.clean, .changed_cells, .violations, ...
```

## It matches the JavaScript implementation

This is a port of the reference implementation (`packages/notebook` in the PyPad repository). The same text produces the same notebook, the
same file, the same Jupyter notebook and the same check value, including for emoji and odd characters. That is tested against a file of vectors
that the JavaScript implementation generates (`tests/vectors.json`), so the two cannot drift apart unnoticed.

## The format, in one screen

```python
# %% [pypad-start] v1 sha=3f9a1c0d7b2e4a65

# %% [config] {"policy":"fixed","kernel":"skulpt"}

# %% [markdown] {"id":"k3j9a0xq","editable":false}
"""
Print the sum of 1 and 2.
"""

# %% [code] {"id":"p8w2m1zc"}
print(1 + 2)

# %% [pypad-end]
```

Code is code and everything else sits in triple-quoted strings, so the file is (nearly) valid Python and readable anywhere. The `sha` is a check
value of the notebook's content: it notices an editor or a hand edit changing something, and ignores indentation and line endings. It is not a
security measure. Reading is forgiving (Jupytext-style comment blocks, indented text, Windows line endings); writing has one form.

MIT licensed.
