Skip to content
Carlos Linares López edited this page May 23, 2021 · 1 revision

Mathprob

How to create new problems

The process for creating a new problem involves two main features:

  1. To generate .pdf files with random instances of the new problem which are driven by user parameters
  2. To generate JSON output that might be redirected to a third-party application to use it its own way

The following subsections provide a step-by-step description of the design of mathprob that allow both things

Artistic design: LaTeX/TikZ guides

mathprob uses text templates for automatically substituting certain templates with LaTeX/TikZ code. These text templates consist of LaTeX documents so that by substituting acknowledged templates by LaTeX/TikZ code it is possible to generate customized output which is the overall goal of this project.

The first step consists of determining the LaTeX/TikZ code that generates the desired output. These templates are stored in tex/template from where different directories provide different .tex files explaining in detail how to generate the output for different types of problems such as sequences, divisions, etc.

This step is absolutely mandatory and it is anything but simple. As a result, it is not only necessary to get the common code to all instances of the same operation but also the values of different parameters that characterize its appearance. These arguments, of course, are different from one problem to another.

Code design

The process to automatically substitute patterns with LaTeX/TikZ code can be summarized as follows. The common steps to all types of operations are:

  1. The user provides a master file with the contents of the document to generate and the patterns to substitute. A masterFile is generated to handle it which uses masterToBufferFromTemplate to generate a bytes.Buffer with the contents of the output file.
  2. User commands can use an arbitrary selection of arguments, either mandatory or optional. Thus, the first task of masterToBufferFromTemplate is to automatically extracting these parameters with the aid of template.FuncMap which does the task returning a map[string]interface{}. Once done, a regular text template execute operation is performed. This means that commands as they are shown in the text template are now executed as methods of masterFile taking as argument the map[string]interface{} automatically extracted.

Here it is where the specific implementation of an operation starts. Let us take for example a command in the text master file such as:

{{.Division (dict "nbdvdigits" 2 "nbdrdigits" 1 "nbqdigits" 1)}}

In this case, the method masterFile.Division (map[string]interface{}) is invoked. The argument contains precisely the values provided by the user. The following steps provide a skeleton for other operations to be implemented:

  1. Division starts by ensuring that the arguments are correct by invoking verifyDivisionDict. This function returns an instance of division which ordinarily consists of a struct just for placing the values provided by the user. It next invokes the method execute of that struct: division.execute(). Up to this point, all this logic is implemented in mathtools.go which actually contains the same procedure for all types of operations. Next, specific files for each operation are implemented
  2. divisions.go implements the method division.execute() (note that no arguments are required as it works solely over the values stored in the fields of the receiver) which again uses text templating for generating its output. From this point on templates are stored as raw constant strings which are implemented in the same file.
  3. Although it is possible to kill two birds with one stone, for the sake of convenience two templates are provided. The first one provides all the text surrounding {{.GetTikzPicture}} which is the responsible to work on the LaTeX/TikZ inner circle of the code. Thus, division.execute() simply parses this template and return the result of the substitution.
  4. While parsing the preceding text template, the method division.GetTikzPicture() (again with no arguments) is eventually invoked. This method is the bridge between the text templating operations performed so far and the generation of the LaTeX/TikZ code. To do this, it creates an instance of another struct (divisionProblem in the running example) which contains the values of all parameters identified in the Artistic design for automatically generating the final picture. In addition, it also creates the values of the problem according to the values provided by the user. In the case of a division, this translates into selecting a dividend and a divisor with the required number of digits so that the quotient has also the required number of digits. One this inner structure has been created, GetTikZPicture returns straight ahead the result of its method execute()
  5. divisionProblem.execute() is the one fully in charge of generating the specific code for this type of operation. To do this, it also uses another raw constant string with the specific code determined in the Artistic design. Thus, it just parses and substitutes a raw string template which actually performs the right substitutions so that the resulting code actually generates a LaTeX/TikZ picture
Clone this wiki locally