Exercise and Solution Blocks
Contents
Exercise and Solution Blocks¶
Sometimes you may want to set some (programming) exercises for your readers,
and help them to learn by also publishing corresponding solutions.
While Jupyter Book supports enumerated environments for figures, tables,
equations and (part/chapter/section) headers, it lacks support for
(enumerable, referenceable and interlinked) exercise and solution boxes.
Our sphinx_prolog.solex
Sphinx extension module addresses this shortcoming
by implementing two coupled boxes – exercise
and solution
– based on
Jupyter Book admonitions.
See also
See the Information Boxes section for more information about Jupyter Book admonitions.
Setup¶
To enable the sphinx_prolog.solex
extension module in your Jupyter Book,
include its name in your _config.yml
file under the sphinx.extra_extensions
key
sphinx:
extra_extensions:
# Load sphinx-prolog <https://github.com/simply-logical/sphinx-prolog>
- sphinx_prolog.solex
See also
See the Usage section of the sphinx-prolog Extension page for more details.
Configuration¶
You can configure and personalise the sphinx_prolog.solex
extension
in a number of ways.
For example, the content of exercise and solution boxes can be sourced
from different locations depending on the user’s preferences.
It can either be provided explicitly within a document or loaded from an
external markdown file – an option that allows to streamline repeating the
exercise text in its corresponding solution box.
By default, each exercise is assigned a sequential number and it is named according to the “Exercise #” pattern. Similarly, a solution linked to a particular exercise reuses its sequential number with the “Solution #” template. Both of these naming patterns can be adapted to one’s liking, e.g., to “Task #” and “Answer #”.
Setting up External Files¶
The content of exercise and solution boxes can either be:
provided manually within each box, or
loaded from an external markdown file.
The latter possibility has been implemented to streamline inclusion of solution boxes. Since you may decide to collect all the solutions on a single page, say in the appendix, it may be useful to repeat the exercise text for clarity. In this case you only need to edit the exercise source file to update the text displayed in the exercise and solution blocks pair. See the Loading External Files section of this page for more details.
Note
An exercise block and its corresponding solution box may be placed on two different pages in your book.
To load exercise and solution blocks from external markdown files,
they must be placed in a dedicated directory.
The sphinx_prolog.solex
extension is then informed of this location via
the sp_exercise_directory
configuration parameter, which is placed under
the sphinx.config
key in the _config.yml
file.
sphinx:
config:
# Configure sphinx-prolog <https://github.com/simply-logical/sphinx-prolog>
sp_exercise_directory: src/ex/
This path must be relative to the root directory of your book, i.e., the place
where you hold your _config.yml
file.
It must also be added to the exclude_patterns
configuration parameter
to exclude it from the book build sources.
exclude_patterns:
- src/ex
This is to avoid build errors since Jupyter Book expects all of the markdown files placed below its root directory to be included in the table of content.
See also
See the Configuration section of the Jupyter Book page for more details about configuring your book.
Custom Naming¶
By default, exercise blocks are assigned a sequential number with a title
based on the “Exercise #” template.
Similarly, solutions reuse the sequential numbers of their corresponding
exercises and are given a title based on the “Solution #” pattern.
These templates can be changed in the Jupyter Book configuration file
(config.yml
) under the sphinx.config.numfig_format
key.
sphinx:
config:
numfig_format:
exercise: "Task %s"
solution: "Answer %s"
Custom formatters are strings with a special %s
component that gets
automatically replaced with the sequential number of a given exercise or
solution.
See also
See the Tagging and Referencing sections of this page for more details. Alternatively, refer to the referencing overview section of the Jupyter Book documentation.
Usage¶
Exercise blocks are included with an admonition-like syntax, with their content
explicitly stated in the definition statement.
To build an exercise block use a triple-backtick fence with the exercise
keyword wrapped in curly braces followed by a user-defined
tag, i.e., ```{exercise} ex:my-tag
Solution boxes follow a similar syntax with the exercise
keyword replaced
by solution
By hovering your mouse over the title section of an exercise or a solution box (respectively, the green- and yellow-coloured bar at the top), a hyper-link marker (¶) will be revealed to the right of the title text (“Exercise #” and “Solution #” correspondingly). By clicking the marker you will get a link pointing directly to this particular exercise or solution box.
Tagging¶
Definitions of both exercise and solution boxes require one parameter.
For exercise blocks, it assigns a unique tag to this box and it
must be prefixed with ex:
.
While not every exercise block requires a corresponding solution box,
solution blocks can only be built by linking them to existing exercise
boxes.
This linking is achieved by reusing exercise tags when defining solution
blocks.
For example, to associate a solution to an existing exercise tagged
with ex:my-tag
, it needs to be defined as ```{solution} ex:my-tag
– see Exercise 1 and Solution 1 above.
Linking guarantees that both blocks will have the same sequential number.
It also embeds a hyper-link from an exercise to its solution – marked with
the glyph on the right-hand side of the title bar
– and vice versa (the glyph).
Naturally, exercises without corresponding solutions will lack the
solution hyper-link – see Exercise 2 below.
This is an example of an exercise without a solution.
Tip
Every solution must be linked to an existing exercise, but not all exercises require a solution.
Referencing¶
Similar to Information Boxes,
solution and exercise blocks can be referenced with their tags.
Exercises can be referenced with the {ref}`ex:my-tag`
syntax, which
produces a hyper-link displayed as “exercise”, e.g., exercise points to
Exercise 1.
The default “exercise” text can be manually substituted with a custom label
using the {ref}`custom exercise label <ex:my-tag>`
syntax, e.g.,
see this exercise also points to Exercise 1.
You can also reference exercises with their automatically assigned sequence
number.
This is achieved with the {numref}`ex:my-tag`
syntax – it was used to
generate the numbered exercise references above.
The hyper-link text displayed by this referencing strategy is controlled by
the exercise naming scheme defined in the configuration file –
see the Custom Naming section of this page for more
information.
If you wish to change the numbered hyper-link text for individual references,
this can be achieved with the
{numref}`Custom Sequential Name %s <ex:my-tag>`
syntax.
For example, Challenge 2 is a custom numbered reference
to Exercise 2.
Hyper-linking solution boxes follows the same logic with one minor caveat.
Because solutions reuse tags of their respective exercises,
to reference a solution with an ex:my-tag
label
substitute the ex:
prefix with sol:
.
For example, referencing Solution 1 using its number is achieved with
{numref}`sol:my-tag`
.
Tip
To reference a solution to an exercise tagged with ex:my-tag
,
substitute the ex:
prefix with sol:
, i.e., use {ref}`sol:my-tag`
.
Loading External Files¶
Thus far, each exercise and solution block embedded on this page had
its content explicitly inserted when defining the box.
Alternatively, this content can be loaded from an external markdown file –
see the setup instructions
described above.
Assuming that you have an exercise file in the designated directory –
in our case, exercise_file.md
placed in src/ex/
– you can load it
into a selected exercise box and its corresponding solution block.
This is achieved by using a label derived from the name of this file.
To this end, prepend the ex:
prefix to and discard the .md
extension from
the exercise file name;
for example, our exercise_file.md
file can be loaded with
ex:exercise_file
tag.
Outcome
Exercise content loaded from the
src/ex/exercise_file.md
file.
Syntax
```{exercise} ex:exercise_file
```
Building a solution box from the source file underlying its corresponding exercise follows the same pattern.
Outcome
Exercise content loaded from the
src/ex/exercise_file.md
file.
Syntax
```{solution} ex:exercise_file
```
Tip
To load the content of an exercise box and its corresponding solution block
from a file, compose their label by prepending the ex:
prefix to and
discarding the .md
extension from this file’s name.
For example, a file named exercise_file.md
can be loaded with the
ex:exercise_file
tag.
In some cases, you may wish to overwrite the content of an exercise or a solution box loaded from a file. To this end, provide the content of such a box explicitly when defining it – verbatim content takes precedence over the tag-matching file if one exists. This functionality may be helpful when you want the solution box to use a phrasing that is different to the content of the corresponding exercise. For example, when the exercise refers to a figure placed outside of its box on the same page, and you want include it in the solution box.
Outcome
Exercise content loaded from the
src/ex/exercise_file.md
file.
Syntax
```{exercise} ex:exercise_file
```
Note
If you look at the markdown source of this document, you will notice
that the syntax of Exercise 4 and
Solution 4 presented above uses a different tag
(ex:exercise_file
) than the actual definition of these blocks
(ex:exercise_file_copy
).
Since two exercise boxes cannot be built from the same source file
(due to a label conflict), we duplicated the exercise_file.md
exercise
source file with the exercise_file_copy.md
name.
Tip
To overwrite the content of an exercise or a solution box loaded from a file, simply provide its new content explicitly when defining it.
See also
For more information about the Exercise and Solution module see its technical documentation.