{ "cells": [ { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "slide" } }, "source": [ "# Guide for Authors" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2024-06-30T17:30:54.122213Z", "iopub.status.busy": "2024-06-30T17:30:54.121789Z", "iopub.status.idle": "2024-06-30T17:30:54.132197Z", "shell.execute_reply": "2024-06-30T17:30:54.131885Z" }, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Welcome to \"The Debugging Book\"!\n" ] } ], "source": [ "print('Welcome to \"The Debugging Book\"!')" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "slide" } }, "source": [ "This notebook compiles the most important conventions for all chapters (notebooks) of \"The Debugging Book\"." ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "slide" } }, "source": [ "## Organization of this Book" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Chapters as Notebooks\n", "\n", "Each chapter comes as its own _Jupyter notebook_. A single notebook (= a chapter) should cover the material (text and code, possibly slides) for a 90-minute lecture.\n", "\n", "A chapter notebook should be named `Topic.ipynb`, where `Topic` is the topic. `Topic` must be usable as a Python module and should characterize the main contribution. If the main contribution of your chapter is a class `FooDebugger`, for instance, then your topic (and notebook name) should be `FooDebugger`, such that users can state\n", "\n", "```python\n", "from FooDebugger import FooDebugger\n", "```\n", "\n", "Since class and module names should start with uppercase letters, all non-notebook files and folders start with lowercase letters. this may make it easier to differentiate them. The special notebook `index.ipynb` gets converted into the home pages `index.html` (on fuzzingbook.org) and `README.md` (on GitHub).\n", "\n", "Notebooks are stored in the `notebooks` folder." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### DebuggingBook and FuzzingBook\n", "\n", "This project shares some infrastructure (and even chapters) with \"The Fuzzing Book\". Everything in `shared/` is maintained in \"The Debugging Book\" and only copied over to \"The Fuzzing Book\". If you want to edit or change any of the files in `shared/`, do so in \"The Debugging Book\"." ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Output Formats\n", "\n", "The notebooks by themselves can be used by instructors and students to toy around with. They can edit code (and text) as they like and even run them as a slide show.\n", "\n", "The notebook can be _exported_ to multiple (non-interactive) formats:\n", "\n", "* HTML – for placing this material online.\n", "* PDF – for printing\n", "* Python – for coding\n", "* Slides – for presenting\n", "\n", "The included Makefile can generate all of these automatically (and a few more).\n", "\n", "At this point, we mostly focus on HTML and Python, as we want to get these out quickly; but you should also occasionally ensure that your notebooks can (still) be exported into PDF. Other formats (Word, Markdown) are experimental." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Sites\n", "\n", "All sources for the book end up on the [GitHub project page](https://github.com/uds-se/debuggingbook). This holds the sources (notebooks), utilities (Makefiles), as well as an issue tracker.\n", "\n", "The derived material for the book ends up in the `docs/` folder, from where it is eventually pushed to the [debuggingbook website](http://www.debuggingbook.org/). This site allows\n", "* reading the chapters online, \n", "* launching interactive Jupyter notebooks using the binder service, and\n", "* accessing code and slide formats.\n", "Use `make publish` to create and update the site." ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### The Book PDF\n", "\n", "The book PDF is compiled automatically from the individual notebooks. Each notebook becomes a chapter; references are compiled in the final chapter. Use `make book` to create the book." ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "slide" } }, "source": [ "## Creating and Building" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Tools you will need\n", "\n", "To work on the notebook files, you need the following:\n", "\n", "1. Jupyter notebook. The easiest way to install this is via the [Anaconda distribution](https://www.anaconda.com/download/).\n", "\n", "2. Once you have the Jupyter notebook installed, you can start editing and coding right away by starting `jupyter notebook` (or `jupyter lab`) in the topmost project folder.\n", "\n", "3. If (like me) you don't like the Jupyter Notebook interface, I recommend [Jupyter Lab](https://jupyterlab.readthedocs.io/en/stable/), the designated successor to Jupyter Notebook. Invoke it as `jupyter lab`. It comes with a much more modern interface, but misses autocompletion and a couple of extensions. I am running it [as a Desktop application](http://christopherroach.com/articles/jupyterlab-desktop-app/) which gets rid of all the browser toolbars.\n", "\n", "4. To create the entire book (with citations, references, and all), you also need the [ipybublish](https://github.com/chrisjsewell/ipypublish) package. This allows you to create the HTML files, merge multiple chapters into a single PDF or HTML file, create slides, and more. The Makefile provides the essential tools for creation." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Version Control\n", "\n", "We use git in a single strand of revisions. Feel free branch for features, but eventually merge back into the main \"master\" branch. Sync early; sync often. Only push if everything (\"make all\") builds and passes.\n", "\n", "The GitHub repo thus will typically reflect work in progress. If you reach a stable milestone, you can push things on the fuzzingbook.org website, using `make publish`." ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "subslide" } }, "source": [ "#### nbdime\n", "\n", "The [nbdime](https://github.com/jupyter/nbdime) package gives you tools such as `nbdiff` (and even better, `nbdiff-web`) to compare notebooks against each other; this ensures that cell _contents_ are compared rather than the binary format.\n", "\n", "`nbdime config-git --enable` integrates nbdime with git such that `git diff` runs the above tools; merging should also be notebook-specific." ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "subslide" } }, "source": [ "#### nbstripout\n", "\n", "Notebooks in version control _should not contain output cells,_ as these tend to change a lot. (Hey, we're talking random output generation here!) To have output cells automatically stripped during commit, install the [nbstripout](https://github.com/kynan/nbstripout) package and use\n", "\n", "```\n", "nbstripout --install\n", "```\n", "\n", "to set it up as a git filter. The `notebooks/` folder comes with a `.gitattributes` file already set up for `nbstripout`, so you should be all set.\n", "\n", "Note that _published_ notebooks (in short, anything under the `docs/` tree _should_ have their output cells included, such that users can download and edit notebooks with pre-rendered output. This folder contains a `.gitattributes` file that should explicitly disable `nbstripout`, but it can't hurt to check.\n", "\n", "As an example, the following cell \n", "\n", "1. _should_ have its output included in the [HTML version of this guide](https://www.debuggingbook.org/beta/html/Guide_for_Authors.html);\n", "2. _should not_ have its output included in [the git repo](https://github.com/uds-se/debuggingbook/blob/master/notebooks/Guide_for_Authors.ipynb) (`notebooks/`);\n", "3. _should_ have its output included in [downloadable and editable notebooks](https://github.com/uds-se/debuggingbook/blob/master/docs/beta/notebooks/Guide_for_Authors.ipynb) (`docs/notebooks/` and `docs/beta/notebooks/`)." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2024-06-30T17:30:54.152243Z", "iopub.status.busy": "2024-06-30T17:30:54.152102Z", "iopub.status.idle": "2024-06-30T17:30:54.153990Z", "shell.execute_reply": "2024-06-30T17:30:54.153722Z" }, "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "import random" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2024-06-30T17:30:54.155647Z", "iopub.status.busy": "2024-06-30T17:30:54.155537Z", "iopub.status.idle": "2024-06-30T17:30:54.158934Z", "shell.execute_reply": "2024-06-30T17:30:54.158603Z" }, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "0.18730771056084317" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "random.random()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Inkscape and GraphViz\n", "\n", "Creating derived files uses [Inkscape](https://inkscape.org/en/) and [Graphviz](https://www.graphviz.org/) – through its [Python wrapper](https://pypi.org/project/graphviz/) – to process SVG images. These tools are not automatically installed, but are available on pip, _brew_ and _apt-get_ for all major distributions." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### LaTeX Fonts\n", "\n", "By default, creating PDF uses XeLaTeX with a couple of special fonts, which you can find in the `fonts/` folder; install these fonts system-wide to make them accessible to XeLaTeX.\n", "\n", "You can also run `make LATEX=pdflatex` to use `pdflatex` and standard LaTeX fonts instead." ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Creating Derived Formats (HTML, PDF, code, ...)\n", "\n", "The [Makefile](../Makefile) provides rules for all targets. Type `make help` for instructions.\n", "\n", "The Makefile should work with GNU make and a standard Jupyter Notebook installation. To create the multi-chapter book and BibTeX citation support, you need to install the [iPyPublish](https://github.com/chrisjsewell/ipypublish) package (which includes the `nbpublish` command)." ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Creating a New Chapter\n", "\n", "To create a new chapter for the book,\n", "\n", "1. Set up a new `.ipynb` notebook file as copy of [Template.ipynb](Template.ipynb).\n", "2. Include it in the `CHAPTERS` list in the `Makefile`.\n", "3. Add it to the git repository." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Teaching a Topic\n", "\n", "Each chapter should be devoted to a central concept and a small set of lessons to be learned. I recommend the following structure:\n", "\n", "* Introduce the problem (\"We want to parse inputs\")\n", "* Illustrate it with some code examples (\"Here's some input I'd like to parse\")\n", "* Develop a first (possibly quick and dirty) solution (\"A PEG parser is short and often does the job\")\n", "* Show that it works and how it works (\"Here's a neat derivation tree. Look how we can use this to mutate and combine expressions!\")\n", "* Develop a second, more elaborated solution, which should then become the main contribution. (\"Here's a general LR(1) parser that does not require a special grammar format. (You can skip it if you're not interested)\")\n", "* Offload non-essential extensions to later sections or to exercises. (\"Implement a universal parser, using the Dragon Book\")\n", "\n", "The key idea is that readers should be able to grasp the essentials of the problem and the solution in the beginning of the chapter, and get further into details as they progress through it. Make it easy for readers to be drawn in, providing insights of value quickly. If they are interested to understand how things work, they will get deeper into the topic. If they just want to use the technique (because they may be more interested in later chapters), having them read only the first few examples should be fine for them, too.\n", "\n", "Whatever you introduce should be motivated first, and illustrated after. Motivate the code you'll be writing, and use plenty of examples to show what the code just introduced is doing. Remember that readers should have fun interacting with your code and your examples. Show and tell again and again and again." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Special Sections" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Quizzes" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "You can have _quizzes_ as part of the notebook. These are created using the `quiz()` function. Its arguments are\n", "\n", "* The question\n", "* A list of options\n", "* The correct answer(s) - either\n", " * the single number of the one single correct answer (starting with 1)\n", " * a list of numbers of correct answers (multiple choices)\n", " \n", "To make the answer less obvious, you can specify it as a string containing an arithmetic expression evaluating to the desired number(s). The expression will remain in the code (and possibly be shown as hint in the quiz)." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2024-06-30T17:30:54.160757Z", "iopub.status.busy": "2024-06-30T17:30:54.160660Z", "iopub.status.idle": "2024-06-30T17:30:54.232920Z", "shell.execute_reply": "2024-06-30T17:30:54.232617Z" }, "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "from bookutils import quiz" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2024-06-30T17:30:54.234764Z", "iopub.status.busy": "2024-06-30T17:30:54.234647Z", "iopub.status.idle": "2024-06-30T17:30:54.239343Z", "shell.execute_reply": "2024-06-30T17:30:54.239060Z" }, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " \n", " \n", "
\n", "
\n", "
\n", " \n", " \n", " \n", "\n", "
\n", "
\n", " \n", " \n", " \n", "$\\frac{a}{b}$ | $b$ | $c$ |
1 | 2 | 30 |
2 | 3 | 400 |