Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracker: redesign problem.sty #391

Closed
11 of 13 tasks
kohlhase opened this issue Mar 25, 2023 · 20 comments
Closed
11 of 13 tasks

Tracker: redesign problem.sty #391

kohlhase opened this issue Mar 25, 2023 · 20 comments

Comments

@kohlhase
Copy link
Contributor

kohlhase commented Mar 25, 2023

We are using problem.sty more and more, it needs some serious redesign, I will collect ideas here.

  • {solution}, {gnote}, {exnote}, {hint} should have an optional keyword argument with keys id=, title=
  • {solution} should probably have more keys for e.g. answer classes
  • {solution} should have a key testspace=3cm that in test mode leaves 3 cm space for students to fill in the solution. We currently use the \testspace macro for that.
  • vollki.sty should be merged into problem.stystex.sty.
  • We should probably also have some convenience abbreviations for \objective. I would like to write \lobj[a]{foo} instead of \objective{apply}{foo} (remember is the defaut).
  • MMT linter support for \objective and friends.
  • the current {mcb} (multiple choice block) should be re-designed to work for single-choice as well, and we need to be able to style it. See (new env for single-choice problems in problem.sty #389)
  • make F the default for \mcc(so that we do not have to write \mcc[F,...] any more.
  • \fillinsol (it currently takes a single argument with the "intended solution" should become more like {mcb}, i.e. a set of "answer class specifications" (like the current \mcc, but with a "recognizer predicate specification" that auto-selects the answer class rather than the T/F) that allows to hang feedback and grading information. Then fillinsol can become a convenience macro for the case with a single answer class.
  • we need a better designed way of expressing the answer classes that we currently use {eecs} for.
  • {sproblem} and {subproblem} should maybe get a key autocorrect which states that it can be auto-corrected, and therefore could be selected for quizzes.
  • subproblem environment
  • documentation for all of this (in particular for vollki.sty in the sTeX tutorial.

There are also a lot of useful things maybe worth considering in George Goguadse's dissertation from 2010 which addresses task management in the ActiveMath System. I am not aware of something better since.

@kohlhase
Copy link
Contributor Author

kohlhase commented Jun 29, 2023

Here is a first idea for fillinsol environment:

\begin{sproblem}
  In 2019, Erlangen was a city of
  \begin{fillin}[type=int]
    \numrange[feedback={No,that would be a village}]{0-1000}
    \numrange[feedback={No,that would be a town}]{1001-100000}
    \exactanswer[T,feedback={Wow, you known your numbers, that is exactly correct according to wikipedia}]{111962}
    \numrange[T,feedback={Yes, it is close to 109000}]{100000-120000}
    \numrange[feedback={No, that is too large}]{1200001-}
    \regex[feedback={What do negative Inhabitants even mean?}]{-.[0-9]+}
    \otheranswer[feedback={Please give a natural number}]
  \end{fillin}
  inhabitants
\end{sproblem}

The {fillin} yields a text box, its type attribute may allow to reject ill-typed entries (that could also be a regular expression).

The children specify answer classes in various ways they all have the same keyword attributes as \mcc to arrange for feedback, grading, ... ;

  • \numrange checks for number ranges given in the usual (from-to notation)
  • \exactanswer checks for string equality
  • \regex checks for regular expressions (this is for the pros)
  • \otheranswer takes the rest.
  • There may be an open ended supply of other macros that we can come up eventually

Of course, names can still change, but this would work. I am not sure yet what the PDF is I want to generate for this. Have to implement it to play around with it.

The currently existing \fillinsol{4} is equivalent to

\begin{fillin}
\exactanswer[T]{4}
\otheranswer
\end{fillin}

@kohlhase
Copy link
Contributor Author

kohlhase commented Jun 29, 2023

As a general design I am leaning towards generalizing all the functionality into the concept of an "answer set" (a set of answer class representations) that have different interactions and styles. Let's hash this out a bit
The current

\begin{mcb}
  \mcc[T]{some description}

would become

\begin{answerset}[interaction=multiple-choice]
  \achoice[T]{some description}

and analogously for single-choice, making #389 obsolete. The {fillin} proposed above would become

\begin{answerset}[interaction=fillin,filter=remove-blanks]

And finally, the current {solution} envionment becomes

\begin{answerset}[interaction=manual]
  \begin{solution}

Admittedly, this is more verbose, but we could just leave the {answerset}[interaction=manual] for the OMDoc harvester to integrate by default.

@kohlhase
Copy link
Contributor Author

I am also leaning towards re-organizing how we do subproblems. Currently we commonly use "corresponding enumeration", which is very implicit, like so:

\begin{sproblem}[id=thisnthat,title=This and That]
  Some general setup
  \begin{enumerate}
  \item do this
  \item do that based on this
  \item finally do something else
  \end{enumerate}
\begin{solution}
  \begin{enumerate}
  \item we do this
  \item we do that based on this
  \item we finally do something else
  \end{enumerate}
\end{solution}
\end{sproblem}

And I think that slightly more verbose but more more modularly the following would be much better.

\begin{sproblem}[id=thisnthat,title=This and That]
  Some general setup
  \begin{subproblems}[style=enumerate]
    \begin{sproblem}[id=this]
      do this
      \begin{solution}
        this is how we do this
      \end{solution}
    \end{sproblem}
    \begin{sproblem}[id=that,requires=this]
      do that based on this
      \begin{solution}
        this is how we do that based on this 
      \end{solution}
    \end{sproblem}
    \begin{sproblem}
      finally do something else
      \begin{solution}[id=else]
        and finally this is how we do something else
      \end{solution}
    \end{sproblem}
  \end{subproblems}
\end{sproblem}

This is quite obvious, and should be very easy to realize. But we can already see an advantage: The modularity allows us to leave out some subproblems, e.g. we could specify them in

\includeproblem[leaveout={that,else}]{...

which would give us a problem with only one subproblem (where we could leave out the enumerate altogether). Currently Florian "solves" this situation by commenting out the respective \items in the source code.

And there is another advantage: in the second subproblem we have specified a requires=this, which means that there is a conceptual dependency, so that we could raise an exception when we try leaveout={this} which would result in a dangling second subroblem.

@kohlhase
Copy link
Contributor Author

Dennis just convinced me that the leaveout idea is dangerous and very hard to realize.
We will have to develop a practice with \inputref to get this done, i.e. instead of

\includeproblem[leaveout={that,else}]{...

we would have a separate problem file that inputrefs the shared snippets to get around the copy/paste problems.

@kohlhase
Copy link
Contributor Author

Also Dennis comments that instead of nesting {sproblem} we should use a new environment {subproblem}.

@kohlhase
Copy link
Contributor Author

I have a first impementation for the {fillin} environment:

\documentclass{article}
\usepackage{keyval,amssymb}
%\usepackage[hints,notes]{problem}
\usepackage[solutions,hints,notes]{problem}
\newenvironment{fillin}[2][]{%
  \fbox{\ifsolutions#2\else\phantom{\Huge{#2}}\fi}%
  \ifsolutions\par%
  \begin{tabular}{|l|l|l|p{6cm}|}\hline%
    \multicolumn{4}{|c|}{Autocorrection Rules}\\\hline%
    rel & what & verdict & Feedback\\\hline%
    \fi}
{\ifsolutions\end{tabular}\fi}
\makeatletter
\def\answer@verdict{Incorrect}
\define@key{answer}{T}[t]{\gdef\answer@verdict{Correct}}
\define@key{answer}{feedback}{\gdef\answer@feedback{#1}}
\newcommand\exactanswer[2][]{\setkeys{answer}{#1}%
\ifsolutions =& #2&\answer@verdict & \answer@feedback\\\hline\fi}
\newcommand\numrange[2][]{\setkeys{answer}{#1}%
\ifsolutions range & #2&\answer@verdict & \answer@feedback\\\hline\fi}
\newcommand\regex[2][]{\setkeys{answer}{#1}%
\ifsolutions regex & #2&\answer@verdict & \answer@feedback\\\hline\fi}
\newcommand\otheranswer[1][]{\setkeys{answer}{#1}%
\ifsolutions other &answer &\answer@verdict & \answer@feedback\\\hline\fi}
\makeatother 
\begin{document}
\begin{sproblem}
  In 2019, Erlangen is a city of
  \begin{fillin}[type=int,width=3cm,height=1cm]{111962}
    \exactanswer[T,feedback={Wow, you known your numbers, that is exactly correct according to wikipedia}]{111962}
    \numrange[feedback={No,that would be a village}]{0-1000}
    \numrange[feedback={No,that would be a town}]{1001-100000}
   \numrange[T,feedback={Yes, it is close to 109000}]{100000-120000}
    \numrange[feedback={No, that is too large}]{1200001-}
    \regex[feedback={What do negative Inhabitants even mean?}]{-.[0-9]+}
    \otheranswer[feedback={Please give a natural number}]
 \end{fillin}
  inhabitants
\end{sproblem}
\end{document}

@kohlhase
Copy link
Contributor Author

With the solutions option given it gives
Screenshot 2023-06-30 at 09 46 49
without the expected
Screenshot 2023-06-30 at 09 47 17

@kohlhase
Copy link
Contributor Author

Jonas just made me aware of the fact that the last three should be incorrect. Have to see.

@kohlhase
Copy link
Contributor Author

kohlhase commented Jul 1, 2023

OK, fixed that in my private version, it was just the naive way of handling keyword arguments. Shoudl be fixed in a real implementation.

@kohlhase
Copy link
Contributor Author

kohlhase commented Jul 1, 2023

The more I think about the {subproblems} approach, the more it seems right to me. I am starting to use it in the problems. I only had to add

\newif\ifinsubproblems\insubproblemsfalse
\newenvironment{subproblems}[1][]{\begin{enumerate}\insubproblemstrue}{\end{enumerate}}
\newenvironment{subproblem}[1][]{\ifinsubproblems\item\fi}{}

to MathHub/MiKoProblems/meta-inf/lib/preamble.tex to get it to run. The conditional is to allow {subproblem} environments to be snippetized into their own documents. The problem there is that this does not allow {solution} environments yet. That still has to be restored.

I am also ignoring the keyword arguments for the moment, but they are quite natural, the ones for {subproblem} should be the same as for {sproblem}. Then we can replace the common

\item\pts4

with

\begin{subproblem}[pts=4]

@Jazzpirate
Copy link
Contributor

Jazzpirate commented Jul 6, 2023

Protocol over what I'm doing:

  • \objective and \precondition are now defined in stex.sty
  • sproblem is no longer a module
  • solution, gnote, exnote, and hint take optional argument id= and title=
  • solution additionally takes optional arguments testspace and answerclass
  • the subproblem environment checks whether it occurs in an sproblem. If not, it outputs a warning in PDF mode only that the (very likely) standalone document is missing context, and "activates" solution, gnote etc.
  • subproblem is stylable like other macros/environments. By default, it uses a list-environment with the subproblem number.
  • subproblem takes the same optional arguments as sproblem does.
  • If a problem has no explicit number of pts (analogously min), the value is computed as the sum of all of its subproblems
  • (currently, the pts are therefore now printed at the end of a problem, but that can likely be changed by using the aux file instead. I'll deal with that later)
  • A subproblem's pts and min values are printed iff a) not contained in an sproblem (standalone), or b) the containing sproblem has no explicit pts/min to avoid inconsistencies.

@kohlhase
Copy link
Contributor Author

kohlhase commented Jul 6, 2023

Do I understand correctly that the {subproblems} environment is no longer needed?

@Jazzpirate
Copy link
Contributor

cont'd:

  • {sproblem} and {subproblem} take optional agument autogradable (by default false)
  • {mcb} is stylable, with predefined {mcb}[style=inline] for (duh) inline boxes
  • to make feedback, Ttext and Ftext compatible with inline \mccs, the resulting text from these options is now put into a footnote (if solutions is on - otherwise it's ignored, of course). In the HTML, it is put right next to the \mcc in the expectation that the frontend does something with it anyway.
  • {scb} environment (and \scc macro) behaving exactly like mcb (resp. \mcc), except for the HTML annotations and using \bigcirc instead of \square in the PDF. The HTML has no circle/box anyway, I expect the frontend should insert those as actual <form>s or whatever
  • short forms \yesTnoF, \yesFnoT, \trueTfalseF, \trueFfalseT for the corresponding scbs
  • \fillinsol now takes as optional argument a list of key-value-pairs with keys exact, numrange, regex and values being triples {<string>}{T|F}{<feedback>} (the answer case "description", whether that case is correct/wrong, and feedback). The mandatory argument in \fillinsol is now only used to a) determine the size of the fillinbox, and b) to fill the box with if \ifsolutions is true.
    multiple values for the same key are allowed. In PDF mode, the information is accumulated into a table and inserted as a footnote. In HTML mode, it is inserted as annotations.
  • It also takes a testspace argument determining the horizontal width of the fillinbox (overriding the mandatory argument)
    Example: In 2019, Erlangen is a city of \fillinsol[exact={111962}T{Wow, you know your numbers...},numrange={0-1000}F{No, that would be...},numrange={1001-100000}F{No, that would be...} ]{111962}

@kohlhase
Copy link
Contributor Author

kohlhase commented Jul 9, 2023

cool, what is still missing?

@Jazzpirate
Copy link
Contributor

The MMT side of things and answer classes in general problems we discussed - but since we can't exploit the latter for now anyway, I should probably just implement the superficials so we have something to work with for now

@kohlhase
Copy link
Contributor Author

kohlhase commented Jul 9, 2023

I agree. After you have completed problem.sty, then I have to do a lot of work on the sTeX sources.

@Jazzpirate
Copy link
Contributor

  • In gnote, the \anscls{...}-macro is now valid. The argument is a human-oriented description of the answer class. Optional arguments are:
    • id: An ID, by default ACi, where i is an internal counter
    • schema: A string describing a PL0-formula describing when this case applies. Is not checked currently, but printed if provided
    • update: How to update a user model if this case applies. Currently just ignored, syntax to be determined
    • pts: How many points to give. Is not checked currently, but printed if provided.
  • MMT changes, I hope.

Pushed sTeX and MMT (on the newrelational branch). Will restart buildserver on staging soon

@kohlhase
Copy link
Contributor Author

Can this work? I have not done anything to the problems to adapt the syntax yet.

@Jazzpirate
Copy link
Contributor

Oh. Right. Nevermind then - I'll leave you to it first :D Let me know when to do the thing :)

@kohlhase
Copy link
Contributor Author

kohlhase commented Oct 3, 2023

We have a first stable release, it even has documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants