Re: Wo liegt der Fehler?
Verfasst: Sonntag 2. Juli 2023, 16:41
Vielen Dank 

Seit 2002 Diskussionen rund um die Programmiersprache Python
https://www.python-forum.de/
Code: Alles auswählen
import random
def make_formula(formula_typ = 'sum'):
a = random.randint(1,9)
b = random.randint(1,9)
match formula_typ:
case 'sum':
return f"{a}+{b}", a+b
case 'product':
return f"{a}*{b}", a*b
print("Summen-/Produkt-Trainer (Ende mit x)")
formula_types, new = ('sum','product'), True
while True :
if new:
formula, result = make_formula(random.choice(formula_types))
answer = input(f" Wie lautet die Lösung von {formula} = ? ")
if answer.isnumeric() and int(answer) == result:
print("Die Lösung ist richtig!")
new = True
elif answer.isnumeric() and int(answer) != result:
print(f"Die Lösung ist falsch! Richtig ist {formula} = {result}.")
new = True
elif answer != 'x':
print("Bitte nur ganze Zahlen eingeben.")
new = False
else:
print("Auf Wiedersehen!")
break
Summen-/Produkt-Trainer (Ende mit x)
Wie lautet die Lösung von 3+7 = ?
Bitte nur ganze Zahlen eingeben.
Wie lautet die Lösung von 3+7 = ? 12
Die Lösung ist falsch! Richtig ist 3+7 = 10.
Wie lautet die Lösung von 3*5 = ? 15
Die Lösung ist richtig!
Wie lautet die Lösung von 1*2 = ? a
Bitte nur ganze Zahlen eingeben.
Wie lautet die Lösung von 1*2 = ? 2.0
Bitte nur ganze Zahlen eingeben.
Wie lautet die Lösung von 1*2 = ? 2
Die Lösung ist richtig!
Wie lautet die Lösung von 6+8 = ? x
Auf Wiedersehen!
Code: Alles auswählen
In [126]: "²".isnumeric()
Out[126]: True
In [127]: int("²")
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Input In [127], in <cell line: 1>()
----> 1 int("²")
ValueError: invalid literal for int() with base 10: '²'
Das sehe ich ein, guter Hinweis!__blackjack__ hat geschrieben: Sonntag 2. Juli 2023, 22:34 @Qubit: ``match``/``case`` ist mir persönlich noch zu neu, das können noch viele LTS-Distributionen nicht mit dem standardmässig installierten Python. Und das ist IMHO auch kein sinnvoller Einsatz hier. Warum kein ``if``/``elif``/``else``? ``match`` macht erst wirklich Sinn wenn man den Mehrwert dieses Konstrukts, das strukturelle ”matchen” von Werte/Strukturen verwendet. Ein ``else`` beziehungsweise ``case _:`` fehlt mir hier auch. Die Funktion sollte nicht einfach ein implizites `None` zurück geben, sondern eine Ausnahme auslösen, oder wenigstens *explizit* `None` zurückgeben.
[...]Das ist noch nicht mal wirklich exotisch, das kann ich ganz regulär über eine Taste eingeben wo das auf der Taste draufgedruckt ist.Code: Alles auswählen
In [126]: "²".isnumeric() Out[126]: True In [127]: int("²") --------------------------------------------------------------------------- ValueError Traceback (most recent call last) Input In [127], in <cell line: 1>() ----> 1 int("²") ValueError: invalid literal for int() with base 10: '²'
Code: Alles auswählen
import random
def make_formula(formula_typ = 'sum'):
a = random.randint(1,9)
b = random.randint(1,9)
return {
'sum' : (f"{a}+{b}", a+b),
'product': (f"{a}*{b}", a*b)
}.get(formula_typ)
formula_types, new = ('sum','product'), True
print("Summen-/Produkt-Trainer (Ende mit x)")
while True:
formula, result = make_formula(random.choice(formula_types))
while True:
answer = input(f" Wie lautet die Lösung von {formula} = ? ")
if answer == 'x':
new = False
break
try:
if int(answer) == result:
print("Die Lösung ist richtig!")
break
except ValueError:
print("Bitte nur ganze Zahlen eingeben.")
continue
else:
print(f"Die Lösung ist falsch! Richtig ist {formula} = {result}.")
break
if not new:
print("Auf Wiedersehen!")
break
Summen-/Produkt-Trainer (Ende mit x)
Wie lautet die Lösung von 9*6 = ?
Bitte nur ganze Zahlen eingeben.
Wie lautet die Lösung von 9*6 = ? 70
Die Lösung ist falsch! Richtig ist 9*6 = 54.
Wie lautet die Lösung von 8+2 = ? 10
Die Lösung ist richtig!
Wie lautet die Lösung von 5*8 = ?
Bitte nur ganze Zahlen eingeben.
Wie lautet die Lösung von 5*8 = ? a
Bitte nur ganze Zahlen eingeben.
Wie lautet die Lösung von 5*8 = ? 40.
Bitte nur ganze Zahlen eingeben.
Wie lautet die Lösung von 5*8 = ? 40
Die Lösung ist richtig!
Wie lautet die Lösung von 8*1 = ? x
Auf Wiedersehen!
Code: Alles auswählen
import random
def make_formula(formula_typ = 'sum'):
a = random.randint(1,9)
b = random.randint(1,9)
return {
'sum' : (f"{a}+{b}", a+b),
'product': (f"{a}*{b}", a*b)
}.get(formula_typ)
formula_types, new = ('sum','product'), True
print("Summen-/Produkt-Trainer (Ende mit x)")
while True:
formula, result = make_formula(random.choice(formula_types))
while True:
answer = input(f" Wie lautet die Lösung von {formula} = ? ")
if answer == 'x':
new = False
break
try:
is_ok = (int(answer) == result)
except ValueError:
print("Bitte nur ganze Zahlen eingeben.")
continue
else:
if is_ok:
print("Die Lösung ist richtig!")
else:
print(f"Die Lösung ist falsch! Richtig ist {formula} = {result}.")
break
if not new:
print("Auf Wiedersehen!")
break
Summen-/Produkt-Trainer (Ende mit x)
Wie lautet die Lösung von 3*4 = ?
Bitte nur ganze Zahlen eingeben.
Wie lautet die Lösung von 3*4 = ? 13
Die Lösung ist falsch! Richtig ist 3*4 = 12.
Wie lautet die Lösung von 9*1 = ? 9
Die Lösung ist richtig!
Wie lautet die Lösung von 1*5 = ? 6.0
Bitte nur ganze Zahlen eingeben.
Wie lautet die Lösung von 1*5 = ? a
Bitte nur ganze Zahlen eingeben.
Wie lautet die Lösung von 1*5 = ? x
Auf Wiedersehen!
Code: Alles auswählen
import random
def make_formula(formula_typ = 'sum'):
a = random.randint(1,9)
b = random.randint(1,9)
return { # (formula, result, points)
'sum' : (f"{a}+{b}", a+b, 2),
'product': (f"{a}*{b}", a*b, 4)
}.get(formula_typ)
formula_types = ('sum','product')
sum_points = 0
get_points = 0
nr_calcs = 0
print("Summen-/Produkt-Trainer (Ende mit x)")
while new:= True:
formula, result, points = make_formula(random.choice(formula_types))
while True:
answer = input(f"[{get_points}P] Wie lautet die Lösung von {formula} = ? ")
if answer == 'x':
new = None
break
try:
is_ok = (int(answer) == result)
except ValueError:
print("Bitte nur ganze Zahlen eingeben.")
continue
else:
nr_calcs += 1
sum_points += points
if is_ok: # richtig -> +(volle Punktzahl)
get_points += points
print(f"Die Lösung ist richtig! [+{points}P]")
else: # falsch -> -(halbe Punktzahl)
get_points -= int(points/2)
print(f"Die Lösung ist falsch! Richtig ist {formula} = {result}. [-{int(points/2)}P]")
break
if new is None:
break
print("Auf Wiedersehen!")
print(f"Du hast {nr_calcs} Frage(n) beantwort und {get_points} von {sum_points} Punkten erhalten.")
Summen-/Produkt-Trainer (Ende mit x)
[0P] Wie lautet die Lösung von 4+4 = ? 5
Die Lösung ist falsch! Richtig ist 4+4 = 8. [-1P]
[-1P] Wie lautet die Lösung von 3*9 = ? 27
Die Lösung ist richtig! [+4P]
[3P] Wie lautet die Lösung von 5+9 = ? 14
Die Lösung ist richtig! [+2P]
[5P] Wie lautet die Lösung von 3*2 = ? x
Auf Wiedersehen!
Du hast 3 Frage(n) beantwort und 5 von 8 Punkten erhalten.
Code: Alles auswählen
#!/usr/bin/env python3
import random
from operator import add, mul as multiply
CALCULATION_TYPE = [("+", add), ("*", multiply)]
def make_formula(formula_type):
symbol, operation = formula_type
a = random.randint(1, 9)
b = random.randint(1, 9)
return f"{a} {symbol} {b}", operation(a, b)
def main():
print("Summen-/Produkt-Trainer (Ende mit x)")
is_running = True
while is_running:
formula, result = make_formula(random.choice(CALCULATION_TYPE))
while True:
answer = input(f"Wie lautet die Lösung von {formula} = ? ")
if answer == "x":
is_running = False
break
try:
is_correct = int(answer) == result
except ValueError:
print("Bitte nur ganze Zahlen eingeben.")
else:
if is_correct:
print("Die Lösung ist richtig!")
else:
print(
f"Die Lösung ist falsch!"
f" Richtig ist {formula} = {result}."
)
break
print("Auf Wiedersehen!")
if __name__ == "__main__":
main()
Teilweise gebe ich dir Recht, zum anderen Teil scheint es mir aber jetzt nach einer Betrachtung nach Gusto.__blackjack__ hat geschrieben: Montag 3. Juli 2023, 10:44 Edit: Bezog sich alles auf den vorletzten Beitrag. Jetzt zum letzen: ``while new := True:`` ist umständlich für ``while True:``. Das `new` macht da keinen Sinn.
`sum_points` und `get_points` wären Funktionsnamen. Das zweite sollte eher `total_points` heissen, das erste eher `max_points` or `max_reachable_points`.
`nr_calcs` besteht aus zwei Abkürzungen und dazu noch aus einer Deutschen und einer Englischen. `number` abgekürzt ist `no`. Und `no` ist problematisch weil es für sich selbst eine Bedeutung hat und deshalb verwirrend werden kann. `calculation_count` oder `question_count` würde ich da verwenden.
Statt ``int(points/ 2)`` könnte man auch ``points // 2`` schreiben.
Die Punkte pro Aufgabentyp liessen sich in die Tupel aus der Lösung weiter oben einfach einbauen. So anonyme Tupel mit drei Werten sind dann aber für meinen Geschmack auch langsam die Grenze wo man besser auf `collections.namedtuple()` oder eine eigene Klasse umsteigt.
Code: Alles auswählen
# -*- coding: utf-8 -*-
import random
import math
def make_formula(formula_type = 'sum'):
a = random.randint(1,9)
b = random.randint(1,9)
c = random.randint(1,9)
return { # (formula, result, points)
'sum' : (f"{a}+{b}", a+b, 2),
'product' : (f"{a}*{b}", a*b, 4),
'squareroot': (f"√({a**2})",int(math.sqrt(a**2)), 6),
'mixed' : (f"{a}+{b}*{c}",a+b*c, 6)
}.get(formula_type)
def formel_trainer(*types):
formula_types = (types) if types else ('sum',)
max_points = 0
total_points = 0
number_of_calcs = 0
min_number_of_calcs = 5
operations_de = {'sum': 'Summen', 'product': 'Produkte', 'squareroot': 'Wurzel'}
opertion_names = '/'.join(map(lambda x: operations_de.get(x,x),formula_types))
print(f"{opertion_names}-Trainer (Ende mit x)")
while new:= True:
formula, result, points = make_formula(random.choice(formula_types))
retry_bad_answers = 3
while True:
answer = input(f"[{total_points}P] Wie lautet die Lösung von {formula} = ? ")
if answer == 'x':
new = None
break
try:
is_ok = (int(answer) == result)
except ValueError:
print("FEHLER: Bitte nur ganze Zahlen eingeben.")
retry_bad_answers -= 1
if retry_bad_answers == 0:
print("FEHLER: 3 falsche Eingaben. Neue Aufgabe..")
break
#continue
else:
number_of_calcs += 1
max_points += points
if is_ok: # richtig -> +(volle Punktzahl)
total_points += points
print(f"Die Lösung ist richtig! [+{points}P]")
else: # falsch -> -(halbe Punktzahl)
total_points -= points//2
print(f"Die Lösung ist falsch! Richtig ist {formula} = {result}. [-{points//2}P]")
break
if new is None:
if number_of_calcs >= min_number_of_calcs:
break
else:
print(f"Du sollst mindestens {min_number_of_calcs} Aufgaben rechnen! {number_of_calcs} Aufgabe(n) hast Du bisher gerechnet.")
print("Auf Wiedersehen!")
print(f"Du hast {number_of_calcs} Frage(n) beantwort und {total_points} von {max_points} Punkten erhalten.")
if __name__=='__main__':
formel_trainer('sum','product','squareroot','mixed')
Summen/Produkte/Wurzel/mixed-Trainer (Ende mit x)
[0P] Wie lautet die Lösung von √(9) = ? 3
Die Lösung ist richtig! [+6P]
[6P] Wie lautet die Lösung von 3*5 = ? 234
Die Lösung ist falsch! Richtig ist 3*5 = 15. [-2P]
[4P] Wie lautet die Lösung von 9+7*2 = ? x
Du sollst mindestens 5 Aufgaben rechnen! 2 Aufgabe(n) hast Du bisher gerechnet.
[4P] Wie lautet die Lösung von √(64) = ?
FEHLER: Bitte nur ganze Zahlen eingeben.
[4P] Wie lautet die Lösung von √(64) = ? 5
Die Lösung ist falsch! Richtig ist √(64) = 8. [-3P]
[1P] Wie lautet die Lösung von 6*7 = ? 42
Die Lösung ist richtig! [+4P]
[5P] Wie lautet die Lösung von 1*7 = ? x
Du sollst mindestens 5 Aufgaben rechnen! 4 Aufgabe(n) hast Du bisher gerechnet.
[5P] Wie lautet die Lösung von 4*4 = ? 16
Die Lösung ist richtig! [+4P]
[9P] Wie lautet die Lösung von 1+3 = ? x
Auf Wiedersehen!
Du hast 5 Frage(n) beantwort und 9 von 24 Punkten erhalten.
Code: Alles auswählen
#!/usr/bin/env python3
import random
from operator import add, mul as multiply
from attr import attrib, attrs
END_INPUT = "x"
RETRY_COUNT = 3
MIN_ANSWERED_QUESTIONS_COUNT = 5
class RetryCountExceeded(Exception):
pass
@attrs(frozen=True)
class Points:
value = attrib(default=0)
max_value = attrib(default=0)
def __str__(self):
return f"{self.value} von {self.max_value}"
def __add__(self, other):
return Points(
self.value + other.value, self.max_value + other.max_value
)
@attrs(frozen=True)
class Question:
text = attrib()
answer = attrib()
points = attrib()
@attrs(frozen=True)
class CalculationType:
name = attrib()
template = attrib()
calculate = attrib()
points = attrib()
prepare = attrib(default=lambda *operands: operands)
def create_question(self):
operands = [
random.randint(1, 9) for _ in range(self.template.count("{}"))
]
return Question(
self.template.format(*self.prepare(*operands)),
self.calculate(*operands),
self.points,
)
CALCULATION_TYPES = [
CalculationType("Summen", "{} + {}", add, 2),
CalculationType("Produkte", "{} × {}", multiply, 4),
CalculationType("Wurzeln", "√({})", lambda a: a, 6, lambda a: [a**2]),
CalculationType("Mixed", "{} + {} × {}", lambda a, b, c: a + b * c, 6),
]
def ask_result(prompt):
for _ in range(RETRY_COUNT):
answer = input(prompt)
if answer == END_INPUT:
raise KeyboardInterrupt()
try:
return int(answer)
except ValueError:
print("FEHLER: Bitte nur ganze Zahlen eingeben.")
raise RetryCountExceeded()
def ask_question(total_points):
question = random.choice(CALCULATION_TYPES).create_question()
assert question.answer != END_INPUT
try:
result = ask_result(
f"[{total_points.value}P]"
f" Wie lautet die Lösung von {question.text} = "
)
except RetryCountExceeded:
print(f"FEHLER: {RETRY_COUNT} falsche Eingaben. Neue Aufgabe…")
return None
else:
if result == question.answer:
points = question.points
text = "Die Lösung ist richtig!"
else:
points = -(question.points // 2)
text = (
f"Die Lösung ist falsch!"
f" Richtig ist {question.text} = {question.answer}."
)
print(f"{text} [{'' if points < 0 else '+'}{points}P]")
return Points(points, question.points)
def ask_questions():
answered_questions_count = 0
total_points = Points()
while True:
try:
points = ask_question(total_points)
if points is not None:
answered_questions_count += 1
total_points += points
except KeyboardInterrupt:
if answered_questions_count >= MIN_ANSWERED_QUESTIONS_COUNT:
break
print(
f"Du musst mindestens {MIN_ANSWERED_QUESTIONS_COUNT}"
f" Aufgaben rechnen! {answered_questions_count} Aufgabe(n)"
f" hast Du bisher gerechnet."
)
return answered_questions_count, total_points
def main():
operation_names = "/".join(
calculation_type.name for calculation_type in CALCULATION_TYPES
)
print(f"{operation_names}-Trainer (Ende mit {END_INPUT!r})")
answered_questions_count, points = ask_questions()
print("Auf Wiedersehen!")
print(
f"Du hast {answered_questions_count} Frage(n) beantwortet und"
f" {points} Punkten erhalten."
)
if __name__ == "__main__":
main()