Guten Abend allerseits,
ich habe in den letzten Wochen damit begonnen Python zu lernen und wollte euch jetzt mal um eure Meinung/Kritik zu meinem Code bitten. Es handelt sich um ein kleinen Ansatz für ein Programm mit dem man einen Helden für das PnP Rollenspiel "Das Weltenbuch" erstellen kann.
Der Code: HeldenGenerator.py, Held.py, GetData.py, TextInput.py, TextOutput.py.
Weitere Dateien: Klischee, StartAttr.
Grüße
Gerrit
Edit: Sowas ärgerliches. Scheinbar ist beim Kopieren ein Unterstrich in HeldenGenerator.py abhanden gekommen.
Fehler korrigiert.
HeldenGenerator für "Das Weltenbuch"
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Ich hab das grad nur kurz überflogen, aber kann das sein, dass du aus der Java-Welt kommst? Durch "private" Attribute, die du durch simple Getter/Setter bearbeitest, verkomplizierst du deinen Code nur unnötig.
Außerdem muss nicht alles eine Klasse sein, Python kennt durchaus Funktionen
Es gibt ein paar Essays die Python und Java vergleichen: Hier zum Beispiel
Außerdem muss nicht alles eine Klasse sein, Python kennt durchaus Funktionen
Es gibt ein paar Essays die Python und Java vergleichen: Hier zum Beispiel
Danke für's drüber schauen. Was Programmierung angeht bin ich eigentlich ziemlicher Neuling, wenn man mal von den beiden Einführungskursen in FORTRAN und C absieht. Mit Java habe ich also noch nichts zu tun gehabt. Zum Python lernen habe ich mir "Object Oriented Programming in Python" von Goldwasser und Letscher ausgeliehen und bisher den ersten Teil von zweien gelesen.
Hab jetzt mal die ganzen Getter/Setter Funktionen und dadurch den Code doch deutlich entschlackt. Wo sollte ich denn deiner Meinung auf Klassen verzichten und stattdessen Funktionen verwenden.
Der Code: HeldenGenerator2.py
Hab jetzt mal die ganzen Getter/Setter Funktionen und dadurch den Code doch deutlich entschlackt. Wo sollte ich denn deiner Meinung auf Klassen verzichten und stattdessen Funktionen verwenden.
Der Code: HeldenGenerator2.py
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Wenn ich das gerade richtig sehe, dann solltest du nur eine einzige Klasse verwenden, nämlich `Held'.
Bei der objektorientierung versucht man Objekte abzubilden, mit ihren Daten und Fähigkeiten, d.h. in dem Fall:
Benutze die Initialisierung des Helden, keine Extra Klasse. Warum Extra Klassen für input und output? Das kannst du auch gut durch Funktionen erreichen, da du nie wirklich mit den Objekten arbeitest, sondern nur mit deren Methoden -> eigentlich sind es Funktionen in einem extra Namensraum
Die Extra-Dateien kannst du auch in den Anfang deiner Python-Datei schreiben:
Oder wie auch immer du darauf zugreifen willst. Du kannst das natürlich auch in eine extra Datei `config.py' schreiben und das im Code verwenden, das verkompliziert das anpassen etwas, aber wirklich nur wenig, ausserdem sollte es sich ja um quasi Konstanten handeln, wenn ich das richtig sehe.
Auch solltest du Englisch und Deutsch nicht im Quelltext mischen, Kommentare gehn noch, aber sonst sollte man nur Englisch benutzen.
Zu dem Buch: Wow, das ist mal ein Preis oO. Aber ist wohl nicht alles Gold was viel kostet, wenn es dich so einen Code schreiben lässt, weil das doch recht Unpythonisch ist. Schau dir am besten mal das Tutorial an, das verschafft einen guten Überblick.
Bei der objektorientierung versucht man Objekte abzubilden, mit ihren Daten und Fähigkeiten, d.h. in dem Fall:
Benutze die Initialisierung des Helden, keine Extra Klasse. Warum Extra Klassen für input und output? Das kannst du auch gut durch Funktionen erreichen, da du nie wirklich mit den Objekten arbeitest, sondern nur mit deren Methoden -> eigentlich sind es Funktionen in einem extra Namensraum
Die Extra-Dateien kannst du auch in den Anfang deiner Python-Datei schreiben:
Code: Alles auswählen
START_ATTRIBUTES = {"Elf" : (7,6,7,2,5,5)}
Auch solltest du Englisch und Deutsch nicht im Quelltext mischen, Kommentare gehn noch, aber sonst sollte man nur Englisch benutzen.
Zu dem Buch: Wow, das ist mal ein Preis oO. Aber ist wohl nicht alles Gold was viel kostet, wenn es dich so einen Code schreiben lässt, weil das doch recht Unpythonisch ist. Schau dir am besten mal das Tutorial an, das verschafft einen guten Überblick.
Naja, hatte eigentlich das Buch verwendet, weil ich gehofft habe, damit objektorientiertes programmieren zu lernen. Hab mich bei meinem Programm an einem Beispiel aus dem Buch orientiert. Dort ging es um die Programmierung von Mastermind. Dabei wurde auch alles in extra Klassen ausgelagert u.a. Klassen für Input und Output um diese später durch GUI zu ersetzen zu können.cofi hat geschrieben:Wenn ich das gerade richtig sehe, dann solltest du nur eine einzige Klasse verwenden, nämlich `Held'.
Bei der objektorientierung versucht man Objekte abzubilden, mit ihren Daten und Fähigkeiten, d.h. in dem Fall:
Benutze die Initialisierung des Helden, keine Extra Klasse. Warum Extra Klassen für input und output? Das kannst du auch gut durch Funktionen erreichen, da du nie wirklich mit den Objekten arbeitest, sondern nur mit deren Methoden -> eigentlich sind es Funktionen in einem extra Namensraum
Da es im original derzeit 15 Rassen und 55 Klischees gibt, werde ich mal versuchen mir eine 'config.py' zu basteln.Die Extra-Dateien kannst du auch in den Anfang deiner Python-Datei schreiben:Oder wie auch immer du darauf zugreifen willst. Du kannst das natürlich auch in eine extra Datei `config.py' schreibenCode: Alles auswählen
START_ATTRIBUTES = {"Elf" : (7,6,7,2,5,5)}
Da es sich um ein deutsches RPG handelt, hatte ich mich dazu entschieden, die Begriffe aus des Regeln (Held, Name, Rasse, Klischee, Hintergrund, Flags, Attribut, Fertigkeit und Ausrüstung) zu verwenden und ansonsten auf die Englisch zurückzugreifen.Auch solltest du Englisch und Deutsch nicht im Quelltext mischen, Kommentare gehn noch, aber sonst sollte man nur Englisch benutzen.
Zu dem Buch: Wow, das ist mal ein Preis oO. Aber ist wohl nicht alles Gold was viel kostet, wenn es dich so einen Code schreiben lässt, weil das doch recht Unpythonisch ist.
Naja, habs mir ja nicht gekauft. Werde mir mal das Tutorial anschauen und schauen ob der Code dort pythonischer ist.
Hab's mal als "__str__" Methode eingebaut:Hyperion hat geschrieben:Habs nur mal ganz kurz angeguckt, aber print_hero() wäre typerischerweise eine Methode von Held; so in der Richtung: Objekt.druck_dich()!
Code: Alles auswählen
def __str__(self):
'''Gibt den Helden mit "print self" in der Konsole aus.'''
return '\n' + self.name.upper() + '\n' \
'-----------------------------------------------' + '\n' + \
'Rasse: ' + self.rasse + '\n' + \
'Klischee: ' + self.klischee + '\n' + \
'Klischeefertigkeit: ' + self.klischee_fertigkeit + '\n' + \
'Klischeeausrüstung: ' + self.klischee_ausruestung + '\n' + \
'-----------------------------------------------' + '\n' + \
'Startattribute:' + '\n' + \
'Geist: ' + self.attribut[0] + \
' Sozial: ' + self.attribut[3] + '\n' + \
'Körper: ' + self.attribut[1] + \
' Wille: ' + self.attribut[4] + '\n' + \
'Geschick: ' + self.attribut[2] + \
' Sinne: ' + self.attribut[5] + '\n' + \
'-----------------------------------------------\n'
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Also das was du vom Buch erzählst macht es nicht gerade empfehlenswert. Teilung zwischen GUI und Lokig würde man sowieso anders machen. Am einfachsten ist es die Logik in einem Modul zu implementieren und die UI in einem anderen Modul. Dabei müssen Klassen gar nicht verwendet werden, insbesondere für eine einfache Textausgabe ist das völlig unnötig.gkuhl hat geschrieben:Naja, hatte eigentlich das Buch verwendet, weil ich gehofft habe, damit objektorientiertes programmieren zu lernen. Hab mich bei meinem Programm an einem Beispiel aus dem Buch orientiert. Dort ging es um die Programmierung von Mastermind. Dabei wurde auch alles in extra Klassen ausgelagert u.a. Klassen für Input und Output um diese später durch GUI zu ersetzen zu können.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Eher nicht. Ein Objekt der Logik-Schicht hat keine Ahnung vom Darstellungsmedium und kann sich deswegen auch nicht "drucken". Dafür ist dann die entsprechende Ansicht in der Präsentationsschicht verantwortlich.Hyperion hat geschrieben:Habs nur mal ganz kurz angeguckt, aber print_hero() wäre typerischerweise eine Methode von Held; so in der Richtung: Objekt.druck_dich()!
So, hab jetzt mal eure Tipps in den Code einfließen lassen. Hat den Code doch erheblich verbessert und vor allem deutlich kürzer gemacht: Hier der Code.
Danke für die vielen Tipps
Gerrit
Danke für die vielen Tipps
Gerrit
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Ich seh da jetzt allerdings noch einen größeren Haken: Du benutzt die Initialisierung nicht für eine echte Inititialisierung, sondern passt die Werte im Nachhinein an. Ich weiss jetzt nicht wie bindend die gewählten Klischees sind, aber zumindest Name, Rasse und damit zusammenhängend die Startattribute sollten sich doch nicht mehr ändern nachdem der Held erzeugt wurde - geht natürlich trotzdem - also kannst du das auch in die Initialisierung mit rein nehmen.
Zum Buch: Die Trennung von Logik und GUI ist wichtig und gut, aber Klassen? Brauchst du hier nicht wirklich und ich würde deine __str__ methode in eine Funktion abändern, die dann auf einer übergebenen `Held'-Instanz arbeitet(ohne deinen Code anderweitig anzupassen):
Zum Buch: Die Trennung von Logik und GUI ist wichtig und gut, aber Klassen? Brauchst du hier nicht wirklich und ich würde deine __str__ methode in eine Funktion abändern, die dann auf einer übergebenen `Held'-Instanz arbeitet(ohne deinen Code anderweitig anzupassen):
Code: Alles auswählen
def print_hero(hero):
line = '-' * 42 + '\n'
tab = ' ' * 10
return '\n' + self.name.upper() + '\n' + line + \
'Rasse: ' + hero.rasse + '\n' + \
'Klischee: ' + hero.klischee + '\n' + \
'Klischeefertigkeit: ' + hero.klischee_fertigkeit + '\n' + \
'Klischeeausrüstung: ' + hero.klischee_ausruestung + '\n' + \
line + 'Startattribute:\n' \
'Geist: ' + str(hero.attribut[0]) + tab + \
'Sozial: ' + str(hero.attribut[3]) + '\n' + \
'Körper: ' + str(hero.attribut[1]) + tab + \
'Wille: ' + str(hero.attribut[4]) + '\n' + \
'Geschick: ' + str(hero.attribut[2]) + tab + \
'Sinne: ' + str(hero.attribut[5]) + '\n' + line
Hi, ich bin ein alter PnP Rollenspieler, seit einiger Zeit aber im Ruhestandgkuhl hat geschrieben:r das PnP Rollenspiel "Das Weltenbuch" erstellen kann.
Das Weltenbuch kenne ich allerdings noch nicht. Hab es mal überflogen und es macht einen recht spaßigen Eindruck. Spielst du das schon länger?
@burli: Länger ja, aber leider nicht im Sinne von oft. Wir versuchen zur Zeit seit etwa einem Jahr zu spielen, haben bisher aber nur einen einzigen Spielabend geschafft. Da ich zur Zeit im Ausland bin, wird das vor nächstes Jahr wohl auch wieder nichts werden.
@cofi: Meinst du damit in etwa so etwas?
Ich hab mittlerweile übrigens nach sinnvollen englischen Übersetzungen geschaut. Man kann sich ja leider nie 120% sicher sein.
@cofi: Meinst du damit in etwa so etwas?
Code: Alles auswählen
if __name__ == '__main__':
name = query_name()
race = query_race()
stereotype = query_stereotype(race)
attribute = START_ATTRIBUTES[race]
hero = Hero(name, race, stereotype, attribute)
print print_hero(hero)
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Ja das meine ich - zumindest wenn __init__ entsprechend ausschaut
Zu print_hero nochwas: Du kannst auch Triple Quotes nehmen (""" """), die tolerieren Zeilenumbrüche im Quelltest, so könntest du dir viele `\' und `\n' sparen. Ausserdem kannst du String-Formating benutzen und Zahlen musst du nicht explizit in einen String konvertieren. Wie das geht, erzähl ich jetzt aber nicht *g*
Zu print_hero nochwas: Du kannst auch Triple Quotes nehmen (""" """), die tolerieren Zeilenumbrüche im Quelltest, so könntest du dir viele `\' und `\n' sparen. Ausserdem kannst du String-Formating benutzen und Zahlen musst du nicht explizit in einen String konvertieren. Wie das geht, erzähl ich jetzt aber nicht *g*
Danke, daran hab ich jetzt gar nicht gedacht.cofi hat geschrieben:Du kannst auch Triple Quotes nehmen (""" """)
Hier nochmal der neuste Code:
- HeldenGenerator2.py
- Config.py
Eine Sache noch in dem Zusammenhang. Gibts eine Möglichkeit, dass man trotzdem zwischen den Triple Quotes einrücken kann, ohne dass dies in den String übernommen wird? Negative Leerzeichen zum Beispiel...?
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Wenn ich dich jetzt richtig verstehe, willst du führende Leerzeichen entfernen?
Code: Alles auswählen
import textwrap
textwrap.dedent(text)
Ich glaub ich muss auch mal mitmischen, wenns auch nur ne ganz unwichtige Sache ist:
kannst du auch ersetzen durch:
Eine Iteration über ein Dictionary liefert immer die Keys.
Was mich trotzdem noch stört ist dieses "i=0" und "i+=1", ich komm vom Gedanken nicht weg, dass man das vermeiden könnte... Aber das wird wohl auch nur eine Wunschvorstellung sein
Code: Alles auswählen
i = 0
print ''
for race in STEREOTYPES.keys():
i += 1
print str(i) + ': ' + race
Code: Alles auswählen
i = 0
print ''
for race in STEREOTYPES:
i += 1
print str(i) + ': ' + race
Was mich trotzdem noch stört ist dieses "i=0" und "i+=1", ich komm vom Gedanken nicht weg, dass man das vermeiden könnte... Aber das wird wohl auch nur eine Wunschvorstellung sein
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Klar geht das besser
wenn mans denn bei der Nummerierung lassen will, statt bei 0 anzufangen.
Code: Alles auswählen
for i, race in enumerate(STEREOTYPES):
print i+1 " : " + race
Das ist keine Wunschvorstellung, sondern nennt sich
'enumerate()'
yipyip
'enumerate()'
Code: Alles auswählen
In [49]: for i, k in enumerate(['hexe', 'Gnom', 'Beamter']):
....: print '%s: %s' % (i, k)
....:
....:
0: hexe
1: Gnom
2: Beamter
yipyip