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: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Sonntag 3. Juni 2007, 18:05

Hier mal der Versuch ein TUI mit einer Klasse zu machen:
Gesamter Code inkl. DataBook.


http://www.ubuntuusers.de/paste/11393/


Besonders stört mich selbst noch, dass folgende Methode der Klasse TUI_DataBook, die Anzahl der Einträge überprüft. Das scheint mir nicht so schön.
Mir ist aber noch keine wirkliche gelungene Alternative eingefallen.
Soll ich vielleicht eine Error- und Sucessmessage in DataBook definieren und die von über return an die untenstehende Methode zurückgeben?

Code: Alles auswählen

    def enter(self):
        number = 0
        values = []
        for key in self.keys:
            entry = raw_input("%s: " % key.capitalize())
            if entry:
                values.append(entry)
                number += 1
            else:
                values.append("")
                
        if number >= self.instance.min_entries:
            self.instance.add_entry(values)
            print "Entry added"
        else:
            print "You have to make at least %s entries" % self.instance.min_entries


Für sonstige Hinweise, Kommentare jeder Art bin ich wie immer auch dankbar.


LG

rolgal_reloaded
BlackJack

Sonntag 3. Juni 2007, 20:17

Das man so etwas mit einer Ausnahme, zum Beispiel `ValueError` im `DataBook` beantwortet, ist wahrscheinlich für Deine Zielgruppe angeblich wieder zu kompliziert. ;-)
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Sonntag 3. Juni 2007, 20:54

BlackJack hat geschrieben:Das man so etwas mit einer Ausnahme, zum Beispiel `ValueError` im `DataBook` beantwortet, ist wahrscheinlich für Deine Zielgruppe angeblich wieder zu kompliziert. ;-)
Mach dich ruhig lustig,.....
Ausserdem solltest du gelesen haben, dass ich zur Zeit dieses Beispiel noch nicht für meine Zielgruppe sehe, das kann sich aber auch mit der Zeit, die gute Ideen zur didaktischen Aufarbeitung bringt ändern.

Zum Inhalt:
Wieso mit einem ValueError? Meinst du mit raise ValueError - ?

Code: Alles auswählen

    def add_entry(self, values):
        if sum(1 for value in values if value) >= self.min_entries:
            data = {}
            for i, key in enumerate(self.keys):
                data[key] = values[i]
            self.entries.append(data)
        else:
            raise ValueError("Minimum Entries %s" % self.min_entries)
Dann ist das Programm beendet, irgendwie fände ich es hübscher wenn das Programm weiterläuft, oder verstößt das wieder gegen die zehn Gebote des guten Code :wink:

Oder ich habe es noch nicht verstanden, was du meinst, guuut möglich, kennen wir ja:-))

LG

rolgal_reloaded
BlackJack

Sonntag 3. Juni 2007, 21:32

`ValueError` weil das IMHO von den Standard-Ausnahmen am besten passt -- der Wert des Arguments entspricht nicht den Vorgaben.

Damit sich das Programm nicht beendet, sollte man die Ausnahme natürlich an der entsprechenden Stelle im Programm mit ``try``/``except`` behandeln. Und den Benutzer darüber informieren und ihm am besten den Eintrag nochmal zum bearbeiten vor die Nase setzen.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Sonntag 3. Juni 2007, 21:39

BlackJack hat geschrieben:`ValueError` weil das IMHO von den Standard-Ausnahmen am besten passt -- der Wert des Arguments entspricht nicht den Vorgaben.

Damit sich das Programm nicht beendet, sollte man die Ausnahme natürlich an der entsprechenden Stelle im Programm mit ``try``/``except`` behandeln. Und den Benutzer darüber informieren und ihm am besten den Eintrag nochmal zum bearbeiten vor die Nase setzen.
Sowas habe ich mir eigentlich gedacht, heisst im Idealfall vorgestellt, aber ich habe schon ein except, das mit return eine Meldung zurückgibt, die eigentlich aber nicht zu sehen ist. Irgendwas habe ich im Detail noch nicht geschnallt.

Vielleicht check ich es ja noch.

