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.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Zap hat geschrieben: Beispiele:
neuer_eintrag
neuerEintrag (my favorite)
Aber nicht nur PEP8 lesen sondern auch befolgen :D :
Function names should be lowercase, with words separated by underscores
as necessary to improve readability.

mixedCase is allowed only in contexts where that's already the
prevailing style (e.g. threading.py), to retain backwards compatibility.
Zuletzt geändert von EyDu am Montag 16. April 2007, 12:31, insgesamt 1-mal geändert.
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Hm, ich hatte noch dran gedacht was dazu zu schreiben aber es dann doch vergessen ;)

Ich muss ganz ehrlich sagen das es meiner Meinung nach echt sch** aussieht alles mit Underscores zu bauen.
Spätestens wenn es mehr als 3 Einzelwörter sind.
Ich hatte mit Dive Into Python meinen Einstieg in Python gehabt und bin seit dem Anhänger der Camelcase-Syntax ;)
Beispiel zu meiner Verteidigung

Aber hast recht, man sollte meine schlechten Gewohnheiten nicht weitergeben ;)
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Danke für die vielen Antworten !

Ich brauche diese Prgramm nicht wirklich - hatte eine Idee und wollte sie mit meinen Wissen umsetzen. Das ist noch sehr gering, doch erst alles zu lesen und dann etwas versuchen ist nicht wirklich spannend. Es gibt bestimmt tolle Fuktionen in der Standartbibliothek, doch ich kenne sie halt nicht. Was nicht bedeutet, dass ich es nicht weiter versuchen möchte. Was ist eigentlich IMHO ?

Na ok - Wie sollte ich einen Neuanfang machen ?

Gruss und Dank Frank
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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

Danke CM !

Ich vertstehe evt. ja noch die einzelnen Wörter - was es aber bedeutet ? Ich war vor 20 Jahren mal auf der Hauptschule. Ich sollte mal einen Fremdsprachkurs besuchen !

Na gut - gehe jetzt mal arbeiten.

gruss und dank frank
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi,

"meiner bescheidenen Meinung nach" - kann man sowohl ganz ernst wie völlig ironisch (meistens) meinen.
Geeksprache ist voll von englischen Akronymen. Ist halt so. Muß man mit leben, macht aber auch manchmal viel Spaß.

Gruß,
Christian
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Zap hat geschrieben:Ich muss ganz ehrlich sagen das es meiner Meinung nach echt sch** aussieht alles mit Underscores zu bauen.
Spätestens wenn es mehr als 3 Einzelwörter sind.
Finde ich nicht, ich finde es so lesbarer. Es gibt auch C-Libs wie GTK, GLib und GOject, die nutzen Underscores - siehst du, nicht jeder mag camelCase. CamelCase wird in Python nur für Klassen benutzt und das finde ich auch so sinnvoll.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Da ja keiner mein Vorhaben so richtig verstanden hat, möchte ich es mal erklären.

Ich habe so ein Beispiel in einem Buch mittels Dictionaries gesehen und diese Programm hat Telefonnummern gespeichert. Der Name war der key und so hat das Programm die Telefonnummer gefunden. Ich wollte ein Adressbuch machen und wusste nicht wie ich die Daten für einen Eintrag an einen key hänge, damit sie gefunden werde können. So habe ich es mit dem Speichern in einer Textdatei versucht und habe den "key" durch die Zeilenlänge und den Kriterien erzeugt. So war immer klar wo was gefunden wurde und ich konnte zum Auslesen bzw.Einlesen des Eintragsblockes die ständige Berechnung der Leseposition verwenden. - ok - jeder verstanden ?

Wie macht man es richtig bzw. mit welcher Funktion oder Gedankengang etc ?

gruss und dank für die Antworten

frank
BlackJack

Rechner sind leistungsfähig genug um die Daten im RAM zu halten und falls sie nicht mehr komplett ins RAM passen sollten, ist eine Datenbank angesagt. Selbst mit `seek()` auf Byteebene eine Datei in mühsamer Kleinarbeit zu verwalten ist total überflüssig.

