Gewinnspiel

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.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Bild

So richtig?
BlackJack

@Gary123456: In Spiel sind schon wieder Fragen und Antworten getrennt gespeichert. Und dann auch noch zwei verschiedene Methoden um diese zusammengehörigen Daten hinzuzufügen? Und es sind auch wieder Attribute vorhanden die noch keinen Sinn machen. Schwierigkeit und Level (was ist da der Unterschied?) hast Du doch bisher noch gar nicht berückschtigt. Die Methoden zum Ändern haben doch wahrscheinlich bis auf die Änderung der Werte gar keine Auswirkungen auf den Programmverlauf. Ich würde nur Sachen einbauen die man wirklich braucht und erst dann *wenn* man sie braucht.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

@Gary123456: In Spiel sind schon wieder Fragen und Antworten getrennt gespeichert. Und dann auch noch zwei verschiedene Methoden um diese zusammengehörigen Daten hinzuzufügen? Und es sind auch wieder Attribute vorhanden die noch keinen Sinn machen. Schwierigkeit und Level (was ist da der Unterschied?) hast Du doch bisher noch gar nicht berückschtigt. Die Methoden zum Ändern haben doch wahrscheinlich bis auf die Änderung der Werte gar keine Auswirkungen auf den Programmverlauf. Ich würde nur Sachen einbauen die man wirklich braucht und erst dann *wenn* man sie braucht.
Das wurde mir schon gesagt und habe es versucht umzuwandeln, jedoch falsch. Jetzt habe ich fragen und antworten zusammengefasst in eine Liste. Schwierigkeit und Level ändern fallen weg, da man eh auf die Attribute direkt zugreifen kann. Dann bleibt nur noch frage_antwort_hinzufuegen()

