[geloest] class durchsuchen

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
nihilist
User
Beiträge: 28
Registriert: Dienstag 13. Februar 2007, 07:02

Hallo,
Ich suche nach einer Möglichkeit um eine Klasse

Code: Alles auswählen

class Movie:
    def __init__(self, name, actor, year, direct, lend):
        self.name = name
        self.actor = actor
        self.year = year
        self.direct = direct
        self.lend = lend
zu durchsuchen.
Dabei soll nach einem String, der durch Benutzereingabe erfolgt, die ganze Klasse durchsucht werden und dann jeweils die ganze Zeile ausgegeben werden.

Ich habe mir jetzt mal Regular Expressions angeschaut.
Man kann ja z.B. mit

Code: Alles auswählen

        
        m = p.search([a-z])
        if m: 
            print 'Match found ' , m.group()
        else:
             print 'Nix'
nach kleinbuchstaben suchen.
Wie man statt dem [a-z] gleich die komplette Klasse angeben, die dann nach dem String durchsucht wird.
Zuletzt geändert von nihilist am Montag 19. Februar 2007, 17:42, insgesamt 1-mal geändert.
BlackJack

Ich verstehe die Frage nicht so ganz. Klassen sind Objekte, die haben keine Zeilen. Oder möchtest Du in Quelltextdateien suchen und die Suche auf den Quelltextabschnitt einer bestimmten Klasse beschränken!?

Letzteres dürfte mit einem regulären Ausdruck alleine nicht möglich sein.

Ist es erlaubt das Modul zu importieren? Dann kann man wahrscheinlich mit dem `inspect`-Modul die Klassen und deren Zeilennummern im Quelltext herausfinden. Ansonsten wird man wohl einen kleinen einfachen Parser schreiben müssen, der die Klassen identifiziert.
nihilist
User
Beiträge: 28
Registriert: Dienstag 13. Februar 2007, 07:02

ok ich hab mich etwas unverständlich ausgedrückt.
Ich denke das was ich möchte ist einfacher.

Hier mal das fast komplette Programm:




Code: Alles auswählen

choice = 0
weiter = True
import pickle as p
import os,sys
import simm_help
import re
moviefile = '/home/michael/.simmsave'
neufilm = []

class Movie:
    def __init__(self, name, actor, year, regie, lend):
        self.name = name
        self.actor = actor
        self.year = year
        self.regie = regie
        self.lend = lend
        print 'Film %s added' % self.name


    def __cmp__(self, other):
        return cmp(self.name, other.name)

    def __str__(self):
        return "%-25s %-40s %-20s %-4s %-10s" % (self.name, self.actor, self.year, self.regie, self.lend)


    def info(self):
        print '"%s" "%s" "%s"  "%s" "%s" ' % (self.name, self.actor, self.year, self.regie, self.lend)

        # print "|%-20s|%-20s|" % ("Hallo", "Servus")



try:
    f = file(moviefile)
    sl = p.load(f)

except:
    ab = []
    f = file(moviefile, 'w')
    p.dump(ab, f)
    f.close()

print   '                   (1) Filmliste anzeigen'
print   '                   (2) Film suchen'
menu()
while True:

 if choice == '1':
        sl.sort()
        print "%-25s %-40s %-20s %-4s %-10s"  % ("Titel", "Schauspieler", "Regie", "Jahr", "Ausgeliehen")
        print '----------------------------------------------------------------------------------------------------------'
        for entry in sl:
            print entry
        print '----------------------------------------------------------------------------------------------------------'
    elif choice == '2':
        searchstring = raw_input('Suchen nach: ')

Und genau da bin ich jetzt. Ich möchte wenn ich z.B. nach Rob
suche, er mir die Zeile mit dem Film Robin Hood ausgiebt sowie sie Zeile mit dem Schauspieler Robert de Niro.
Du hast geschrieben das Klassen Objekte sind und keine Zeilen besitzen, aber ich weiß nicht wie ich das hier sonst anders beschreiben soll.
Ich denke es ist klar was ich möchte, aber ob das so einfach ist wie ich mir das vorstelle? ;-)
BlackJack

Du könntest den `Movie`-Objekten eine `search()`-Methode verpassen, die die Attribute durchsucht (ungetestet):

Code: Alles auswählen

    def search(self, string):
        for attribute in (self.name, self.actor, self.year, self.regie):
            if string in attribute:
                return True
        return False
Dann kannst Du alle Filme durchgehen und jeden "fragen" ob die gewünschte Zeichenkette vorkommt.
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

@nihilist: Hallo...

Ich dachte mir sowas schon. Du willst schlicht und einfach alle Argumente der Klasse durchsuchen. Dafuer koenntest du dir zB eine Methode in die Klasse setzen:

Code: Alles auswählen

class Movie:
    def __init__(self, name, actor, year, regie, lend):
        self._name = name
        self._actor = actor
        self._year = year
        self._regie = regie
        self._lend = lend
        print 'Film %s added' % self._name

    def __cmp__(self, other):
        return cmp(self.name, other.name)

    def __str__(self):
        return "%-25s %-40s %-20s %-4s %-10s" %\
            (self._name, self._actor, self._year, self._regie, self._lend)

    def info(self):
        print self._name, self._actor, self._year, self._regie, self._lend

    def search(self, s):
        for attr in (self._name, self._actor, self._year, self._regie, self._lend):
            if s in attr: print attr
PS: ich hab mir mal erlaubt ein paar Zeilen anzupassen...

Achja, du hast im spaeteren Code-Verlauf so schicke Zeilen wie:

Code: Alles auswählen

print "----------------------------------------------------------------"
...das geht mit Hilfe des Multiplikationsoperators sehr viel kuerzer und lesbarer:

Code: Alles auswählen

