diff --git a/aufgabengenerator_formulas_fraction_new.py b/aufgabengenerator_formulas_fraction_new.py
index 953a6eb..d113bda 100644
--- a/aufgabengenerator_formulas_fraction_new.py
+++ b/aufgabengenerator_formulas_fraction_new.py
@@ -15,13 +15,15 @@ ops = {
# Konstanten
# Anzahl der zu generierenden Fragen.
-NUM_QUESTIONS = 1
+NUM_QUESTIONS = 5
# Algebraische Struktur der Aufgaben
-STRUCTURE = "-(+)-"
+STRUCTURE = "(-)-(+(-))"
+# Gleiche Nenner erlauben
+# TODO
# Größter Zähler
-MAX_NUMERATOR = 20
+MAX_NUMERATOR = 10
# Größter Nenner
-MAX_DENOMINATOR = 20
+MAX_DENOMINATOR = 8
# Größter erlaubter gemeinsamer Nenner
MAX_COMMON_DENOMINATOR = 100
# Dateiname für Ausgabe
@@ -36,18 +38,18 @@ def parse_expression(expression):
max_depth = 0
for i, char in enumerate(expression):
- if char == '(':
- paren_count += 1
- elif char == ')':
- paren_count -= 1
-
- # Update max depth when a closed parenthesis is encountered
- max_depth = max(max_depth, paren_count)
+ # if char == '(':
+ # paren_count += 1
+ # elif char == ')':
+ # paren_count -= 1
+ #
+ # # Update max depth when a closed parenthesis is encountered
+ # max_depth = max(max_depth, paren_count)
if char in ops.keys():
op_count += 1
- return max_depth + op_count
+ return max_depth + op_count + 1
# Anzahl der benötigten Brüche
NUM_FRACTIONS = parse_expression(STRUCTURE)
@@ -87,7 +89,7 @@ def add_placeholders(expression):
need_placeholder = False # Nach einem Platzhalter sollten wir keinen weiteren setzen
# Platzhalter am Beginn hinzufügen
- if output and output[0] != f'n{0}':
+ if output and not (output[0] == f'n{0}' or output[0] == '('):
result = [placeholder_generator()] + output
else:
result = output
@@ -99,6 +101,7 @@ def add_placeholders(expression):
# Zusammensetzen des finalen Ausdrucks
final_expression = ''.join(result).strip()
+ print(final_expression)
return final_expression
@@ -119,6 +122,54 @@ def calculate(expression, numbers):
# Evaluate the result
return eval(expression)
+def gen_calculate_string(expression :str, liststring :str):
+ # Replace placeholders with actual number values
+ for i in range(NUM_FRACTIONS):
+ placeholder = f'n{i}'
+ expression = re.sub(rf'\{placeholder}\s*([+-/*])', rf'{liststring}[{i}] \1', expression)
+ expression = re.sub(rf'({placeholder})\s*', rf'{liststring}[{i}]', expression)
+
+ print(expression)
+ # Return the changed expression
+ return expression
+
+def gen_latex_calculate_string(expression :str, liststring: str):
+ # Replace placeholders with actual number values
+ for i in range(NUM_FRACTIONS):
+ placeholder = f'n{i}'
+ replacement = liststring[i]
+ print(replacement)
+ expression = re.sub(rf'\{placeholder}\s*([+-/*])', replacement, expression)
+ expression = re.sub(rf'({placeholder})\s*', replacement, expression)
+
+ # Klammern anpassen
+ expression = re.sub(rf'\(', u'\\\\left(', expression)
+ expression = re.sub(rf'\)', u'\\\\right)', expression)
+ # print(expression)
+ # Return the changed expression
+ return expression
+
+def create_html_table_for_fracture_input(rows: list):
+ table_rows = []
+ # Tabellenzeilen festlegen
+ for i, row in enumerate(rows):
+ if (i % 2) == 0:
+ table_row = "
"
+ else:
+ table_row = "
"
+
+ for cell in row:
+ table_row += f"{cell} | "
+
+ table_row += "
"
+ table_rows.append(table_row)
+
+ # Tabelle zusammenbauen
+ table_html = f"\n" + "\n".join(table_rows) + "
"
+
+ return table_html
+
+
def create_formula_question(ex_number: int):
numerators = []
denominators = []
@@ -132,7 +183,12 @@ def create_formula_question(ex_number: int):
same_denominators = [k for k,v in Counter(denominators).items() if v>1]
while len(same_denominators) > 1:
new_denom = random.randint(2, MAX_DENOMINATOR)
- denominators.replace(same_denominators[0], new_denom)
+ try:
+ index = denominators.index(same_denominators[0])
+ denominators[index] = new_denom
+ except ValueError:
+ pass
+ # denominators.replace(same_denominators[0], new_denom)
same_denominators = [k for k,v in Counter(denominators).items() if v>1]
# [DEBUG]
print(numerators)
@@ -165,11 +221,12 @@ def create_formula_question(ex_number: int):
result_numerator = calculate(STRUCTURE_PH, expanded_numerators)
# [DEBUG]
print(result_numerator)
+ print(cd)
# [DEBUG]
gcd_result = gcd(result_numerator, cd)
if gcd_result > 1:
- # print("kürzbar")
+ print("kürzbar")
shortable = True
shortened_numerator = result_numerator // gcd_result
shortened_denominator = common_denominator // gcd_result
@@ -186,16 +243,16 @@ def create_formula_question(ex_number: int):
has_div = '/' in STRUCTURE
if has_plus and has_minus:
- expression_type = "Addition/Subtraktion"
+ expression_type = "Addition/Subtraktion" + f" ({STRUCTURE})"
exercise_text = "Berechne den Term"
elif has_plus:
- expression_type = "Addition"
+ expression_type = "Addition" + f" ({STRUCTURE})"
exercise_text = "Addiere die Brüche"
elif has_minus:
- expression_type = "Subtraktion"
+ expression_type = "Subtraktion" + f" ({STRUCTURE})"
exercise_text = "Subtrahiere die Brüche"
else:
- expression_type = "Rechnung"
+ expression_type = "Rechnung" + f" ({STRUCTURE})"
exercise_text = "Berechne den Term"
name_elem = ET.SubElement(question, 'name')
text_elem = ET.SubElement(name_elem, 'text')
@@ -272,16 +329,160 @@ def create_formula_question(ex_number: int):
ET.SubElement(answertype_elem, 'text').text = '0'
numbox_elem = ET.SubElement(answers_elem, 'numbox')
ET.SubElement(numbox_elem, 'text').text = '2'
- return question
+
# Berechnungsvariablen
+ # common divisor
+ cdtext = ""
+ for i in range(NUM_FRACTIONS):
+ if i == 0:
+ pass
+ elif i == 1:
+ cdtext += f"cd{i} = lcm(d[{i}],d[{i-1}]);"
+ else:
+ cdtext += f"cd{i} = lcm(cd{i-1}, d[{i}]);"
+ cdtext += f"cd = cd{NUM_FRACTIONS-1};"
+
+ # expansions
+ extext = "e = ["
+ for i in range(NUM_FRACTIONS):
+ extext += f"cd / d[{i}],"
+ extext = extext[:-1]
+ extext += "];"
+
+ # expanded_numerators
+ entext = "ens = ["
+ for i in range(NUM_FRACTIONS):
+ entext += f"n[{i}]*e[{i}],"
+ entext = entext[:-1]
+ entext += "];"
+
+ # result numerator
+ resnum = "resnum = " + gen_calculate_string(STRUCTURE_PH, "ens") + ";"
+
+ # gcd of result numerator and result (common) denominator
+ resgcd = "resgcd = gcd(resnum, cd);"
+
+ # shortened result numerator
+ sresnum = "sresnum = resnum / resgcd;"
+
+ # shortened result denominator
+ sresden = "sresden = cd / resgcd;"
+
vars1_elem = ET.SubElement(answers_elem, 'vars1')
if shortable:
- vars1_elem_text = ""
+ vars1_elem_text = f""
else:
- vars1_elem_text = ""
+ vars1_elem_text = f""
ET.SubElement(vars1_elem, 'text').text = vars1_elem_text
+ # Antwort
+ answer_elem = ET.SubElement(answers_elem, 'answer')
+ if shortable:
+ answer_text = '[resnum, cd, sresnum, sresden]'
+ else:
+ answer_text = '[resnum, cd]'
+ ET.SubElement(answer_elem, 'text').text = answer_text
+
+ answernotunique_elem = ET.SubElement(answers_elem, 'answernotunique')
+ ET.SubElement(answernotunique_elem, 'text').text = '0'
+
+ vars2_elem = ET.SubElement(answers_elem, 'vars2')
+ if shortable:
+ vars2_elem_text = ""
+ else:
+ vars2_elem_text = ""
+ ET.SubElement(vars2_elem, 'text').text = vars2_elem_text
+
+ correctness_elem = ET.SubElement(answers_elem, 'correctness')
+ if shortable:
+ ET.SubElement(correctness_elem, 'text').text = '0.25*ga + 0.25*gb + 0.25*gsa + 0.25*gsb'
+ else:
+ ET.SubElement(correctness_elem, 'text').text = '0.5*ga + 0.5*gb'
+
+ unitpenalty_elem = ET.SubElement(answers_elem, 'unitpenalty')
+ ET.SubElement(unitpenalty_elem, 'text').text = '1'
+
+ postunit_elem = ET.SubElement(answers_elem, 'postunit')
+ ET.SubElement(postunit_elem, 'text').text = ' '
+
+ ruleid_elem = ET.SubElement(answers_elem, 'ruleid')
+ ET.SubElement(ruleid_elem, 'text').text = '1'
+
+ otherrule_elem = ET.SubElement(answers_elem, 'otherrule')
+ ET.SubElement(otherrule_elem, 'text').text = ' '
+
+ # Unterfragen-Text
+ subqtext_elem = ET.SubElement(answers_elem, 'subqtext', attrib={'format': 'html'})
+
+ fractions_latex_strings = []
+ for i in range(NUM_FRACTIONS):
+ l_str = "\\\\frac{{"+ f"n[{i}]" +"}}{{"+ f"d[{i}]" +"}}"
+ fractions_latex_strings.append(l_str)
+ latex_calculation = gen_latex_calculate_string(STRUCTURE_PH, fractions_latex_strings)
+
+
+ sub_q_t_begin = "Berechne:"
+ sub_q_t_math = "\\(\\Large \\displaystyle " + f"{latex_calculation}" + "=\\)
"
+ rows_list = [
+ ["Zähler:", "{_0}"],
+ ["Nenner:", "{_1}"]
+ ]
+
+ sub_q_t_input = ' ='
+ if shortable:
+
+ sub_q_t_input += create_html_table_for_fracture_input(rows_list)
+
+ rows_list_s = [["Gekürzter Zähler:", "{_2}"],
+ ["Gekürzter Nenner:", "{_3}"]]
+ sub_q_t_input += " = "
+ sub_q_t_input += create_html_table_for_fracture_input(rows_list_s)
+
+ else:
+ sub_q_t_input += create_html_table_for_fracture_input(rows_list)
+ sub_q_t_input += '
'
+ sub_q_t_end = "]]>"
+
+ sub_question_text = sub_q_t_begin + sub_q_t_math + sub_q_t_input + sub_q_t_end
+ ET.SubElement(subqtext_elem, 'text').text = sub_question_text
+
+ expanded_fractions_latex_strings = []
+ for i in range(NUM_FRACTIONS):
+ l_str = "\\\\frac{{"+ f"ens[{i}]" +"}}{{"+ f"cd" +"}}"
+ expanded_fractions_latex_strings.append(l_str)
+ expanded_latex_calculation = gen_latex_calculate_string(STRUCTURE_PH, expanded_fractions_latex_strings)
+
+ # Lösungshinweis
+ feedback_elem = ET.SubElement(answers_elem, 'feedback', attrib={'format': 'html'})
+ if shortable:
+ feedback_text = '''Lösungshinweis
+ Die korrekte Lösung ist:
+ \\(\\displaystyle''' + f"{latex_calculation}" +" = " + f"{expanded_latex_calculation}" + ''' = \\frac{{resnum}}{{cd}} = \\frac{{sresnum}}{{sresden}} \\)
]]>'''
+ else:
+ feedback_text = '''Lösungshinweis
+ Die korrekte Lösung ist:
+ \\( \\displaystyle ''' + f"{latex_calculation}" +" = " + f"{expanded_latex_calculation}" + ''' = \\frac{{resnum}}{{cd}} \\)
]]>'''
+ ET.SubElement(feedback_elem, 'text').text = feedback_text
+
+ # correctfeedback
+
+ correctfeedback_elem = ET.SubElement(answers_elem, 'correctfeedback', attrib={'format': 'html'})
+ correctfeedback_text = '''Richtig!]]>'''
+ ET.SubElement(correctfeedback_elem, 'text').text = correctfeedback_text
+
+ # partially correct feedback
+
+ pcorrectfeedback_elem = ET.SubElement(answers_elem, 'partiallycorrectfeedback', attrib={'format': 'html'})
+ pcorrectfeedback_text = '''Teilweise richtig.]]>'''
+ ET.SubElement(pcorrectfeedback_elem, 'text').text = pcorrectfeedback_text
+
+ # incorrect feedback
+ incorrectfeedback_elem = ET.SubElement(answers_elem, 'incorrectfeedback', attrib={'format': 'html'})
+ incorrectfeedback_text = '''Leider nicht richtig.]]>'''
+ ET.SubElement(incorrectfeedback_elem, 'text').text = incorrectfeedback_text
+
+ return question
def generate_questions(num_questions):
@@ -328,6 +529,7 @@ def save_to_file(xml_element, filename):
None
"""
tree = ET.ElementTree(xml_element)
+ ET.indent(tree, space="\t", level=0)
with open(filename, 'wb') as f:
tree.write(f, encoding='utf_8', xml_declaration=True)