Das neueste Programm habe ich mir nicht mehr im Detail angeschaut, aber zumindest bei den ersten Quelltexten waren die Datensätze doch alle gleich gross. Da wäre es ein leichtes den Dateizugriff auf zwei Funktionen zu beschränken, die jeweils einen Datensatz lesen bzw. schreiben. Schon wären bis auf die beiden Funktionen die ganzen `seek()`\s und Positionsberechnungen aus dem Programm verschwunden. Und man könnte diese beiden Funktionen durch welche ersetzen, die die Daten in einer Datenbank ablegen oder einen LDAP-Server befragen ohne das sich am Rest des Programms viel ändert.

Man muss sich überlegen in welcher Form oder Datenstruktur sich die Daten am besten bearbeiten lassen. Das kann durchaus ein anderes Format sein, als dass in dem die Daten langfristig gespeichert werden.

Mit Bordmitteln ist die einfachste Art Daten zu speichern das `pickle`-Modul. Damit kann man Python-Objekte einfach auf die Festplatte speichern und von da wieder lesen. Das Format ist allerdings an die Sprache Python gebunden.

Als "austauschbares" Format für eine Adressdatei ist das simpelste wohl eine CSV-Datei. Die kann man mit dem `csv`-Modul lesen und schreiben.
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Leonidas hat geschrieben:
Zap hat geschrieben:Ich muss ganz ehrlich sagen das es meiner Meinung nach echt sch** aussieht alles mit Underscores zu bauen.
Spätestens wenn es mehr als 3 Einzelwörter sind.
Finde ich nicht, ich finde es so lesbarer. Es gibt auch C-Libs wie GTK, GLib und GOject, die nutzen Underscores - siehst du, nicht jeder mag camelCase. CamelCase wird in Python nur für Klassen benutzt und das finde ich auch so sinnvoll.
mh...
Ok, vielleicht ist dann mal Zeit zum Umdenken ;)
Hoffentlich ist es dafür noch nicht zu spät :roll:
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Danke BlackJack !!

Ich habe mir shelve angeschaut und es macht ja eigentlich genau das was ich machen wollte - nur halt eben viel einfacher. Wie ich auf die keys zugreifen kann habe ich schon verstanden, doch auf die einzelnen Eintäge bzw. alphab. Sortierung etc ?. In pyhthon ge-packt ist das Modul gar nicht aufgeführt (oder ich kann es nicht finden). Den Zugrif mit dem modul operator ? Das habe ich in dem How To/Sorting gefunden.

gruss und dank frank
BlackJack

`shelve` ist genau wie ein Dictionary unsortiert. Man kann den Sortierschlüssel als Schlüssel für das Dictionary benutzen und dann die Liste mit Schlüsseln abfragen und sortieren.

Aber wie schon gesagt, ist das datensatzweise zugreifen auf ein paar Adressen komplizierter als die Daten immer komplett zu lesen und zu schreiben. Dann kann man sie auch problemlos im Speicher sortieren bevor man sie rausschreibt.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Meinst Du es so ?!

Die Daten speichern und nich sortieren. Beim auslesen sortieren und anzeigen - ncht sortiert abspeichern.

Mit .intervalues() oder .['...'] komme ich an die Einträge
Mit keys() an die Anzahl der Einträge.

Wie greife ich auf die Einträge in den Einträgen pro Person ?

gruss und dank frank
BlackJack

Da ich jetzt gerade gar nicht weiss in welcher Datenstruktur Du die Einträge verwalten willst, kann ich fast keine von den Fragen beantworten.

Ich meine am einfachsten ist es die Daten immer komplett im Speicher zu haben, und zwar sortiert. Wenn man eine Adresse ändert, hinzufügt oder entfernt, dann sortiert man die Adressen sofort danach.

Und am Programmanfang und Programmende bzw. auch auf Wunsch des Anwenders lädt und speichert man alle Adressen. Dabei sind `pickle` oder `csv` wohl die einfachsten Formate. Bei letzterem würde ich auch nach dem Laden vorsichtshalber sortieren, weil da ja zwischenzeitlich jemand mit einem Texteditor etwas verändert haben könnte.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

So und nun eine neue Variation meines Adressbuches - noch nicht ganz fertig ! Ein neues Adressbuch legt man mittels einer texdatei an und als 1. Eintrag eine 0. Die Suche muss ich irgendwie mit split und ':' ändern, damit es nur in den Einträgen sucht.

