Hilfe benötigt: Dictonaries

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.
Antworten
Benutzeravatar
newone_XXV.
User
Beiträge: 50
Registriert: Dienstag 20. Juni 2006, 15:03
Wohnort: Direkt vor meinem PC
Kontaktdaten:

So habe ja gesagt melde mich wenn ich's gar nicht schaffe... was leider auch so ist... :? Ich habe mal versucht mit meine eigenes kommandozeilenbasiertes Adressbuch zu schreiben.... Das ganze sah erst so aus...(Hierbei funkte mir auch immer nach der Ausgabe von der Adresse, Alter und so ein 'None' rein):

Code: Alles auswählen

import cPickle as p

personendatei = 'personenliste.data' # Datei in die, die Liste nachher gespeichert werden soll.

class Person:
      '''Stellt eine Person da.'''
      def __init__(self, name, alter, position, adresse):
          self.name = name
          self.alter = alter
          self.position = position
          self.adresse = adresse
          print 'Person %s initialisiert' % self.name

      def auskunft(self):
          '''Gibt genauere Daten über die Person aus'''
          print 'Name: "%s" Alter: "%s" Position: "%s" Adresse: "%s"' %(self.name, self.alter, self.position, self.adresse)

xyz = Person('xyz', 1, '?', '?')
efe = Person('efe', 1, '?', '?')
gtg = Person('gtg', 1, '?', '?')

# 'Ab' steht für 'A'dress'b'uch
ab = {  'xyz'    :   'xyz@web.de' '12313',
        'efe'    :   'efe@arcor.de',
        'gtg' :   'gtg@gmx.de',
     }

f = file(personendatei, 'w')
p.dump(ab, f) #speichern der Liste
f.close()

del ab # lösche das Adressbuch

# Wieder einlesen des Adressbuches aus der Datei
f = file(personendatei)
gespeicherteliste = p.load(f)
print gespeicherteliste
print xyz.auskunft()
print efe.auskunft()
print gtg.auskunft()
Soweit so gut... Dann habe ich beschlosen dem ganezen mal ein Menü zu geben mit den Funktionen Anzeigen des Buches, Beenden und einer kleinen Suchfunktion... Das sieht wei folt aus:

Code: Alles auswählen

import cPickle as p

personendatei = 'personenliste.data' # Datei in die, die Liste nachher gespeichert werden soll.

class Person:
      '''Stellt eine Person da.'''
      def __init__(self, name, alter, position, adresse):
          self.name = name
          self.alter = alter
          self.position = position
          self.adresse = adresse
          print 'Person %s initialisiert' % self.name

      def auskunft(self):
          '''Gibt genauere Daten über die Person aus'''
          print 'Name: "%s" Alter: "%s" Position: "%s" Adresse: "%s"' %(self.name, self.alter, self.position, self.adresse)

bsp = Person('bsp', 1, 'xyz', 'uvw')

# 'Ab' steht für 'A'dress'b'uch
ab = {       bsp             :      'bsp@bsp.bsp'
     }

f = file(personendatei, 'w')
p.dump(ab, f) #speichern der Liste
f.close()

del ab # Loeschen des Adressbuches

# Wieder einlesen des Adressbuches aus der Datei
f = file(personendatei)
gl = p.load(f) # GL steht fuer GespeicherteListe

def menu():
    print 'Willkommen bei Ihrem Adressbuch! Druecken Sie die ...'
    print '1 um das(komplette!) Adressbuch einzusehen'
    print '2 um einen Namen im Adressbuch zu suchen'
    print '3 um genauere Info´s ueber die Leute in Ihrem Adressbuch zu erhalten'
    print '4 um das Menue nocheinmal anzuzeiegen'
    print '5 um das Programm zu beenden'
option = 0
print menu()
while True:
    option = input('Geben Sie nun bitte eine der Zahlen ein! ')
    if option == 1:
        if len(gl) >= 0:
            for name, email in gl.items():
                print '%s hat folgende E-Mail-Adresse: %s' % (name, email)
        else:
            print 'Das Adressbuch hat leider noch keine Eintraege'
    elif option == 2:
        suchname = raw_input('Geben Sie bitte den Namen ein, den Sie im Adressbuch suchen moechten: ')
        if gl.has_key(suchname):
            print '%s hat die E-Mail-Adresse %s' % (suchname, gl.suchname)
        else:
            print 'Name nicht im Adressbuch! Ueberpruefen Sie ggf. die Schreibweise!'
    elif option == 3:
        if len(gl) >= 0:
            info_name = raw_input('Geben Sie den Namen ein zu dem Sie genaueres wissen wollen: ')
            if info_name in gl:
                info.name.auskunft()
            else:
                print 'Name nicht im Adressbuch! Ueberpruefen Sie ggf. die Schreibweise!'
        else:
            print 'Ihr Adressbuch hat leider noch keine Eintraege!'
    elif option == 4:
        print menu()  
    elif option == 5:
        print 'Auf Wiedersehn!'
        break
    else:
        print 'Nichtgültige Eingabe! Bitte waehlen Sie erneut!'

So nun gibt´s folgende Probleme:
1. Immer wenn das Menü erscheint gibt´s unter Option 5 ein 'None'
2. Bei Option 1 wird immer '<__main__.Person instance at 0x00B845A8>' statt 'bsp' angezeigt
3. bei 2 kommt immer nur Name nicht im Adressbuch wenn ich nach Bsp suche... Ebenso bei 3

Alles in allem das einzigste was funktioniert ist Option 5 (die aber ausgezeichnet ;)) und 4, wenn auch mit einem unschoenen 'None'... Wäre nett wenn Ihr mir helfen könntet, weil mir macht´s schon Spaß... Aber ist auch frustrierend, wenn man nur "Hallo Welt!" schreiben kann und bei so etwas kapitulieren muss.... Also bitte helft mir!.....[/code]
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

zu 2 u 3:
ich würde dir empfehlen, dir mal die klassen anzusehen, dann verstehst du auch das mit der "Person". bissl googlen. und selber lernen halte ich für am sinnvollsten.
zu 1 kann ich leider nichts sagen, sehe da nichts un kann das nich ausprobieren, weil alle c-bibliotheken für python bei mir schrott sind.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Zu 1: Zeile 43 aendern zu

Code: Alles auswählen

menu()
Das print ist ueberfluessig. Die Funktion menu() druckt ja schon alles aus, und print menu() druckt dann zusaetzlich den Rueckgabewert der Funktion menu(). Und der ist nunmal None, da nichts explizit zurueckgegeben wird (mit return).
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Habe dir mal Teile deines Codes kommentiert:

Code: Alles auswählen

#Hier wird eine abstrakte Personen-Klasse erstellt: Zu einer Person werden
#Name, Alter Adresse uwsw. gespeichert
class Person:
      '''Stellt eine Person da.'''
      def __init__(self, name, alter, position, adresse):
          self.name = name
          self.alter = alter
          self.position = position
          self.adresse = adresse
          print 'Person %s initialisiert' % self.name

      def auskunft(self):
          '''Gibt genauere Daten über die Person aus'''
          print 'Name: "%s" Alter: "%s" Position: "%s" Adresse: "%s"' %(self.name, self.alter, self.position, self.adresse)


#Hier wir ein Objekt der Personen-Klasse erstellt, d.h. mit der obigen
#"Schablone" eine konkrete Person mit Namem 'bsp', Alter '1', Position 'xyz'
#und Adresse 'uvw' erstellt:
bsp = Person('bsp', 1, 'xyz', 'uvw')

#Hier wird's jetzt merkwuerdig: du ordnest das obige Personenobjekt einer
#Emailadresse zu. Das ist sinnlos. Entweder tust du die Email noch mit
#in die obige Klasse, und dann wird das ganze Adressbuch einfach eine Liste.
#Oder "bsp" wird einfach nur ein String (der Name)
ab = { bsp  :   'bsp@bsp.bsp' }

#Variante 1:
ab1 = [bsp]

#Variante 2:
ab2 = {"Otto Normalverbraucher" : 'bsp@bsp.bsp'}

#Ausdrucken eines Eintrags: Dein Code funktioniert nur mit ab2, du behandelst
#hier den key des Dictionaries wieder wie einen String. Der Key ist aber
#nach wie vor ein Personen-Objekt. 
print '%s hat die E-Mail-Adresse %s' % (suchname, gl.suchname)

#Ausdrucken eines Personen-Objekts:
bsp.auskunkft()
Wie gesagt, du mischst zwei Dinge durcheinander. Du musst dich entscheiden, ob du mit der Personen-Klasse arbeiten willst, oder mit einem Dictionary, dass einem Namens-String einen Adress-String zuordnet.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

murph hat geschrieben:zu 1 kann ich leider nichts sagen, sehe da nichts un kann das nich ausprobieren, weil alle c-bibliotheken für python bei mir schrott sind.
Du weißt schon, dass pickle und cPickle API-kompatibel sind?
wenn du das

Code: Alles auswählen

import cPickle as p
durch

Code: Alles auswählen

import pickle as p
ersetzt sollte das gehen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

ach stimmt ja...bei den sqlite-wrappern ist das unterschiedlcih, die sind nicht umbedingt "befehlskompatibal". thx. leonidas
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

murph hat geschrieben:bei den sqlite-wrappern ist das unterschiedlcih, die sind nicht umbedingt "befehlskompatibal".
Das sind keine "SQLite-Wrapper" sondern Datenbankmodule die die DB-API 2.0 implementieren. PySQLite ist eines davon, aber psycopg ist ebenso eines, genauso wie MySQLdb.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

ich arbeite mit apsw, das ist definitiv ein wrapper, der arbeitet nicht mit DB-API 2.0.
8-)
Benutzeravatar
newone_XXV.
User
Beiträge: 50
Registriert: Dienstag 20. Juni 2006, 15:03
Wohnort: Direkt vor meinem PC
Kontaktdaten:

Ersteinmal ein großes Danke für die vielen Antworten :D Habe mit der Hilfe von Mister Google und Co das ganze jetzt so gemacht:

Code: Alles auswählen

import cPickle as p

personendatei = 'personenliste.data' # Datei in die, die Liste nachher gespeichert werden soll.

class Person:
      '''Stellt eine Person da.'''
      def __init__(self, name, alter, position, adresse, email):
          self.name = name
          self.alter = alter
          self.position = position
          self.adresse = adresse
          self.email = email
          print 'Person %s initialisiert' % self.name

      def auskunft(self):
          '''Gibt genauere Daten über die Person aus'''
          print 'Name: "%s" Alter: "%s" Position: "%s" Adresse: "%s" Email: "%s"' %(self.name, self.alter, self.position, self.adresse, self.email)


# 'Ab' steht für 'A'dress'b'uch
bsp = Person('Bsp', '1', 'testuser', 'heimcomputer', 'bst.testuser@heimpc.de')
ab = [ bsp ]

x = 0     # Da ich das nocht nicht aus meinem Programm komplett entfernen will
if x == 1:  # umgehe ich es einfach mal so...
   f = file(personendatei, 'w')
   p.dump(ab, f)
   f.close()

del ab # Loeschen des Adressbuches


# Wieder einlesen des Adressbuches aus der Datei
f = file(personendatei)
gl = p.load(f) # GL steht fuer GespeicherteListe

def menu():  # Das Menue
    print 'Willkommen bei Ihrem Adressbuch! Druecken Sie die ...'
    print '1 um das(komplette!) Adressbuch einzusehen'
    print '2 um einen Namen im Adressbuch zu suchen'
    print '3 um einen neuen Kontakt hizuzufuegen'
    print '4 um einen Kontakt im Adressbuch zu loeschen'
    print '5 um das Adressbuch zu speichern'
    print '6 um das Menue nocheinmal anzuzeiegen'
    print '7 um das Programm zu beenden'
