__str__(self, index)

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.
KOR
User
Beiträge: 6
Registriert: Dienstag 6. November 2007, 15:05

__str__(self, index)

Beitragvon KOR » Dienstag 6. November 2007, 15:17

ich habe mir ne kleine Vektorkalsse geschriben:

Code: Alles auswählen

class Vector3D:
    def __init__(self):
        self.v=[0,0,0]
    def fill(self,x=0,y=0,z=0):
        self.v[0]=x
        self.v[1]=y
        self.v[2]=z
        return self
    def __add__(self,other):
        self.v[0]+=other.v[0]
        self.v[1]+=other.v[1]
        self.v[2]+=other.v[2]
        return self
    def __sub__(self, other):
        self.v[0]-=other.v[0]
        self.v[1]-=other.v[1]
        self.v[2]-=other.v[2]
        return self
    def __mul__(self,other):
        try:
            #other is a vector
            self.v[0]=self.v[1]*other.v[2]-self.v[2]*other.v[1]
            self.v[1]=self.v[2]*other.v[0]-self.v[0]*other.v[2]
            self.v[2]=self.v[0]*other.v[1]-self.v[1]*other.v[0]
        except:
            #other is a scalar
            self.v[0]*=other
            self.v[1]*=other
            self.v[2]*=other
        return self
    def length(self):
        return(round(sqrt(self.v[0]**2+self.v[1]**2+self.v[2]**2),6))
    def normalize(self):
        length=self.length()
        self.v[0]=self.v[0]/length
        self.v[1]=self.v[1]/length
        self.v[2]=self.v[2]/length
        return self
    def show(self):
        print "[",self.v[0],"]"
        print "[",self.v[1],"]"
        print "[",self.v[2],"]"
    def __str__(self):
        string="["+str(self.v[0])+"]\n["+str(self.v[1])+"]\n["+str(self.v[2])+"]"
        return string
    def __getitem__(self, index):
        try:
            return self.v[index]
        except:
            print "Error index out of range it's a 3D Vector"
    def scalarproduct(self,other):
        print "not yet implementet"

so in diesem script habe ich mir nen vector definiert und ihn mit print ausgegeben:

Code: Alles auswählen

...
vec1.fill(2,0,0)
print "Vector mit print"
print vec1

funktioniert auch jetzt das problem ich habe mir in nem zweiten modul ne liste mit vectoren geschriben und wollte die per print ausgeben und jetzt bekomme ich als ausgabe vector instance at...
Code vom zweiten modul:

Code: Alles auswählen

...
for i in range(nat):
        l=coords[i]
        vec=Vector3D()
        vec.fill(l[0],l[1],l[2])
        molecule.append(vec)
...
for i in range(nat):
        print sym[i]
        molecule[i].show()#funktioniert
        print molecule[i] #funktioniert nicht
...


hat jemand ne ahnung wieso nicht und kann mir sagen was ich ändern muss
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Dienstag 6. November 2007, 15:37

guck mal, was rauskommt, wenn du dir deine Liste printen lässt. Dann probier mal "print str(molecule[i])". Sonst kannste auch mal die gesammte Fehlermeldung posten.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Dienstag 6. November 2007, 15:38

Hallo und willkommen im Forum,

ersetze doch einfach __str__ durch __repr__.

Allgemeine Anmerkung: Mir scheint, Du fängst gerade an in Python zu schreiben und dafür ist es echt gut! Aber warum schreibst Du immer return self, ist das gewollt?

Gruß,
Christian
BlackJack

Beitragvon BlackJack » Dienstag 6. November 2007, 15:42

@KOR: `list.__str__()` benutzt die `repr()`-Form der enthaltenen Objekte. Also müsstest Du `__repr__()` überschreiben. Wenn `__str__()` und `__repr__()` das gleiche ergeben sollen reicht es aus `__repr__()` zu implementieren. Das Standard-`__str__()` greift dann darauf zurück.

Die Darstellung wird durch die Zeilenenden aber bestimmt ziemlich "zerhauen", d.h. so eine Liste mit Vektoren auszugeben bringt nicht viel ausser Verwirrung.

Die `fill()`-Methode könnte man weglassen und stattdessen `x`, `y` und `z` in der `__init__()` übergeben jeweils mit 0 als default-Wert.

Und wenn Du die Rechnungen so lässt, wäre es günstiger die Werte auch auf drei Attribute zu verteilen statt in eine Liste zu stecken. Dann spart man sich die ganze Indexerei. Oder Du benutzt "list comprehensions", dann macht die Liste Sinn.

Das die Rechenoperationen den ersten Operanden verändern ist sehr ungewöhnlich. Wenn man so etwas sieht wie ``c = a + b`` dann erwartet man nicht, dass `a` hinterher einen anderen Wert hat.

Ein ``except`` ohne konkrete Ausnahme maskiert und versteckt *alle* Ausnahmen. Auch solche die man vielleicht gerne sehen möchte weil man damit einen Fehler finden kann.

Warum wird in `length()` gerundet!? Und man könnte die Methode `__abs__()` nennen, weil in der Mathematik hier auch die Betragsstriche zum Einsatz kommen.

`show()` kommt mir überflüssig vor, da es nichts anderes ist, als das Objekt mit ``print`` auszugeben, also ``vector.show()`` äquivalent zu ``print vector`` ist.

Die Ausnahmebehandlung in `__getitem__()` ist "falsch", es sei denn Du möchtest das mit `None` weitergerechnet wird, wenn der `index` nicht zwischen 0 und 2 lag. Und iterierbar ist der Vektor damit auch nicht mehr.
KOR
User
Beiträge: 6
Registriert: Dienstag 6. November 2007, 15:05

Beitragvon KOR » Dienstag 6. November 2007, 16:19

Code: Alles auswählen

def __repr__(self):
        return "["+str(self.v[0])+"]\n["+str(self.v[1])+"]\n["+str(self.v[2])+"]"

Die vector klasse hat inzwischen die funktion erhalten
wenn ich print molecule[i] schreibe kommt als Ausgabe:<vector.Vector3D instance at 0x014ADF58> genau wie vorher
Vielen dank für die schnelle hilfe
das mit den Opperationen ist mir gerade aufgefallen ist ja peinlich änder ich auch gleich.
__abs__() kenne ich noch nicht aber wird auch noch angeschaut.
@CM: ich fange nicht gerade an ich habe nur lange nicht mehr in Python geschrieben. das return self ist meistens gewollt teilweise aber überflüssig
@BlackJack: ich hatte ursprünglich auch einzelkomponenten aber mein Assi hat gesagt wir solln mit Listen arbeiten:-)
Zuletzt geändert von KOR am Dienstag 6. November 2007, 17:51, insgesamt 1-mal geändert.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Dienstag 6. November 2007, 16:42

Wenn ich, __repr__() vorausgesetzt,

Code: Alles auswählen

l = [Vector3D() for x in range(3)]
print l
print l[1]

schreibe, funktioniert das einwandfrei (ja, das Beispiel ist unschön ... und ja, die Ausgabe sieht verwirrend aus - schau Dir mal an, wie das in numpy gelöst ist). Was genau ist molecule? Was hast Du sonst noch verändert?

Gruß,
Christian
KOR
User
Beiträge: 6
Registriert: Dienstag 6. November 2007, 15:05

Beitragvon KOR » Dienstag 6. November 2007, 17:14

molecule ist eine liste die vectoren in meinem beispiel acht enthält. diese Vectoren sind punktvectoren die auf Atome eines molekühls zeigen. Verändert habe ich sonst nichts
ich habe mal deinen code eingefügt:
der consolenoutput war:
[<vector.Vector3D instance at 0x014D5D50>, <vector.Vector3D instance at 0x014D5D78>, <vector.Vector3D instance at 0x014D5CD8>]
<vector.Vector3D instance at 0x014D5D78>
KOR
User
Beiträge: 6
Registriert: Dienstag 6. November 2007, 15:05

Beitragvon KOR » Dienstag 6. November 2007, 18:05

Ja ich habs gelöst vielen dank an alle die so schnell geholfen haben.
das problem war das python immer wieder eine alte version von meiner vector biblio gelesen hat ich habe die pyc gelöscht und alles neu gestartet dann gings. Ich bin so blöd aber naja Erfahrung ist eine strenge lehrerin sie stellt die Prüfungen vor dem Unterricht.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Dienstag 6. November 2007, 22:53

KOR hat geschrieben:@BlackJack: ich hatte ursprünglich auch einzelkomponenten aber mein Assi hat gesagt wir solln mit Listen arbeiten:-)

Was durchaus sinnvoll sein kann:
http://www.python-forum.de/viewtopic.php?p=78776
(allerdings würde ich doch eher einen array-type nehmen).

Schön, daß Du es geschafft hast.
Christian
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Mittwoch 7. November 2007, 11:34

`__repr__` sieht so doch gleich netter aus:

Code: Alles auswählen

def __repr__(self):
        return "[%s]\n[%s]\n[%s]" % tuple(self.v)


Wenn man `self.v` zu einer Tupel und somit immutable macht, was wie ich finde im vorliegenden Fall eine gute Idee ist spart man sich sogar das `tuple()`.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
skypa
User
Beiträge: 97
Registriert: Freitag 5. Januar 2007, 03:13

Beitragvon skypa » Mittwoch 7. November 2007, 13:00

@KOR:
Kannst mal den gesamten Code posten bzw. pasten? Zu Lernzwecken versteht sich! :wink:

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]