Addressbook (Erste Anwendung)

Code-Stücke können hier veröffentlicht werden.
Antworten
n30nl1ght
User
Beiträge: 2
Registriert: Sonntag 11. Oktober 2015, 17:24

Hallo Zusammen.
Habe mich endlich mal dafür entschieden Python zu erlernen.
Möchte diese Sprache nun auch Intensiv lernen und bin auch voll Motiviert.

Ich habe mal eine kleine Anwendung geschrieben mit der man Personen erstellen und löschen kann.
Völlig simpel :-)

Damit ich mich anhand dieses kleinen Scriptes verbessern kann wäre es natürlich cool wenn ihr die Vorgehensweise mal bewerten könntet.

Code: Alles auswählen

liste = []

def anlegen():
	name = input("Name und Vorname: ")
	tel = input("Telefon: ")
	liste.append((name, tel))
	print()
	print(name + " wurde angelegt!")
	modus = None

def delete():
	print("Um eine Person zu löschen gib bitte den Index an!")
	anz = len(liste)
	for i in range(anz):
		print(str(i) + " : " + liste[i][0])
	index = int(input("Index angeben: "))
	liste.pop(index)
	print()
	print("Person wurde gelöscht!")
	modus = None

def listeausgeben():
	anz = len(liste)
	for i in range(anz):
		print(liste[i][0]  + " -> " + liste[i][1])

print("Willkommen im Adressbook von Tom!")
print("Bitte gib an was du machen möchtest.")
while True:
	print("-----------------------------------")
	print("0 = Liste anzeigen")
	print("1 = Kontakt Anlegen")
	print("2 = Kontakt Löschen")
	print("Q = Beenden")
	modus = input("eingabe: ")

	if modus == "0":
		listeausgeben()
	elif modus == "1":
		anlegen()
	elif modus == "2":
		delete()
	elif modus == "q":
		break
Ich danke euch für eure Hilfe.

Grüsse
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@n30nl1ght
Was mir auffällt:

``anlegen()``:
  • Welchen Sinn hat ``modus``?
  • Statt

    Code: Alles auswählen

    print(name + " wurde angelegt!")
    würde ich

    Code: Alles auswählen

    print('{} wurde angelegt!'.format(name))
    schreiben. Ist aber bei so kurzen Sachen sicher Geschmackssache...
``delete()``:
  • Welchen Sinn hat ``modus``? :wink:
  • Du kannst direkt über Sequenzelemente iterieren:

    Code: Alles auswählen

    for index, item in enumerate(liste):
        print('{:2d}: {}'.format(index, item[0]))
``listeausgeben``
  • Selbiges wie bei ``delete()``, iteriere direkt.
  • Weshalb nutzt Du diese Funktion nicht innerhalb ``delete()``? Entweder formatierst Du die Ausgabe konform oder passt sie via übergebene Optionen an...
Hauptmenü:
  • Würde ich auch in eine eigene Funktion ``main()`` oder so stecken. Ansonsten startet das Programm ja mit jedem Import des Moduls.
  • Das wäre dann das nächste Thema: Füge Deinem Modul am Ende

    Code: Alles auswählen

    if __name__ == '__main__':
       main()
    an. Das hat den Effekt, dass die Funktion ``main`` (oder wie immer Du die dann auch nennst) gestartet wird, wenn Du das Modul "von außen" aufrufst, also ein

    Code: Alles auswählen

    python addressbook.py
    liest das Modul ein und startet dann auch gleich die Funktion ``main``.
  • Die Menüeinträge würde ich nicht hardcoden. Eine ganz schöne Lösung, die man bei sowas immer wieder findet:

    Code: Alles auswählen

    def main():
        menu = [
            ('Liste anzeigen', listeausgeben),
            ('Kontakt anlegen', anlegen),
            ('Kontakt loeschen', delete)
        ]
        while True:
            for index, item in enumerate(menu):
                print('{:2d}: {}'.format(index, item[0]))
            print(' q: Ende')
            choice = raw_input('Eingabe: ')
            if choice in 'qQ':
                break
            try:
                menu[int(choice)][1]()
            except (ValueError, IndexError):
                print('Bitte gueltige Nummer oder q eingeben...')
    Somit hast Du einen Ort, an dem Du alle Deine Menüeinträge einträgst und kannst ohne weiteres neue hinzufügen, umsortieren oder wieder welche entfernen. Mit ``if...`` Abfragen ist sowas umständlich, fehleranfällig und irgendwann auch nicht mehr gescheit zu lesen...
Grundsätzlich:
  • Verwende keine globalen Variablen! Lege ``liste`` (schlechter Name!) innerhalb Deiner ``main`` Funktion an und übergib' sie dann an die einzelnen Funktionen. Irgendwann wird sonst etwas an ``liste`` geändert und Du suchst Dir einen Ast ab, weil Du nicht mehr überschaust, wo das passiert. Geschlossene Namensräume sind etwas wunderbares, nutze sie!! :wink:
  • Meinst Du, eine Liste ist eine gute Datenstruktur für ein Adressbuch? Wie willst Du das z. B. lösen, wenn Du einen Eintrag nicht über seinen Index sondern über den Namen ansprechen möchtest? Oder eine Invertsuche (den Namen zur Telefonnummer?)? Schau' Dir mal die verschiedenen Möglichkeiten an, da gibt's IMHO bessere Lösungen als eine Liste.
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
n30nl1ght
User
Beiträge: 2
Registriert: Sonntag 11. Oktober 2015, 17:24

Hei ich danke dir vielmals für deine Schnelle Antwort
Mit solch einer Ausführlichen Antworte habe ich nicht gerechnet, umso mehr freut es mich natürlich das du dir die Zeit genommen hast um mir Tipps zu geben.
Echt klasse Danke, das ist jedenfalls ein guter Empfang hier im Forum :-)

Ich werde deine Verbesserungsvorschläge dann in Ruhe analysieren und umsetzen, natürlich auch versuchen nach zu vollziehen.
Habe das Script mit meinem Aktuellen Wissensstand erstellt und der ist natürlich noch recht bedürftig :-D

Danke und bis dann.

Gruss
n30nl1ght
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@n30nl1ght
In einem Beispiel hat sich ein ``raw_input`` eingeschlichen, das muss in Deinem Fall (Python 3) natürlich ``input`` lauten.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@n30nl1ght: zusätzlich zu dem was mutetella schon schreibt, entscheide Dich für englische oder deutsche Namen, wobei sich für mich englisch flüssiger liest, weil alle Schlüsselwörter und die Namen aus den Bibliotheken englisch sind. Eingerückt wird immer mit 4 Leerzeichen pro Ebene, vermeide globale Variablen. Einzelne Elemente löscht man mit "del liste[index]".

@mutetella: in einem try-Block sollte nur so viel stehen, wie man auch sinnvoll behandeln kann. Sonst führt ein falsch eingegebener Index in "delete" zu einer unsinnigen Fehlerausgabe:

Code: Alles auswählen

        try:
            command = menu[int(choice)][1]
        except (ValueError, IndexError):
            print('Bitte gueltige Nummer oder q eingeben...')
        else:
            command()
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@Sirius3
Ab wann wird dann ein ``try`` Block verlassen? Also ich meine, wenn innerhalb eines solchen Blocks eine Funktion aufgerufen wird und diese nochmals eine Funktion aufruft etceterapepe... Wird der ``try`` Block erst dann verlassen, wenn alle Funktionen zurückgegeben haben?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@mutetella
Alles andere wäre ja auch blödsinnig, genauso wie die Frage...

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Antworten