Minimum und Maximum

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
python12345
User
Beiträge: 3
Registriert: Donnerstag 30. Juni 2016, 10:24

Hallo ich habe folgendes Problem:
Ich möchte in der Funktion Normalkraft_x1 aus dem Wert n_x1 das Minimum bekommen.
Wie stelle ich das an und wie kann ich das weiter unten bei print("\n- Normalkraft im Stab 1:\n") ausgeben, dass mir dann das Minimum angezeigt wird?

Code: Alles auswählen

class s_geometrie:
	laenge = float()
	hoehe = float()
	a = float()
	b = float()
class s_belastung_auflagerkraefte_schnittgroessen:
	belastung = float()
	Av = float()
	Ah = float()
	Bv = float()
	Bh = float()
	Nx = float()
class dgr(s_geometrie, s_belastung_auflagerkraefte_schnittgroessen):
    geo = s_geometrie
    bas = s_belastung_auflagerkraefte_schnittgroessen

def Normalkraft_x1():
	n_x1 = - dgr.bas.Av
	return n_x1


print("*** Statik: Dreigelenkrahmen unter Gleichlast ***\n")
print("Bitte geben Sie die Geometrie und die Belastung ein: \n")
print("- Stuetzlaenge l [m] = ")
dgr.geo.laenge = input()
print("- Hoehe h [m] = ")
dgr.geo.hoehe = input()
print("- Abstand des Gelenks in horizontaler Richtung a [m] = ")
dgr.geo.a = input()
if dgr.geo.a < 0 or dgr.geo.a > dgr.geo.laenge:
	print("- Fehler!")
	dgr.geo.a = input()
print ("- Abstand des Gelenks in vertikaler Richtung b [m] = ")
dgr.geo.b = input()
if dgr.geo.b <= 0 or dgr.geo.b > dgr.geo.hoehe:
	print("- Fehler!")
	dgr.geo.b = input()
print("- Gleichlast q [kN/m] = ")
dgr.bas.belastung = input()
print("\nEingaben:\n")
print("- Stuetzlaenge l = " + str(dgr.geo.laenge) + " m")
print("- Hoehe h = " + str(dgr.geo.hoehe) + " m")
print("- Abstand des Gelenks in horizontaler Richtung a = " + str(dgr.geo.a) + " m")
print("- Abstand des Gelenks in vertikaler Richtung b = " + str(dgr.geo.b) + " m")
print("- Gleichlast q = " + str(dgr.bas.belastung) + " m")
print("\nErgebnisse:\n")
if dgr.geo.a > 0 and dgr.geo.a < dgr.geo.laenge and dgr.geo.b < dgr.geo.hoehe:
    print("- Fehler! Das Gelenk befindet sich in der Luft!")
else:
	dgr.bas.Av = dgr.bas.Ah = dgr.bas.belastung*dgr.geo.laenge/2
	dgr.bas.Ah = dgr.bas.Bh = dgr.bas.belastung*(dgr.geo.laenge - dgr.geo.a)*dgr.geo.a/(2*dgr.geo.b)
	print("- Auflagerkraefte V: Av = Bv = " + str(dgr.bas.Av))
	print("- Auflagerkraefte H: Ah = Bh = " + str(dgr.bas.Ah))
	print("\n- Normalkraefte:\n")
	print("\n- Normalkraft im Stab 1:\n")
	schleife = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
	for i in schleife:
		x = dgr.geo.hoehe*i/10
		dgr.bas.Nx = Normalkraft_x1()
		print(" N(x=" + str(x) + ") = " + str(dgr.bas.Nx) + " kN")
Zuletzt geändert von Anonymous am Donnerstag 30. Juni 2016, 11:12, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@python12345: Mal davon abgesehen das ich die Frage nicht verstehe machst Du da *ganz* komische Sachen mit der ``class``-Anweisung. So funktioniert das nicht, und falls es so ”funktionieren” sollte ist das Missbrauch von Spracheigenschaften die so nicht gedacht waren/sind.

Edit: Ausserdem hast Du da erst einmal andere Probleme als ein Minimum zu ermitteln:
[codebox=text file=Unbenannt.txt]$ python3 forum.py
*** Statik: Dreigelenkrahmen unter Gleichlast ***

Bitte geben Sie die Geometrie und die Belastung ein:

- Stuetzlaenge l [m] =
5
- Hoehe h [m] =
2
- Abstand des Gelenks in horizontaler Richtung a [m] =
5
Traceback (most recent call last):
File "forum.py", line 30, in <module>
if dgr.geo.a < 0 or dgr.geo.a > dgr.geo.laenge:
TypeError: unorderable types: str() < int()[/code]
Falls das für Python 2 sein sollte, dann gehören bei der ``print``-Anweisung entweder keine Klammern um das ”Argument”, es sei denn man macht mit dem entsprechenden `__future__`-Import eine Funktion daraus. Und vor allem sollte man da dringend die Finger von `input()` lassen. Das wertet in Python 2 beliebige Python-Ausdrücke aus. Da nimmt man `raw_input()` + die entsprechenden Funktionen um die eingegebene Zeichenkette in einen Typ umzuwandeln mit dem man weiter arbeiten möchte.

`float()` ohne Argumente aufzurufen ist auch komisch. Da schreibt man normalerweise 0.0.
python12345
User
Beiträge: 3
Registriert: Donnerstag 30. Juni 2016, 10:24

Ich will dass, mir das Minimum den minimalsten Wert für n_x1 anzeigt. Sprich, wenn ich folgende Angaben eingebe:
l = 10, h = 10, a = 5, b = 10, gleichlast = 10;
sprich Av = 50, sodass mir dann das Minimum für n_x1 = -50 , da Av = 50, -50 bei der Ausführung angezeigt wird.
BlackJack

@python12345: Es gibt die `min()`-Funktion. Du musst also entweder alle Werte sammeln und nach der Schleife davon das Minimum ermitteln oder in jedem Schleifendurchlauf das aktuelle Minimum bestimmen, so dass Du das nach der Schleife dann ausgeben kannst.

Du solltest aber vorher ganz dringend das mit den Klassen angehen. Das ist pervers was da mit dieser Spracheigenschaft angestellt wird. Und auch die anderen erwähnten Punkte solltest Du ändern.

Das was Du da `schleife` nennst ist keine Schleife, sondern eine Liste mit Zahlen. Die unnötig ist — Du willst dafür `xrange()` oder `range()` einsetzen, je nachdem welche Python-Version Du einsetzt.

Dann wäre da der nicht wirklich sinnvoll gestaltete Versuch Fehleingaben zu vermeiden. Dort wird geprüft ob der Wert plausibel ist, und nochmal nachgefragt falls nicht. Und wenn der Benutzer dann wieder einen falschen Wert eingibt? Üblicherweise fragt man solange bis es passt. Und wenn man durch die vorher eingegebenen Werte einen Bereich kennt in dem ein neu einzugebender Wert liegen muss, wäre es sinnvoll diesen Bereich auch dem Benutzer mitzuteilen, damit der nicht raten muss was denn an seinem Wert falsch war.

Insgesamt sollte auch das Hauptprogramm von Modulebene in eine Funktion verschwinden.
python12345
User
Beiträge: 3
Registriert: Donnerstag 30. Juni 2016, 10:24

und wie geht das mit den klassen richtig? :(
kannst du da nicht bitte schnell so einen quellcode runterschreiben?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ich bin nicht BlackJack, aber ich bin mir jedenfalls nicht sicher, was genau du da machen willst. Das macht es schwierig es in "richtig" zu veraendern.

Das einzige was ich dazu sagen kann ist, dass es keinen Sinn macht und Python kein Java oder C++ ist. Weder muessen Namen noch deren Typ deklariert werden.
Fuer das was momentan passiert wuerde ich sagen, dass du die Klassen einfach loeschen und einfache Namen verwenden solltest.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich hoffe, ich habe mal das ganze richtig interpretiert:

Code: Alles auswählen

from collections import namedtuple

Geometry = namedtuple("Geometry", "length, height, a, b")
Strain = namedtuple("Strain", "Av,Ah,Bv,Bh")

def input_float(text, min=float('-inf'), max=float('inf')):
    while True:
        try:
            value = float(raw_input(text))
        except ValueError:
            print "Bitte Zahl eingeben."
        else:
            if min<=value<=max:
                return value
        print "Bitte Zahl zwischen {} und {} eingeben.".format(min, max)
            
def input_geometry():
    length = input_float("- Stuetzlaenge l [m] = ")
    height = input_float("- Hoehe h [m] = ")
    a = input_float("- Abstand des Gelenks in horizontaler Richtung a [m] = ", 0, length)
    b = input_float("- Abstand des Gelenks in vertikaler Richtung b [m] = ", 0, height)
    return Geometry(length, height, a, b)

def calculate_normal_force(strain, xpositions):
    return [(x, -strain.Av) for x in xpositions]
 

def main():
    print "*** Statik: Dreigelenkrahmen unter Gleichlast ***"
    print "Bitte geben Sie die Geometrie und die Belastung ein:"
    geometry = input_geometry()
    belastung = input_float("- Gleichlast q [kN/m] = ")
    
    print """
Eingaben:
- Stuetzlaenge l = {0.length} m
- Hoehe h = {0.height} m
- Abstand des Gelenks in horizontaler Richtung a = {0.a} m
- Abstand des Gelenks in vertikaler Richtung b = {0.b} m
- Gleichlast q = {1} kN/m
""".format(geometry, belastung)
    
    print "Ergebnisse:\n"
    if geometry.a > 0 and geometry.a < geometry.length and geometry.b < geometry.height:
        print "- Fehler! Das Gelenk befindet sich in der Luft!"
    else:
        v = belastung * geometry.length / 2
        h = belastung * (geometry.length - geometry.a) * geometry.a / (2*geometry.b)
        strain = Strain(v,h,v,h)
        normal = calculate_normal_force(strain, [geometry.height*i/10 for i in range(11)])
        
        print "- Auflagerkraefte V: Av = Bv = {0.Av}".format(strain)
        print "- Auflagerkraefte H: Ah = Bh = {0.Ah}".format(strain)
        print "\n- Normalkraefte:\n"
        print "\n- Normalkraft im Stab 1:\n"
        for x, n in normal:
            print " N(x={}) = {} KN".format(x,n)
        print "Minimum: x={} N={}".format(*min(normal, key=lambda (x,n):n))

if __name__ == '__main__':
    main()
BlackJack

Mit Klassen könnte das ansatzweise so aussehen:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function


class Geometrie(object):

    def __init__(
        self, laenge=0, hoehe=0, horizontaler_abstand=0, vertikaler_abstand=0
    ):
        if laenge < 0 or hoehe < 0:
            raise ValueError('negative Laengenangaben')
        if (
            not 0 <= horizontaler_abstand <= laenge
            or not 0 <= vertikaler_abstand <= hoehe
        ):
            raise ValueError('abstand ausserhalb des erlaubten bereichs')
        self.laenge = laenge
        self.hoehe = hoehe
        self.horizontaler_abstand = horizontaler_abstand
        self.vertikaler_abstand = vertikaler_abstand

    def ist_gelenk_in_der_luft(self):
        return (
            0 <= self.horizontaler_abstand < self.laenge
            and self.vertikaler_abstand < self.hoehe
        )


class BelastungAuflagerkraefteSchnittgroessen(object):

    def __init__(self, belastung, geometrie):
        if geometrie.ist_gelenk_in_der_luft():
            raise ValueError('das Gelenk befindet sich in der Luft')
        self.belastung = belastung
        self.Av = self.Ah = self.belastung * geometrie.laenge / 2
        self.Ah = self.Bh = (
            self.belastung
            * (geometrie.laenge - geometrie.vertikaler_abstand)
            * geometrie.vertikaler_abstand
            / (2 * geometrie.horizontaler_abstand)
        )
        #self.Nx = 0  # Das gehört hier nicht zum Zustand.

# ...
Ob's sinnvoller ist als das was Sirius3 zeigt, ist fraglich.
Antworten