Das mit dem ValueError leuchtet ein.

Danke,

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

Sonntag 3. Juni 2007, 22:15

...also mit try....except müsste es so aussehen, oder?

Code: Alles auswählen

    def add_entry(self, values):
        try:
            if sum(1 for value in values if value) >= self.min_entries:
                data = {}
                for i, key in enumerate(self.keys):
                    data[key] = values[i]
                self.entries.append(data)
                return "Entry added!"
            else: raise ValueError
        except ValueError:
            return "Minimum Entries %s" % self.min_entries
Aber der Aufruf dieser Methode muss dann an eine Variable gebunden sein und deren Inhalt muss dann mit print ausgegeben werden.
Da gibts wohl keine andere Möglichkeit?

LG

r_r
BlackJack

Sonntag 3. Juni 2007, 22:40

Das macht doch gar keinen Sinn die Ausnahme dort zu behandeln. Dann hätte man doch gleich die ``return``\s in die ``if``- und ``else``-Zweig unterbringen können. Die Ausnahme ist ein Signal für den Aufrufer und im Gegensatz zu einem einfachen Rückgabewert für Erfolg oder Misserfolg nicht zwangsläufig für den *direkten* Aufrufer, sondern für irgendeinen in der Aufruferkette, der sich verantwortlich fühlt die Ausnahme zu behandeln.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Sonntag 3. Juni 2007, 22:50

BlackJack hat geschrieben:..... Die Ausnahme ist ein Signal für den Aufrufer und im Gegensatz zu einem einfachen Rückgabewert für Erfolg oder Misserfolg nicht zwangsläufig für den *direkten* Aufrufer, sondern für irgendeinen in der Aufruferkette, der sich verantwortlich fühlt die Ausnahme zu behandeln.
:?: - liegt wohl an Wochentag und Uhrzeit

Wenn dies nicht der richtige Ort ist, dann bleiben nur 2 andere Möglichkeiten.
TUI_DataBook, oder das Hauptprogramm. Ersteres finde ich nicht sinnvoll.

Also?

Code: Alles auswählen

        elif choice == "i":
            values = app.enter()
            try:
                if sum(1 for value in values if value) >= adressbuch.min_entries:
                    adressbuch.add_entry(values)
                else:
                    raise ValueError
            except ValueError:
                print "Minimum Entries must be %s" % adressbuch.min_entries
LG

r_r
BlackJack

Sonntag 3. Juni 2007, 23:58

Es liegt wohl an der Uhrzeit. Es macht keinen Sinn die Ausnahme an dem Ort zu behandeln wo sie ausgelöst wird! Das sollte man doch eigentlich *sehen*, dass das so einfach nur unnötiger Schreibaufwand ist!

Da die minimale Anzahl zur `DataBook`-Klasse gehört, sollte sie auch dort überprüft werden. Und wenn die Bedingung nicht erfüllt ist, dann wird dort die Ausnahme ausgelöst.

Wenn Du ``int('fortytwo')`` ausführst, dann wird innerhalb der `int()`-Funktion geprüft, ob es sich bei der Zeichenkette um eine Zahl handelt und wenn nicht, wird in der Funktion ein `ValueError` ausgelöst. Und der wird nicht da drin wieder behandelt und in einen Rückgabewert umgewandelt. Dann würde man "aussen" ja gar nichts davon mitbekommen.

Die `add_entry()`-Methode kann dann also die Ausnahme auslösen, also muss man die *aussherhalb* der Methode irgendwo auf dem "Weg nach draussen" abfangen, wenn man nicht möchte, dass das Programm beendet wird.

Code: Alles auswählen

        elif choice == "i":
            values = app.enter()
            try:
                adressbuch.add_entry(values)
            except ValueError, error:
                print error
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Montag 4. Juni 2007, 00:18

@BlackJack

Die Sache mit Fehler-, Ausnahmenbehandlung muss ich mir noch intensiver anschauen.

Für den Fall hier dürfte jetzt alles klar sein:

Code: Alles auswählen

    def add_entry(self, values):
        if sum(1 for value in values if value) >= self.min_entries:
            data = {}
            for i, key in enumerate(self.keys):
                data[key] = values[i]
            self.entries.append(data)
        else:
            raise ValueError("Minimum Entries must be %s" % self.min_entries)
Also wie schon gehabt und im Hauptprogramm die Behandlung wie von dir gezeigt.

@edit:
Dann muss ich das mit der Methode load natürlich auch entsprechend ändern.



Vielen Dank nochmal,

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

Mittwoch 6. Juni 2007, 18:49

So, hier ist die neueste Fassung, in der ich versuchte einen Kompromiss aus den verschiedensten Ansrpüchen, Möglichkeiten, Zielsetzungen etc. zu finden.

Gleich vorweg: ich wollte eigentlich show_result noch umschreiben bevor ich es poste, das geht eleganter, habs vergessen, egal.....beim nächsten mal ist es dabei.

Grundsätzlich habe ich eine Menge geändert. Das TUI als Klasse zu implementieren habe ich verworfen, aber warum nicht mal was versuchen.



http://www.ubuntuusers.de/paste/11499/

Für Kommentare jeder Art, sofern sie konstruktiv sind, bin ich wie immer dankbar.

@edit:
Was mir selber gleich einfällt poste ich hier, dann braucht man auf das nicht mehr hinzuweisen.

1.

Code: Alles auswählen

    def search(self, keyword):
        return [data for data in self.entries if keyword in data.itervalues()]
2.

Code: Alles auswählen

    def sort_entries(self):
        return sorted(self.entries, key=lambda x: x[self.keys[0]])
Ist wohl kompakter, denke ich.


LG

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

Donnerstag 7. Juni 2007, 18:08

Zur Methode show_result():

Leider habe ich das nicht wirklich so viel schöner lösen können wie ich dachte, einfach eine neue Liste erstellen und die dann über " ".join() zurückgeben ist ja auch nicht so viel besser, oder übersehe ich da einen wesentlichen Vorteil?

Mir wäre eher folgendes vorgeschwebt:

Die Dictionaries in der Liste an Ort und Stelle fertig umändern und dann diese zurückgeben, aber irgendwie will das nicht....

LG

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

Freitag 8. Juni 2007, 11:27

:?: :?: Die Vorschläge und Kommentare sind ja gewaltig !!!

Wird der Thread boykottiert :roll: ?

Es ist schon alles perfekt, das muss es sein :wink:

Oder liegt es daran, dass die Diskussion mit mir selbst, effizient genug ist 8)

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

Samstag 9. Juni 2007, 23:07

rolgal_reloaded hat geschrieben: Mir wäre eher folgendes vorgeschwebt:

Die Dictionaries in der Liste an Ort und Stelle fertig umändern und dann diese zurückgeben, aber irgendwie will das nicht....

r_r
@rolgal_reloaded :D 8)

So geht das natürlich im Kontext mit dem Code nicht, weil es dann z. Bsp. beim Aufruf von search() knallt! Aber das hier ist vielleicht eine hübsche Variante:

Code: Alles auswählen

def show_result(self, result=None):
    if result == None:
        result = self.entries
    return "\n".join(data["index"] + " " + " ".join((data[key] for key in self.keys)) \
                     for data in result)
LG

rolgal_reloaded
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Sonntag 10. Juni 2007, 07:14

rolgal_reloaded hat geschrieben:

Code: Alles auswählen

    if result == None:
Hallo rolgal_reloaded!

Dann durchbreche ich hiermit mal deinen Monolog. :D

Man sollte None nicht mit ``==``, sondern mit ``is`` vergleichen. Warum -- weiß ich nicht mehr, denn es funktioniert in jedem Fall auch mit ``==``. Also steckt eher etwas Esoterisches dahinter. Unsere Sprachwissenschaftler können dir sicher genauer sagen, warum das so ist. :wink:

mfg
Gerold
:-)
[url]http://halvar.at[/url] | [url=http://halvar.at/elektronik/kleiner_bascom_avr_kurs/]Kleiner Bascom AVR Kurs[/url]
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten