rock paper scissor

Code-Stücke können hier veröffentlicht werden.
Antworten
bitssalad
User
Beiträge: 7
Registriert: Montag 13. Juni 2011, 13:18

Hallo liebes Forum,

über einen Thread von Blackjack bin ich auf die Idee gekommen, mich auch mal an einem 'rock paper scissors' Game in python 3.x zu probieren. Leider bin ich noch absoluter Neuling in der programmierung und Python, deshalb denke ich das nicht alles so elegant gelöst ist, wie es vielleicht hätte sein können. Ist mein erstes wirklich "sinnvolles" Programm :-) ! Vielleicht hat jemand ein paar Anregungen und Ratschläge.

Liebe Grüße

bitssalad
Zuletzt geändert von bitssalad am Donnerstag 7. Juli 2011, 21:05, insgesamt 2-mal geändert.
Intrepid
User
Beiträge: 6
Registriert: Montag 13. Juni 2011, 14:35

Hi,
der Quellcode sieht ganz gut aus.
Was du evtl. verbessern könntest wäre,
dass du sämtliche Eingaben zwischen

Code: Alles auswählen

try:
    # Dein Code
    # z. Bsp. raw_input("y/n")
except
    print "\nSorry, error 200\n"
    game_run = False
setzt. Irgendwie funktioniert das Programm nicht richtig bei mir,
tippe ich rock ein:

File "rps.py", line 21, in <module>
usr_inp = input(str("choose rock, paper or scissors: "))
File "<string>", line 1, in <module>
NameError: name 'rock' is not defined

Deshalb hier kurz meine angepasste Version:

Code: Alles auswählen

usr_inp = raw_input("choose rock, paper or scissors: ")
....
....
....
goes_on = raw_input("play again? y/n ")
Leider bin ich noch absoluter Neuling in der programmierung und Python
Tolle Leistung ;-)
Mein erstes Programm war da ein wenig anders :D

Intrepid
bitssalad
User
Beiträge: 7
Registriert: Montag 13. Juni 2011, 13:18

Hallo intrepid,

danke erstmal für das Feedback :) !.

Code: Alles auswählen

File "rps.py", line 21, in <module>
usr_inp = input(str("choose rock, paper or scissors: "))
File "<string>", line 1, in <module>
NameError: name 'rock' is not defined
Vielelicht hätte ich erwähnen sollen, dass ich das Programm in Python 3.x geschrieben habe.
Soviel ich weiß gibt es in Python 2.x, und ich hoffe ich sage das hier jetzt richtig ( bitte sonst um Verbesserung ), keine Möglichkeit einen String im input Parameter zu übergeben. Daher wohl auch die Fehlermeldung. Da ich kein Python 2.x benutze verwende ich auch kein raw_input.

Liebe Grüße

bitssalad
Zuletzt geändert von bitssalad am Montag 13. Juni 2011, 16:28, insgesamt 1-mal geändert.
lunar

@Intrepid: Das Programm ist für Python 3 geschrieben. Mit Python 2 funktioniert es nicht, weil "input()" in Python 2 eine andere Bedeutung hat.

Was soll es bringen, alle Eingaben pauschal mit Ausnahmebehandlung zu versehen?

@bitssalad: Auf „Prüfvariablen“ wie "inp_check" würde ich verzichten, und eher eine Endlosschleife verwenden:

Code: Alles auswählen

while True:
    response = input('choose rock, paper or scissors: ')
    if response in items:
        break
    else:
        print('wrong input!')
Gilt in gleicher Form auch für die äußere Schleife und "game_run".

Die endlose if…elif…else Kaskade zur Bestimmung des Gewinners ist unschön. Überlege Dir, wie Du das abkürzen könntest. Ein Weg wäre beispielsweise ein Wörterbuch, welches Paare von Eingaben auf Ergebnisse abbildet:

Code: Alles auswählen

results = {
    ('rock', 'paper'): 'computer wins',
    ('rock', 'scissors'): 'user wins'
    # …
    }

result = results[(user_inp, cp_input)]
Gewöhne Dir ab, Namen abzukürzen, Du stirbst nicht, wenn Du statt "cp_inp" "computer_input" schreibst, und erst recht nicht, wenn Du "usr_inp" mit "user_input" ersetzt. Dafür ist das Programm wesentlich leichter zu lesen.

In "input(str(…))" ist "str" überflüssig.
Intrepid
User
Beiträge: 6
Registriert: Montag 13. Juni 2011, 14:35

bitssalad hat geschrieben:Hallo intrepid,

danke erstmal für das Feedback :) !
Kein Problem!

Also einen String der input() Funktion als Parameter input(string) zu übergeben??
Warum man dass aber muss oder soll ist für mich komisch:

Code: Alles auswählen

print "Name: " # bzw. print("Name")
name = raw_input() # bzw. input()
Das würde für mich mehr Sinn ergeben, Python und Pascal sind meines Wissens die einzigen
Programmiersprachen die es trotzdem so verlangen.

