Funktionen richtig formuliert ?

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.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Das mit dem Löschen habe ich nun so geändert. Der Name "loeschliste" ist bestimmt nicht schön - ich bin da nicht wirklich besonders kreativ.

Code: Alles auswählen

        if auswahl == 'L':
            loeschliste.append(''.join(eintrag))
        elif auswahl =='E':
            eintragen(adressbuch)
            adressbuch.remove(eintrag)
    for eintrag_loeschen in loeschliste:
        adressbuch.remove(eintrag_loeschen)
gruss frank
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

kaytec hat geschrieben:Das mit dem Löschen habe ich nun so geändert. Der Name "loeschliste" ist bestimmt nicht schön - ich bin da nicht wirklich besonders kreativ.

Code: Alles auswählen

        if auswahl == 'L':
            loeschliste.append(''.join(eintrag))
        elif auswahl =='E':
            eintragen(adressbuch)
            adressbuch.remove(eintrag)
    for eintrag_loeschen in loeschliste:
        adressbuch.remove(eintrag_loeschen)
gruss frank
Aus welchem Grund auch immer die Liste nicht so heissen kann wie ich vorgeschlagen habe......

dann fände ich noch das hier besser:

Code: Alles auswählen

for element in liste:
        adressbuch.remove(element)
Ich will eigentlich nur sagen, dass ich nicht glaube, dass so aufwendige Namen in dem Fall notwendig und sinnvoll sind.
Um welche Art von Liste es sich handelt, ergeht doch aus dem Context zur Funktion in der sie steht, oder nicht?
funktion loechen - darin definierte liste speichert elemente zum löschen.

LG

r_r
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Danke rolgal_reloaded !

Die Möglichkeit des Löschens habe ich in die Fuktion ausgabe() gebaut, da ich diese Lösung recht einfach fand und wollte daher keine eigene Fuktion loeschen() schreiben. In der Fuktion ausgabe() ist aber der Begriff eintrag schon verwendet.

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

Also ich bin ja nur ein Hobbycoder und mach mit Python in der Schule ein bisschen was, aber ich glaube sagen zu dürfen, dass das kein guter Stil ist.

Ich lehne mich jetzt mal weit raus, mal sehen ob ich falle, lol.

Für mein Verständnis muss loeschen eine eigene Funktion sein.

LG

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

Hier mal eine funktionstüchtige Skizze:

Wenn ich für ein Adressbuch ein Dictionary wählen würde, würde ich mir auch nicht viel mehr antun. Freileich müsste das Dict. noch geladen und gespeichert werden und man könnte noch die eine oder andere Fehlerbehandlung einbauen, ansonsten besonders wenn man z.b. eintragen() noch differenzierter haben will, würde ich eine Datenbank ansprechen.
Damit hast es dann wahrscheinlich schneller gelöst als mit einem Dictionary.
Das Beispiel wird vielleicht wieder mal was für die Schule.

Code: Alles auswählen

# -*- coding: cp1252 -*-


adressbuch = {1: ["Gnom","Gustav","Grummelweg", "8", "7777", "Buxtehude"],
              2: ["Gnom","Brunhilde","Grummelweg", "8", "7777", "Buxtehude"],
              3: ["Gnom","Detlef","Grummelweg", "8", "7777", "Buxtehude"]}

def anzeigen():
    ausgabe =[str(eintrag[0]) + " " + " ".join(eintrag[1])+ \
              "\n" for eintrag in adressbuch.iteritems()]
    print "".join(ausgabe)        
        

def eintragen():
    eintraege = raw_input("Bitte Adresse eingeben: ")
    schluessel = len(adressbuch.keys()) + 1
    adressbuch[schluessel] = eintraege.split()

    
def bearbeiten():
    auswahl = raw_input("Bitte die Nummer des Eintrags angeben: ")
    eintrag = raw_input("Bitte Adresse eingeben: ")
    adressbuch[int(auswahl)] = eintrag.split()


def loeschen():
    auswahl = raw_input("Bitte die Nummer des zu löschenden Eintrags eingeben: ")
    del(adressbuch[int(auswahl)])


def suchen():
    auswahl = raw_input("Bitte einen Begriff eingeben: ")
    treffer = []
    for eintrag in adressbuch.itervalues():
        if auswahl in eintrag:
            treffer.append(" ".join(eintrag))

    if treffer:
        print "Die Suche ergab folgende Treffer:\n%s " % "\n".join(treffer)
    else:
        print "Leider kein Eintrag gefunden"