option = 0
menu()
while True:
    option = raw_input('Geben Sie nun bitte eine der Zahlen ein! ')
    if option == '1': # Anzeigen des gesamten Adressbuches
        if len(gl) >= 0:
            for item in gl:
                item.auskunft()
        else:
            print 'Das Adressbuch hat leider noch keine Eintraege'
    elif option == '2':  # Die Suchoption
            item = raw_input('Geben Sie bitte den Namen ein, den Sie im Adressbuch suchen moechten: ')
            if item in gl:
                item.auskunft()
            else:
                print 'Name nicht im Adressbuch! Ueberpruefen Sie ggf. die Schreibweise!'
    elif option == '3': # Erstellen eines neuen Kontaktes, wobei erst alle Daten ueber den Kontakt eingegeben werden
        neu_name = raw_input('Geben Sie den Namen des neuen Kontaktes ein: ')
        neu_alter = raw_input('Geben Sie das Alter des neuen Kontaktes ein: ')
        neu_position = raw_input('Geben Sie die Beziehung zu Ihrem neuen Kontakt ein! z.B. bester Freund: ')
        neu_adresse = raw_input('Geben Sie den Wohnort(Strasse, Ort, PLZ, und ggf. Land) an: ')
        neu_email = raw_input('Geben Sie nun die E-Mali-Adresse des Kontaktes ein: ')
        neu_name = Person(neu_name, neu_alter, neu_position, neu_adresse, neu_email)
        gl.append(neu_name)
    elif option == '4': # Die loeschfunktion
        loeschname = raw_input('Geben Sie den Namen des Kontaktes ein, den Sie loeschen moechten: ')
        if loeschname in gl:
            index_zahl = gl.index(loeschname)
            del gl[index_zahl]
            if loeschname in gl:
                print 'Loeschen fehlgeschlagen'
            else:
                print 'Loeschen erfolgreich'
        else:
            print 'Name nicht im Adressbuch! Ueberpruefen Sie ggf. die Schreibweise!'
    elif option == '5': # Das speichern der Liste mittels cPickle
        f = file(personendatei, 'w')
        p.dump(gl, f)
        f.close()
        print 'Sicherung des Adressbuches erfolgreich'
    elif option == '6': # Ausgabe des Menues
        menu()
    elif option == '7':  # Beenden des Programmes
        print 'Auf Wiedersehn!'
        break
    else: # Ausgabe falls eine nicht definierte Option eingegeben wird
        print 'Nichtgültige Eingabe! Bitte waehlen Sie erneut!'
Dabei sind leider 2 neue Probleme aufgetaucht und ich weiß wirklich nicht mehr weiter...
Das erste der Probleme ist dass die Suchfunktion immer noch nicht funktioniert und das Zweite ist die ebenfalls immer noch nicht funktionierende Löschfunktion.... Könnte mir vllt. jmd. bitte sagen wo der (?Denk-?)Fehler liegt?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

murph hat geschrieben:ich arbeite mit apsw, das ist definitiv ein wrapper, der arbeitet nicht mit DB-API 2.0.
Tja, hättst halt PySQLite genommen, dann hättest etwas "Befehlskompatibles".
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

murph hat geschrieben:ich arbeite mit apsw
Hi murph!

Was gibt es noch für einen Grund, mit Python etwas anderes als einen DB-API 2.0 kompatiblen Wraper zu verwenden? pySQLite wird ab Python 2.5 mit dabei sein. Jetzt noch etwas anderes zu lernen ist kontraproduktiv.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

es hat keinen genauen grund, warum ich apsw genommen habe...
wenn pysqlite das in 2.5 zur stdlib gehörende ist, werde ich darauf umsteigen.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Newone, bei dem Suchen machst du:

Code: Alles auswählen

if item in gl:
item ist ein String, und die Eintraege in gl sind aber Objekte, d.h. Instanzen der Klasse Person.

Code: Alles auswählen

for g in gl:
      print g
ergibt naemlich

Code: Alles auswählen

