Seite 1 von 1

Attribut nicht vorhanden?

Verfasst: Freitag 2. August 2019, 04:18
von Newbe
Hallo zusammen,
leider verstehe ich den Fehler in meinem Code nicht, vielleicht könnt ihr mir hier helfen.
Das ist der Programmcode:

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
import scipy.integrate as integrate
from scipy.spatial.distance import pdist, squareform


from Box import Box

np.random.seed(0)
init_status = -0.5 + np.random.random((50,4))
init_status[2] = init_status[2] * 3.9

kiste = Box()
dt = 1. / 30


fig = plt.figure()
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
ax = fig.add_subplot(111)
ax.set_xlim((-3,3))
ax.set_ylim((-3,3))

punkt, = ax.plot([],[],'ro',ms=6)

rechteck = plt.Rectangle(kiste.grenzen[0:3:2],kiste.grenzen[1]-kiste.grenzen[0],kiste.grenzen[3]-kiste.grenzen[2],ec='none',lw=2,fc='none')
ax.add_patch(rechteck)

def init():
    global box, rechteck
    punkt.set_data([],[])
    return (punkt)

def animate(i):
    global box,dt,ax,fig, rechteck
    kiste.bewegen(i)
    
    punkt.set_data(kiste.status[0], kiste.status[1])
    return punkt

ani = animation.FuncAnimation(fig,animate,frames=600,interval=10,blit=True,init_func=init)

plt.show()

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt



class Box:
    
    def _init_(self,init_status=[1,1,1,1],grenzen=[-2,2,-2,2],size=0.02):
        self.init_status = np.asarray(init_status, dtype=float)
        self.status = self.init_status.copy()
        self.time_verstrichen = 0
        self.grenzen = grenzen
        self.size = size
        
    def bewegen(self,dt):
        self.time_verstrichen = self.time_verstrichen + dt
        
        self.status[0:1:1] = self.status[0:1:1] + dt * self.status[2:3:1]
        
        grenze_x1 = (self.state[0] < self.grenzen[0] + self.size)
        grenze_x2 = (self.state[0] > self.grenzen[1] - self.size)
        grenze_y1 = (self.state[1] < self.grenzen[2] + self.size)
        grenze_y2 = (self.state[1] > self.grenzen[3] - self.size)
        
        if(grenze_x1==True):
            self.status[0] = (self.grenzen[0] + self.size)
            self.status[2] = (self.status[2] * (-1))
        elif(grenze_x2==True):
            self.status[0] = (self.grenzen[1] - self.size)
            self.status[2] = (self.status[2] * (-1))
        else:
            self.status[0] = (self.status[0])
        
        if(grenze_y1==True):
            self.status[1] = (self.grenzen[2] + slef.size)
            self.status[3] = (self.status[3] * (-1))
            
        elif(grenze_y2==True):
            self.status[1] = (self.grenzen[3] - self.size)
            self.status[3] = (self.status[3] * (-1))
            
        else:
            self.status[1] = self.status[1]
            self.status[3] = self.status[3]
Wenn ich das Programm ausführe bekomme ich die Fehlermeldung:

Code: Alles auswählen

    rechteck = plt.Rectangle(kiste.grenzen[0:3:2],kiste.grenzen[1]-kiste.grenzen[0],kiste.grenzen[3]-kiste.grenzen[2],ec='none',lw=2,fc='none')

AttributeError: 'Box' object has no attribute 'grenzen'
Die Klasse Objekt hat doch ein Attribut Grenzen, wieso kann ich diesen nicht aufrufen?

Re: Attribut nicht vorhanden?

Verfasst: Freitag 2. August 2019, 08:59
von sparrow
Laut Namenskonvention werden Module kleingeschrieben. Und das Modul dann wie eine Klasse zu benennen, die importiert wird, halte ich für schwierig.

Dein Problem ist aber, dass _init_ nicht aufgerufen wird, weil es davor und danach jeweils 2 Unterstriche sein müssen. Also

Code: Alles auswählen

def __init__(...):
Wie in dem anderen Thread schon geschrieben:
if ist keine Funktion und benötigt keine Klammer.
Der Vergleich gegen True ist unsinnig, weil True==True wieder True ergibt. Also muss man auch direkt den Ausgangswert als Bedingung nehmen.
Du spammst zu viele unnötige Klammern in deinem Code. Rechnungen müssen nicht in Klammern gesetzt werden. Es sei denn, man macht das wegen Punkt-vor-Strich mit Absicht:

Code: Alles auswählen

# Dein Code:
self.status[2] = (self.status[2] * (-1))
# Warum nicht einfach?!?
self.status[2] = self.status[2] * -1

Re: Attribut nicht vorhanden?

Verfasst: Freitag 2. August 2019, 10:26
von Sirius3
Warum nicht einfach

Code: Alles auswählen

self.status[2] = -self.status[2]
`global` hat in einem ordentlichen Programm nichts verloren, zumal alles was da als globale deklariert wird, gar nicht benutzt wird. Die einzige globale Variable `punkt` sollte in den Funktionen als Parameter übergeben werden.
Auf oberster Ebene sollte kein ausführbarer Code stehen, sondern nur Definitionen. Vor allem sollte man aber Funktionsdefinitionen nicht mitten in den Code schreiben.

Das Modul Box sieht so aus, als ob da nur eine Klasse drin wäre. Solltest Du denken, dass es eine gute Idee wäre, pro Klasse ein eigenes Modul zu schreiben: nein ist es nicht. Module umfassen meist mehrere zusammengehörige Definitionen.
Matplotlib wird importiert aber nicht benutzt.
Wenn in einem Slice der Step 1 ist (wie fast immer) kann man ihn auch weglassen.
Wenn in einem else-Zweig effektiv nichts gemacht wird, kann man ihn auch weglassen.
`status` heißt an einigen Stellen `state` und `self` an einer `slef`.
Es ist wenig hilfreich, etliche Zeilen Code zu schreiben, ohne sie zu testen. Schreibe Tests am besten gleich als Unit-Tests um sie immer wieder ausführen zu können.

`status` ist ein sehr schlechter Name, weil er nichts aussagt, und es gibt wahrscheinlich keinen guten Namen, weil in Wirklichkeit enthält dieser Vektor zwei verschiedene Dinge, die Du einfach in einen gepackt hast (position und velocity).

Das Mischen von Englisch und Deutsch macht das Lesen schwierig. `time_verstrichen`?