This section describes the format parsed by learn-ocaml
for
exercises, tutorial and lessons.
A group is either a set of exercices or other groups. As such exercices are classified
into a tree representation, where groups are nodes and leafs are exercises. This
tree (or index of exercises) can be described by a file index.json
at the root
of the exercises
directory from the repository. If no index.json
is found, the subdirectories are scanned and all exercises found are returned.
The file index.json
has the following format (in version “1”):
<group name> = <string>
<directory> = <string>
<exercices> = "exercises : [ <directory>, .., <directory> ]
<groups> =
"groups" :
{ ( <group name> : { "title" : <string>, (<groups> | <exercices> ) } )+ }
{ "learnocaml_version": <string>, <groups> }
For example, this index.json
describes two groups of exercices, one with only
one exercise, two in the other:
{ "learnocaml_version": "1",
"groups":
{ "imperative-traits":
{ "title": "Imperative traits",
"exercises": [ "mooc-simple-input-output" ] },
"data-structures":
{ "title": "Data Structures",
"exercises": [ "mooc-binary-search-trees",
"mooc-trie-data-structure" ] } } }
This format reflects how exercises should be classified into the application. If this file does not exists, the exercises are simply put at the root of the index.
An exercise is described by a directory containing at most the following files:
Note: as of learn-ocaml 1.0, the
.ml
files get compiled into the exercise. It is therefore not possible to use directives like#install_printer
. However, you can still define your own printers in a way similar to defining customsample_<type>
functions:(* Custom printer for a pre-defined type *) let print_float ppf x = Format.fprintf ppf "%.2f" x (* Name the alias to define a printer for a specific instanciation of a generic type *) type int_list = int list let print_int_list ppf l = ... (* Define a generic printer for a generic type *) let print_result ppok pperr ppf = function | Ok ok -> Format.fprintf ppf "OK(%a)" ppok ok | Error err -> Format.fprintf ppf "ERR(%a)" pperr err
Printers defined in
prelude.ml
orprepare.ml
affect the toplevel and the grader. Printers defined intest.ml
, obviously, affect only the grader.
Json description with the following format (in version “1”):
{ "learnocaml_version" : "1",
"kind" : "exercise" | "problem" | "project",
"stars" : [1 .. 5]
}
Json description in version “2” contains more metadata:
{
"learnocaml_version" : "2",
"kind" : "exercise" | "problem" | "project",
"stars" : [1 .. 5],
"title" : "Title of the exercise",
/* In an exercise repository, each exercise must have a unique identifier. */
"identifier" : "some_unique_identifier",
/* Authors with their emails. */
"authors" : [["Xavier Leroy", "some@email"], ["Damien Doligez", "someother@email"]],
/* The skills and concepts that are practiced by this exercise. */
"focus" : ["skill1", ..., "skillN", ..., "concept1", ..., "conceptM"],
/* The skills and concepts that are required to do this exercise. */
"requirements" : ["skill1", ..., "skillN", ..., "concept1", ..., "conceptM"],
/* The suggested exercises in case of success */
"forward_exercises" : [ "exercise1", "exercise2", ... ],
/* The suggested exercises in case of difficulty */
"backward_exercises" : [ "exercise1", "exercise2", ... ],
/* Maximum score for the exercise. */
"max_score" : [ 0 .. n ],
}
Description of the exercise in HTML format.
OCaml file containing the definitions that are known by the user. In the
web-application, the prelude is shown after the exercise description. The
prelude is loaded in the environment before any other .ml
files from the
exercise directory.
OCaml file containing some definitions that are unknown by the user. As such, it
can be used to to redefine some functions, or execute some code. For example, it
is useful to redefine some standard library functions to track their usage for
algorithmic purpose. prepare.ml
is loaded directly after prelude.ml
in the
environment.
OCaml file containing a template of code for the exercise, and loaded into the editor by default if the user does not have a saved code for the current exercise.
OCaml file containing the solution for the exercise. It can be used for testing the user’s code by comparing its results with a code reference.
OCaml file containing the test program that is used to check and grade the user’s code and the solution. It has access to many functions allowing the introspection of the code, which will be described and detailed in another section.
Maximum score that is possible to get for this exercise, even if the grader
grades more. Overridden by the field max_score
, if present in meta.json
.
List of additional libraries (one per line) to be used by the grader. The
libraries will be looked up using ocamlfind
, available to test.ml
during its
compilation, and bundled in the exercise grader.
When building the corpus and extracting the metadatas of all exercises, the
builder will generate two files requirements.json
and focus.json
, which
aggregates every skill present in their respecting fields in every
meta.json
. It associates a skill to the list of exercises that requires it (or
focuses on it). These files behave as some sort of static database for this
information and should not be written by hand.
Their format is the following:
[{ "<skill name>" : [ "<exercise_id>" ; .. ; "<exercise_id>" ] }; .. ]