Was geht noch einfacher?

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.
rolgal_reloaded
User
Beiträge: 309
Registriert: Dienstag 24. Oktober 2006, 19:31

Beitragvon rolgal_reloaded » Samstag 26. Mai 2007, 16:57

@alle

Danke nochmal für die interessanten Antworten.
Rein zufällig habe ich sie gesehen, ich bekomme nämlich die halbe Zeit keine Mail, dass ich eine Antwort erhalten habe.

LG

rolgal_reloaded
rolgal_reloaded
User
Beiträge: 309
Registriert: Dienstag 24. Oktober 2006, 19:31

Beitragvon rolgal_reloaded » Samstag 26. Mai 2007, 17:02

BlackJack hat geschrieben:Nochmal kurz zum Beispiel oben: Beim Speichern werden die Argumente `pfad` und `adressbuch` nicht verwendet. In `suchen()` wird `treffer` unnötigerweise an das Objekt gebunden.

`anzeigen()` zeigt nichts an, sondern liefert eine Zeichenkette. Könnte man also als `__str__()` implementieren und `Adressbuch`-Objekte dann einfach mit ``print`` ausgeben.

Hier das gewünschte Beispiel: http://www.ubuntuusers.de/paste/11081/


Das wollte ich ursprünglich auch, hat nicht geklappt, inzwischen glaube ich auf Grund deines Beispieles gesehen zu haben warum.

LG

rolgal_reloaded
rolgal_reloaded
User
Beiträge: 309
Registriert: Dienstag 24. Oktober 2006, 19:31

Beitragvon rolgal_reloaded » Samstag 26. Mai 2007, 17:10

schlangenbeschwörer hat geschrieben:Da es hier ja um Codeverbesserung geht, und dieses Programm gut dafür geeignet ist, da es kurz aber dennoch sinnvoll ist, hätte ich da mal Frage: Man soll ja die Programmierung und die Graphik möglichst komplett auseinanderhalten. Die ´print´ und ´raw_input´-Sachen sind ja eigentlich nur ein GUI-Ersatz, müssten also doch eigentlich auch von der Adressbuch-Klasse getrennt werden, oder? Mich würde das mal interessieren, wie das wirklich sauber geht, da ich, wenn ich Programme mit Gui schreibe, zwar das GUI in eine eigene Klasse packe, die "Inhalts-Klasse" aber genau auf diese abstimme, sodass es fast keine Sinn mehr macht.
Dieses Programm wär doch jetzt mal gut, um es als Grundlage für das ultimative Beispielprogramm für guten Progammierstil zu verbessern, denn es gibt zwar Tutorials für den Inhalt, aber für sowas doch recht selten (habs zumindest noch nicht gesehen).
Was haltet ihr davon, die Klassenversion oben so zu verbessern, dass ein paar Leute sie verwenden können, und, ohne sie zu verändern, ein GUI in dem entsprechenden Toolkit zu schreiben? Ich hab schon überlegt, wie ich das mit Tkinter machen würde, aber da müsste ich die komplette Klasse umbasteln, und die wär dann wieder so, das einer, der ein wx-Beispiel damit machen will, es wieder ändern muss....Zudem käme hierbei noch der Toolkit-Vergleich zustande, da das Programm ja recht gewöhnlich ist, für ein Programm, wofür man ein GUI schreibt.
Ich fänd das echt lehrreich.

Gruß, jj


Gute Idee, bei mir sind da auf Grund der Weiterentwicklung der Lösung 1 - alles global noch viele Dinge drin, die natürlich in weiterer Folge rausgehören. Ich finde es sehr fein, nicht nur für mich, sondern für jeden im Lernprozess, viele Abstufungen bzw. Weiterentwicklungen zu sehen und an ihnen im Detail den Mehrwert zu erkennen.

LG

rolgal_reloaded
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Samstag 26. Mai 2007, 18:14

schlangenbeschwörer hat geschrieben:Da es hier ja um Codeverbesserung geht, und dieses Programm gut dafür geeignet ist, da es kurz aber dennoch sinnvoll ist, hätte ich da mal Frage: Man soll ja die Programmierung und die Graphik möglichst komplett auseinanderhalten. Die ´print´ und ´raw_input´-Sachen sind ja eigentlich nur ein GUI-Ersatz, müssten also doch eigentlich auch von der Adressbuch-Klasse getrennt werden, oder?

