Verbesserungen für ein Minigame

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mkay_93
User
Beiträge: 8
Registriert: Donnerstag 22. Juni 2017, 11:43

Hallo an alle,
da man programmieren bekanntlich nur lernt in dem man es tut, dachte ich mir ich schreibe mal ein simples Kopfrechenspiel. Das Spiel funktioniert auch ganz gut, jedoch glaube ich dass man die ganze Geschichte einfacher oder besser/eleganter hätte lösen können. Vielleicht hat ja ein etwas mehr erfahrener Programmierer als ich es bin, einen Tipp wie man sowas richtig macht.
Beste Grüße

Code: Alles auswählen

import random
random.seed()


print("Hallo wie viele Aufgaben moechtest du loesen? ")
an = input()

richtig = 0

    
# Aufgabe
for  i in range(1,an+1):
    a = random.randint(1,11)
    b = random.randint(1,11)
    operator = random.randint(1,4)
    turn = 0
    if operator == 1:
        c = a + b
        print("%s.Aufgabe: %s + %s")%(i,a,b)
    elif operator == 2:
        c = a - b
        print("%s.Aufgabe: %s - %s")%(i,a,b)
    else:
        c = a*b
        print("%s.Aufgabe: %s * %s")%(i,a,b)
    
    #Eingabe des Ergebnises und Ueberpruefung
    print("Bitte geben sie eine Loesung ein")
    
    while turn < 3: 
        z = input()
        if z == c:
            print(("%s ist richtig")%(z))
            richtig += 1
            break
        else:
            print(("%s ist falsch")%(z))
            turn += 1
    print("Das Ergebnis ist: %s")%(c)
    
print("Sie haben von %s Aufgaben %s richtig")%(i,richtig)
Zuletzt geändert von Anonymous am Donnerstag 10. August 2017, 14:55, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@mkay_93: Für Python 2 ist `input()` falsch, weil gefährlich, und die Klammern bei der ``print``-Anweisung sind falsch solange man durch den ensprechenden Import aus dem `__future__`-Modul da keine Funktion draus macht. Statt `input()` wo der Benutzer beliebe Python-Ausdrücke eingeben kann, die dann ausgeführt werden, sollte man `raw_input()` verwenden und die eingegebene Zeichenkette explizit in eine Zahl umwandeln (`int()` oder `float()`-Funktion).

Der `random.seed()`-Aufruf ist nicht nur sinnfrei, sondern kann unter umständen sogar zu weniger zufälligem Zufall führen. Also weg damit.-

Ein- oder Zweibuchstabige Namen sind selten gute Namen. Das geht bei gewissen, *sehr* geläufigen Sachen wie `i`, `j`, `k` bei ganzzahligen Lauf- oder Indexvariablen oder `x`, `y`, `z` für Koordinaten, oder bei Namen deren Gültigkeitsbereich auf *einen* Ausdruck beschränkt sind („list|dict|set comprehensions“, Generatorausdrücke, anonyme Funktionen, …). `an` hiesse aber besser `anzahl` oder `aufgabenanzahl`.

Multiplikationsaufgaben sind doppelt so wahrscheinlich wie Aufgaben zur Addition oder Subtraktion — ist das so gewollt?

Die innere ``while``-Schleife sollte auch eine ``for``-Schleife sein, dann spart man sich den Test und das manuelle erhöhen innerhalb der Schleife.

Nach der Schleife würde ich nicht `i` sonder `an` (bzw. `aufgabenanzahl`) für die Ausgabe verwenden.

Bei `operator` könnte man die Indirektion über die ”magischen” Zahlwerte überdenken und Beispielsweise `random.choice()` auf die Operationssymbole anwenden. Multiplikation zweimal, wenn das öfter gewählt werden soll. Damit wäre die Ausgabe die in allen ``if``/``elif``/``else``-Zweigen steht nur noch von `i`, `a`, und `b` abhängig, weil man das Operatorsymbol auch per Platzhalter einsetzen kann, womit man das ``print`` nur noch einmal *nach* diesem ``if``/``elif``/``else``-Konstrukt stehen haben muss. Oder davor.
mkay_93
User
Beiträge: 8
Registriert: Donnerstag 22. Juni 2017, 11:43

Hey,
danke für die gute und schnelle Antwort. Sind ja doch noch einige Dinge die ich verbessern kann, aber learning by doing :P. Hab fast alle deine Tipps umgesetzt. Dass multiplikation doppelt ist, ist nicht so gewollt... kann ich aus dem else einfach auch ein elif machen ? Ich frage mich auch ob es sinnvoll ist mit Funktionen zu arbeiten oder nach den int(raw_input) mit einer Schleife und try , except mögliche Fehler bei der Eingabe abzufangen?

Grüße
mkay
BlackJack

@mkay_93: Wenn Du ein ``elif`` aus dem ``else`` machst, was soll denn da als Bedingung hin?

Mit Funktionen zu arbeiten ist auf jeden Fall sinnvoll. Eigentlich sollte auf Modulebene kein Code stehen der nicht Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Das heisst *eine* Funktion hat man damit immer im Programm.

Und dann kann man Code in Funktionen auslagern der für sich genommen, eigenständige in sich geschlossene Aufgaben übernimmt. Beispielsweise den Benutzer nach einer Zahl zu fragen, so lange bis er eine gültige Eingabe gemacht hat.

Was man üblicherweise auch trennt ist die Programmlogik und die Benutzerinteraktion. Im Beispiel könnte man das Erzeugen der Aufgabe in eine Funktion auslagern, so dass man den Code auch in einer Webanwendung oder einer GUI wiederverwenden könnte. Da muss man sich dann auch ein bisschen Gedanken über Datenstrukturen machen. Also zum Beispiel aus welchen Daten setzt sich die benötigte Information für eine Aufgabe zusammen und wie kann man das in Python ausdrücken.
Antworten