Hallo,
ich will ein Programm von mir restaurieren bzw. neu schreiben. Der Grundansatz zur Lösung des Problems (Berechnung geometrischer Eigenschaften) bleibt der selbe, aber ich will die ganze Struktur ausmisten und verbessern. Außerdem will ich hier nun auch erstmals größer mit OOP arbeiten. Ich bin nun aber schon bei der Planung auf einige Fragen gestoßen, die evtl. schon vorher geklärt werden könnten.
1. Wie kommt ihr auf die Klassen? Die Frage ist evtl. blöd formuliert, aber ich weiß nicht wie ich das Ausdrücken soll. Wenn ich beispielsweise einen Jeep genauer spezifizieren will, schreibe ich dann die Klasse Auto, die Klasse Geländewagen oder die Klasse Jeep? Soll ich (jetzt konkret) lieber die Klassen 'Rechner' und 'Interface' oder für jede geometrische Figur (Dreieck, Rechteck etc.) eine eigene klasse und dann noch das Interface machen? Letzendlich könnte ich ja auch für die 10 Zeilen Output eine eigene Klasse machen - wann ist also OOP sinnvoll und wann sinnlos? Und ist das "mischen" von OOP und "normalem" Code ein No-Go oder geduldet?
2. Ich würde gerne die Funktionen zur Berechnung auch eigenständig per Konsole verwenden können - nur wie gebe ich dem Programm die Intelligenz zu wissen, ob es nun importiert wird oder als Konsolenanwendung ausgeführt wird und mit den sys.argv-Parameter arbeiten soll?
3. Wie kann ich einen eventuellen mehrsprachensupport (Deutsch, Englisch) möglichst einfach mit Sprachdateien realisieren? (Immerhin kennt nicht jedes Betriebssystem das Wort Kathete und dessen englische Übersetzung)
Die Oberfläche sollte vorübergehend konsolenorientiert sein.
Wäre über Antworten auf meine ganzen, wohl mehr oder weniger dummen Fragen dankbar.
Lg HH
Einige Fragen zur Programmstruktur und eigenen Modulen
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Ad 1) Wenn es sind macht, d.h. wenn man damit den Code verstaendlicher und wartbarer machen kann und es sich um echte Objekte handelt. Deshalb ist das mischen nicht nur geduldet, sondern erwuenscht.
Bei deinem konkreten Problem kann man dir so nicht helfen. Im Prinzip: Ja, aber erzaehl mal, was die Figuren in deiner Anwendung unterscheidet.
Ad 2) "ifmain" und entsprechende Funktionen.
Ad 3) [mod]gettext[/mod]
Bei deinem konkreten Problem kann man dir so nicht helfen. Im Prinzip: Ja, aber erzaehl mal, was die Figuren in deiner Anwendung unterscheidet.
Ad 2) "ifmain" und entsprechende Funktionen.
Ad 3) [mod]gettext[/mod]
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Naja, das allgemein bekannte halt: Ein Kreis ist rund und hat keine Ecken, beim Dreieck gibt es viele Spezialformen (Gleichschenklig, Rechtwinklig, gleichseitig etc.) und das Viereck hat eine ecke mehr als ein Dreieck und eben auch eine Seite mehr etc.cofi hat geschrieben:Ad 1) Wenn es sind macht, d.h. wenn man damit den Code verstaendlicher und wartbarer machen kann und es sich um echte Objekte handelt. Deshalb ist das mischen nicht nur geduldet, sondern erwuenscht.
Bei deinem konkreten Problem kann man dir so nicht helfen. Im Prinzip: Ja, aber erzaehl mal, was die Figuren in deiner Anwendung unterscheidet.
Alles was man also noch aus der Schule kennt (kennen sollte).
Muss ich dann die Funktionen entsprechend umschreiben oder kann ich bei der "if __name__ (blabla)"-Methode einfach die zu übergebenden Argumente mit dem sys-argv-Werten belegen? Eigentlich schon oder?cofi hat geschrieben: Ad 2) "ifmain" und entsprechende Funktionen.
Huch, trockenes Futter. Perfekt für den Latein-Unterricht Werd mich da mal durchwühlen.cofi hat geschrieben:Ad 3) [mod]gettext[/mod]
Lg hh
edit:// noch eine kleine Zwischenfrage: Ganz am Anfang Module importieren oder in der Klassendefinition? Habe das nämlich auch schon gesehen...
@heiliga horsd: Ad 1) Klassen fassen Daten und zugehörige Funktionen zu Objekten zusammen. Insofern eignen sich geometrische Figuren ganz gut dafür. Es gibt Daten die eine Figur beschreiben, zum Beispiel den Durchmesser oder den Radius bei einem Kreis, und Operationen darauf wie zum Beispiel Umfang und Flächeninhalt ausrechnen. Ein weiterer Aspekt bei OOP ist Polymorphie, also ganz grob dass man verschiedene Objekte gleich behandeln kann. Zum Beispiel kann man bei allen Figuren mit einer Fläche selbige berechnen. Dadurch kann man Code schreiben, dem es egal ist was für eine konkrete Figur er bekommt, solange sie nur eine Methode zum Berechnen der Fläche hat die bei allen Figuren gleich heisst.
Importieren würde ich am Anfang vom Modul machen, wenn es keine guten Gründe gibt, die dagegen sprechen.
Code: Alles auswählen
def print_info(shape):
print ('Figur %s hat den Umfang %f und die Fläche %f.'
% (shape.name, shape.circumference(), shape.area()))
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Nein, halte die Funktionen allgemein benutzbar und die Verrenkungungen im "ifmain".heiliga horsd hat geschrieben:Muss ich dann die Funktionen entsprechend umschreiben oder kann ich bei der "if __name__ (blabla)"-Methode einfach die zu übergebenden Argumente mit dem sys-argv-Werten belegen? Eigentlich schon oder?
Die guten Gründe gibt es eigentlich nur, wenn ein selten benutzte Funktion grosse Importe nach sich zieht, im Allgemeinen wiegt der Vorteil das zusammengruppiert zu haben hoeher als der kleine Geschwindigkeitsvorteil.BlackJack hat geschrieben:Importieren würde ich am Anfang vom Modul machen, wenn es keine guten Gründe gibt, die dagegen sprechen.
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
@cofi: Die "guten Gründe" gibt es immer dann, wenn man die Abhängigkeiten kontrollieren möchte. Schließlich ist alles, was man global importiert, zwingende Abhängigkeit des Moduls. Zu den globalen Imports gehört also nur, was auch wirklich zwingende Abhängigkeit des gesamten Moduls sein darf und soll. Das gilt insbesondere für Module, die nicht Bestandteil der Standardbibliothek und vielleicht sogar noch plattformabhängig sind.
Ich finde es dementsprechend beispielsweise recht unschön, "optparse" oder "getopt" global zu importieren, wenn das Modul eigentlich als Modul und nicht als Programm gedacht ist, und die Kommandozeilenschnittstelle nur zum Testen oder als Demo gedacht ist.
Ich finde es dementsprechend beispielsweise recht unschön, "optparse" oder "getopt" global zu importieren, wenn das Modul eigentlich als Modul und nicht als Programm gedacht ist, und die Kommandozeilenschnittstelle nur zum Testen oder als Demo gedacht ist.
OK also ich bin mir nicht ganz sicher was du meinst ich denke mit einem Codeschnipsel sähe das besser aus, das ist jetzt nur kurz zusammengetippt also bitte nicht allzustreng auf fehler achtencofi hat geschrieben:Nein, halte die Funktionen allgemein benutzbar und die Verrenkungungen im "ifmain".heiliga horsd hat geschrieben:Muss ich dann die Funktionen entsprechend umschreiben oder kann ich bei der "if __name__ (blabla)"-Methode einfach die zu übergebenden Argumente mit dem sys-argv-Werten belegen? Eigentlich schon oder?
Code: Alles auswählen
import sys
def Flaeche(a, b):
print("Fläche", a*b)
if __name__ == '__main__':
a = sys.argv[1]
b = sys.argv[2]
Flaeche(a, b)
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Dir sollte klar sein, dass das auch so laeuft:
oder gleich:
Ich meinte damit, dass du dich nicht in deinen Funktionen anpassen sollst, sondern eben die eingaben von der Kommandozeile den entsprechenden Funktionen uebergibst und u.U. vorbereitest etc, ich glaube das hast du schon richtig verstanden.
@lunar: Ja bedingte Importe sind unbedingt zu erwaehnen, aber die sollten eben auch auf oberster Ebene bzw an typischen Stellen sein und nicht tief versteckt.
Code: Alles auswählen
import sys
def Flaeche(a, b):
print("Fläche", a*b)
if __name__ == '__main__':
b = sys.argv[1]
a = sys.argv[2]
Flaeche(b, a)
Code: Alles auswählen
...
if __name__ == '__main__':
Flaeche(sys.argv[1], sys.argv[2])
@lunar: Ja bedingte Importe sind unbedingt zu erwaehnen, aber die sollten eben auch auf oberster Ebene bzw an typischen Stellen sein und nicht tief versteckt.
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
@cofi: Über den Ort, an dem bedingte bzw. optionale Importe stehen sollte, lässt sich jetzt trefflich streiten. Ich persönlich finde den Import an der Stelle, an welcher sie wirklich benötigt werden, in den meisten Fällen eleganter als Konstrukte der Art:
Insbesondere, wenn der optionale Import nur an wenigen Stellen verwendet werden. "subprocess" aus der Standardbeispiel ist ein schönes Beispiel dafür, wie man es nicht machen sollte.
Code: Alles auswählen
try:
import foobar
except ImportError:
foobar = None
…
def some_func():
if foobar:
foobar.do_something()
Aber nur bei der Fläche oder? Immerhin kann ich ja bei Differenzen bspw. nicht drehen wie ich lustig bin, dann kommt Quatsch als Ergebnis raus!cofi hat geschrieben:Dir sollte klar sein, dass das auch so laeuft:oder gleich:Code: Alles auswählen
import sys def Flaeche(a, b): print("Fläche", a*b) if __name__ == '__main__': b = sys.argv[1] a = sys.argv[2] Flaeche(b, a)
Code: Alles auswählen
... if __name__ == '__main__': Flaeche(sys.argv[1], sys.argv[2])
Ja so war es auch anfangs gemeint. Meine Funktionen sollen nur rechnen, ich versuche die Daten immer gleich (im Sinne von 'auf die selbe Art und Weise') zu übergeben.cofi hat geschrieben: Ich meinte damit, dass du dich nicht in deinen Funktionen anpassen sollst, sondern eben die eingaben von der Kommandozeile den entsprechenden Funktionen uebergibst und u.U. vorbereitest etc, ich glaube das hast du schon richtig verstanden.
Da hab ich wohl eine schöne Diskussion losgetreten. Ich denke ich werde die importe global machen, immerhin sind die genannten Gründe wohl eher immer persönliche Geschmackssache bzw. für mich von geringer Bedeutung.cofi hat geschrieben: @lunar: Ja bedingte Importe sind unbedingt zu erwaehnen, aber die sollten eben auch auf oberster Ebene bzw an typischen Stellen sein und nicht tief versteckt.
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Ich hab wohl ins schwarze getroffen. `a` und `b` wird im Funktionsaufruf durch die Reihenfolge (oder Schluesselwortargumente) bestimmt, nicht durch den Bezeichner an den es gebunden wird.heiliga horsd hat geschrieben:Aber nur bei der Fläche oder? Immerhin kann ich ja bei Differenzen bspw. nicht drehen wie ich lustig bin, dann kommt Quatsch als Ergebnis raus!
Die Reihenfolge war in allen 3 Snippets dieselbe.
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Ah, das habe ich wohl übersehen, ich dachte du hast die Zeilen generell vertauscht. Also dass die Argumente der Reihenfolge wie sie rein kommen nach zugeordnet werden wusste ich... Sorry
- mkesper
- User
- Beiträge: 919
- Registriert: Montag 20. November 2006, 15:48
- Wohnort: formerly known as mkallas
- Kontaktdaten:
Ich verwende lieber
für die beiden letzten Elemente. So ist man auch sicher, dass es funktioniert, egal ob jetzt das Skript mit oder ohne vorangestellten Pythonbefehl aufgerufen wird.
Code: Alles auswählen
sys.argv[-2], sys.argv[-1]
@mkesper: Verstehe ich nicht!?
Der Python-Interpreter nimmst sich selbst aus 'argv' raus.
Code: Alles auswählen
#!/usr/bin/env python
import sys
print sys.argv
Code: Alles auswählen
bj@s8n:~$ python test.py a b
['test.py', 'a', 'b']
bj@s8n:~$ ./test.py a b
['./test.py', 'a', 'b']
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo HH!heiliga horsd hat geschrieben:2. Ich würde gerne die Funktionen zur Berechnung auch eigenständig per Konsole verwenden können - nur wie gebe ich dem Programm die Intelligenz zu wissen, ob es nun importiert wird oder als Konsolenanwendung ausgeführt wird und mit den sys.argv-Parameter arbeiten soll?
Das mit ``if __name__ == "__main__"`` weißt du ja schon. Nur würde ich bei deinem Programm nicht direkt auf ``sys.argv`` zugreifen wollen. Nimm lieber das Modul optparse um die Kommandozeilenargumente zu parsen und dir auch die Syntax/Hilfe zu den Argumenten anzeigen zu lassen.
gettext und z.B. PoEditheiliga horsd hat geschrieben:3. Wie kann ich einen eventuellen mehrsprachensupport (Deutsch, Englisch) möglichst einfach mit Sprachdateien realisieren?
mfg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- mkesper
- User
- Beiträge: 919
- Registriert: Montag 20. November 2006, 15:48
- Wohnort: formerly known as mkallas
- Kontaktdaten:
Ich meine, dass ich da mal Probleme hatte im Zusammenhang mit Debugging in Eclipse (keine Ahnung mehr ob's Eclipse war, jedenfalls benutze ich seither dieses Verfahren).BlackJack hat geschrieben:@mkesper: Verstehe ich nicht!?
Code: Alles auswählen
#!/usr/bin/env python import sys print sys.argv
Der Python-Interpreter nimmst sich selbst aus 'argv' raus.Code: Alles auswählen
bj@s8n:~$ python test.py a b ['test.py', 'a', 'b'] bj@s8n:~$ ./test.py a b ['./test.py', 'a', 'b']
Davon unabhängig hat Gerold natürlich Recht, direkter Zugriff auf sys.argv ist eben "Quick and Dirty".
@gerold:
Danke dir, von dem Modul hatte ich keine Ahnung. Sieht ja beim Überfliegen doch recht mächtig aus und hat schon fast Tutorial-Charakter.
Nun ist mir noch was bezüglich des Mehrsprachensupports eingefallen. Wenn ich bspw. Englisch auch anbieten will, muss ich auch auf deren Gewohnheiten eingehen, was letzendlich heißt: Bogenmaß. Letzendlich würden sich da also wieder ein paar Berechnungen ändern. Ist wohl am besten eine de-Funktion und eine en_us-Funktion zu schreiben, oder?
Danke dir, von dem Modul hatte ich keine Ahnung. Sieht ja beim Überfliegen doch recht mächtig aus und hat schon fast Tutorial-Charakter.
Nun ist mir noch was bezüglich des Mehrsprachensupports eingefallen. Wenn ich bspw. Englisch auch anbieten will, muss ich auch auf deren Gewohnheiten eingehen, was letzendlich heißt: Bogenmaß. Letzendlich würden sich da also wieder ein paar Berechnungen ändern. Ist wohl am besten eine de-Funktion und eine en_us-Funktion zu schreiben, oder?