<__main__.Person instance at 0x402d790c>
und eben nicht 'Bsp'. Du vergleichst also Aepfel mit Birnen. Du willst ja den eingegebenen String mit dem Namen einer Person vergleichen, d.h. deine Abfrage sollte so aussehen:

Code: Alles auswählen

for pers in gl:
    if pers.name == item:
        pers.auskunft()
        break
else:
    print 'Name nicht im Adressbuch! Ueberpruefen Sie ggf. die Schreibweise'
Gleiches gilt fuers Loeschen.
Benutzeravatar
newone_XXV.
User
Beiträge: 50
Registriert: Dienstag 20. Juni 2006, 15:03
Wohnort: Direkt vor meinem PC
Kontaktdaten:

Ersteinmal danke für diese Erklärung... So ist das also.... Nun ist das auch mir klar geworden... (gleube ich und hoffe ich) Das Suchen geht jetzt, aber das Löschen immer noch nicht... :( Immer wenn ich etwas löschen lasse und mir dann das Adressbuch anzeigen lasse steht 'Bsp' immer noch im Adressbuch... So langsam glaube ich, dass ich da zu dumm für bin.... :( Oder mache ich schon wieder den gleichen Fehler?
Also nocheinmal der Code so wie das Löschen jetzt aussieht... Was mache ich denn diesmal falsch?:

Code: Alles auswählen

    elif option == '4':
        item = raw_input('Geben Sie den Namen des Kontaktes ein, den Sie loeschen moechten:')
        for pers in gl:
            if pers.name == item:
                del pers
                break
[/code]
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Nein, du hast nicht den gleichen Fehler nochmal gemacht. :)

Das Problem liegt darin, dass Python alle Variablen eigntlich Referenzen sind. Bsp:

Code: Alles auswählen

>>> class Person:
...     def __init__(self, name):
...         self.name = name
... 
>>> liste = [Person("Hans"), Person("Helga")]
>>> print liste
[<__main__.Person instance at 0x402d6c0c>, <__main__.Person instance at 0x402d6c6c>]
Es werden die beiden Objekte Hans und Helga erzeugt und irgenwo im Speicher abgelegt. Die Liste enthaelt nicht die Objekte selbst, sondern lediglich Referenzen auf die Position im Speicher (in diesem Fall liegen Hans und Helga bei den Speicher-Adressen 0x402d6c0c und 0x402d6c6c).

Bei folgender Schleife

Code: Alles auswählen

>>> for p in liste: print p
... 
<__main__.Person instance at 0x402d6c0c>
<__main__.Person instance at 0x402d6c6c>
durchlaeuft p die Liste. Aber p ist wiederum kein Personen-Objekt, sondern nur eine Referenz auf die Positionen von Hans und Helga im Speicher. Meist bemerkt man gar nicht, dass man mit Referenzen arbeitet statt mit den Objekten selbst , aber wenn du nun einfach del p machst, loeschst du die eine Referenz auf das entsprechende Objekt. Die Liste bleibt davon unbeeinflusst, denn sie enthaelt eigene Referenzen auf die Objekte, die immer noch im Speicher sind. Um die Referenz zu loeschen, die in der Liste enthalten ist:

Code: Alles auswählen

>>> for p in liste:
...     if p.name == "Helga":
...         liste.remove(p);
Python ist dann so freundlich, alle Objekte im Speicher zu loeschen, auf die keine Referenz mehr zeigt (das nennt sich Garbage Collection). D.h. wenn du den Listeneintrag, der eine Referenz auf Helga ist, loeschst und die Laufvariable p auch nicht mehr auf Helga zeigt, enfernt Python das Objekt Helga komplett aus dem Speicher.
Benutzeravatar
newone_XXV.
User
Beiträge: 50
Registriert: Dienstag 20. Juni 2006, 15:03
Wohnort: Direkt vor meinem PC
Kontaktdaten:

Ganz großes Danke :D für die beiden Erklärungen! Nun funktioniert es endlich einwandfrei...
Antworten