print "=============Menü============="
print "1. Adressen anzeigen"
print "2.  - eintragen"
print "3.  - bearbeiten"
print "4.  - loeschen"
print "5.  - suchen"
print "E für Ende"
print "=============================="

while True:

    auswahl = raw_input("Auswahl: ")
    if auswahl == "1":
        anzeigen()
    elif auswahl == "2":
        eintragen()
    elif auswahl == "3":
        bearbeiten()
    elif auswahl == "4":
        loeschen()
    elif auswahl == "5":
        suchen()
    elif auswahl == "E":
        break
    else:
        print auswahl, "ist eine ungültige Eingabe!"

print "Ende des Programms"
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Das Programm hat BlackJack so umgeschrieben , da meines einen sehr "unpythonischen" Stil hatte und einige Fehler. Ich habe das umgeschriebene Programm verwendet, denn ich fand es halt gut so. Eine Funktion für das Editieren hatte ich noch vor, da auch das Editieren Darstellungsfehler verursacht. Das Löschen über die keys finde ich persönlich problematisch, weil ich bei mehreren Adressen den Überblick verliere. Ich habe es in die Ausgabe gepackt, damit ich gleich die Möglichkeit zum Löschen habe. Es wäre natürlich auch über eine Funktion möglich, die in der Ausgabe aufgerufen wird.

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

kaytec hat geschrieben:Das Programm hat BlackJack so umgeschrieben , da meines einen sehr "unpythonischen" Stil hatte und einige Fehler. Ich habe das umgeschriebene Programm verwendet, denn ich fand es halt gut so.
Wenn es von BlackJack ist, dann ist es sicherlich auch gut.
Eine Funktion für das Editieren hatte ich noch vor, da auch das Editieren Darstellungsfehler verursacht. Das Löschen über die keys finde ich persönlich problematisch, weil ich bei mehreren Adressen den Überblick verliere.
Wie gesagt: für wirklich eine große Adressenverwaltung würde ich sowieso auf eine Datenbank setzen.
Ich habe es in die Ausgabe gepackt, damit ich gleich die Möglichkeit zum Löschen habe. Es wäre natürlich auch über eine Funktion möglich, die in der Ausgabe aufgerufen wird.

gruss und dank frank
Naja, wenn du es so lieber hast, dann mach es so.

LG

rolgal_reloaded
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Habe mal eine Funktion für das Editieren geschrieben:

Code: Alles auswählen

def editieren(eintrag):
    neu_eintrag = list()
    index = 0
    for feldname, feld_wert in zip(FELDNAMEN, eintrag):
        print '_' * 35
        print 'alter Eintrag:', feld_wert
        neu_eintrag.append((raw_input(feldname)) + '\n')
        eintrag[index] = neu_eintrag[index]
        index += 1
gruss frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Das Editieren habe ich nun so geändert, daß man Einträge übernehmen kann.

Code: Alles auswählen

def editieren(eintrag):
    neu_eintrag = list()
    index = 0
    for feldname, feld_wert in zip(FELDNAMEN, eintrag):
        print '_' * 35
        print feldname
        print 'alter Eintrag:', feld_wert
        eingabe = raw_input('neuer Eintrag:')
        if eingabe != '':
            neu_eintrag.append((eingabe) + '\n')
            eintrag[index] = neu_eintrag[index]
        elif eingabe == '':
            neu_eintrag.append(' ')
        index += 1
gruus frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Habe mal versucht eine Geburtstagsinfo einzufügen, doch beim Speichern wird aus dem testergebnis das adressbuch und ich habe immer den Geburtstagseintrag der gefundenen Person beim nächsten Start des Adressbuches als neuen Eintrag. Bei der Suche passiert es doch auch nicht ?

Code: Alles auswählen