Warum ausgerechnet Python (die kompatibelste Sprache, wenn man mal das nicht-OpenSource-Java wegdenkt)
einen solchen Unterschied zwischen v2.x und 3.x macht, kann ich nicht verstehen. :(

Intrepid
Intrepid
User
Beiträge: 6
Registriert: Montag 13. Juni 2011, 14:35

lunar hat geschrieben:Was soll es bringen, alle Eingaben pauschal mit Ausnahmebehandlung zu versehen?
Ich habe eine Zeit lang in C++/C# programmiert, da kann sovieles passieren
deshalb habe ich es mir langsam angewöhnt try / except zu setzen.

Intrepid
lunar

@Intrepid: Auch in C# und C++ ist es nicht sinnvoll, Ausnahmen abzufangen, wenn man gar nicht sinnvoll behandeln kann.

Lies die Dokumentation zur "input()"-Funktion, um zu verstehen, welchem Zweck der (optionale) Parameter dient.
Intrepid
User
Beiträge: 6
Registriert: Montag 13. Juni 2011, 14:35

lunar hat geschrieben:@Intrepid: Auch in C# und C++ ist es nicht sinnvoll, Ausnahmen abzufangen, wenn man gar nicht sinnvoll behandeln kann.
Aber es macht deutlich mehr Sinn, und in Python können im Gegensatz zu C++ die Fehlertypen ziemlich genau abgefragt werden...
BlackJack

@Intrepid: Wieso sollte es sinnvoller sein den Prompt für eine Eingabe vorher mit einem eigenen Aufruf beziehungsweise einer Anweisung separat auszugeben? Und es sind hier auch nicht die Sprachen die das ”verlangen” sondern die Funktionen aus der jeweiligen Standardbibliothek. Und es gibt andere Sprachen die ähnliche Funktionen haben. Eben weil es Sinn macht bei einer Funktion die eine Eingabe erhält vorher einen Prompt auszugeben und das mit in die Funktion einzubauen. So kann man die Funktion zum Beispiel austauschen durch eine, welche die Abfrage über ein Fenster macht. Das geht mit dem vorherigen ``print`` nicht oder nur wesentlich komplizierter.

Der Bruch mit der Rückwärtskompatibilität wurde zwischen 2.x und 3.x absichtlich gemacht. Gerade weil bei Python da immer viel Wert drauf gelegt wird, hat sich in den vergangenen zwei *Jahrzehnten* einiges aufgestaut was man gerne geändert hätte, aber wegen der Rückwärtskompatibilität nicht konnte.

Das ``try``/``except`` ist gerade *weil* so vieles passieren kann, absoluter Unsinn! Statt einem Stacktrace und durch die Ausnahme einen Hinweis was denn genau und wo schief gegangen ist, gibst Du einfach nur eine völlig nichtssagende Fehlermeldung aus. Und machst danach im Programm weiter, mit der Gefahr, dass der aufgetretene Fehler zu einem inkonsistenten Programmzustand und damit zu weiteren Fehlern führt. Ausnahmen sollte man nur behandeln, wenn man sinnvoll darauf reagieren kann und nicht ”prophylaktisch”.
deets

Intrepid hat geschrieben:
lunar hat geschrieben:@Intrepid: Auch in C# und C++ ist es nicht sinnvoll, Ausnahmen abzufangen, wenn man gar nicht sinnvoll behandeln kann.
Aber es macht deutlich mehr Sinn, und in Python können im Gegensatz zu C++ die Fehlertypen ziemlich genau abgefragt werden...
Das ist beides schlicht falsch. Von ein paar unruehmlichen Ausnahmen in Bibliotheken (socket-errors, anyone..) abgesehen ist die Fehlerbehandlung absolut equivalent.

Weder hat zB C++ zwingend einen Exception-Basistypen, noch hat es checked exceptions (wie Java, und die sind eh eine der besch...eidensten Ideen ueberhaupt). Beides gilt auch fuer Python.

Ueber C# weiss ich nicht so viel, aber AFAIK hat es ebenfalls keine checked exceptions, niemand zwingt dich also irgendwas zu machen, wenn du nicht willst.

Und *ob* und *wann* du eine Exception faengst, ist in allen Sprachen exact gleich, wenn die Problemstellung dieselbe ist.
bitssalad
User
Beiträge: 7
Registriert: Montag 13. Juni 2011, 13:18

@Lunar,

vielen Dank für die vielen Tipps. Ich habe den Code jetzt nach deinen Vorschlägen angepasst.
Die Idee mit dem Dictonary find ich super. Hatte das schon mal in meinem Lernbuch gesehen, bislang aber keine Möglichkeit gefunden es sinnvoll einzusetzen.
Zuletzt geändert von bitssalad am Donnerstag 7. Juli 2011, 21:05, insgesamt 1-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich würde das ganze in (kleine) Funktionen verpacken und den ganzen Kram von Modulebene wegbringen :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@bitssalad: Sich wiederholende Zeichenketten könnte man an Namen binden, dann liesse sich
das Programm einfacher ändern. Zum Beispiel eine einfache Übersetzung oder auch mit `gettext` mehrsprachig umsetzen.

Bei der Zuweisung von `goes_on` ist immer noch ein überflüssiger `str()`-Aufruf.
derrick
User
Beiträge: 34
Registriert: Mittwoch 8. Juni 2011, 20:32

Hab neulich nen ähnlichen Post aufgemacht und /me hat eine Lösung mit matrix gepostet.
Gucksdu(http://www.python-forum.de/pastebin.php?mode=view&s=194)
Grüße
derrick
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dann kannst du dein Spiel beruhigt zu Rock-paper-siccosrs-lizard-Spock erweitern ;-)
Das Leben ist wie ein Tennisball.
bitssalad
User
Beiträge: 7
Registriert: Montag 13. Juni 2011, 13:18

Danke, ihr habt mir sehr geholfen!
Werde demnächst noch mal am Code weiterarbeiten, momentan schreite ich noch etwas mehr vorran in meinem Python Buch.
EyDu hat geschrieben:Dann kannst du dein Spiel beruhigt zu Rock-paper-siccosrs-lizard-Spock erweitern ;-)
Dafür müsste ich mir erst nochmal die BBT Folge anschauen, damit ich weiß wer wen schlägt :) ...
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Schau dir einfach die beiden Grafiken an: http://en.wikipedia.org/wiki/Rock-paper ... zard-Spock
Antworten