print "-"*50 #oder wieviele auch immer
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
nihilist
User
Beiträge: 28
Registriert: Dienstag 13. Februar 2007, 07:02

Wie kann ich die Funktion dann aufrufen?
So

Code: Alles auswählen

 s = raw_input('Suchen nach: ')
 s.search()
geht wohl nicht?

Und danke für:

Code: Alles auswählen

 print '-'*105
Ist wirklich sehr viel übersichtlicher
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Falls du eine Konsole verwendest solltest du nicht ueber 80 Zeichen kommen... am besten sind 79, also:

Code: Alles auswählen

print '-'*79

Ansonsten rufst du die search-Methode mit dem zu suchenden String als Parameter auf, in pythonisch:

Code: Alles auswählen

bla = Movie(argumente...)
s=raw_input("Suchstring eingeben: ")
bla.search(s)
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
nihilist
User
Beiträge: 28
Registriert: Dienstag 13. Februar 2007, 07:02

Versteh ich nicht:

Code: Alles auswählen

 bla = Movie(name, actor, year, regie, lend)
 s = raw_input('Suchen nach: ')
 bla.search(s)
sollte doch gehen, aber

Code: Alles auswählen

Traceback (most recent call last):
  File "./simm-0.2.py", line 117, in ?
    bla = Movie(name, actor, year, regie, lend)
NameError: name 'name' is not defined
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Die uebergebenen parameter sind variablen, die nicht existieren.

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

class Movie:
    def __init__(self, name, actor, year, regie, lend):
        self._name = name
        self._actor = actor
        self._year = year
        self._regie = regie
        self._lend = lend
        print 'Film %s added' % self._name

    def __cmp__(self, other):
        return cmp(self.name, other.name)

    def __str__(self):
        return "%-25s %-40s %-20s %-4s %-10s" %\
            (self._name, self._actor, self._year, self._regie, self._lend)

    def info(self):
        print self._name, self._actor, self._year, self._regie, self._lend

    def search(self, s):
        for attr in (self._name, self._actor, self._year, self._regie, self._lend):
            if s in attr: print attr

m = Movie("name", "actor", "year", "regie", "lend")
m.search("e")

EDIT: Es geht um die Anfuehrungsstriche... verstehst?
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
nihilist
User
Beiträge: 28
Registriert: Dienstag 13. Februar 2007, 07:02

Nein,
wenn ich die Anführungstriche setze, sucht er doch nur in den Wörtern
name,actor usw..., d.h. er behandelt sie wie strings.

Wie kann ich dann die gespeicherten Inhalte durchsuchen?

Vielleicht stelle ich mich auch extrem blöd an, aber bitte ein bischen Geduld noch...:-)


Edit:
Oder meintest du das ich die Variablen noch initialisieren muss? Aber das ist ja eigentlich schon oben geschehen?
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Ehm... die Klasse "Movie" bekommt doch die Variablen uebergeben. Vielleicht solltest du dich erstmal ein wenig naeher mit der Funktionsweise der Klasse auseinandersetzen??

Hier noch ein (eigentlich idiotensicherer) Versuch eines Beispiels:

Code: Alles auswählen

m = Movie("Good Will Hunting", "Ben Affleck, Matt Damon, Robin Williams", "1997", "Gus Van Sant", "nicht verliehen")
Es ginge zB auch so:

Code: Alles auswählen

name = "Good Will Hunting"
actors = "Ben Affleck, Matt Damon, Robin Williams"
year = "1997"
regie = "Gus Van Sant"
lend = "nicht verliehen"

m = Movie(name, actor, year, regie, lend)
m.search("Williams")
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
nihilist
User
Beiträge: 28
Registriert: Dienstag 13. Februar 2007, 07:02

nkoehring hat geschrieben:. Vielleicht solltest du dich erstmal ein wenig naeher mit der Funktionsweise der Klasse auseinandersetzen??
Das denke ich mir auch gerade...

Zu deinen Beispielen:
Das verstehe ich und es funktioniert bei mir auch, aber wenn ich schon etliche Filme gespeichert habe. und diese durchsuchen möchte, muss ich es doch eingentlich so:

Code: Alles auswählen

bla = Movie(name, actor, regie, year, lend)
schreiben, und nicht die Variablen noch mal vor der suchaktion festlegen?

Die Verschiedenen Daten lasse ich so eingeben:

Code: Alles auswählen

 elif choice == '3':
        new_name = raw_input('Filmname: ')
        new_actor = raw_input('Schauspieler: ' )
        new_regie = raw_input('Regie: ')
        new_year = raw_input('Jahr: ')
        new_lend = raw_input('Ausgeliehen: ')
        new_name = Movie(new_name, new_actor, new_regie, new_year, new_lend)
        sl.append(new_name)
Mir fehlt das Verständniss wie ich die Suchfunktion auf schon gespeicherte Daten "loslassen" kann.
BlackJack

Den Namen `new_name` einmal für den Namen und dann für ein `Movie`-Objekt zu benutzen ist ein wenig irreführend. Der 'new_'-Präfix bei den ganzen Namen ist IMHO überflüssig.

Du hast jetzt eine Liste mit `Movie`-Objekten. Und jedes dieser Objekte hat eine `search()`-Methode. Die musst Du auf jedem aufrufen. Angenommen die Methode gibt `True` oder `False` zurück, dann könnte das so aussehen:

Code: Alles auswählen

for movie in movies:
    if movie.search('Rob'):
        print movie
nihilist
User
Beiträge: 28
Registriert: Dienstag 13. Februar 2007, 07:02

jetzt hats funktioniert ;-) ...

Danke euch beiden für die Hilfe, Geduld und eure Tipps.
Habt mir sehr weitergeholfen...
Antworten