Wert aus übersprungenen Codeblock verwenden.

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
Chow Gar
User
Beiträge: 6
Registriert: Mittwoch 18. Dezember 2013, 03:03

Guten Morgen,

bin Anfänger und möchte zur Übung ein paar Berechnungen machen lassen.

folgende Struktur liegt vor:

-2 listen über input einlesen
-dann die frage was man tun will:
-->
if Fall_A:
wert_a
elif Fall_B:
wert_b
else:
--> hier brauch ich den wert_b für eine weiterführende Berechnung, ist aber logischerweise nicht definiert, weil direkt zum else-Block gesprungen wurde.
Ich könnte den Block duplizieren oder vor der Bedingungsabfrage ausrechnen, was aber beides unschön und ineffizient wäre. Zudem wird im Grunde die gleiche Operation wie bei Fall_A mit dem Wert_b ausgeführt. Also meine Traumlösung wäre nimm "Wert aus B setze in A ein und gibt bei C aus."

Notlösung wäre:
--------------------
elif Fall_B:
wert_b
input wollen Sie C ausrechnen
if == "ja"
x = input ()
wert_c = wert_b * x
else
ende
--------------------
hier wird es aber bei der Auswahl der Fälle am Anfang sehr hässlich.
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo Chow Gar,
man kann auch if-Blöcke verschachteln:

Code: Alles auswählen

if fall_A:
    result = calc_A()
elif fall_B or fall_C:
    value = calc_common_BC()
    if fall_B:
        result = calc_B(value)
    else:
        result = calc_C(value)
else:
    assert False, "this shouldn't happen"
Chow Gar
User
Beiträge: 6
Registriert: Mittwoch 18. Dezember 2013, 03:03

Danke jetzt geht es :)
Ein Freund von mir meinte, dass man sowas auch mit import von eigenen Modulen lösen kann, indem man im Hauptprogramm Funktionen aus einer anderen Datei aufruft. Jetzt hab ich mir das mal angesehen, kann man sowas auch ohne Paramter in den () nach der def Funktion() machen ?
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Könnte man machen. Funktionen sollten aber, wenn sie mit Parametern arbeiten, diese Parameter auch als Funktionsargumente (also in den Klammern) übergeben bekommen. Welchen großen Vorteil versprichst du dir denn von Funktionsaufrufen ohne Argumenten? Falls du das Durchreichen von Werten vermeiden willst, dann ist wohl eher die Verwendung von Klassen angesagt. Klassen sind allerdings eher ein fortgeschrittenes Thema. Kein Hexenwerk, aber auch nicht unbedingt etwas, was man nach 2 Wochen Programmiererfahrung oder so angehen würde. Wenn einem Klassen momentan noch "zu hoch" sind, dann sollte man es IMHO bei der Lösung des Durchreichens belassen.
Chow Gar
User
Beiträge: 6
Registriert: Mittwoch 18. Dezember 2013, 03:03

Das mit den Klassen, hatte ich mal in einer Vorlesung, allerdings rein theoretisch.
Also ich weiß "eigentlich" schon was das ist. Die Idee war eher den Hauptcode übersichtlicher zu halten und da brauch ich ja keine Vererbung,etc. und was da alles möglich wäre, sondern nur die Funktion an der passenden Stelle, sonst wirds mit den Logikoperatoren in den Bedingungen auch schlecht lesbar, da ich ein paar aufwendige Standardberechnungen automatisieren will, erstmal für einfache Fälle, dann erweitern. Z.B. wenn ich jetzt alle Möglichkeiten wo ich ein Skalarprodukt brauche mit ifs untergliedern muss ist das eher doof.
BlackJack

@Chow Gar: Klassen bedeuten nicht zwingend auch Vererbung, in Python eigentlich sogar relativ selten (ausser das man in Python 2 von `object` erben sollte). Eine Klasse fasst zusammengehörige Daten und Funktionen die darauf operieren zu einem Objekt zusammen. Das solltest Du nicht machen wenn es keinen Sinn macht, aber umgekehrt sollte man wenn es nur mit Funktionen zu aufwändig wird, Klassen verwenden wenn es dadurch besser wird.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Na, Du kannst das ja auch mittels "Dependency Injection" so lösen:

Code: Alles auswählen

if fall_A:
    result = calc_A()
elif fall_B:
    result = calc_B(calc_common_BC())
elif fall_C:
    result = calc_C(calc_common_BC())
else:
    assert False, "this shouldn't happen"
Und wenn Du ``calc_B`` und ``calc_C`` selber eine Funktion aufrufen lässt, also so:

Code: Alles auswählen

def calc_B(common_func):
    value = common_func()
    # weiter wie gehabt
... dann kannst Du das ganze sogar in eine hübsche Datenstruktur verpacken:

Code: Alles auswählen

calc_dispatching = {
    fall_A: calc_A,
    fall_B: partial(calc_B, calc_common_BC),
    fall_C: partial(calc_C, calc_common_BC)
}
calc_dispatching[fall]()
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Chow Gar
User
Beiträge: 6
Registriert: Mittwoch 18. Dezember 2013, 03:03

@BlackJack
also doch mit Funktionen aus einer anderen Datei ?
ich möchte die im Hauptscript eingegebenen Listen die mit json.loads erzeugt werden als Variablen für meine Berechnungen nehmen. kann ich also einfache die Variablen aus dem Hauptprogramm in die aufgerufenen Funktionen als Argumente einsetzen ? Weil wenn die von den Namen her passen müssten die doch mit leerer () das gleiche tun, wie gesagt ich will es nur überslchtlich und struktiert halten.
Chow Gar
User
Beiträge: 6
Registriert: Mittwoch 18. Dezember 2013, 03:03

am besten mal den code:

Code: Alles auswählen

import json

    str_list1 = input("Geben Sie den 1. Vektor in der Form [x, y, z] ein: ")
    my_list1 = json.loads(str_list1)
    print(my_list1)

    str_list2 = input("Geben Sie den 2. Vektor in der Form [x, y, z] ein: ")
    my_list2 = json.loads(str_list2) 
    print(my_list2)
    #... bis hierhin Vektoren im R3 als liste definieren
    elif Fall == "s":#den Block brauch ich mehrmals 
          D=0
          
          for i in range(3):
                         D = D + my_list1[i] * my_list2[i] 
          
          print("Das Skalarprodukt beträgt: ")
          print(D)
Chow Gar
User
Beiträge: 6
Registriert: Mittwoch 18. Dezember 2013, 03:03

@Hyperion: ja so in etwa hab ich mir das vorgestellt nur ich nehme den Block aus meinem Hauptprogramm und will ihn praktisch outsourcen, alle Namen passen dann ja 1:1 ins Hauptscript daher verstehe ich das mit den Argumenten nicht ganz wenn er immer dasselbe machen soll nur in unterschiedlichen Konstellationen. Was ihr meint mit den Argumenten ist doch eher wenn die nicht vorhersehbar entstehen.
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@Chow Gar: Es ist vollkommen egal, ob die Argumente vorhersehbar sind oder nicht. Eingaben in eine Funktion erfolgen immer über Argumente und Ausgaben über Rückgabewerte. Alles andere ist das Gegenteil von "überslchtlich und struktiert halten".
BlackJack

@Chow Gar: Argumente ganz grundsätzlich für alles was nicht Konstant ist und in einer Funktion oder Methode verwendet wird. Nicht in Funktionen etwas einfach so verwenden weil es im Hauptprogramm zufällig den gleichen Namen hat und das Hauptprogramm auf Modulebene steht — wo es auch nicht stehen sollte.
Antworten