From c082d716e3a59d4ccb084fcb3ee68e29f44fcf74 Mon Sep 17 00:00:00 2001 From: Jan Maximilian Michal <j.michal@stud.uni-goettingen.de> Date: Wed, 23 Nov 2016 02:57:04 +0000 Subject: [PATCH] Added three new scripts. Selection gaps implemented and other minor improvements. --- grim.py | 41 +++++-- hallgrim/IliasXMLCreator/gap.py | 65 ++++++++--- hallgrim/IliasXMLCreator/multi.py | 13 ++- hallgrim/IliasXMLCreator/packer.py | 5 +- hallgrim/IliasXMLCreator/single.py | 4 +- hallgrim/IliasXMLCreator/xmlBuildingBlocks.py | 68 +++++++++--- hallgrim/parser.py | 44 +++++++- scripts/feldarbeit_param.py | 63 +++++++++++ scripts/nur_sterne_sehen.py | 42 +++++++ scripts/originale_kopien.py | 33 ++++++ scripts/zeilen_sind_anders.py | 105 ++++++++++++++++++ 11 files changed, 430 insertions(+), 53 deletions(-) create mode 100644 scripts/feldarbeit_param.py create mode 100644 scripts/nur_sterne_sehen.py create mode 100644 scripts/originale_kopien.py create mode 100644 scripts/zeilen_sind_anders.py diff --git a/grim.py b/grim.py index 346c9b8..325ab5d 100755 --- a/grim.py +++ b/grim.py @@ -20,6 +20,8 @@ def type_selector(type): return 'MULTIPLE CHOICE QUESTION' if 'single' in type: return 'SINGLE CHOICE QUESTION' + if 'gap' in type: + return 'CLOZE QUESTION' def file_exists(path): @@ -28,8 +30,7 @@ def file_exists(path): raise argparse.ArgumentTypeError(msg) return path -def script_is_valid(script): - required = ['meta', 'task', 'choices', 'feedback'] +def script_is_valid(script, required): for field in required: if not hasattr(script, field): error("script does not export '{}' field.".format(field)) @@ -93,16 +94,42 @@ def parseme(): args = parser.parse_args() if args.command == 'gen': - handle_choice_questions(args.out, args.input, args.instances) + delegator(args.out, args.input, args.instances) if args.command == 'new': handle_new_script(args.name, args.type, args.author, args.points) if args.command == None: parser.print_help() - -def handle_choice_questions(output, script_name, instances): +def delegator(output, script_name, instances): script = importlib.import_module(file_to_module(script_name)) - script_is_valid(script) + handler = { + 'gap' : handle_gap_questions, + 'single choice' : handle_choice_questions, + 'multiple choice' : handle_choice_questions + }[script.meta['type']] + + handler(output, script, instances) + +def handle_gap_questions(output, script, instances): + script_is_valid(script, required=['meta', 'task', 'feedback']) + data = { + 'type': type_selector(script.meta['type']), + 'description': "_description", + 'gap_list': gap_parser(script.task), + 'author': script.meta['author'], + 'title': script.meta['title'], + 'shuffle': script.meta['shuffle'] if 'shuffle' in script.meta else True, + 'feedback': markdown(script.feedback), + 'gap_length': script.meta['gap_length'] if 'gap_length' in script.meta else 20, + } + + output = os.path.join( + 'output', script.meta['title']) + '.xml' if not output else output + packer.convert_and_print(data, output, instances) + info('Processed "{}" and wrote xml to "{}".'.format(script.__name__, output)) + +def handle_choice_questions(output, script, instances): + script_is_valid(script, required=['meta', 'task', 'choices', 'feedback']) data = { 'type': type_selector(script.meta['type']), 'description': "_description", @@ -118,7 +145,7 @@ def handle_choice_questions(output, script_name, instances): output = os.path.join( 'output', script.meta['title']) + '.xml' if not output else output packer.convert_and_print(data, output, instances) - info('Processed "{}" and wrote xml to "{}".'.format(script_name, output)) + info('Processed "{}" and wrote xml to "{}".'.format(script.__name__, output)) def handle_new_script(name, type, author, points): diff --git a/hallgrim/IliasXMLCreator/gap.py b/hallgrim/IliasXMLCreator/gap.py index fbe51a9..61470b7 100644 --- a/hallgrim/IliasXMLCreator/gap.py +++ b/hallgrim/IliasXMLCreator/gap.py @@ -2,32 +2,38 @@ import xml.etree.ElementTree as et from hallgrim.IliasXMLCreator.xmlBuildingBlocks import * +def xml_print(element, **kwargs): + import xml.dom.minidom + + xml = xml.dom.minidom.parseString(et.tostring(element, encoding='utf8', method='xml')) # or xml.dom.minidom.parseString(xml_string) + print( xml.toprettyxml(), **kwargs ) + ### # Solution 1 # ['text', 'text', 'text'] -# [('gap_solution', points, length), ..., (['one', 'two', 'three'], points, length)] +# [('gap_solution', points), ..., (['one', 'two', 'three'], points)] # # str : str_gap # list : choice_gap # tuple : num_gap (x, min, max) # # Solution 2 -# ['text', ('gap_solution', points, length), ('gap_solution', points, length), 'text', ...] +# ['text', ('gap_solution', points), ('gap_solution', points), 'text', ...] # ### class GapQuestion: """docstring for GapQuestion""" - def __init__(self, type, description, gap_list, author, title, questions, feedback, gapLength): + def __init__(self, type, description, gap_list, author, title, shuffle, feedback, gap_length): self.type = type self.description = description self.gap_list = gap_list self.author = author self.title = title - self.questions = questions + self.shuffle = shuffle self.feedback = feedback - self.gapLength = gapLength + self.gap_length = gap_length self.itemmetadata = self.itemmetadata(feedback_setting=1) self.presentation = self.presentation() @@ -45,7 +51,7 @@ class GapQuestion: subroot.append(qtimetadatafield('additional_cont_edit_mode', 'default')) subroot.append(qtimetadatafield('externalId', '99.99')) subroot.append(qtimetadatafield('textgaprating', 'ci')) - subroot.append(qtimetadatafield('fixedTextLength', str(self.gapLength))) + subroot.append(qtimetadatafield('fixedTextLength', str(self.gap_length))) subroot.append(qtimetadatafield('identicalScoring', '1')) subroot.append(qtimetadatafield('combinations', 'W10=')) root = et.Element('itemmetadata') @@ -62,24 +68,49 @@ class GapQuestion: if type(item) == str: f = material(item) if type(item) == tuple: - if type(item[0] == list): - f = response_choice(gap_ident, item[0]) - if type(item[0] == str): - f = response_str(gap_ident, self.gapLength) - if type(item[0] == tuple): - f = response_num(gap_ident, self.gapLength, item[1], item[2]): + if type(item[0]) == list: + f = response_choice("gap_{}".format(gap_ident), item[0]) + if type(item[0]) == str: + f = response_str("gap_{}".format(gap_ident), self.gap_length) + if type(item[0]) == tuple: + f = response_num("gap_{}".format(gap_ident), self.gap_length, item[1], item[2]) gap_ident += 1 flow.append(f) + + return root ############################################################################ def resprocessing(self): root = et.Element('resprocessing') outcomes = et.Element('outcomes') - outcomes.append(simple_elemet('decvar')) + outcomes.append(simple_element('decvar')) root.append(outcomes) - is_gap = lambda t: type(t) = tuple - for i, (_, correct, points) in enumerate(filter(is_gap, self.gap_list)): - root.append(respcondition(points if correct else 0, i, True)) - root.append(respcondition(points if not correct else 0, i, False)) + is_gap = lambda t: type(t) == tuple + for i, (answer, points) in enumerate(filter(is_gap, self.gap_list)): + if type(answer) == list: + for j, (choice, points) in enumerate(answer): # verschattung + root.append(respcondition_gap(points, i, choice, j)) + if type(answer) == str: + root.append(respcondition_gap(points, i, answer)) + if type(answer) == tuple: + root.append(respcondition_gap(points, i, answer[0])) return root + + ### returns the final object ############################################### + def create_item(self): + """ This method stacks all the previously created structures together""" + item = et.Element('item', attrib={ + 'ident': 'undefined', + 'title': self.title, + 'maxattempts': "99" + }) + + item.append(simple_element('description', text=self.description)) + item.append(simple_element('duration', text='P0Y0M0DT0H30M0S')) # 30 min + item.append(self.itemmetadata) + item.append(self.presentation) + item.append(self.resprocessing) + item.append(itemfeedback('response_allcorrect', self.feedback)) + item.append(itemfeedback('response_onenotcorrect', self.feedback)) + return item diff --git a/hallgrim/IliasXMLCreator/multi.py b/hallgrim/IliasXMLCreator/multi.py index 7836a22..9c9b91e 100644 --- a/hallgrim/IliasXMLCreator/multi.py +++ b/hallgrim/IliasXMLCreator/multi.py @@ -2,6 +2,7 @@ import xml.etree.ElementTree as et from hallgrim.IliasXMLCreator.xmlBuildingBlocks import * + class MultipleChoiceQuestion: """docstring for MultipleChoiceQuestion""" def __init__(self, type, description, question_text, author, title, maxattempts, questions, feedback, shuffle=True): @@ -30,7 +31,7 @@ class MultipleChoiceQuestion: subroot = et.Element('qtimetadata') subroot.append(qtimetadatafield('ILIAS_VERSION', '5.1.8 2016-08-03')) subroot.append(qtimetadatafield('QUESTIONTYPE', self.type)) - subroot.append(qtimetadatafield('AUTHOR', self.author)) + subroot.append(qtimetadatafield('AUTHOR', self.author)) subroot.append(qtimetadatafield('additional_cont_edit_mode', 'default')) subroot.append(qtimetadatafield('externalId', '99.99')) subroot.append(qtimetadatafield('thumb_size', None)) @@ -62,11 +63,11 @@ class MultipleChoiceQuestion: def resprocessing(self): root = et.Element('resprocessing') outcomes = et.Element('outcomes') - outcomes.append(simple_elemet('decvar')) + outcomes.append(simple_element('decvar')) root.append(outcomes) for i, (_, correct, points) in enumerate(self.questions): - root.append(respcondition(points if correct else 0, i, True)) - root.append(respcondition(points if not correct else 0, i, False)) + root.append(respcondition(points if correct else 0, 'MCMR', i, True)) + root.append(respcondition(points if not correct else 0, 'MCMR', i, False)) return root ### returns the final object ############################################### @@ -78,8 +79,8 @@ class MultipleChoiceQuestion: 'maxattempts': self.maxattempts }) - item.append(simple_elemet('description', text=self.description)) - item.append(simple_elemet('duration', text='P0Y0M0DT0H30M0S')) # 30 min + item.append(simple_element('description', text=self.description)) + item.append(simple_element('duration', text='P0Y0M0DT0H30M0S')) # 30 min item.append(self.itemmetadata) item.append(self.presentation) item.append(self.resprocessing) diff --git a/hallgrim/IliasXMLCreator/packer.py b/hallgrim/IliasXMLCreator/packer.py index 0226593..f3cccb6 100644 --- a/hallgrim/IliasXMLCreator/packer.py +++ b/hallgrim/IliasXMLCreator/packer.py @@ -1,7 +1,6 @@ import xml.etree.ElementTree as et -from hallgrim.IliasXMLCreator import multi, single - +from hallgrim.IliasXMLCreator import multi, single, gap def create_xml_tree(item_list): root = et.Element('questestinterop') @@ -16,6 +15,8 @@ def convert_and_print(data, output, instances=1): item_list = [multi.MultipleChoiceQuestion(**data)() for _ in range(instances)] if data['type'] == 'SINGLE CHOICE QUESTION': item_list = [single.SingleChoiceQuestion(**data)() for _ in range(instances)] + if data['type'] == 'CLOZE QUESTION': + item_list = [gap.GapQuestion(**data)() for _ in range(instances)] tree = create_xml_tree(item_list) tree.write(output, encoding="utf-8", xml_declaration=True) diff --git a/hallgrim/IliasXMLCreator/single.py b/hallgrim/IliasXMLCreator/single.py index e69b9a5..747fd68 100644 --- a/hallgrim/IliasXMLCreator/single.py +++ b/hallgrim/IliasXMLCreator/single.py @@ -10,8 +10,8 @@ class SingleChoiceQuestion(MultipleChoiceQuestion): def resprocessing(self): root = et.Element('resprocessing') outcomes = et.Element('outcomes') - outcomes.append(simple_elemet('decvar')) + outcomes.append(simple_element('decvar')) root.append(outcomes) for i, (_, correct, points) in enumerate(self.questions): - root.append(respcondition(points if correct else 0, i, True)) + root.append(respcondition(points if correct else 0, 'MCSR', i, True)) return root diff --git a/hallgrim/IliasXMLCreator/xmlBuildingBlocks.py b/hallgrim/IliasXMLCreator/xmlBuildingBlocks.py index 428f184..c35ebac 100644 --- a/hallgrim/IliasXMLCreator/xmlBuildingBlocks.py +++ b/hallgrim/IliasXMLCreator/xmlBuildingBlocks.py @@ -10,7 +10,14 @@ import xml.etree.ElementTree as et ########################################################################## -def simple_elemet(name, text=None, attrib={}): +def xml_print(element, **kwargs): + import xml.dom.minidom + + xml = xml.dom.minidom.parseString(et.tostring(element, encoding='utf8', method='xml')) # or xml.dom.minidom.parseString(xml_string) + print( xml.toprettyxml(), **kwargs ) + + +def simple_element(name, text=None, attrib={}): if not text: return et.Element(name, attrib=attrib) node = et.Element(name, attrib=attrib) @@ -20,14 +27,14 @@ def simple_elemet(name, text=None, attrib={}): def qtimetadatafield(label, entry): root = et.Element('qtimetadatafield') - root.append(simple_elemet('fieldlabel', text=label)) - root.append(simple_elemet('fieldentry', text=entry)) + root.append(simple_element('fieldlabel', text=label)) + root.append(simple_element('fieldentry', text=entry)) return root def material(content): material = et.Element('material') - material.append(simple_elemet( + material.append(simple_element( 'mattext', text=content, attrib={'texttype': 'text/xhtml'} @@ -40,14 +47,16 @@ def response_label(content, count): response_label.append(material(content)) return response_label +def displayfeedback(gap=False): + pass -def respcondition(points, count, correct=True): +def respcondition(points, respident, count, correct=True): root = et.Element('respcondition', attrib={'continue': 'Yes'}) conditionvar = et.Element('conditionvar') - varequal = simple_elemet( + varequal = simple_element( 'varequal', text=str(count), - attrib={'respident': 'MCMR'} + attrib={'respident': respident} ) if correct: @@ -59,7 +68,7 @@ def respcondition(points, count, correct=True): root.append(conditionvar) - setvar = simple_elemet( + setvar = simple_element( 'setvar', text=str(points), attrib={'action': 'Add'} @@ -85,30 +94,63 @@ def itemfeedback(ident, content='NONE'): return root ### gap specific ######################################################### +def respcondition_gap(points, resp_count, answer, count=0): + root = et.Element('respcondition', attrib={'continue': 'Yes'}) + conditionvar = et.Element('conditionvar') + varequal = simple_element( + 'varequal', + text=answer, + attrib={'respident': 'gap_{}'.format(resp_count)} + ) + + conditionvar.append(varequal) + setvar = simple_element( + 'setvar', + text=str(points), + attrib={'action': 'Add'} + ) + + displayfeedback = et.Element( + 'displayfeedback', + attrib={'feedbacktype': 'Response', + 'linkrefid': '{}_Response_{}'.format(resp_count, count)}) + + root.append(conditionvar) + root.append(setvar) + root.append(displayfeedback) + return root + + def material_raw(content): material = et.Element('material') - material.append(simple_elemet( + material.append(simple_element( 'mattext', text=content )) return material def response_str(ident, columns): - response_str = et.Element('response_str', attrib={'ident': indent, 'rcardinality': 'Single'}) + response_str = et.Element('response_str', attrib={'ident': ident, 'rcardinality': 'Single'}) render_fib = et.Element('render_fib', attrib={'columns': str(columns), 'fibtype': "String", 'prompt': "Box"}) response_str.append(render_fib) return response_str def response_choice(ident, answers): - response_str = et.Element('response_str', attrib={'ident': indent, 'rcardinality': 'Single'}) + response_str = et.Element('response_str', attrib={'ident': str(ident), 'rcardinality': 'Single'}) render_choice = et.Element('render_choice', attrib={'shuffle': 'Yes'}) - for i, answer in enumerate(answers): + response_str.append(render_choice) + for i, (answer, _) in enumerate(answers): response_label = et.Element('response_label', attrib={'ident': str(i)}) response_label.append(material_raw(answer)) + render_choice.append(response_label) return response_str def response_num(ident, columns, _min, _max, numtype='Decimal'): response_num = et.Element('response_num', attrib={'ident': ident, 'numtype': numtype, 'rcardinality': 'Single'}) render_fib = et.Element('render_fib', attrib={'columns': columns, 'fibtype': numtype, 'maxnumber': _min, 'minnumber': _max, 'prompt': "Box"}) response_num.append(render_fib) - return response_num \ No newline at end of file + return response_num + + +# xml_print(response_choice(2, ['a', 'b', 'c'])) + diff --git a/hallgrim/parser.py b/hallgrim/parser.py index b9c5c55..0ad49d0 100644 --- a/hallgrim/parser.py +++ b/hallgrim/parser.py @@ -4,16 +4,25 @@ try: from mistune import Renderer, InlineLexer, Markdown, escape from pygments import highlight from pygments.lexers import get_lexer_by_name - from pygments.formatters import html, HtmlFormatter + from pygments.formatters import HtmlFormatter except ImportError as err: print("Please install mistune to make use of markdown parsing.") print("\t pip install mistune") +## TODO get lexer elsewhere + + +no_copy = "-webkit-touch-callout: none; \ + -webkit-user-select: none; \ + -khtml-user- select: none; \ + -moz-user-select: none;\ + -ms-user-select: none;\ + user-select: none;" -no_copy = "-webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;" def box(content, color): - return '<div style="background-color: #ffedc9; border: 1px solid {}; padding: 10px; font-size: smaller;">{}</div>'.format(color, content) + return '<div style="background-color: #ffedc9; border: 1px solid {}; \ + padding: 10px; font-size: smaller;">{}</div>'.format(color, content) def yellow_box(content): @@ -23,11 +32,13 @@ def yellow_box(content): def blue_box(content): return box(content, '#9999ff') + def markdown(value): renderer = HighlightRenderer() markdown = Markdown(renderer=renderer) return markdown(value) + class LaTeXRenderer(Renderer): def latex(self, formula): @@ -56,7 +67,7 @@ class LaTeXInlineLexer(InlineLexer): self.default_rules.insert(3, 'latex') def output_latex(self, m): - formula = m.group(1) + formula = m.group(1).replace('\n', ' ') return self.renderer.latex(formula) @@ -68,6 +79,9 @@ def get_custom_markdown(): inline.enable_latex() return Markdown(renderer, inline=inline) +markdown = get_custom_markdown() + + def choice_parser(raw_choices, points): """ Parse the multiple choice answers and form an array that has the @@ -85,8 +99,26 @@ def choice_parser(raw_choices, points): final = [( markdown(text), True if mark != ' ' else False, - float(mark) if mark not in ' X' else points) for mark, text in parse] + float(mark) if mark not in ' X' else points) + for mark, text in parse] return final +def gap_parser(task): + r = re.compile('\[select\]([\w\W]+?)\[\/select\]', re.MULTILINE) + m = re.findall(r, task) -markdown = get_custom_markdown() + final = [] + for s in m: + lines = s.strip().split('\n') + regex = re.compile('\[(\d|X| )\]\s+([\w\W]+)', re.MULTILINE) + parse = [re.search(regex, line).groups() for line in lines] + final.append([(text.strip(), float(points) if not points == ' ' else 0) for points, text in parse]) + + sep = ' !"§$%&/(XCVBNM; ' + no_gaps = re.sub(r, sep, task) + text_only = [markdown(text) for text in no_gaps.split(sep)] + + for i, s in enumerate(final): + text_only.insert(2*i+1, (s, -1)) + + return text_only diff --git a/scripts/feldarbeit_param.py b/scripts/feldarbeit_param.py new file mode 100644 index 0000000..b803eca --- /dev/null +++ b/scripts/feldarbeit_param.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- + +from random import shuffle, sample + +meta = { + 'author': 'Jan Maximilian Michal', + 'title': 'Feldarbeit (I1-ID: p0kaixs0lyg0)', + 'type': 'single choice', + 'points': 1, # per correct choice +} + + +def list_to_str(lst): + return str(lst).strip('[]') + + +N = 8 +a = sample(range(20), N) +o = list(a) +for i in range(N): + a[i] = a[(i + 1) % N] + +c = a[:-1] + [o[0]] + +task = """ +Welche Ausgabe erzeugt folgender Code: + +```java +public class Feldarbeit { + public static void main(String[] args) { + int[] a = { %s }; + int N = a.length; + for (int i = 0; i < N; i++) { + a[i] = a[(i+1) %% N]; + } + for (int i = 0; i < N; i++) + System.out.print(a[i] + " "); + System.out.println(); + } +} +``` +""" % list_to_str(o) + +choices = """ +[4] `%s` +[2] `%s` +[ ] `1 1 1 1 1 1 1 1` +[ ] `%s` +""" % (list_to_str(a), list_to_str(c), list_to_str(shuffle(o))) + +feedback = """ + +Betrachten Sie die folgenden Zeilen: +```java +for (int i = 0; i < N; i++) { + a[i] = a[(i+1) %% N]; +} +``` + +Der Inhalt jeder Zelle des Arrays jeweils durch den linken Nachbarn ersetzt, +wobei an den Rändern zyklisch verfahren wird. Dadurch, dass *in-place* verfahren +wird, also keine Kopie erstellt wird, wird der neue Inhalt der 0. Zelle in die +letzte geschrieben, daher enthält das neue Array keine %d mehr.""" % o[0] diff --git a/scripts/nur_sterne_sehen.py b/scripts/nur_sterne_sehen.py new file mode 100644 index 0000000..8f7473e --- /dev/null +++ b/scripts/nur_sterne_sehen.py @@ -0,0 +1,42 @@ +meta = { + 'author': 'Jan Maximilian Michal', + 'title': 'Nur Sterne sehen (I1-ID: cgu8rno0kyg0)', + 'type': 'single choice', + 'points': 1, # per correct choice +} + +task = """ + +Das folgende Programm (nach [Sedgewick/Wayne]) erzeugt als Ausgaben mehrere +Zeilen mit Ziffern (hier genau vier): + +```java +public class Ruler { + public static void main(String[] args) { + String ruler1 = "1"; System.out.println(ruler1); + String ruler2 = ruler1 + "2" + ruler1; System.out.println(ruler2); + String ruler3 = ruler2 + "3" + ruler2;or System.out.println(ruler3); + String ruler4 = ruler3 + "4" + ruler3; System.out.println(ruler4); + // usw. + } +}``` + +Wäre `main` auf genügend Codezeilen nach dem gleichen Schema ergänzt, wieviele +Zahlen würde bei Ausführung die n-te Ausgabezeile enthalten? """ + +choices = """ +[ ] [[n]] +[4] [[2^n−1]] +[ ] [[2^n]] +[ ] [[2n+1]]""" + +feedback = r""" Die erste Zeile ergibt genau die Ausgabe `1`. In jeder folgenden +Zeile wird die Anzahl der Zahlen verdoppelt und um eine weitere Zahl ergänzt. +Die Anzahl der Zahlen [[a_n]] im Schritt [[n]] ist daher: [[a_n = 2a_{n-1} + +1]]. +Als natürlche Folge ergibt sich: + +* [[S_n = a_0 + 2a_0 + 4a_0 + \dots + 2^{n-1}a_0 = a_0 (2^n - 1)]] + +Weil [[a_0 = 1]] ist [[2^n−1]] die korrekte Antwort. +""" \ No newline at end of file diff --git a/scripts/originale_kopien.py b/scripts/originale_kopien.py new file mode 100644 index 0000000..cf03214 --- /dev/null +++ b/scripts/originale_kopien.py @@ -0,0 +1,33 @@ +meta = { + 'author': 'Jan Maximilian Michal', + 'title': 'Originale Kopien? (I1-ID: 0c05by80syg0)', + 'type': 'multiple choice', + 'points': 0.5, # per correct choice +} + + +task = """ `a`, `b` sind Variablen vom Typ `char[]` und `c`, `d` sind Variablen +vom Typ `String`. `a`, `b`, `c` und `d` sind bereits korrekt mit Zeichenfolgen +der Länge 2 initialisiert (d.h. die jeweiligen Felder/Strings belegen +Speicherplatz und man kann auf ihre Inhalte zugreifen). Welcher Code ist +geeignet, um festzustellen, ob die in a und b bzw. in c und d gespeicherten +Zeichenfolgen gleich sind? """ + +# Antworten bitte aus drop-down-Menü wählen lassen: +# Auswahl jeweils geeignet/nicht geeignet + +choices = """ +[ ] `if (a == b) ...` +[ ] `if (a.equals(b)) ...` +[ ] `if (a[0] == b[0] || a[1] == b[1]) ...` +[X] `if (a[0] == b[0] && a[1] == b[1]) ...` +[ ] `if (c == d) ...` +[X] `if (c.equals(d)) ...` +[X] `if (c.compareTo(d) == 0) ...` +[ ] `if (c[0] == d[0] && c[1] == d[1]) ...` +""" + +feedback = """ + +""" + diff --git a/scripts/zeilen_sind_anders.py b/scripts/zeilen_sind_anders.py new file mode 100644 index 0000000..4aefe5d --- /dev/null +++ b/scripts/zeilen_sind_anders.py @@ -0,0 +1,105 @@ +meta = { + 'author': 'Jan Maximilian Michal', + 'title': 'Zeilen sind anders, Spalten auch (I1-ID: lhu27691fzg0)', + 'type': 'gap', +} + + +gap_1 = """[select] +[1] int n_ze = m.length; +[ ] int n_ze = m[0].length; +[ ] int n_ze = m.length(); +[ ] int n_ze = m[0].length(); +[/select]""" + +gap_2 = """[select] +[ ] int n_sp = m.length(); +[ ] int n_sp = m[0].length(); +[ ] int n_sp = m.length; +[1] int n_sp = m[0].length; +[/select]""" + +gap_3 = """[select] +[ ] for (int i = 1; i <= n_ze; i++) +[1] for (int i = 0; i < n_ze; i++) +[ ] for (int i = 1; i <= n_sp; i++) +[ ] for (int i = 0; i < n_sp; i++) +[/select]""" + +gap_4 = """[select] +[ ] ms[i] = ms[i] + m[j][i]*s[i]; +[ ] ms[i] = ms[i] + m[i][j]*s[i]; +[ ] ms[i] = ms[i] + m[j][i]*s[j]; +[1] ms[i] = ms[i] + m[i][j]*s[j]; +[/select]""" + + +task = """ Folgendes Codefragment soll die Multiplikation eines Zeilenvektors mit einer Matrix sowie einer Matrix mit einem Spaltenvektor realisieren. Wählen Sie die fehlenden Zeilen unten entsprechend aus: + +```java +01: int[][] m = {{ 0, 1, 2, 3}, // Matrix +02: { 4, 5, 6, 7}, +03: {8, 9, 10, 11}}; +04: int[] z = { 12, 13, 14}; // Zeile +05: int[] s = {15, 16, 17, 18}; // Spalte +06: +07: /* CODEZEILE AUSWÄHLEN */ // Zeilenanzahl der Matrix +08: /* CODEZEILE AUSWÄHLEN */ // Spaltenanzahl der Matrix +09: +10: /* 1: Zeile mal Matrix */011: int[] zm = new int[n_sp]; +12: for (int j = 0; j < n_sp; j++) { +13: zm[j] = 0; +14: /* CODEZEILE AUSWÄHLEN */ +15: zm[j] = zm[j] + z[i]*m[i][j]; +16: } +17: /* 2: Matrix mal Spalte */ +18: int[] ms = new int[n_ze]; +19: for (int i = 0; i < n_ze; i++) { +20: ms[i] = 0; +21: for (int j = 0; j < n_sp; j++) +22: /* CODEZEILE AUSWÄHLEN */ +23: +``` + +**Zeile 7:** +%s + +**Zeile 8:** +%s + +**Zeile 14:** +%s + +**Zeile 22:** +%s +""" % (gap_1, gap_2, gap_3, gap_4) + +feedback = """ + +Der vollständige Code: + +```java +int[][] m = {{ 0, 1, 2, 3}, // Matrix + { 4, 5, 6, 7}, + {8, 9, 10, 11}}; +int[] z = { 12, 13, 14}; // Zeile +int[] s = {15, 16, 17, 18}; // Spalte + +int n_ze = m.length; // Zeilenanzahl der Matrix +int n_sp = m[0].length; // Spaltenanzahl der Matrix + +/* 1: Zeile mal Matrix */011: int[] zm = new int[n_sp]; +for (int j = 0; j < n_sp; j++) { + zm[j] = 0; + for (int i = 0; i < n_ze; i++) + zm[j] = zm[j] + z[i]*m[i][j]; +} +/* 2: Matrix mal Spalte */ +int[] ms = new int[n_ze]; +for (int i = 0; i < n_ze; i++) { + ms[i] = 0; + for (int j = 0; j < n_sp; j++) + ms[i] = ms[i] + m[i][j]*s[j]; + +``` +""" \ No newline at end of file -- GitLab