Telefonbuch aus byte of Python

Code-Stücke können hier veröffentlicht werden.
Cenz
User
Beiträge: 12
Registriert: Donnerstag 21. Mai 2009, 16:02

Hallo

Ich fange gerade an Python zu lernen, ist meine erste Sprache.
Ich habe "Byte of Python" gelesen und habe dann versucht das Telefonbuch als Übung zu programmieren, aber es will einfach nicht die gespeicherten Daten anzeigen.

Ich würde mich freuen, wenn mir jemand helfen könnte

Code: Alles auswählen

#!/usr/bin/python
# Filename: telefonbuch.py

import pickle


Personenfile = 'Personen.data'
Personen = {}


print ('1: Person hinzufügen')
print ('2: Zeige Personen')

class Person:
	'''Representiert jede Person'''
	def __init__(self, name, number):
		self.name = name
		self.number = number
		print( 'Person: {0}'.format(self.name))

	def tell(self):
		'''Erzählt ihre details'''
		print('Name:"{0}" Nummer:"{1}"\n'.format(self.name, self.number), end="")


do = input('Was möchtest du tun')


def addPerson():
	name = input('Wie ist ihr name? ')
	number = input('Wie ist ihre Nummer? ')
	name = Person(name, number)
	Personen[name] = ''
	f = open(Personenfile, 'ab')
	pickle.dump(Personen, f) # dump das objekt zum file
	f.close()

def zeigePersonen():
	f = open(Personenfile, 'rb')
	Personenspeicher = pickle.load(f) # lädt das object von dem file
	print(Personenspeicher)

if do == '1':
	addPerson()

if do == '2':
	zeigePersonen()
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Du bekommst keine Fehlermeldungen?
Die Zeilen 33 und 34 sehen für mich so aus, als würdest du das Dictionary mit ungültigen Schlüsseln füttern - auch sehen die für mich so aus als wär das gewolltes Verhalten ;)

Aber noch ein paar Worte zum Stil:
1. Es gibt das `with`-Statement, damit kann man übrigens auch nicht mehr vergessen die Objekte zu schliessen ;):

Code: Alles auswählen

with open(Personenfile, "ab") as f:
    pickle.dump(Personen, f)
2. Schau dir mal [wiki]PEP 8 (Übersetzung)[/wiki] oder das Orginal an
Cenz
User
Beiträge: 12
Registriert: Donnerstag 21. Mai 2009, 16:02

In Byte of Python steht man solle ein dictionary erzeugen um darin die Objekte für die Personen abzulegen.
Das ist der einzige weg den ich gefunden habe. Fehlermeldungen bekomme ich keine, nur wenn ich die Personendaten abrufen will:
1: Person hinzufügen
2: Zeige Personen
Was möchtest du tun2
{<__main__.Person object at 0x7f0852210f90>: ''}

Ich werde mir mal gleich den Artikel durchlesen, danke.
Ich fände es trotzdem schön, wenn mir jemand meinen Fehler genau erklärt.
BlackJack

@Cenz: Was hättest Du denn erwartet da zu sehen? Du bekommst genau das zurück was Du in das Dictionary reingesteckt hast. Eine Person als Schlüssel unter dem eine leere Zeichenkette gespeichert ist. Was irgendwo reichlich sinnfrei ist.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Cenz hat geschrieben:{<__main__.Person object at 0x7f0852210f90>: ''}
Hier wird dir ja die Person angezeigt. Da Python natuerlich nicht weiss, was eine Person genau ist, weiss es auch nicht, was genau es anzeigen soll, damit es fuer dich verstaendlich ist. So wird nur der Objekttyp und die Speicheradresse angezeigt.

Moechtest du das aendern, solltest du die __str__-Methode des Person-Klasse ueberschreiben, sodass sie einen vernuenftigen String zurueckgibt, z.B.:

Code: Alles auswählen

def __str__(self):
    return "%s %s" % (self.number, self.name)
Bitte benenne deine Variablennamen (in diesem Fall Personenspeicher) mit Kleinbuchstaben, so ist es sehr verwirrend.

EDIT: Ich hab nicht richtig hingeschaut, BlackJack hat natuerlich Recht. Mein Vorschlag hilft nur, wenn du dir das Person-Objekt selbst ausgeben laesst, nicht ein Dictionary mit einer Person drin.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Cenz
User
Beiträge: 12
Registriert: Donnerstag 21. Mai 2009, 16:02

Also, die Anleitung sieht folgendermaßen aus (Byte of Python)
"Create a class to represent the person's information. Use a dictionary to store person
objects with their name as the key. Use the pickle module to store the objects
persistently on your hard disk. Use the dictionary built-in methods to add, delete and
modify the persons."

Ich habe mein bestes gegeben, das umzusetzen.

Ich habe mich auch schon gewundert was ich als value im dict angeben soll. Wenn ich dort die Nummer angeben würde könnte ich doch nur eine Information zur Person speichern, oder?

Ich würde mich freuen, wenn mir jemand zeigt wie man es besser macht.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich denke der meint da dass der Name als String der Key sein soll, der Value soll das Personenobject sein.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Du sollst den *Namen* als Schlüssel nehmen. Was hast Du genommen? Und wenn Du den Namen nimmst, was sollte dann wohl der Wert sein?

So ein Dictionary bildet Schlüssel auf Werte ab. Wenn man in einem Telefonbuch einen Namen nachschlägt, was möchte man dann finden?

Ausserdem solltest Du immer das gesamte Telefonbuch, also in diesem Fall das Dictionary laden und speichern und nicht Objekte an die Datei anhängen. Dann müsstest Du nämlich auch mühsam solange `load()` aufrufen bis alle einzelnen Objekte wieder ausgelesen sind, und das Löschen von Einträgen wird auch viel komplizierter.
Cenz
User
Beiträge: 12
Registriert: Donnerstag 21. Mai 2009, 16:02

Ok, verstanden.
Kann in einen dict ein key mehr als einen value haben?
Ansonsten könnte ich nicht mehr Informationen als die Nummer angeben was wäre dann mit der email und so weiter. Wozu brauche ich dann überhaupt Klassen wenn ich doch sowieso nur Name und Nummer verwende?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Cenz hat geschrieben:Kann in einen dict ein key mehr als einen value haben?
Nein. Wenn man mehr als einen einzelnen Wert abspeichern will nimmt man Listen oder Objekte.
Cenz hat geschrieben:Ansonsten könnte ich nicht mehr Informationen als die Nummer angeben was wäre dann mit der email und so weiter. Wozu brauche ich dann überhaupt Klassen wenn ich doch sowieso nur Name und Nummer verwende?
Klassen brauchst du wenn du noch weitere Informationen abspeichern willst. Wie etwa die E-Mail-Adresse.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Cenz
User
Beiträge: 12
Registriert: Donnerstag 21. Mai 2009, 16:02

danke :)

Wie muss denn jetzt meine

Code: Alles auswählen

def addPerson():
aussehen damit es funktioniert.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Wie schon gesagt: Zeile 33+34 sind der Knackpunkt.
Das solltest du so ändern:

Code: Alles auswählen

Personen[name] = Person(name, number)
Cenz
User
Beiträge: 12
Registriert: Donnerstag 21. Mai 2009, 16:02

Also nach der Änderung wird die Meldung nur länger:
{<__main__.Person object at 0x7f53a9d3cf90>: <__main__.Person object at 0x7f53a9d3ced0>}
BlackJack

Du musst als Schlüssel den *Namen* nehmen, nicht die ganze `Person`.
Cenz
User
Beiträge: 12
Registriert: Donnerstag 21. Mai 2009, 16:02

Aber wie mache ich das. Das einzige was mir einfällt ist dort name einzugeben.
Ich weiß, das ist nicht nur der Name sondern auch gleichzeitig die Person, wie trenne ich das.?
BlackJack

In dem Du den Namen `name` nicht an das `Person`-Objekt bindest. Einen Namen innerhalb einer Funktion für so unterschiedliche Typen zu "recyclen" ist sowieso keine gute Idee, weil das bei längeren Programmen nur Verwirrung stiftet wenn man immer ganz genau hingucken muss an welcher Stelle nun welcher Typ an den Namen gebunden ist. `name` war ja *vorher* wirklich mal an den Namen gebunden.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Cenz hat geschrieben:Also nach der Änderung wird die Meldung nur länger:
{<__main__.Person object at 0x7f53a9d3cf90>: <__main__.Person object at 0x7f53a9d3ced0>}
Du sollst auch nicht Zeile 34, sondern 33+34 durch meine Zeile ersetzen.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Cenz hat geschrieben:Ich fange gerade an Python zu lernen, ist meine erste Sprache.
Das war dein erster Satz in diesem Thread und vielleicht wäre es nicht das schlechteste, einen Schritt zurück zu gehen, und zunächst einmal die Konstruktion eigener Klassen wegzulassen.

Experimentiere doch erst mal auf einer "niedrigeren Ebene" mit Dictionaries, etwa so:

Code: Alles auswählen

telefonbuch = {}
while True:
	name = input("Gib deinen Nachnamen ein: ")
	if name == "":
		break
	vorname = input("Dein Vorname: ")
	stadt = input("Dein Wohnort: ")
	telefon = input("Deine Telefonnummer: ")
	telefonbuch[name] = {"Vorname":vorname, "Stadt":stadt, "Telefon":telefon}

for name in telefonbuch:
	eintrag = telefonbuch[name]
	print("\nEintrag für {0} {1}:".format(eintrag["Vorname"], name))
	print("Wohnort: {0}  Telefon: {1}".format(eintrag["Stadt"], eintrag["Telefon"]))
Cenz
User
Beiträge: 12
Registriert: Donnerstag 21. Mai 2009, 16:02

cofi hat geschrieben:
Cenz hat geschrieben:Also nach der Änderung wird die Meldung nur länger:
{<__main__.Person object at 0x7f53a9d3cf90>: <__main__.Person object at 0x7f53a9d3ced0>}
Du sollst auch nicht Zeile 34, sondern 33+34 durch meine Zeile ersetzen.
Habe ich auch anschließend gemacht, hat aber nicht viel an der Meldung geändert.

Danke für die viele Hilfe, ich glaube ich lerne noch ein bisschen bevor ich mich wieder an das Projekt Wage. :D
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Das kann nicht sein, denn in Zeile 33 überschreibst du `name` mit dem `Person`-Objekt was eben zu dem seltsamen und unbrauchbaren Dictionary-Mapping führt.
Antworten