Zylinderberechnung mit Python

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
BlowKissFireGun
User
Beiträge: 5
Registriert: Mittwoch 9. Juni 2021, 11:50

Hallo liebe Forengemeinde,

da ich komplett neu hier im Forum bin, bitte ich meine Unwissenheit schonmal im Voraus zu entschuldigen. Ich habe mir vor kurzem ein Buch gekauft, in dem die wichtigsten Hintergründe für Ingenieure und Wissenschaftler in Bezug auf Python drinstehen. So weit, so gut. Ich habe mich jetzt bis zur Seite 82 durchgearbeitet. Hier ist allerdings Schluss, da das Python-Programm in meiner Shell nicht zum Laufen kommt. Das hier ist das Programm, bei dem es kurz gesagt um die Zylinderberechnung geht, mittels des Verwendens von Klassen.

Code: Alles auswählen

#28_oop.py
class Zylinder:
    self.rho=7.85
    def __init__(self,durchmesser,laenge,alpha):
        self.__d=durchmesser  #private
        self.__l=laenge       #private
        self.__a=alpha        #private

    def volumen(self):
        return 0.785*self.__d**2*self.__l

    def masse(self):
        return self.rho*self.volumen()

    def traegheitsmoment(self):
        return 0.5*self.masse()*(self.__d/2)**2

    def beschleunigungsmoment(self):
        return self.__a*self.traegheitsmoment()

z=Zylinder(1,10,1.2)
#Zylinder.rho=2.3
#z.__d=100
print("Volumen: ",z.volumen(),"dm^3")
print("Masse: ",z.masse(),"kg")
print("Traegheitsmoment: ",z.traegheitsmoment(), "kgm^2")
print("Beschleunigungsmoment",z.beschleunigungsmoment(),"NM")
Das ist das Musterbeispiel aus dem Buch, das ich zur Überprüfung und Nachvollziehung auch so eingegeben habe. Das Programm will ich Laufen lassen, doch es kommt folgende Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\juss\AppData\Local\Programs\Python\Python39\28_oop.py", line 2, in <module>
    class Zylinder:
  File "C:\Users\juss\AppData\Local\Programs\Python\Python39\28_oop.py", line 3, in Zylinder
    self.rho=7.85
NameError: name 'self' is not defined
Ich vermute, dass ich NumPy installieren muss. Liege ich hier richtig? Habe auch schon versucht, dass ganze über die Konsole zu installieren. Jedoch funktionieren die handelsüblichen Befehle hier nicht wie zum Beispiel "pip3 install numpy". Bin totaler Anfänger, deswegen bitte ich um Nachsehen. Habe schon versucht, dass ganze in Anaconda zu starten, allerdings bekomme ich hier noch nichtmals Python zum Laufen.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

An der Stelle ist self ja auch nicht definiert. `self` bezieht sich immer auf eine Instanz der Klasse, und wird in Methoden als Argument übergeben.
Wenn das Buch etwas über "Privat" und doppelte Unterstriche schreibt, dann vergiss das gleich wieder. Es gibt keine "privat" in Python und doppelte Unterstriche werden selten verwendet.
Attributnamen sollten auch aussagekräftig sein. Warum werden die schönen Argumentnamen wie durchmesser zu d?
Wenn man pi/4 meint, dann schreibt man das auch und nicht 0.785.

Code: Alles auswählen

import math

class Zylinder:
    def __init__(self,durchmesser, laenge, alpha, dichte=7.85):
        self.durchmesser = durchmesser
        self.laenge = laenge
        self.alpha = alpha
        self.dichte = dichte

    def volumen(self):
        return math.pi / 4  * self.durchmesser**2 * self.laenge

    def masse(self):
        return self.dichte * self.volumen()

    def traegheitsmoment(self):
        return 0.5 * self.masse() * (self.durchmesser / 2) ** 2

    def beschleunigungsmoment(self):
        return self.alpha * self.traegheitsmoment()

def main():
    zylinder = Zylinder(1, 10, 1.2)
    print(f"Volumen: {zylinder.volumen():.3f} dm^3")
    print(f"Masse: {zylinder.masse():.3f} kg")
    print(f"Traegheitsmoment: {zylinder.traegheitsmoment():.3f} kgm^2")
    print(f"Beschleunigungsmoment {zylinder.beschleunigungsmoment():.3f} NM")

if __name__ == "__main__":
    main()
BlowKissFireGun
User
Beiträge: 5
Registriert: Mittwoch 9. Juni 2021, 11:50

Hallo Sirius3,

danke für deine schnelle Antwort. Sie hilft mir sehr weiter. Im Buch steht, dass diese Privatdeklaration aus dem Grund benutzt wird, damit die Variablen von außen nicht mehr verändert werden können.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Können sie aber trotzdem. Python kann die nicht schützen. Deren Name ist lediglich (völlig vorhersehbar, weil systematisch) um den Klassennamen erweitert, und das macht man, um Namenskollisionen bei Vererbung zu vermeiden. Wer aber dran WILL, kommt dran. Ist also Unfug das aus dem Grund zu machen.
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

BlowKissFireGun hat geschrieben: Mittwoch 9. Juni 2021, 13:14 Im Buch steht, dass diese Privatdeklaration aus dem Grund benutzt wird, damit die Variablen von außen nicht mehr verändert werden können.
Nenn uns doch mal Buch und Autor, damit wir in Zukunft anderen von diesem Buch abraten können.
Wenn da sowas drin steht, dann wissen hier viele, was für eine Programmiersprache
der Autor zuvor verinnerlicht hat und beim Umstieg auf Python nicht mehr losgeworden ist.
Ich kann dir nur raten, dein Wissen rund um Python nicht nur aus diesem Buch zu erlangen,
sondern auch noch andere, bessere Bücher oder online Tutorials zu verwenden.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
BlowKissFireGun
User
Beiträge: 5
Registriert: Mittwoch 9. Juni 2021, 11:50

Es handelt sich um das Buch "Der Python-Kurs für Ingenieure und Naturwissenschaftler" von Veit Steinkamp. Na toll, jetzt hab ich relativ viel Geld in die Hand genommen und bekomme von Experten erzählt, dass es nur bedingt brauchbar ist...
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Man kann den Quelltext ja herunterladen. Die Dichte ist da ein Klassenattribut und im Code wird auskommentiert gezeigt wie das neu zugewiesen wird. Also eine globale Variable letztendlich.

Bei der Vererbung sind dann die doppelten führenden Unterstriche wieder verschwunden. Das Beispiel ist, das `Volumen` von `Flaeche` erbt. Da Vererbung ja eigentlich eine „ist-ein(e)“-Beziehung ist, wäre es interessant wie der Text im Buch erklärt in wie weit ein Volumen eine Fläche ist.

Noch interessanter wird es in der Musterlösung L_02_10.py:

Code: Alles auswählen

class Volumen:
    def __init__(self,durchmesser,laenge):
        self.d=durchmesser
        self.l=laenge
        
    def volumen(self):
        return 0.785*self.l*self.d**2
    
class Masse(Volumen):   
    def __init__(self,rho,durchmesser,laenge):
        super().__init__(durchmesser,laenge)
        self.r=rho
        
    def masse(self):
        return Volumen.volumen(self)*self.r

class Traegheitsmoment(Masse):
    def __init__(self,rho,durchmesser,laenge):
        super().__init__(rho,durchmesser,laenge)
    
    def traegheitsmoment(self):
        return Masse.masse(self)*self.d**2/8

class Beschleunigungsmoment(Traegheitsmoment):
    def __init__(self,rho,durchmesser,laenge,alpha):
        self.a=alpha
        super().__init__(rho,durchmesser,laenge)
    
    def beschleunigungsmoment(self):
        return Traegheitsmoment.traegheitsmoment(self)*self.a

#Hauptprogramm    
V=Volumen(1,10)
m=Masse(7.85,1,10)
J=Traegheitsmoment(7.85,1,10)
Mb=Beschleunigungsmoment(7.85,1,10,1.2)
print("Volumen:",V.volumen()," m^3")
print("Masse:",m.masse()," kg")
print("Trägheitsmoment:",J.traegheitsmoment()," kgm^2")
print("Beschleunigungsmomnet:",Mb.beschleunigungsmoment()," Nm")
Und der Quelltext zur Einführung ist dann auch das einzige wo man die ``class``-Anweisung findet. Letztes Kapitel ist Tkinter, da wird wie wohl im Rest von den Quelltexten immer schön alles in den Modulnamensraum abgekippt. Beispie (ja, da kommt auch ``global`` drin vor):

Code: Alles auswählen

#16_regelkreis2.py
import tkinter as tk
main = tk.Tk()
main.title("Regelkreis mit Strecke 2. Ordnung")
xmax, ymax = 800,400
xy=0     #Globale Variable
U1=100.0 #Sollwert
w=ymax/2.#Führungsgröße
rd=4     #Rand
main.minsize(xmax,ymax)
main.resizable(False,False)
canZ = tk.Canvas(width=xmax,height=ymax,bg='white')
canZ.grid(row=0,column=0,columnspan=5)
def rahmen():
    canZ.create_line(0,w,xmax,w,fill='red',width=2)
    canZ.create_line(rd,rd,xmax,rd,fill="black",width=2)
    canZ.create_line(rd,ymax,xmax,ymax,fill="black",width=2)
    canZ.create_line(rd,0,rd,ymax,fill="black",width=2)
    canZ.create_line(xmax, rd, xmax, ymax,fill="black",width=2)

def loesche():
    return canZ.delete(xy)

