From: Charles Connell Date: Wed, 14 May 2014 15:05:04 +0000 (-0400) Subject: Matching-style quiz questions X-Git-Tag: release-20150131~79 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=8332635760e64d5d4b2ed8435917b565be26a002;p=oweals%2Fkarmaworld.git Matching-style quiz questions --- diff --git a/karmaworld/apps/notes/templatetags/__init__.py b/karmaworld/apps/notes/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/karmaworld/apps/notes/templatetags/notes.py b/karmaworld/apps/notes/templatetags/notes.py new file mode 100644 index 0000000..cba5016 --- /dev/null +++ b/karmaworld/apps/notes/templatetags/notes.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# -*- coding:utf8 -*- +# Copyright (C) 2014 FinalsClub Foundation +import string +from django import template + +register = template.Library() + +@register.filter() +def ordinal_letter(value): + try: + num = int(value) + result = num + if num >= 0 and num < 26: + result = string.ascii_uppercase[num] + return result + except ValueError: + return value + + +@register.filter +def keyvalue(dict, key): + return dict[key] + diff --git a/karmaworld/apps/quizzes/create_quiz.py b/karmaworld/apps/quizzes/create_quiz.py index 076a368..d7fd8e0 100644 --- a/karmaworld/apps/quizzes/create_quiz.py +++ b/karmaworld/apps/quizzes/create_quiz.py @@ -54,13 +54,35 @@ class TrueFalseQuestion(BaseQuizQuestion): return str(self) +class MatchingQuestion(BaseQuizQuestion): + def __init__(self, question_text, left_column, right_column, left_right_mapping): + self.question_text = question_text + self.left_column = left_column + self.right_column = right_column + self.left_right_mapping = left_right_mapping + + def rows(self): + return zip(self.left_column, self.right_column) + + def __unicode__(self): + return u"Matching question: {0} / {1}".format(self.left_column, self.right_column) + + def __str__(self): + return unicode(self) + + def __repr__(self): + return str(self) + + KEYWORD_MULTIPLE_CHOICE = 1 DEFINITION_MULTIPLE_CHOICE = 2 KEYWORD_DEFINITION_TRUE_FALSE = 3 +KEYWORD_DEFINITION_MATCHING = 4 GENERATED_QUESTION_TYPE = ( KEYWORD_MULTIPLE_CHOICE, DEFINITION_MULTIPLE_CHOICE, KEYWORD_DEFINITION_TRUE_FALSE, + KEYWORD_DEFINITION_MATCHING, ) MULTIPLE_CHOICE_CHOICES = 4 @@ -107,6 +129,22 @@ def _create_keyword_definition_true_false(keyword, keywords): return TrueFalseQuestion(question_text, true) +def _create_keyword_definition_matching(keyword, keywords): + question_keywords = [keyword] + question_keywords.extend(random.sample(keywords.exclude(id=keyword.id), MULTIPLE_CHOICE_CHOICES - 1)) + + answer_mapping = {k.word: k.definition for k in question_keywords} + word_column = [k.word for k in question_keywords] + random.shuffle(word_column) + definition_column = [k.definition for k in question_keywords] + random.shuffle(definition_column) + + question_text = u'Match the words with their definitions' + + return MatchingQuestion(question_text, left_column=word_column, + right_column=definition_column, left_right_mapping=answer_mapping) + + def quiz_from_keywords(note): keywords = Keyword.objects.filter(note=note).exclude(word__iexact='').exclude(definition__iexact='') questions = [] @@ -127,6 +165,9 @@ def quiz_from_keywords(note): elif question_type is KEYWORD_DEFINITION_TRUE_FALSE: questions.append(_create_keyword_definition_true_false(keyword, keywords)) + elif question_type is KEYWORD_DEFINITION_MATCHING: + questions.append(_create_keyword_definition_matching(keyword, keywords)) + return questions diff --git a/karmaworld/apps/users/templatetags/__init__.py b/karmaworld/apps/users/templatetags/__init__.py index 8be6577..e69de29 100644 --- a/karmaworld/apps/users/templatetags/__init__.py +++ b/karmaworld/apps/users/templatetags/__init__.py @@ -1 +0,0 @@ -__author__ = 'charles' diff --git a/karmaworld/assets/css/note_course_pages.css b/karmaworld/assets/css/note_course_pages.css index 1dec4fd..e5096c2 100644 --- a/karmaworld/assets/css/note_course_pages.css +++ b/karmaworld/assets/css/note_course_pages.css @@ -193,3 +193,30 @@ button.add-note-btn { background-color: #740b00; } +.matching-select-wrapper { + width: 40px; + margin: 0; + display: inline-block; +} + +.matching-select { + width: 80px; + font-weight: bold; + margin: 0; +} + +.matching-select option { + font-weight: bold; +} + +.matching-select-label { + display: inline-block; + margin: 0 0 0 5px; + padding: 0; + vertical-align: top; + font-weight: bold; +} + +.matching-choice { + margin: 0 0 15px 0; +} \ No newline at end of file diff --git a/karmaworld/assets/js/note-detail.js b/karmaworld/assets/js/note-detail.js index 1718ee0..3f83db2 100644 --- a/karmaworld/assets/js/note-detail.js +++ b/karmaworld/assets/js/note-detail.js @@ -311,13 +311,29 @@ function initQuizPage() { $('.quiz-question-wrapper').each(function() { var choice = $(this).find('input:checked'); if (choice.length) { - console.log(choice); if (choice.data('correct') == true) { markQuestionCorrect($(this)); } else { markQuestionIncorrect($(this)); } } + + var matching_correct = false; + var options_selected = $(this).find('option:selected'); + if (options_selected.length > 0) { + matching_correct = true + } + options_selected.each(function() { + if ($(this).data('correct') == false) { + matching_correct = false; + } + }); + if (matching_correct) { + markQuestionCorrect($(this)); + } else { + markQuestionIncorrect($(this)); + } + }); }); } diff --git a/karmaworld/templates/notes/note_quiz.html b/karmaworld/templates/notes/note_quiz.html index 9126d24..b248b70 100644 --- a/karmaworld/templates/notes/note_quiz.html +++ b/karmaworld/templates/notes/note_quiz.html @@ -1,3 +1,5 @@ +{% load notes %} +
@@ -59,6 +61,39 @@
{% endif %} + {% if question.question_type == 'MatchingQuestion' %} + {% for row in question.rows %} +
+
+ {% with left_row=row.0 %} +
+
+ +
+ +
+ {% endwith %} +
+
+ {% with right_row=row.1 %} +
+ {{ forloop.counter0|ordinal_letter }}. {{ right_row }} +
+ {% endwith %} +
+
+ {% endfor %} + {% endif %}