Quizz with Runnable code
alexeygrinevich opened this issue · 6 comments
My goal is to make a quizz where user needs to write code. The "Check" is supposed to validate the code (by running a piece) and become passed/failed based on validation result.
So I have everything in Lia - I can have code to run, I can have Generic quizzes. I'd love to have some tweaks if possible:
- If possible combine "Execute" button with "Check". I.e. pressing "Execute" also triggers "Check" if execution passed.
- Or vise versa - pressing "Check" runs execution and becomes checked if passed.
- Remember user's code (as it currently stores user input's)
- Have more control over "Execute" button if possible (it is now very small and not everyone finds it). Having "Execute" instead of icon would be awesome option in my case.
I managed to implement #2 by adding common
I made up a little example, that you can modify so that it fits your needs, this adds a very simple test, where the last statement of the executed code is checked within a quiz. The first quiz depicts, how a script and a generic-quiz can be stitched together, by using a bit CSS-magic, the other part is a simple macro that could be reused to simplify the coding:
<!--
@@ this is a custom styling, that will hide the check-button
@@ in all quizzes with class quiz-hide
@style
.quiz-hide > div:nth-of-type(2) > button:first-child {
display: none;
}
@end
@@ @codingQuiz will call a helper-macro and use @uid as a first
@@ parameter, this will generate a unique id, every time it is used
@@ the second-param is the actual input-parameter, the backticks
@@ make allow to input commas as well ...
@codingQuiz: @codingQuiz_(@uid,`@0`)
@@ This helper uses the uid to store the result in a global variable,
@@ which is used in the generic quiz. If the code is evaluated, the
@@ the click-event is released for this specific button, such that
@@ it looks like the quiz is checked ...
@codingQuiz_
<script>
if(!window.result) {
window.result = {}
}
try {
window.result["@0"]=eval(`@input`)
console.log(window.result["@0"])
let btn = document.querySelector('#quiz-@0 > div:nth-child(2) > button:first-child');
btn.click()
} catch(e) {
console.error(e.message)
}
"LIA: stop"
</script>
<!-- class="quiz-hide" id="quiz-@0"-->
[[!]]
<script>
window.result["@0"]=="@1"
</script>
@end
-->
# Code-Quiz
``` javascript
console.log("Hallo Welt")
22
```
<script>
try {
window.quiz=eval(`@input`)
console.log(window.quiz)
let btn = document.querySelector('#hidden-quiz > div:nth-child(2) > button:first-child');
btn.click()
} catch(e) {
console.error(e.message)
}
"LIA: stop"
</script>
<!-- class="quiz-hide" id="hidden-quiz" -->
[[!]]
[[?]] Test Hint
<script>
window.quiz==33
</script>
## Macro
``` javascript
console.log("Hallo Welt")
22
```
@codingQuiz(`11`)
``` javascript
console.log("Hallo Welt")
22
```
@codingQuiz(`22`)
``` javascript
console.log("Hallo Welt")
22
```
@codingQuiz(`33`)
you can modify this example here
If you plan to use SCORM, the quiz result should be stored, but not the code-snippets. Unfortunately SCORM allows only to store 254bytes, which are not enough for us to store different version of the editors, thus previous edits will be lost if the course is reloaded... Only the quiz is stored persistently ...
I hope this helps ...
Andre, Thank you a million!
That is an awesome and detailed example.
From script it looks like what I need. And your explanations are very clear. I have just one problem, for some reason I cannot build it.
First I tried it locally and since it is not rendering I tried your link
Here is how it renders in the LiveScript:
I.e. it looks like @codingQuizz is ignored. Is there anything I need to upgrade/update to see it working?
Br/Alexey
I am sorry, I just added the wrong comment-notation afterwards without checking ...
Within the following example the macros should work as expected ...
Awesome!
I apologize for the persistence, but I can't help but take advantage of your responsiveness:)
One more question. Is it possible to force "Check" button to also do "Execute"?
I see how you locate the "Check" button:
let btn = document.querySelector('#quiz-@0 > div:nth-child(2) > button:first-child');
The little problem is there is one small "Execute" button and big "Check" button. And the fact that you first have to click on a little Execute button that doesn't even have a signature is not intuitively obvious.
I think I can hide 'Check' button via css style, but can I change 'Execute' to look like check? Or Make it bigger and add text "Validate" to it?
Br/Alexey
Here is an updated version ... I changed the appearance of the execute-button with the style, which is a bit more complicated, since now I need to change the code-block and the quiz, therefore both elements have been surrounded by a div.
Changing the execute-button is easier, than executing the code from the Check-Button, then await the calculation and react onto it ... Since i cannot directly deactivate the new Check-Button I added a solution to the end of the quiz.
The macro is a bit more difficult now and it does not close the div, since the solution is added and this is part of the quiz ... You can move the div back into the macro if you don't need solutions. Adding the macro to the head of the code-block is just another way of saying, that the content of the entire code-block should be passed as the last parameter. This is a nice way, if you require to pass in more complex JSON, YAML or what so ever configuration ...
I will think of a simpler solution ... adding a new quiz-type as a combination with code-blocks might be also interesting for others ...
Hi Andre,
Thanks a lot for this example, it works! I've modified it a bit to demonstrate a bunch of examples of my needs here
Just for the case you decide to make a dedicated quiz-type of such kind (like Moodle has) you may see my version as a reference.
Thank you again for your invaluable help!