def testen(adressbuch):
    testergebnis = list()
    test_eintrag = list()
    for eintrag in adressbuch:
        for feldname, feld_wert in zip(FELDNAMEN, eintrag):
            if feldname == 'Geburtstag:':
                geburtstag = feld_wert.split('.')
                datum =(strftime('%x'))
                datum = datum.split('/')
                datum.pop()
                geburtstag.pop()
                if datum[0] == geburtstag[1]:
                    test_feld_wert = feld_wert
                    test_eintrag = eintrag
                    auswertung = (float(datum[1]) - float(geburtstag[0])) * -1
                    if 1 < auswertung <= 7:
                        test_eintrag.remove(test_feld_wert)
                        test_feld_wert += 'Geburtstag ist in ' + 
                                                            str(int(auswertung)) + ' Tagen'
                        test_eintrag.append(test_feld_wert)
                        testergebnis.append(test_eintrag)
                    elif auswertung == 1:
                        test_eintrag.remove(test_feld_wert)
                        test_feld_wert += '!Geburtstag ist morgen!'
                        test_eintrag.append(test_feld_wert)
                        testergebnis.append(test_eintrag)
                    elif auswertung == 0:
                        test_eintrag.remove(test_feld_wert)
                        test_feld_wert +=  '!!!der Geburtstag ist heute!!!'
                        test_eintrag.append(test_feld_wert)
                        testergebnis.append(test_eintrag)
    ausgabe(testergebnis, 'im Adressbuch gefunden')
gruss und dank frank
BlackJack

Du bindest den Eintrag in Zeile 15 nur an einen neuen Namen, das ist immer noch das Objekt im Adressbuch, also werden Änderungen an dem Objekt auch gespeichert.

Fürs rechnen mit Datumswerten schau mal ins `datetime`-Modul. Und statt der ``* -1`` könntest Du auch einfach die Reihenfolge bei der Subtraktion vertauschen.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Danke BlackJack !

Soweit habe ich es verstanden. Das mit dem Erstellen von "Sicherungslisten" ist überflüssig ? Ist mein Ansatz komplett falsch oder muss ich am Ende der Funktion den Eintrag aus dem Adressbuch Löschen und neu einschreiben?

gruss und dank frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Habe es mal so gelöst !!

Code: Alles auswählen

def testen(adressbuch):
    for eintrag in adressbuch:
        for feldname, feld_wert in zip(FELDNAMEN, eintrag):
            if feldname == 'Geburtstag:':
                geburtstag = feld_wert.split('.')
                datum =(strftime('%x'))
                datum = datum.split('/')
                datum.pop()
                geburtstag.pop()
                if datum[0] == geburtstag[1]:
                    auswertung = float(geburtstag[0]) - float(datum[1])
                    for feldname, feld_wert in zip(FELDNAMEN, eintrag):
                        print '_' * 35
                        print feldname, feld_wert
                    if 1 < auswertung <= 7:
                        print 'Geburtstag ist in ' + str(int(auswertung)) + ' Tagen'
                    elif auswertung == 1:
                        print '!Geburtstag ist morgen!'
                    elif auswertung == 0:
                        print '!!!der Geburtstag ist heute!!!'
gruss frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Habe noch eine Falscheingabe berücksichtigt.

Code: Alles auswählen

                try:
                    if datum[0] == geburtstag[1]:
                        auswertung = float(geburtstag[0]) - float(datum[1])
                        for feldname, feld_wert in zip(FELDNAMEN, eintrag):
                            print '-' * 35
                            print feldname, feld_wert
                        print '=' * 35
                        if 1 < auswertung <= 7:
                            print 'Geburtstag ist in ' + str(int(auswertung)) + ' Tagen'
                        elif auswertung == 1:
                            print '!Geburtstag ist morgen!'
                        elif auswertung == 0:
                            print '!!!der Geburtstag ist heute!!!'
                        print '=' * 35
                        raw_input()

                except IndexError:
                    for feldname, feld_wert in zip(FELDNAMEN, eintrag):
                        print '-' * 35
                        print feldname, feld_wert
                    print '=' * 35
                    print 'Dieser Eintrag hat eine falsche Geburtstagsangabe'
                    continue
 
gruss frank
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Da ist aber noch einiges was man verbessern könnte:

Ich würde die Zeilen

Code: Alles auswählen

print '-' * 35
noch in eine Funktion packen, da sich dieser Trenner doch öfter mal wiederholt, und du diesen so wesentlich leichter anpassen kannst.

Sollten "geburtstag[0]" und "datum[0]" Zahlen sein, und keine sein, kannst du die Zeile

Code: Alles auswählen

auswertung = float(geburtstag[0]) - float(datum[1])
noch in

Code: Alles auswählen

auswertung = float(geburtstag[0] - datum[1])
vereinfachen.

Weiter versuchst du offensichtlich, eine Fließkommazahl per "==" mit einer anderen Zahl zu vergleichen:

Code: Alles auswählen

elif auswertung == 1
elif auswertung == 0
Früher oder später wird da etwas auf Grund von Rundungsfehler schiefgehen.