Richtig. Die Klasse ist eine API, auf die der Nutzer des Programms keinen Zugriff haben sollte. Die Klasse sollte eine Aufgabe haben und nur eine. Die meisten Klassen sind dazu Daten strukturiert zu kapseln und zu verarbeiten. Die Ausgabe übernimmt ein anderer Code.

schlangenbeschwörer hat geschrieben:Mich würde das mal interessieren, wie das wirklich sauber geht, da ich, wenn ich Programme mit Gui schreibe, zwar das GUI in eine eigene Klasse packe, die "Inhalts-Klasse" aber genau auf diese abstimme, sodass es fast keine Sinn mehr macht.

Dann solltest du die GUI und die Klasse nicht gleichzeitig machen, weil sowas dann zur zu engen Verzahnung zwischen Inhalt (=Daten) und Darstellung (=GUI) kommt, die zu schwer verständlichen Programmen führt.
Eine solche Trennung hat beispielsweise Dookies 7-Segmente-Programm, welches verschiedene UIs hat (auch denn die UI-unabhängige Klasse Properties teilweise sinnlos nutzt. What's On Air ist ebenso UI-unabhängig:
es hat ein Kommandozeileninterface aber auch ein PyGTK-Interface. Eine Zeitlang gab es auch eine Tkinter-UI (die jemand anders geschrieben hat), aber da sie keiner maintaint hat, wurde die rausgenommen.

schlangenbeschwörer hat geschrieben:Dieses Programm wär doch jetzt mal gut, um es als Grundlage für das ultimative Beispielprogramm für guten Progammierstil zu verbessern, denn es gibt zwar Tutorials für den Inhalt, aber für sowas doch recht selten (habs zumindest noch nicht gesehen).

Wäre ok. Aber ich wäre dafür die benötigten Spezifikationen aufzustellen und diese zu implementieren - das geht sicherlich schneller, als rolgal_reloadeds Programm umzuschreiben, denke ich. Zumindest finde ich, dass das schneller geht. Wir können ja auch erstmal Unittests schreiben und dann das Programm implementieren, als Test-first-Ansatz, der von selbst schon eine Art Spezifikation ist.

schlangenbeschwörer hat geschrieben:Ich fänd das echt lehrreich.

Können wir machen. Während man aber eine GUI schreibt, merkt man eben manchmal, dass die API an einigen stellen schlecht ist - dann muss dort nachgebessert werden. Ich glaube aber, dass man sowas merkt, wenn man Unittests schreibt.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
rolgal_reloaded
User
Beiträge: 309
Registriert: Dienstag 24. Oktober 2006, 19:31

Beitragvon rolgal_reloaded » Samstag 26. Mai 2007, 19:50

BlackJack hat geschrieben:
Hier das gewünschte Beispiel: http://www.ubuntuusers.de/paste/11081/



Vielleicht habe ich mir jetzt zu wenig Zeit gelassen,....wie auch immer, was bringt es die ganzen Methoden wie __len__ zu implementieren. __str__ ist mir klar.
Ich mein die Auswirkung ist schon klar: adressbuch.len(), aber der tatsächliche Nutzen bleibt mir noch verborgen.

Irgendwas seh und/oder check ich da jetzt nicht :oops:

LG

rolgal_reloaded
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Samstag 26. Mai 2007, 20:02

rolgal_reloaded hat geschrieben:was bringt es die ganzen Methoden wie __len__ zu implementieren.

Wenn du ``__len__`` implementiest, kannst du ``len()`` auf eine Instanz deiner Klasse anwenden und bekommst somit ihre "Länge", d.h. die Anzahl der in ihr gespeicherten Adressen. Das ist insofern praktisch, dass der Anwender der Klasse nicht wissen muss ob man die anzahl der Einträge mit ``instanz.lenght()`` oder ``instanz.get_number_of_items()`` oder ``instanz.getItemNumber()`` aufrufen muss. Er kann einfach ``len(instanz)`` nutzen und das gibt ihm dann die Anzahl aus. Es ist eine Art, die API aller Klassen einheitlich zu halten.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
rolgal_reloaded
User
Beiträge: 309
Registriert: Dienstag 24. Oktober 2006, 19:31

Beitragvon rolgal_reloaded » Samstag 26. Mai 2007, 20:14

Leonidas hat geschrieben:
rolgal_reloaded hat geschrieben:was bringt es die ganzen Methoden wie __len__ zu implementieren.

Wenn du ``__len__`` implementiest, kannst du ``len()`` auf eine Instanz deiner Klasse anwenden und bekommst somit ihre "Länge", d.h. die Anzahl der in ihr gespeicherten Adressen. Das ist insofern praktisch, dass der Anwender der Klasse nicht wissen muss ob man die anzahl der Einträge mit ``instanz.lenght()`` oder ``instanz.get_number_of_items()`` oder ``instanz.getItemNumber()`` aufrufen muss. Er kann einfach ``len(instanz)`` nutzen und das gibt ihm dann die Anzahl aus. Es ist eine Art, die API aller Klassen einheitlich zu halten.


Das heisst, es geht darum jmd. der mit dieser Klasse etwas programmiert Methoden anzubieten, wie er sie auch von der Klasse List kennt?
Immerhin ist es ja eine Liste.

LG

rolgal_reloaded
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Sonntag 27. Mai 2007, 10:43

Wie intensiv man diese magischen Methoden für eine Klasse überläd hängt natürlich davon ab, es für eine Klasse ist und wer damit arbeitet. Wenn sie eh nur von einem Programm verwendet wird, in dem man diese Funktion nicht immer braucht, sind sie eher überflüssig, aber wenn man eine Klasse schreibt, die auch von anderen als Grundlage für verschiedenen Programme genutzt wird, hilft es schon. Zum einen ist es kürzer und zum anderen muss man den fremden Code nicht so verinnerlichen.

@Leonidas: Ehmm...wie schreibt man Unittests?
Und wie trennt man dann Daten und Darstellung, wenn man nicht nur auf die Klasse zugreift, sondern diese auch selbstständig bei bestimmten Gegebenheiten etwas darstellen will? Der __init__ entsprechende Methoden übergeben, die bestimmte Vorraussetzungen erfüllen? Also so, wie man stdout eine Instanz einer Klasse mit einer write-Methode übergibt? Oder alles mit return regeln, sodass man überprüfen muss, was zurückgegeben wird? Das denke ich, ist wohl besser, aber oft schwer zu machen...

Gruß, jj
rolgal_reloaded
User
Beiträge: 309
Registriert: Dienstag 24. Oktober 2006, 19:31

Beitragvon rolgal_reloaded » Sonntag 27. Mai 2007, 13:39

Hallo nochmal,

also ich versuche immer gezeigtes einfließen zu lassen und dabei eigenes nicht gleich komplett zu verwerfen.
Weil einfach etwas zu 100% übernehmen = abschreiben nicht so das Ultimative ist, denke ich mal.

Ich habe jetzt bez. anzeigen() mal folgende Lösung probiert. Ein Mix BlackJack - Leonidas - rolgal_reloaded.....im Ernst gibts da grob was einzuwenden?

Code: Alles auswählen

    def __str__(self, ergebnis = None):
        if not ergebnis:
            ergebnis = self.eintraege
        ausgabe = ""
        for i, adresse in enumerate(ergebnis):
            ausgabe += str(i + 1)
            for key in self.keys:
                ausgabe += " "
                ausgabe += adresse[key]
            ausgabe += "\n"
        return ausgabe

    def anzeigen(self):
        return self

    def suchen(self, suchbegriff):
        self.treffer = []
        for adresse in self.eintraege:
            if suchbegriff in adresse.itervalues():
                self.treffer.append(adresse)
        if self.treffer:
            return self.__str__(self.treffer)
        else:
            return 'Leider keinen Eintrag gefunden'



Jetzt kann man auf die Instanz print anwenden und __str__ innerhalb der Klasse wiederverwenden.
anzeigen() kann man wohl auch weglassen.

LG

rolgal_reloaded
BlackJack

Beitragvon BlackJack » Sonntag 27. Mai 2007, 14:18

Warum `self.treffer` statt nur `treffer`?
rolgal_reloaded
User
Beiträge: 309
Registriert: Dienstag 24. Oktober 2006, 19:31

Beitragvon rolgal_reloaded » Sonntag 27. Mai 2007, 14:32

BlackJack hat geschrieben:Warum `self.treffer` statt nur `treffer`?


Das ist noch ein Überbleibsel, in irgendeinem Versuch habe ich es als Instanzattribut gebraucht , das gehört jetzt natürlich weg , danke für den Hinweis!

LG

rolgal_reloaded
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Sonntag 27. Mai 2007, 16:25

Könntest du vlt. nochmal deinen aktuellen Code im Ganzen posten, möglichst schon Daten und Darstellung getrennt? Dann würd ich mal sehn, was man noch ändern bzw. anpassen muss und versuchen, ein einfaches GUI zu schreiben, aber deine Klasse so zu lassen, das andere hier GUIs mit anderen Toolkits schreiben können.
rolgal_reloaded
User
Beiträge: 309
Registriert: Dienstag 24. Oktober 2006, 19:31

Beitragvon rolgal_reloaded » Sonntag 27. Mai 2007, 16:55

schlangenbeschwörer hat geschrieben:Könntest du vlt. nochmal deinen aktuellen Code im Ganzen posten, möglichst schon Daten und Darstellung getrennt? Dann würd ich mal sehn, was man noch ändern bzw. anpassen muss und versuchen, ein einfaches GUI zu schreiben, aber deine Klasse so zu lassen, das andere hier GUIs mit anderen Toolkits schreiben können.


Meinst du mich :?:
Nehme ich an wegen - nochmal deinen aktuellen usw.

Oder eine Version von Leonidas - nehme ich an, weil du mit ihm ein Projekt besprochen hast.

LG

rolgal_reloaded
rolgal_reloaded
User
Beiträge: 309
Registriert: Dienstag 24. Oktober 2006, 19:31

Wie ist das eigentlich....

Beitragvon rolgal_reloaded » Sonntag 27. Mai 2007, 17:08

mit folgendem:

Code: Alles auswählen

    def eintragen(self):
        adresse = {}
        anzahl = 0
        for key in self.keys:
            eintrag = raw_input("%s: " % key.capitalize())
            if eintrag:
                adresse[key] = eintrag
                anzahl += 1
            else:
                adresse[key] = ""

        if self.mindestanzahl:
            if anzahl < self.mindestanzahl:
                return "Es müssen mindestens\
 %s Einträge gemacht werden!" % self.mindestanzahl
            else:
                self.eintraege.append(adresse)
                return "Eintrag hinzugefügt!"


Ich habe hiermal die Printanweisungen rausgenommen.
Das bedeutet für den Aufruf:
eintrag = adressbuch.eintragen()
print eintrag

oder nur adressbuch.eintragen()

Dann wird die Rückgabe aber wohl zu einem anonymen Objekt oder?
Sollte man sowas irgendwie unterbinden, weil es schlechter Stil ist.
Oder ist es einfach dem Benutzer seine Sache wie er den Aufruf macht?

LG

rolgal_reloaded
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Sonntag 27. Mai 2007, 17:20

rolgal_reloaded hat geschrieben:Meinst du mich :?:

:arrow: ja

Zu deiner letzten Frage: Es geht ja grade darum, das die Klasse nicth für den "Endverbraucher" sein soll, sondern für Leute wie mich grade, die die Klasse dann dem "Endverbraucher", der nix von Pyhton versteht bzw. verstehen muss, nutzbar machen. Du kannst auch eine Konsolenanwendung schreiben. Das machst du dann in einer neuen Klasse oder Funktion, wo du mit einer Instanz deiner Grundklasse arbeitest und die Eingaben in Methodenaufrufe umwandelst und umgekehrt die zurückgegebenen Werte entsprechend dem Benutzer ausgibst.

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder