Seite 1 von 1

VBA for next Schleife in Python

Verfasst: Dienstag 3. März 2020, 17:30
von r4mp4g3
Hallo Leute,

Ich bin ganz neu hier und habe gleich die erste Frage :)

Ich habe in VBA eine Schleife erstellt welche ich gerne nach Python übertragen würde, da ich in Python einfach viel mehr anstellen kann als in VBA.

Leider bin ich bei Python noch Anfänger und etwas Hilfe wäre toll.

Hier der VBA code:

Code: Alles auswählen

Public Function Fahrzeit_Weg(Weg As Double, Beschleunigung As Double, Geschwindigkeit As Double) As Double
If Weg >= Geschwindigkeit ^ 2 / Beschleunigung Then
   Fahrzeit_Weg = Weg / Geschwindigkeit + Geschwindigkeit / Beschleunigung
Else
   Fahrzeit_Weg = 2 * (Weg / Beschleunigung) ^ 0.5
End If
End Function

                
Public Function FahrzeitEA_Platz(Stpb_x As Double, Stph_z As Double, xrichtung1 As Integer, yrichtung1 As Integer, Bbeschl As Double, Bgeschw As Double, Kbeschl As Double, Kgeschw As Double, Anfahrtx As Integer, Anfahrty As Integer) As Double
Dim v_x, v_z, AnzFahrten As Integer
Dim Fahrzeit, Zeitx, Zeitz As Double
    
    For v_x = 1 To AnzStp_x
        For v_z = 1 To AnzStp_z
        
     
            'zunächst x-Weg und x-Zeit berechnen
            Zeitx = Fahrzeit_Weg(Abs(v_x - Startposition) * Stpb_x, Bbeschl, Bgeschw)
            Zeitz = Fahrzeit_Weg(Abs(v_z - Startposition) * Stph_z, Kbeschl, Kgeschw)
            If Zeitx > Zeitz Then
                Fahrzeit = Fahrzeit + Zeitx
                AnzFahrten = AnzFahrten + 1
                'Debug.Print Fahrzeit
            Else
                Fahrzeit = Fahrzeit + Zeitz
           
                AnzFahrten = AnzFahrten + 1
             
                'Debug.Print Fahrzeit
            End If
        Next v_z
    Next v_x
    'Debug.Print Fahrzeit
    'Debug.Print AnzFahrten
    FahrzeitEA_Platz = Fahrzeit / (1# * AnzFahrten)
Und hier mein Versuch in Python:

Code: Alles auswählen

def Fahrzeit_Weg(Weg, Beschleunigung, Geschwindigkeit):

    if Weg >= (Geschwindigkeit**2 / Beschleunigung):
        Fahrzeit_Weg = Weg / Geschwindigkeit + Geschwindigkeit / Beschleunigung
    else:
        Fahrzeit_Weg = 2 * (Weg / Beschleunigung)**0.5



v_x = int
v_z = int
AnzFahrten = int
Fahrzeit = float
Zeitx = float
Zeitz = float

for v_x in range(xrichtung1):     # 2 schleifen nacheinander ?
    for v_z in range(yrichtung1):
        Zeitx = Fahrzeit_Weg(abs(v_x - Startposition - 1) * Stpb_x, Bbeschl, Bgeschw)
        Zeitz = Fahrzeit_Weg(abs(v_z - Startposition - 1) * Stph_z, Kbeschl, Kgeschw)
        if Zeitx > Zeitz:
            Fahrzeit = Fahrzeit + Zeitx
            AnzFahrten += 1                            #AnzFahrten = AnzFahrten += 1
        else:
            Fahrzeit = Fahrzeit + Zeitz
            AnzFahrten += 1                            #AnzFahrten = AnzFahrten += 1 #woher weiß wie oft gezählt

FahrzeitEA_Platz = Fahrzeit / (1 * AnzFahrten) #Gesammte Zeit / AnzahlFahrten

print(FahrzeitEA_PlatzEA_Platz)

#    if Zeitx > Zeitz:
TypeError: '>' not supported between instances of 'NoneType' and 'NoneType'
Wäre sehr nett wenn Ihr mir ein wenig helfen könntet.

MfG

Re: VBA for next Schleife in Python

Verfasst: Dienstag 3. März 2020, 17:36
von __deets__
Bitte den kompletten Fehler, mit dazu passendem Code zeigen. Nicht nur einen Auschnitt, und nicht Code, der so offensichtlich nicht gelaufen sein kann, denn da bekomme ich einen ganz anderen Fehler.

Code wie

Code: Alles auswählen

Fahrzeit = float
ist in Python wirkungslos, und dementsprechend kannst du dir den sparen.

Re: VBA for next Schleife in Python

Verfasst: Dienstag 3. März 2020, 18:01
von r4mp4g3
Danke schonmal für die Antwort.

Also der komplette code wäre (ganz unten die Schleife):

Code: Alles auswählen

global Rollendurchmesser
global Toleranz
global Sicherheitsabstand
global Gebäudebreite
global Gebäudelänge
global Lagereinganglänge
global Lagereingangbreite
global Lagerausganglänge
global Lagerausgangbreite
global Anfahrmaßbrückestrom
global Anfahrmaßbrücke
global Anfahrmaßkranost
global Anfahrmaßkranwest
global Aufnahmeabgabe
global Hubsenk
global Bgeschw
global Bbeschl
global Kgeschw
global Kbeschl
global Startposition

Startposition = int
Startposition = 1
Rollendurchmesser = float
Rollendurchmesser = 1000
Toleranz = float
Toleranz = 0
Sicherheitsabstand = float
Sicherheitsabstand = 0
Gebäudebreite = float
Gebäudebreite = 9
Gebäudelänge = float
Gebäudelänge = 14
Lagereinganglänge = float
Lagerausganglänge = float
Lagereingangbreite = float
Lagerausganglänge = float
Lagerausgangbreite = float
Anfahrmaßbrückestrom = float
Anfahrmaßbrückestrom = 0
Anfahrmaßbrücke = float
Anfahrmaßbrücke = 0
Anfahrmaßkranost = float
Anfahrmaßkranost = 0
Anfahrmaßkranwest = float
Anfahrmaßkranwest = 0
Aufnahmeabgabe = float
Aufnahmeabgabe = 2
Hubsenk = float
Hubsenk = 2
Bgeschw = float
Bgeschw = 2
Bbeschl = float
Bbeschl = 0.25
Kgeschw = float
Kgeschw = 1.6
Kbeschl = float
Kbeschl = 0.37




f1 = (0.5 * (Rollendurchmesser + Toleranz + Sicherheitsabstand))/1000

print(f1)

f2 = (((Rollendurchmesser + Toleranz + Sicherheitsabstand)**2 - (0.5 * (Rollendurchmesser + Toleranz + Sicherheitsabstand))**2)**0.5)/1000

print(f2)

if Anfahrmaßbrückestrom == 0:
    Anfahrmaßbs = 0
else:
    Anfahrmaßbs = Anfahrmaßbrückestrom - f1

print (Anfahrmaßbs)

if Anfahrmaßbrücke == 0:
    Anfahrmaßb = 0
else:
    Anfahrmaßb = Anfahrmaßbrücke - f1


if Anfahrmaßkranost == 0:
    Anfahrmaßo = 0
else:
    Anfahrmaßo = Anfahrmaßkranost - f1



if Anfahrmaßkranwest == 0:
    Anfahrmaßw = 0
else:
    Anfahrmaßw = Anfahrmaßkranwest - f1

print(Anfahrmaßw)


Lagerlängenetto = (Gebäudelänge - (Anfahrmaßb + Anfahrmaßw)) 

print(Gebäudelänge)

Lagerbreitenetto = (Gebäudebreite - (Anfahrmaßbs + Anfahrmaßb))



import math

Anzahlrolleny1 = math.floor (Lagerbreitenetto/f2)

print(Anzahlrolleny1)

Anzahlrollenx1 = math.floor ((Lagerlängenetto/f1)/2)

print(Anzahlrollenx1)




if Anzahlrollenx1 % 2 == 0 and Anzahlrolleny1 % 2 == 0:
    Korrekturwert = Anzahlrolleny1/2


if Anzahlrollenx1 % 2 == 0 and Anzahlrolleny1 % 2 == 1:
    Korrekturwert = (Anzahlrolleny1/2) - 0.5

if Anzahlrollenx1 % 2 == 1:
    Korrekturwert = 0

print(Korrekturwert)


Anzahlmaxrollen = Anzahlrolleny1*Anzahlrollenx1 - Korrekturwert

print(Anzahlmaxrollen)


xrichtung1 = Anzahlrollenx1


if (Lagerlängenetto/f1) % 2 == 0:
    xrichtung2 = Anzahlrollenx1 - 1
else:
    xrichtung2 = Anzahlrollenx1

print(xrichtung2)

yrichtung1 = int(Anzahlrolleny1/2+0.5) #aufrunden auf ganze zahl , so oder dannach int(yrichtung1+0,5)

yrichtung2 = math.floor(Anzahlrolleny1/2)   #abrunden ganze zahl
print(yrichtung1)
print(yrichtung2)

Anfahrtx = f1

Anfahrty = f2

Stpb_x = 2*f1

Stph_z = 2*f2


def Fahrzeit_Weg(Weg, Beschleunigung, Geschwindigkeit):

    if Weg >= (Geschwindigkeit**2 / Beschleunigung):
        Fahrzeit_Weg = Weg / Geschwindigkeit + Geschwindigkeit / Beschleunigung
    else:
        Fahrzeit_Weg = 2 * (Weg / Beschleunigung)**0.5



v_x = int
v_z = int
AnzFahrten = int
Fahrzeit = float
Zeitx = float
Zeitz = float

for v_x in range(xrichtung1):     # 2 schleifen nacheinander ?
    for v_z in range(yrichtung1):
        Zeitx = Fahrzeit_Weg(abs(v_x - Startposition - 1) * Stpb_x, Bbeschl, Bgeschw)
        Zeitz = Fahrzeit_Weg(abs(v_z - Startposition - 1) * Stph_z, Kbeschl, Kgeschw)
        if Zeitx > Zeitz:
            Fahrzeit = Fahrzeit + Zeitx
            AnzFahrten += 1                            #AnzFahrten = AnzFahrten += 1
        else:
            Fahrzeit = Fahrzeit + Zeitz
            AnzFahrten += 1                            #AnzFahrten = AnzFahrten += 1 #woher weiß wie oft gezählt

FahrzeitEA_Platz = Fahrzeit / (1 * AnzFahrten)

print(FahrzeitEA_Platz)

#Fehler:

Traceback (most recent call last):
  File "C:/Users/ED/PycharmProjects/Spielzeit/venv/test.py", line 227, in <module>
    if Zeitx > Zeitz:
TypeError: '>' not supported between instances of 'NoneType' and 'NoneType'

Re: VBA for next Schleife in Python

Verfasst: Dienstag 3. März 2020, 18:10
von __deets__
Wie schon erwaehnt, das zuweisen eines Typs an einen Namen hat in Python nicht die von dir unterstellte Wirkung. Im Gegenteil, es produziert bestenfalls Folgefehler, weil du mit den Typen dann rechnen willst. Das global-Statement auf Modulebene ist komplett wirkungslos. Ganz grundsaetzlich sollte man natuerlich sowieso auf globale variablen verzichten - eine Erkenntnis, die in der Programmierung auch schon seit ~40 Jahren vorherrscht. Importe gehoeren an den Anfang eines Skriptes. Ein leicht korrigierter Code, der fuer mich durchlaeuft, sieht so aus:

Code: Alles auswählen

import math

def Fahrzeit_Weg(Weg, Beschleunigung, Geschwindigkeit):

    if Weg >= (Geschwindigkeit**2 / Beschleunigung):
        return Weg / Geschwindigkeit + Geschwindigkeit / Beschleunigung
    else:
        return 2 * (Weg / Beschleunigung)**0.5


def main():
    Startposition = 1
    Rollendurchmesser = 1000
    Toleranz = 0
    Sicherheitsabstand = 0
    Gebäudebreite = 9
    Gebäudelänge = 14
    Anfahrmaßbrückestrom = 0
    Anfahrmaßbrücke = 0
    Anfahrmaßkranost = 0
    Anfahrmaßkranwest = 0
    Bgeschw = 2
    Bbeschl = 0.25
    Kgeschw = 1.6
    Kbeschl = 0.37
    Fahrzeit = 0
    AnzFahrten = 0

    f1 = (0.5 * (Rollendurchmesser + Toleranz + Sicherheitsabstand))/1000

    print(f1)

    f2 = (((Rollendurchmesser + Toleranz + Sicherheitsabstand)**2 - (0.5 * (Rollendurchmesser + Toleranz + Sicherheitsabstand))**2)**0.5)/1000

    print(f2)

    if Anfahrmaßbrückestrom == 0:
        Anfahrmaßbs = 0
    else:
        Anfahrmaßbs = Anfahrmaßbrückestrom - f1

    print (Anfahrmaßbs)

    if Anfahrmaßbrücke == 0:
        Anfahrmaßb = 0
    else:
        Anfahrmaßb = Anfahrmaßbrücke - f1

    if Anfahrmaßkranost == 0:
        Anfahrmaßo = 0
    else:
        Anfahrmaßo = Anfahrmaßkranost - f1



    if Anfahrmaßkranwest == 0:
        Anfahrmaßw = 0
    else:
        Anfahrmaßw = Anfahrmaßkranwest - f1

    print(Anfahrmaßw)


    Lagerlängenetto = (Gebäudelänge - (Anfahrmaßb + Anfahrmaßw))

    print(Gebäudelänge)

    Lagerbreitenetto = (Gebäudebreite - (Anfahrmaßbs + Anfahrmaßb))



    Anzahlrolleny1 = math.floor (Lagerbreitenetto/f2)

    print(Anzahlrolleny1)

    Anzahlrollenx1 = math.floor ((Lagerlängenetto/f1)/2)

    print(Anzahlrollenx1)




    if Anzahlrollenx1 % 2 == 0 and Anzahlrolleny1 % 2 == 0:
        Korrekturwert = Anzahlrolleny1/2


    if Anzahlrollenx1 % 2 == 0 and Anzahlrolleny1 % 2 == 1:
        Korrekturwert = (Anzahlrolleny1/2) - 0.5

    if Anzahlrollenx1 % 2 == 1:
        Korrekturwert = 0

    print(Korrekturwert)


    Anzahlmaxrollen = Anzahlrolleny1*Anzahlrollenx1 - Korrekturwert

    print(Anzahlmaxrollen)


    xrichtung1 = Anzahlrollenx1


    if (Lagerlängenetto/f1) % 2 == 0:
        xrichtung2 = Anzahlrollenx1 - 1
    else:
        xrichtung2 = Anzahlrollenx1

    print(xrichtung2)

    yrichtung1 = int(Anzahlrolleny1/2+0.5) #aufrunden auf ganze zahl , so oder dannach int(yrichtung1+0,5)

    yrichtung2 = math.floor(Anzahlrolleny1/2)   #abrunden ganze zahl
    print(yrichtung1)
    print(yrichtung2)

    Stpb_x = 2*f1

    Stph_z = 2*f2

    for v_x in range(xrichtung1):     # 2 schleifen nacheinander ?
        for v_z in range(yrichtung1):
            Zeitx = Fahrzeit_Weg(abs(v_x - Startposition - 1) * Stpb_x, Bbeschl, Bgeschw)
            Zeitz = Fahrzeit_Weg(abs(v_z - Startposition - 1) * Stph_z, Kbeschl, Kgeschw)
            if Zeitx > Zeitz:
                Fahrzeit += Zeitx
            else:
                Fahrzeit += Zeitz

            AnzFahrten += 1

    FahrzeitEA_Platz = Fahrzeit / (1 * AnzFahrten)

    print(FahrzeitEA_Platz)

if __name__ == '__main__':
    main()

Da ist noch viel anderes im argen - die Benamungen entsprechenen nicht den Konventionen des PEP8, sind inkonsistent und komisch abgekuerzt.

Re: VBA for next Schleife in Python

Verfasst: Mittwoch 4. März 2020, 10:23
von Sirius3
@r4mp4g3: Benutze keine Abkürzungen, die sind schwer lesbar, man vertippt sich leichter und es besteht Verwechslungsgefahr, wenn man sich z.b. Bbeschl, und Bgeschw, Kbeschl und Kgeschw anschaut. Da sind immer nur einzelne Buchstaben ausgetauscht. Anfahrmaßbrücke und Anfahrmaßb sind auch leicht zu verwechseln, was ist denn der Unterschied zwischen den beiden? Das sollte man im Namen lesen.
`Rollendurchmesser + Toleranz + Sicherheitsabstand` wird drei mal berechnet, sollte man aber nur einmal.
Wenn Du schon math.floor kennst, dann solltest Du auch math.ceil kennen. Hier sollte aber das konsequente Nutzen von Ganzzahldivision einiges vereinfachen.
Wenn man if-Abfragen hat, die sich gegenseitig ausschließen:

Code: Alles auswählen

    if Anzahlrollenx1 % 2 == 0 and Anzahlrolleny1 % 2 == 0:
        Korrekturwert = Anzahlrolleny1/2


    if Anzahlrollenx1 % 2 == 0 and Anzahlrolleny1 % 2 == 1:
        Korrekturwert = (Anzahlrolleny1/2) - 0.5

    if Anzahlrollenx1 % 2 == 1:
        Korrekturwert = 0
sollte man das mit else oder elif umschreiben

Code: Alles auswählen

    if Anzahlrollenx1 % 2 == 0:
        if Anzahlrolleny1 % 2 == 0:
            Korrekturwert = Anzahlrolleny1/2
        else:
            Korrekturwert = (Anzahlrolleny1/2) - 0.5
    else:
        Korrekturwert = 0
oder eben mit Ganzzahldivision:

Code: Alles auswählen

    if Anzahlrollenx1 % 2 == 0:
        Korrekturwert = Anzahlrolleny1 // 2
    else:
        Korrekturwert = 0
Variablen sollte man immer erst dann einführen, wenn sie gebraucht werden. AnzFahrten und Fahrzeit wird erst ganz zum Schluß gebraucht, aber schon ganz am Anfang definiert. `AnzFahrten` muß man auch nicht zählen, sondern kann es als xrichtung1 * yrichtung1 ausrechnen.

Re: VBA for next Schleife in Python

Verfasst: Donnerstag 5. März 2020, 01:21
von r4mp4g3
Vielen Dank für diese hilfreichen Tipps, diese haben mir auf jeden Fall weitergeholfen.

So macht es spaß mit Python zu arbeiten.

MfG