Als letztes fällt mir noch dein try/except-Block auf: Die goldene Regel für dieses Konstrukt ist, dass im try-Teil nur so wenig wie nötig steht. Alles was nach dem laufen soll, wo ein Fehler auftreten könnte hat im else-Block zu stehen (oder nach dem try/except-Teil, wenn except das Problem auflöst).

Grüße,
Sebastian
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo EyDu !!

Das mit dem Teiler ist eine gute Idee, da ich diesen oft verwende. Das eine float kann ich weglassen, doch bei dem Vergleichen der Zahlen ist es doch egal, da keine kommastellen entstehen können - sind doch immer ganze Zahlen.

Das mit der try - except Anweisung verstehe ich nicht so ganz ?

gruus und dank frank
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

kaytec hat geschrieben:Das eine float kann ich weglassen, doch bei dem Vergleichen der Zahlen ist es doch egal, da keine kommastellen entstehen können - sind doch immer ganze Zahlen.
In diesem Kontext wird das mit hoher Wahrscheinlichkeit immer funktionieren, aber man weiss ja nie was noch hinzugebaut wird. Das Problem mit Fließkommazahlen ist also eher allgemeiner Natur. Wenn aber nur ganze Zahlen auftreten können, dann frage ich mich, warum du nicht gleich Integers benutzt ;-)

kaytec hat geschrieben:Das mit der try - except Anweisung verstehe ich nicht so ganz ?
Das Problem ist, um so größer der try-Teil wird, desto höher ist auch die Wahrscheinlichkeit, dass du Fehler abfängst die du gar nicht abfangen willst. Hinzu kommt noch, dass man bei einem langen try-Teil suchen muss, welche(r) Fehler denn abgefangen werden soll. Ist dieser kurz gehalten, ist dieses im Allgemeinen jedoch recht einfach.

Aus

Code: Alles auswählen

try:
    spam = eggs[0] #Hier kann etwas schiefgehen (Index-Fehler)
    
    #Code bei dem kein Index-Fehler auftreten sollte
    #...
    wert = berechne_etwas()
except IndexError:
    #Defaultwert setzen
    wert = 1
solltest du also folgendes machen:

Code: Alles auswählen

try:
    spam = eggs[0] #Moeglicher Indexfehler
except IndexError:
    #Defaultwert setzen
    wert = 1
else:
    #Code bei dem kein Index-Fehler auftreten sollte
    #...
    wert = berechne_etwas()
Wenn jetzt nämlich beispielsweise in "berechne_wert" ein Index-Fehler auftritt, den du eigentlich nicht abfangen wolltest, wird dir dieser auch gemeldet und nicht aus Versehen verdeckt.

Wenn du aus dem except-Teil mit "return" springst, kannst du auch den else-Teil weglassen, und hinter dem except-Teil auf gleicher Ebene wie das try-Statement weiterarbeiten.

Sebastian
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Danke DIr EyDu!!

Hatte gedacht das Strings immer mit float ausgelesen werden - geht auch mit int.

Code: Alles auswählen

def testen(adressbuch):
    s = sys.winver
    os.system("cls")
    for eintrag in adressbuch:
        for feldname, feld_wert in zip(FELDNAMEN, eintrag):
            if feldname == 'Geburtstag:':
                geburtstag = feld_wert.split('.')
                datum =(strftime('%x'))
                datum = datum.split('/')
                datum.pop()
                geburtstag.pop()
                try:
                    if datum[0] == geburtstag[1]:
                        auswertung = int(geburtstag[0]) - (datum[1])
                except IndexError:
                        for feldname, feld_wert in zip(FELDNAMEN, eintrag):
                            print '-' * 35
                            print feldname, feld_wert
                        print '=' * 35
                        try:
                            if 1 < auswertung <= 7:
                                print 'Geburtstag ist in ' + str(auswertung) + ' Tagen'
                            elif auswertung == 1:
                                print '!Geburtstag ist morgen!'
                            elif auswertung == 0:
                                print '!!!der Geburtstag ist heute!!!'
                            print '=' * 35
                        except UnboundLocalError:
                            print 'Dieser Eintrag hat eine falsche Geburtstagsangabe'
                        raw_input()
etwa so ?

frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Habe jetzt mal damit rumprobiert, doch es geht nicht so richtig! Es werden jetzt alle Einträge angezeigt - muss ich mal überarbeiten ?!

gruss frank
Antworten