Bild
So sollte es stimmen. Schwierigkeit könnte man auch noch weglassen.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Gary123456 hat geschrieben:
Bei Methoden musst du dich fragen, ob sie im Kontext der Klasse als Schnittstelle nach aussen Sinn machen. Alle 4 Methoden erfuellen das nicht, weil der Aufrufende hier folgende Fragen beantworten muss: "Ist die Frage richtig beantwortet?", "Wie viele Punkte ist diese Antwort wert?" usw.
Meinst Du damit, dass man einen bestimmten Wert einsetzen muss (den Wert, der z.B. die Punkteanzahl bestimmt?
Bei den Punkteanzahl-ändernden-Methoden? Das würde zumindest die Komplexität für den Nutzer wegnehmen und gäbe zumindest einen kleinen Grund dafür, dass die Methode existiert.
Klassendesign ist leider etwas fuer das man Erfahrung braucht und das man nicht von jetzt auf gleich erlernen kann. Ein guter Ansatz ist sich in den anwendenden Code hineinzuversetzen und die Frage zu beantworten "Was muss die Klasse dafuer leisten koennen".
Klassen sind wie Baupläne. Daher will ich mit Hilfe dieser Klasse einen Bauplan für mein Projekt erstellen.[/quote]

Soso, du würdest auch ein Haus mit Bauplänen für Nägel planen?

Klassen sind ein Strukturierungsmittel für Code, aber nicht das einzige: Funktionen und geeignete Datenstrukturen sind andere, die manchmal sinnvoller sind.
Um es nochmal zu betonen, da du so viel mit UML vorausplanen willst: Erstelle und erweitere deine Klassen (das gilt auch für Funktionen und alles andere) so wie du sie brauchst und erst dann, wenn es tatsächliche Anforderungen sind und nicht gedachte Anforderungen.

Ich glaube du hast noch die Vorstellung, dass es schlecht ist, wenn man Code wegwerfen oder großzügig umschreiben musst. Das ist es aber nicht und lässt sich meist gar nicht erst vermeiden: Anforderungen ändern sich, Ideen funktionieren nicht oder machen für andere Komponenten Probleme, etc.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Klassen sind ein Strukturierungsmittel für Code, aber nicht das einzige: Funktionen und geeignete Datenstrukturen sind andere, die manchmal sinnvoller sind.
Das ist es ja! Ich weiss nicht, was in meinem kleinen Programm sinnvoller wäre. Klassen sind wunderschön! Funktionen und Datenstrukturen sind schön!
Um es nochmal zu betonen, da du so viel mit UML vorausplanen willst: Erstelle und erweitere deine Klassen (das gilt auch für Funktionen und alles andere) so wie du sie brauchst und erst dann, wenn es tatsächliche Anforderungen sind und nicht gedachte Anforderungen.
Habe ich gemacht. Alter Code in Klassen umgewandelt. Nur eine kleine neue Funktion: Es gibt Geld!

Code: Alles auswählen

import easygui,random

class Spiel(object):
    def __init__(self, punkte, geld, name, frage_antwort):
        self.punkte = punkte
        self.geld = geld
        self.name = name
        self.frage_antwort = frage_antwort

    def fragen(self):
        for frage, antwort in self.frage_antwort:
            frage_gui = easygui.buttonbox(frage, choices = random.sample(antwort, len(antwort)))
            if frage_gui == antwort[0]:
                easygui.msgbox("Das war eine richtige Antwort!")
                self.punkte += 100
                self.geld += 1000
            else:
                easygui.msgbox("Das war eine falsche Antwort!")
                self.punkte -= 100
                self.geld -= 1000

    def aussteigen(self):
        pass


'''
Hauptprogramm!
'''


frage_antwort = [
       
        ("Was ist Fifa13?", ["Ein Computerspiel", "Ein Monster", "Eine Uhrzeit"]),
        ("Was ist eine Computermaus?", ["Ein Steuerungsgeraet", "Eine Tastatur", "Ein Bildschirm"]),
        ("Test1", ["Test2", "Test3", "Test4"])
        ]

a = Spiel(0, 0, "Wolf", frage_antwort)
a.fragen()
print a.punkte
Habe das jetzt in eine Klasse zusammengefasst. So ist es kürzer und übersichtlicher! Meiner Meinung ist das korrekt.
Zuletzt geändert von Gary123456 am Samstag 13. April 2013, 15:06, insgesamt 1-mal geändert.
BlackJack

@Gary123456: Es gibt eine Klasse die `Spiel` heisst, aber Du versuchst ein Exemplar von `Spieler` zu erstellen, was zu einem `NameError` führt.

`frage_antwort` ist ein unpassender Name, da er in der Einzahl ist, es wird aber ein Container-Objekt mit mehreren Frage/Antwort-Tupeln daran gebunden.

Der Name `a` ist total nichtssagend. Und mit `aussteigen()` gibt es eine Methode die überhaupt nichts macht. Die kann man also weglassen.

Das neue `geld`-Attribut wäre ein guter Kandidat für ein `property()` — oder unnötig — denn `geld` und `punkte` sind offensichtlich abhängig voneinander. Was ist denn der Sinn dieser *beiden* Attribute?
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

@Gary123456: Es gibt eine Klasse die `Spiel` heisst, aber Du versuchst ein Exemplar von `Spieler` zu erstellen, was zu einem `NameError` führt.

`frage_antwort` ist ein unpassender Name, da er in der Einzahl ist, es wird aber ein Container-Objekt mit mehreren Frage/Antwort-Tupeln daran gebunden.

Der Name `a` ist total nichtssagend. Und mit `aussteigen()` gibt es eine Methode die überhaupt nichts macht. Die kann man also weglassen.
Jep, hatte noch was geändert und vergessen, das genau an dem Code anzupassen, daher sorry. Mit aussteigen werde ich nopch was machen , aber später, daher die pass Anweisung.
Das neue `geld`-Attribut wäre ein guter Kandidat für ein `property()` — oder unnötig — denn `geld` und `punkte` sind offensichtlich abhängig voneinander. Was ist denn der Sinn dieser *beiden* Attribute?
Ein User besitzt am Anfang kein Geld und keine Punkte. Wenn die Antwort richtig ist, erhöhe um 100 Punkte und 1000 Geld. Mehr nicht.

Aber vom AUfbau der Klasse her richtig?
BlackJack

@Gary123456: Mir ist klar was der Code mit `geld` und `punkte` macht, was mir nicht klar ist *warum* es diese *beiden* Attribute gibt. Denn der Wert von dem einen lässt sich jederzeit aus dem anderen berechnen, womit das irgendwie witzlos ist.

Wenn Du mit `aussteigen()` *jetzt* noch nichts machen willst, dann sollte die Methode *jetzt* auch noch nicht existieren.

Ansonsten geht die Klasse so. Später sollte man vielleicht darüber nachdenken die Spiellogik von der Benutzerinteraktion zu trennen.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Gary123456 hat geschrieben:Ein User besitzt am Anfang kein Geld und keine Punkte. Wenn die Antwort richtig ist, erhöhe um 100 Punkte und 1000 Geld. Mehr nicht.
Du hast die Frage falsch verstanden: Warum gibt es überhaupt das Attribut Geld, wenn das Geld immer dem Zehnfachen der Punkte entspricht? Dann kannst du Geld auch gleich weglassen und nur Punkte verwenden.

`frage_gui` ist übrigens auch ein schlechter Name, darin befindet sich nämlich die vom Benutzer gegebene Antwort. Auch solte `antwort` wohl eher `antworten` heißen. Hinzu kommt, dass du schon wieder doppelten Code geschrieben hast. Sowohl der if-Zweig, als auch der else-Zweig machen im Prinzip das selbe. Hier kannst du wieder zudammenfassen.

Wenn du `aussteigen` nicht brauchst, dann lässt du es weg oder schmeißt einen `NotImplementedError`, dann hat man auch eine Chance einen möglichen Fehler zu finden.
Das Leben ist wie ein Tennisball.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Du hast die Frage falsch verstanden: Warum gibt es überhaupt das Attribut Geld, wenn das Geld immer dem Zehnfachen der Punkte entspricht? Dann kannst du Geld auch gleich weglassen und nur Punkte verwenden.
Jep, ich habe da jetzt eine Formel eingebaut, damit sie nicht immer um das gleiche erhöht wird :)
`frage_gui` ist übrigens auch ein schlechter Name, darin befindet sich nämlich die vom Benutzer gegebene Antwort. Auch solte `antwort` wohl eher `antworten` heißen. Hinzu kommt, dass du schon wieder doppelten Code geschrieben hast. Sowohl der if-Zweig, als auch der else-Zweig machen im Prinzip das selbe. Hier kannst du wieder zudammenfassen.
frage_gui ist ein schlechter Name. Das gebe ich zu. Im if Zweig wird zwar im Prinzip das selbe gemacht nur mit anderen Operatoren und jetzt auch mit anderen Werten ;) Und das ich mich später nicht verwirren lasse, möchte ich es auch so stehen lassen. (Vorallem, da ich ja noch Übung brauche, sollte man alles möglich übersichtlich gestalten!) Das ist meine Meinung.