Code: Alles auswählen

# adressbuch.py
def ausgabe(adressbuch):

    for anzahl_eintraege in range (len(adressbuch)):

        print '____________________________________'
        print
        print adressbuch[anzahl_eintraege]
        print '===================================='
        raw_input()
                         
    anzahl_eintraege = anzahl_eintraege + 1
    
    if anzahl_eintraege == 1:
             
        print
        print anzahl_eintraege,'Eintrag im Adressbuch'
        print
                          
    if anzahl_eintraege > 1:
        
        print
        print anzahl_eintraege,'Eintraege im Adressbuch'
        print

        
def suchen(adressbuch):

    suche = raw_input('Suchbegriff:')                    

    zaehler = 0
         
    for anzahl_eintraege in range (len(adressbuch)):

        s=adressbuch[anzahl_eintraege].upper().find(suche.upper())
        
        if s >= 0:

            zaehler = zaehler + 1
            print '____________________________________'
            print
            print adressbuch[anzahl_eintraege]
            print '===================================='
            raw_input()

    if zaehler == 1:
             
        print
        print zaehler,'Eintrag im Adressbuch gefunden'
        print
                          
    if zaehler > 1 or zaehler == 0:
        
        print
        print zaehler,'Eintraege im Adressbuch gefunden'
        print


def eintragen(adressbuch, spkrit):
   
    neu_eintrag = ''
    
    for x in range (len(spkrit)):
        
        neu_eintrag = neu_eintrag + spkrit[x] + ' ' + raw_input(spkrit[x]) +'\n'

    adressbuch.insert((len(adressbuch)+1), neu_eintrag)
    adressbuch.sort()


def beenden(adressbuch):

    f = file('adressbuch.txt','w')
    
    f.seek(0)
    f.write(str(len(adressbuch)) + '\n')
    
    for anzahl_eintraege in range (len(adressbuch)):
        
        f.writelines(adressbuch[anzahl_eintraege])
        

adressbuch = []
eintrag = ''
spkrit=('Name:      ', 'Strasse:   ', 'Ort:       ',
      'Festnetz:  ', 'Handy:     ', 'email:     ', 'Bemerkung: ')

f = file('adressbuch.txt','r')

for anzahl_eintrag in range (int(float(f.readline()))):

    for anzahl_kriterien in range(len(spkrit)):
        
        eintrag = eintrag + f.readline()
        
    adressbuch.insert(anzahl_eintrag, eintrag)
    eintrag=''
    
f.close()

while True:
       
    print
    print '____(A)nzeigen des Adressbuches____'
    print '____(E)ingabe neuer Adresse________'
    print '____(S)uche von Adressen___________'
    print '____(B)eenden des Adressbuches_____'
    print
                  
    auswahl=raw_input('Auswahl:')
                        
    if auswahl.upper() in ['A']:
          
        ausgabe(adressbuch)

    if auswahl.upper() in ['E']:
          
        eintragen(adressbuch, spkrit)
                       
    if auswahl.upper() in ['S']:
          
        suchen(adressbuch)
                              
    if auswahl.upper() in ['B']:
          
        beenden(adressbuch) 
        break
pocco.org hat nicht funktioniert

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

Viele Leute haben das gleiche Problem - 1000mal geschaut 1000mal hab ich nichts kapiert - oder so! :-)

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

Hinter "if", "def", "while" und "for" kommen keine Leezeilen, das macht den Code etwas unleserlich.

Sachen wie:

Code: Alles auswählen

for anzahl_eintraege in range (len(adressbuch)): 

        s=adressbuch[anzahl_eintraege].upper().find(suche.upper()) 
Kannst du noch vereinfachen auf:

Code: Alles auswählen

for anzahl_eintraege in adressbuch: 
        s=anzahl_eintraege.upper().find(suche.upper()) 
Dann, sparst du dir die ganzen unnötigen Indexzugriffe.

Und aus Zeilen wie dieser:

Code: Alles auswählen

print "-------------------"
Kannst du folgendes machen:

Code: Alles auswählen

print "-"*15
Am besten gleich mit Konstanten, oder einer Funktion die solche Zeilen ausgibt (oder gar beides :D ).
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Danke für die Antwort EyDu !

