Skip to content

Commit

Permalink
Merge pull request #6 from jverzani/sylvaticus-main
Browse files Browse the repository at this point in the history
Sylvaticus main
  • Loading branch information
jverzani committed Mar 29, 2022
2 parents 27e48d5 + 8238a6a commit fef0717
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "QuizQuestions"
uuid = "612c44de-1021-4a21-84fb-7261cf5eb2d4"
authors = ["jverzani <jverzani@gmail.com> and contributors"]
version = "0.2.0"
version = "0.3.0"

[deps]
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
Expand Down
2 changes: 1 addition & 1 deletion src/QuizQuestions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ include("question_types.jl")
include("html_templates.jl")
include("show_methods.jl")

export numericq, radioq, booleanq, yesnoq, stringq
export numericq, radioq, multiq, booleanq, yesnoq, stringq

end
40 changes: 37 additions & 3 deletions src/html_templates.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
## Could tidy up this HTML to make it look nicer
html_templates = Dict()

const grading_partial = """
grading_partial = """
if(correct) {
msgBox.innerHTML = "<div class='pluto-output admonition note alert alert-success'><span class='glyphicon glyphicon-thumbs-up'>👍&nbsp;Correct</span></div>";
msgBox.innerHTML = "<div class='pluto-output admonition note alert alert-success'><span class='glyphicon glyphicon-thumbs-up'>👍&nbsp; {{#:CORRECT}}{{{:CORRECT}}}{{/:CORRECT}}{{^:CORRECT}}Correct{{/:CORRECT}} </span></div>";
} else {
msgBox.innerHTML = "<div class='pluto-output admonition alert alert-danger'><span class='glyphicon glyphicon-thumbs-down'>👎&nbsp; Incorrect</span></div>";
msgBox.innerHTML = "<div class='pluto-output admonition alert alert-danger'><span class='glyphicon glyphicon-thumbs-down'>👎&nbsp; {{#:INCORRECT}}{{{:INCORRECT}}}{{/:INCORRECT}}{{^:INCORRECT}}Incorrect{{/:INCORRECT}} </span></div>";
}
"""

Expand Down Expand Up @@ -82,3 +82,37 @@ rb.addEventListener("change", function() {
$(grading_partial)
})});
"""

html_templates["Multiq"] = mt"""
{{#:ITEMS}}
<div class="form-check">
<label>
<input class="form-check-input" type="checkbox" name="check_{{:ID}}"
id="check_{{:ID}}_{{:VALUE}}" value="{{:VALUE}}">
<span = class="label-body">
{{{:LABEL}}}
</span>
</input>
</label>
</div>
{{/:ITEMS}}
"""

html_templates["multi_grading_script"] = """
document.querySelectorAll('input[name="check_{{:ID}}"]').forEach(function(rb) {
rb.addEventListener("change", function() {
var choice_buttons = document.getElementsByName("check_{{:ID}}");
selected = [];
for (var i=0; i < choice_buttons.length; i++) {
if (choice_buttons[i].checked) {
selected.push(i+1)
}
}
var a = selected;
b = {{{:CORRECT_ANSWER}}};
// https://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript
correct = (a.length === b.length && a.find((v,i) => v !== b[i]) === undefined)
var msgBox = document.getElementById('{{:ID}}_message');
$(grading_partial)
})});
"""
54 changes: 54 additions & 0 deletions src/question_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,60 @@ function radioq(choices, answer::Integer;
end




##
mutable struct Multiq <: Question
choices
answer
values
labels
label
hint
inline
end

"""
multiq(choices, answers; label="", hint="", keep_order=false)
Multiple choice question (one *or more* of several)
Arguments:
* `choices`: indexable collection of choices. As seen in the example, choices can be formatted with markdown.
* `answers::Vector{Int}`: index of correct choice(s)
* `keep_order::Boolean`: if `true` keeps display order of choices, otherwise they are shuffled.
* `inline::Bool`: hint to render inline (or not) if supported
* `label`: optional label for the form element
* `hint`: optional plain-text hint that can be seen on hover
Example:
```
choices = ["pear", "tomato", "banana"]
answers = [1,3]
multiplecq(choices, answers; hint="not the red one!")
```
"""
function multiq(choices, answers;
label="", hint="", inline::Bool=(hint!=""),
keep_order::Bool=false)
inds = collect(1:length(choices))
values = copy(inds)
labels = choices
!keep_order && shuffle!(inds)

Multiq(choices[inds], findall(in(answers), inds),
values, labels[inds], label, hint, inline)
end


"""
booleanq(ans; [label, hint])
True of false questions:
Expand Down
30 changes: 30 additions & 0 deletions src/show_methods.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,33 @@ function Base.show(io::IO, m::MIME"text/html", x::Radioq)
)

end

function Base.show(io::IO, m::MIME"text/html", x::Multiq)

ID = randstring()

choices = string.(x.choices)
items = [_make_item(i, choice) for (i,choice) enumerate(choices)]

GRADING_SCRIPT = Mustache.render(html_templates["multi_grading_script"];
ID = ID,
CORRECT_ANSWER = x.answer,
INCORRECT = "Not yet",
CORRECT = "Correct"
)
FORM = Mustache.render(html_templates["Multiq"];
ID = ID,
ITEMS = items,
INLINE = x.inline ? " inline" : ""
)

Mustache.render(io, html_templates["question_tpl"],
ID = ID,
TYPE = "radio",
FORM = FORM,
GRADING_SCRIPT = GRADING_SCRIPT,
LABEL=_markdown_to_html(x.label),
HINT = x.hint # use HINT in question
)

end

6 comments on commit fef0717

@jverzani
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sylvaticus
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems it didn't go. Did you install the Registrator app? See my tutorial here: https://syl1.gitbook.io/julia-language-a-concise-tutorial/language-core/11-developing-julia-packages#pkg_registration

@jverzani
Copy link
Owner Author

@jverzani jverzani commented on fef0717 Mar 30, 2022 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jverzani
Copy link
Owner Author

@jverzani jverzani commented on fef0717 Mar 30, 2022 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sylvaticus
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congratulations to you... This module, providing interaction for students, allows me to move a whole course from Moodle to GitHub.
I have already moved 2 quizzes here and here , but I have another 12 to still move.. :-)

I also opened a pull request to Documenter to include QuizQuestions in the list of packages that work with it: JuliaDocs/Documenter.jl#1783

Thank you again !

@jverzani
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool. Are there other question types that might be useful? (Some people like matching, for example.) I basically only use numeric and multiple choice in my use of this (https://docs.juliahub.com/CalculusWithJulia), but other people are more ambitious in there question writing.

Please sign in to comment.