Changelog

v0.1.1

New

  • Add type hints to configurations to make it clearer for users.

  • Configure how many options of OneOf nodes will be rendered as radio buttons at most with maximal_radio_buttons.

  • ExpressionType interprets e and i as euler’s number and the imaginary unit if they are not specified as symbols.

  • Input fields have a correct flag. Jupyter frontends use this flag to highlight input fields after submission.

  • Weight scores with weights when instantiating an exercise and test weights.

  • Implement atol and rtol for Complex and Real nodes.

  • Add specific exercises from a Python script to an exercise pool via the CLI, i.e. /path/to/exercises/exercises.py:Example1,Example2,....

  • New nodes: Polynomial, ElementwisePolynomial, LinearExpression, ElementwiseLinearExpression and MultipleChoice.

  • New compare option up_to_multiple for Vector. With this option linear dependent input vectors will also get the maximal score.

  • An exercise’s difficulty can be set with difficulty on Exercise.run().

  • When an exercise is instantiated, the range from which difficulty is randomly chosen from can be specified with keyword arguments min_difficulty and max_difficulty.

  • The following metadata can be specified as class attributes for an exercise: title, subtitle, author, language, license, URL, pyrope_versions, origin, discipline, area, topic, keywords and taxonomy. If specified, they get tested via unit tests when MyExercise().test() is called.

  • Rudimentary database functionalities.

  • History log for statistical purposes and learning analytics.

  • New exercise method hints(): This method can be used to return a string or an iterable of strings containing tips for students to solve an exercise. In JupyterFrontend these hints can be rendered via a button.

  • History logging for learning analytics.

  • Make JupyterFrontend Notebook 7 and JupyterLab compatible.

  • Exercise.test() now returns a boolean value whether all tests passed or not. Furthermore, it got a new option suppress_output which defaults to False.

  • ignore_case and squash_whitespaces option for String nodes.

  • Define default values in scores() for input fields.

Changes

  • Downgrade required Python version to 3.10.

  • While adding exercises to an exercise pool, reload already imported modules so that changes in exercises are considered.

  • In Jupyter frontends, Feedbacks and total scores will now have the same style as problem and preamble templates.

  • Remove Widget.new_instance() because Node.clone() made it obsolete.

  • Jupyter frontend: Encode and decode templates with Base64.

  • Drop ColumnVector and RowVector. Use Vector with keyword argument orientation instead. Vectors are now represented as a flat numpy.array internally.

  • Validate arguments of widgets.

  • Rename score_types to float_types.

  • Create a nodes package and outsource errors into a separate module to avoid circular imports.

  • Composed input fields can be invalid even if all children nodes are valid. Therefore all children nodes are now invalid if the composed input field is invalid.

  • Messages sent between frontends and runners are now encapsulated by the class Message.

  • Line breaks are handled differently in templates: One or more blank lines start a new paragraph and escaping a newline character enforces a line break. For multiline strings this means you only have to write a double backslash at the end of a line or a single backslash in case of raw multiline strings.

  • Accept None and empty strings as solutions.

  • If there are empty input fields with no default values in a joint input field scoring scenario, the exercise gets a total score of zero.

Fixes

  • Raise an error in MatrixType if atol or rtol are not real numbers.

  • In Jupyter frontends, use Pandoc’s tex_math_dollars Markdown extension to respect LaTeX environments in all templates.

  • Return False in ExpressionType.compare() if sympy.Expr.equals() returns None.

  • Widgets now use their correct parent node to calculate scores automatically.