Das mit dem split() müsste ja nicht sein, doch habe ich halt zur Darstellung einfach Name:, Wohnort etc: eingefügt. Das habe ich nur gemacht, weil ich nicht an die Eintäge in den Einträgen pro Person gekommen bin. Habe es mit adressbuch[1,2] oder so versucht. Wie komme ich daran.

gruss frank und danke
BlackJack

Man kann über Einträge in einer Liste direkt iterieren, dazu braucht man nicht den Umweg über einen Index. Und einen Index `anzahl_*` zu nennen ist etwas irreführend.

Wenn man nach einem ``if`` mit einem weiteren ``if`` auf die genau gegenteilige Bedingung prüft, dann kann man dafür auch ein ``else`` benutzen.

Anstelle von `find()` könnte man den ``in``-Operator benutzen, was wesentlich leichter lesbar ist:

Code: Alles auswählen

if suchbegriff.upper() in eintrag.upper():
In `suchen()` ist dann auch gleich wieder eine Menge Quelltext, der nahezu identisch mit der `ausgabe()` ist. Das Programm würde kürzer, wenn man in `suchen()` einfach eine Liste mit den Adressen erstellt, auf die der Suchbegriff passt und damit dann `ausgabe()` aufruft.

Beim `eintragen()` wird wieder ein unnötiger Umweg über den Index gemacht und die vorletzte Zeile ist eine umständliche Art ``adressbuch.append(neu_eintrag)`` zu schreiben. Da taucht auch wieder dieses `spkrit` auf. Ich würd's `FELDNAMEN` oder so nennen und an den Anfang des Quelltextes verschieben.

Beim `beenden()` ist das ``f.seek(0)`` überflüssig. Und ob man die Anzahl der Datensätze wirklich in die Datei schreiben muss, hatte ich früher ja schon einmal hinterfragt. Man weiss ja, dass ein Datensatz sieben Zeilen lang ist, also kann man beim einlesen einfach alle sieben Zeilen einen neuen Datensatz an die Adressen-Liste anfügen.

Das schreiben ist dann wieder maximal umständlich. Wieder ein unnötiger Index und dann wird für eine einzelne Zeichenkette `writelines()` benutzt. Die Funktion erwartet ein "iterable" über Zeichenketten und schreibt jedes Element nacheinander in die Datei. In diesem Fall wird also jeder Buchstabe einzeln geschrieben. Da die Adressenliste schon Zeichenketten enthält, reicht ein einfaches ``f.writelines(adressbuch)`` um alles zu schreiben. Danach sollte man die Datei schliessen.

Das laden des Adressbuchs würde ich auch in eine Funktion verpacken. Auf Modulebene sollte so wenig wie möglich ausführbarer Code stehen.

Die Überprüfung der Auswahl ist auch wieder umständlich. Wieso wird auf enthaltensein in einer Liste mit einem Element geprüft, wenn ein einfacher Vergleich genügen würde?

So wie es jetzt da steht, könnte man die Funktionen so schreiben, dass alle das Adressbuch als einzelnes Argument entgegennehmen und eine Abbildung von Buchstabe zu Funktion benutzen.

Das speichern der Feldnamen in den Daten ist etwas ungünstig. Man sollte zum Beispiel nicht nach dem Vornahmen 'Andy' suchen, weil der durch 'Handy:' Bestandteil von jedem Datensatz ist.

Angepasste Version: http://paste.pocoo.org/show/1426/
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Danke BlackJack !

Deine Hilfe und Kritik ist immer sehr ausführlich und du gibst dir sehr viel Mühe mit deinen Erklärungen. Ich verstehe es oft nicht und deswegen mache ich die gleichen Fehler wieder. Mein "schräger" Stiel liegt in meinem "Unwissen" und falls es klappt bin ich zufrieden und lasse es so. Es gibt bestimmt für alles eine schöne "pythonische" Lösung - die kenne ich halt leider nicht bzw. noch nicht. Jetzt hast du mein "schönes" Programm perfekt gemacht und mir den Spass verdorben :-). Wolltest dem Trauerspiel ein Ende machen - ok - schon verstanden!

gruss und dank frank
Antworten