Code: Alles auswählen

import easygui,random

class Spiel(object):
    def __init__(self, punkte, geld, name, frage_antwort):
        self.punkte = punkte
        self.geld = geld
        self.name = name
        self.frage_antwort = frage_antwort

    def fragen(self):
        for fragen, antworten in self.frage_antwort:
            antwort = easygui.buttonbox(fragen, choices = random.sample(antworten, len(antworten)))

            if antwort == antworten[0]:
                easygui.msgbox("Das war eine richtige Antwort!")
                self.punkte = (0.5 * self.punkte) + 10 
                self.geld = (0.5 * self.geld) + 50
            else:
                easygui.msgbox("Das war eine falsche Antwort!")
                self.punkte -= 100
                self.geld -= 1000
Das ist mal die reine Klasse. Jetzt müsste ich noch überlegen, was das Spiel noch haben muss.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Naja, ich habe wieder mal die Idee Schwierigkeiten eingebaut. Jedoch gibt es im realen Wer wird Millionär auch keine Schwierigkeitsauswahl. Im Prinzip wars das ja schon. Ich kann problemlos Fragen stellen, feststellen ob sie richtig oder falsch ist und Geld abheben und aufnehmen. Das wars doch für den Anfang. Wie schon gesagt kommt später noch Sound und Grafik dazu, jedoch sehe ich das Projekt (zurzeit!) als fertig an. Ich werde jetzt mit einem anderen Anfänger Hangman programmieren. Danach gehts zum Kapitel Sound und Grafik und danach werd ich mich wieder melden.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Gary123456 hat geschrieben:
Du hast die Frage falsch verstanden: Warum gibt es überhaupt das Attribut Geld, wenn das Geld immer dem Zehnfachen der Punkte entspricht? Dann kannst du Geld auch gleich weglassen und nur Punkte verwenden.
Jep, ich habe da jetzt eine Formel eingebaut, damit sie nicht immer um das gleiche erhöht wird :)
Das ist nicht der Punkt: Die beiden Attribute sind effektiv dasselbe. Will man trotzdem beides haben sollte man das eine aus dem anderen berechnen, um keine inkonsistenten Daten zu haben:

Code: Alles auswählen

class Spiel(object):
    ...
    def geld(self):
        return self.punkte * 10
Mit einem Property kann man dann wieder auf `geld` zugreifen, als waere es ein Attribut:

Code: Alles auswählen

class Spiel(object):
    ...
    @property
    def geld(self):
        return self.punkte * 10
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Gary123456 hat geschrieben:Das wars doch für den Anfang. Wie schon gesagt kommt später noch Sound und Grafik dazu, jedoch sehe ich das Projekt (zurzeit!) als fertig an.
An deiner Stelle würde ich das Programm jetzt noch so weit entwickeln, dass ein Benutzer die Art de Eingabe auswählen kann. GUI oder über die Konsole. Dann bist du dazu gezwungen dir Gedanken darüber zu machen, wie du Eingabe/Ausgabe und Logik vollständig trennen kannst. Das ist in jedem Fall sinnvoll und du kannst ein wenig über Objektorientierung lernen.
Das Leben ist wie ein Tennisball.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Das wird sich alles noch verbessern. Ich plane mit einem Kumpel, der mit mir übrigens auch das Chatprogramm entwickeln will, ein Hangman Game, basierend auf Turtle, TKINTER (evtl. Alternative ist Easygui) und Pygame Sound.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Ich habe das wichtigste vergessen: Ich wollte euch allen lieben, lieben, lieben Dank sagen! Ich verstehe zurzeit viel mehr und kann jetzt auch in anderen Programmen Datenstrukturen richtig aufbauen. Dazu werde ich auch mich in OOP mehr vertiefen. Ich versteh immer mehr. Ihr seid ... unbeschreiblich..... geil. So würden wir das in der heutigen Jugendsprache sagen. :lol: Es geht sogar so weit, dass ich in den mathematischen Fächern viel besser geworden bin.

Gute Nacht
Gerrit
Tengel
User
Beiträge: 210
Registriert: Sonntag 17. März 2013, 12:29

Die heutige Jugend benutzt (wieder) geil?
Na wenn das mal kein Rückschritt ist^^
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Tengel hat geschrieben:Die heutige Jugend benutzt (wieder) geil?
Na wenn das mal kein Rückschritt ist^^
Find ich voll dufte. 8)
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

snafu hat geschrieben:
Tengel hat geschrieben:Die heutige Jugend benutzt (wieder) geil?
Na wenn das mal kein Rückschritt ist^^
Find ich voll dufte. 8)
Da springt mein Herz vor Freude.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Wie knorke!
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Ihr seid ja sowas von 8bit.
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Antworten