def koordinate(event):
    tmax=float(txtTmax.get())
    x, y = event.x, event.y
    x, y = tmax*x/xmax-2, U1*(ymax-y)/w
    x, y = ('{0:4.0f}'.format(x)), ('{0:3.0f}'.format(y))
    lblKoordinate["text"]="t:"+str(x)+" ms  y:"+str(y)+"%" 

def regelkreis():
    global xy
    tmax=float(txtTmax.get())
    Kp = float(txtKp.get())
    Tn = float(txtTn.get())
    Tv = float(txtTv.get())
    R = float(txtR.get())
    L=float(txtL.get())
    J = float(txtJ.get())
    Ia= float(txtIa.get())
    Mn = float(txtMn.get())
    C=1.0e3*J*(Ia/Mn)**2
    t=y=ui=ud=i=e=e0=0
    dt=0.05
    sx=xmax/tmax
    u2_t = []
    while t<=tmax:
        e=w-y
        up = Kp*e
        ui = ui + Kp*e*dt/Tn
        ud = Kp*Tv*(e-e0)/dt
        e0=e
        U1 = up + ui + ud
        i = i + (U1-R*i-y)*dt/L
        y = y + i*dt/C
        t=t+dt
        u2_t.append(sx*t+rd)
        u2_t.append(-y+ymax)        
    xy=canZ.create_line(u2_t,fill='blue',width=2)    

rahmen()
txtTmax=tk.Entry(main, width=5)
txtTmax.insert(5,"250")
#Ankerwiderstand
tk.Label(main, text="R in Ohm").grid(row=1,column=0,sticky="w")
txtR=tk.Entry(main, width=5)
txtR.insert(5,"1.5")
txtR.grid(row=1,column=1,sticky="w")
#Ankerinduktivität
tk.Label(main, text="L in mH").grid(row=2,column=0,sticky="w")
txtL=tk.Entry(main, width=5)
txtL.insert(5,"24")
txtL.grid(row=2,column=1,sticky="w")
#Bemessungsmoment
tk.Label(main, text="Mn in Nm").grid(row=3,column=0,sticky="w")
txtMn=tk.Entry(main, width=5)
txtMn.insert(5,"172")
txtMn.grid(row=3,column=1,sticky="w")
#Bemessungstrom
tk.Label(main, text="Ia in A").grid(row=4,column=0,sticky="w")
txtIa=tk.Entry(main, width=5)
txtIa.insert(5,"41")
txtIa.grid(row=4,column=1,sticky="w")
#Trägkeitsmoment
tk.Label(main, text="J in kgm^2").grid(row=5,column=0,sticky="w")
txtJ=tk.Entry(main, width=5)
txtJ.insert(5,"1")
txtJ.grid(row=5,column=1,sticky="w")
#Verstärkung des Reglers
tk.Label(main, text="Kp").grid(row=1,column=2,sticky="w")
txtKp=tk.Entry(main, width=5)
txtKp.insert(5,"5")
txtKp.grid(row=1,column=3,sticky="w")
#Nachstellzeit
tk.Label(main, text="Tn in ms").grid(row=2,column=2,sticky="w")
txtTn=tk.Entry(main, width=5)
txtTn.insert(5,"50")
txtTn.grid(row=2,column=3,sticky="w")
#Vorhaltezeit
tk.Label(main, text="Tv in ms").grid(row=3,column=2,sticky="w")
txtTv=tk.Entry(main, width=5)
txtTv.insert(5,"5")
txtTv.grid(row=3,column=3,sticky="w")
#Koordinaten
tk.Label(main, text="tmax").grid(row=4,column=2,sticky="w")
txtTmax.grid(row=4,column=3,sticky="w")
tk.Label(main, text="Koordinate").grid(row=5,column=2,sticky="w")
lblKoordinate=tk.Label(main,width=15)
lblKoordinate.grid(row=5,column=3,sticky="w")
#Befehlschaltflächen
tk.Button(main,text="Start",command=regelkreis,width=7).grid(row=1,column=4)
tk.Button(main,text="Neu",command=loesche,width=7).grid(row=2,column=4)
tk.Button(main,text="Beenden",command=main.destroy,width=7).grid(row=3,column=4)
canZ.bind('<Motion>', koordinate)
main.mainloop()
Das scheint ein „Skripten von Bibliotheken“ zu sein. Mit typischen Mathematikernamen, also alles kurz und kryptisch. Und PEP8 wird auch ignoriert.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
Dennis89
User
Beiträge: 1123
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

da stimmt doch nicht mal die Rechnung. Wenn eine Funktion 'volumen' heißt was hat dann darin die Dichte zu suchen, wo ist die Kreiszahl pi und irgendwie sollte man das auch noch durch vier teilen, oder liegts jetzt an mir :shock:

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na was ist denn Pi geteilt durch 4?
Benutzeravatar
Dennis89
User
Beiträge: 1123
Registriert: Freitag 11. Dezember 2020, 15:13

0,7853981634... :P

Hab mich schon gewundert wieso das niemand aufgefallen ist, sollte ich das nächste mal für mich behalten.


Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Antworten