Mehrere aufeinander folgende if anweisung in python kürzen

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.
karomi
User
Beiträge: 18
Registriert: Mittwoch 12. Juli 2006, 12:42

Hallo Allerseits,
mein python Skript läuft einbahnfrei. Solang ich ein statische Code Analyse durchführe, spuckt mir der Analysator (PyLint) eine Warning aus:
Ich verwende viele if Anweisungen hintereinander in einer Funktion.
Wie kann man das verhindern dass ich weniger if Anweisungen schreibe?
Es gibt ja kein swith und case wie in C oder C++!!!!!!!!!!!!

Kann jemand mir ein Tipp geben??
Vielen Dank
Karomi
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

karomi hat geschrieben:Wie kann man das verhindern dass ich weniger if Anweisungen schreibe?
Mit der Benutzung eines Hastables, d.h. eines Dicts, an das Funktionen gebunden werden.
karomi hat geschrieben:Es gibt ja kein swith und case wie in C oder C++!!!!!!!!!!!!
Brauchts auch nicht (und ein Ausrufezeichen reicht, bei dir klingt es so, als wäre es sehr schlimm, dass es kein Switch/Case gibt).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

karomi hat geschrieben:Ich verwende viele if Anweisungen hintereinander in einer Funktion.
Hi Karomi!

Solange dein Code funktioniert, gut lesbar ist und du nicht zehn oder zwanzig unnötige If-Anweisungen untereinander stehen hast, würde ich mir keine Sorgen machen.

Gerade in die "zuviele IF"-Geschichte wird manchmal zu viel Energie gesteckt. Oft ist es die Aufregung nicht wert. Und andere Lösungen sind auch nicht gerade einfacher und übersichtlicher.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Leonidas hat geschrieben:Mit der Benutzung eines Hastables, d.h. eines Dicts, an das Funktionen gebunden werden.
So würde ich das auch machen ;)

@karomi: Zeig doch mal den Code an dieser Stelle.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Ich denke man sollte diese Warnung von PyLint ernst nehmen wenn es sich um verschachtelte ``if``-Anweisungen handelt, denn dann hat man es mit erhöhter und wahrscheinlich zu hoher Komplexität in einer Funktion zu tun.

Wenn die ``if``/``elif``-Anweisungen linear als switch/case Ersatz benutzt werden, dann kann man dem Quelltext in der Regel einfach folgen.

Man kann natürlich trotzdem kurz überlegen ob ein Dictionary oder eine Schleife benutzt werden kann.
karomi
User
Beiträge: 18
Registriert: Mittwoch 12. Juli 2006, 12:42

Hallo,
ijr habt geschrieben:
Mit der Benutzung eines Hastables, d.h. eines Dicts, an das Funktionen gebunden werden.

Was ist ein Hastables?
Kann jemand ein Beispiel hier schreiben???

Noch was?
ich konnte mir nicht vorstellen wie ich IF Anweisungen durch ein Dictionary ersetzen kann, kann jemand ein Beispiel geben???

Vielen Dank
Karomi
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Leonidas hat geschrieben:
karomi hat geschrieben:Wie kann man das verhindern dass ich weniger if Anweisungen schreibe?
Mit der Benutzung eines Hastables, d.h. eines Dicts, an das Funktionen gebunden werden.
[...]
ich verstehe nicht was du meinst :? Wie kann ein Dict ifs ersetzen?

lg
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi,

etwas Pseudocode zur Erklärung wie ein dict (hashtable in anderen Sprachen) switch oder case Statements ersetzen kann:

Code: Alles auswählen

def f1(): pass
def f2(): pass
def f3(): pass

function_dict = {
'parameter1' : f1,
'parameter2' : f2,
'parameter3' : f3}

#entweder:
function_to_call = function_dict[paramter]
function_to_call()
#oder in einer Zeile:
function_dict[paramter]()
Gruß,
Christian
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Hmm, allso stat so...

Code: Alles auswählen

[...]
para = "parameter1"
if para == "parameter1":
    f1()
elif para == "parameter2":
    f2()
elif para == "parameter3":
    f3()
[...]
...schreibe ich das so?

Code: Alles auswählen

[...]
para = "parameter1"
function_dict[para]()
Hmm, das funtzt aber nur mit Funktionen/Methoden und nciht für mehrere Zeilen code in nem if-block.

Oder anders: Sol das ein Wink mit den Zaunpfahl sein, das man Anweisungen die man in if-blöcke packt (wo man sehr viel if-blöcke hat ca. um die 20), lieber in Funktionen aufteilen sollte, die dann über ein hashtable aufgerufen werden um sich die ifs zu sparren?

lg
r2d2
User
Beiträge: 43
Registriert: Donnerstag 2. März 2006, 23:05
Wohnort: Bielefeld

vielleicht hilft das hier:

Code: Alles auswählen

def f0(): print "0"
def f1(): print "1"
def f2(): print "2"

fx = [f0,f1,f2]

dann:
for i in range(0,3):
    fx[i]()
    '''statt:
    if i == 0: f0()
    if i == 1: f1()
    if i == 2: f2()'''
die funktionen werden einfach in einer liste gespeichert.

r2d2
äh, nimm diese schlange von meinem hals.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

XtraNine hat geschrieben:Sol das ein Wink mit den Zaunpfahl sein, das man Anweisungen die man in if-blöcke packt (wo man sehr viel if-blöcke hat ca. um die 20), lieber in Funktionen aufteilen sollte, die dann über ein hashtable aufgerufen werden um sich die ifs zu sparren?
Hi XtraNine!

Sicher nicht! Das würde die Sache nur verkomplizieren.

Du kannst auch einfache Werte zurück geben lassen. Z.B. so:

Code: Alles auswählen

def is_ok(parameter):
    d = {
        "TRUE": "ok",
        "OK": "ok",
        "FALSE": "nicht ok"
    }
    return d[parameter]
print is_ok("TRUE")
Das kann aber kein Ersatz für das wirklich einfach zu verwendende if-elif-else sein, wenn einfach nur ein paar logische Bedingungen ausgewertet werden sollen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BlackJack

XtraNine hat geschrieben:Oder anders: Sol das ein Wink mit den Zaunpfahl sein, das man Anweisungen die man in if-blöcke packt (wo man sehr viel if-blöcke hat ca. um die 20), lieber in Funktionen aufteilen sollte, die dann über ein hashtable aufgerufen werden um sich die ifs zu sparren?
Im Fall von 20 ``if``-Blöcken, die mehrere Zeilen Quelltext enthalten, würde sagen ja. Wenn diese Blöcke komplett unterschiedlichen Code enthalten, macht die Funktion zu viele verschiedene Dinge auf einmal und wenn nahezu das gleiche mit leichten Variationen gemacht wird, dann braucht man nicht für jeden Block eine andere Funktion, sondern kann die Gemeinsamkeiten in einer oder zwei parametrisierten Funktionen herausziehen.

Aber das kommt wie gesagt auch immer auf den konkreten Fall und ein wenig auf den eigenen Geschmack an, wie man das am "besten" löst.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

r2d2 hat geschrieben:vielleicht hilft das hier:
...
die funktionen werden einfach in einer liste gespeichert.
Na, das allerdings ist Code schön nach der Reihe ausführen - nur etwas verkompliziert.

Im Übrigen habe ich nichts zu meinen Vorschreibern hinzuzufügen - manches ist Geschmackssache. Ich wollte nur die Eingabe von 'Leonidas' erläutern.
Gruß,
Christian
r2d2
User
Beiträge: 43
Registriert: Donnerstag 2. März 2006, 23:05
Wohnort: Bielefeld

@CM

der code sollte lediglich die prinzipielle funktionsweise veranschaulichen. klar, dass das beispiel sinnfrei ist.

r2d2
äh, nimm diese schlange von meinem hals.
sozo
User
Beiträge: 3
Registriert: Montag 14. November 2022, 20:48

Hi,

habt ihr ne Idee ob ich das noch verkürzen / verbessern kann? Weil ich brauche noch weitere Bedingungen und rücke immer weiter nach rechts was dann schlechter zu lesen ist...?

if bought:
if (abstand_aktuell_zu_slow > sell_level_slow):
if (abstand_aktuell_zu_fast > sell_level_fast):
if (symbol0_price > last_ema_xxl):
if (profit_since_buy_sy0 > -(buy_level_slow-sell_level_slow)):
#dann mach das.....


Danke für weitere Tipps
LG M
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Code: Alles auswählen

if dies and das and folgendes:
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@sozo
Weiterhin könnte man viele Prüfungen über mehrere Funktionen oder Methoden aufbauen. Also nicht alles "stumpf" runterschreiben, sondern sich ein bisschen mehr Struktur beim Programmaufbau überlegen. Einzelne Prüfungen lassen sich meist sinnvoll gruppieren und als Eigenschaften ausdrücken. Ich habe keine Ahnung, was dein Code genau machen soll, aber als erstes fällt mir bei dem Beispiel etwas wie should_sell_fast() / should_sell_slow() ein. Somit kann man die dahinter stehende Mathematik schrittweise hinter einer eigenen Schnittstelle kapseln. Das gibt dann zwar mehr Zeilen Code, ist aber in aller Regel lesbarer.

EDIT: Und es wäre beim nächsten Mal schön, wenn du einen eigenen Thread erstellst und keine 16 Jahre alten Beiträge hochholst. Das wird hier, wie in den meisten anderen Foren auch, nicht so gern gesehen...
sozo
User
Beiträge: 3
Registriert: Montag 14. November 2022, 20:48

__deets__ hat geschrieben: Montag 14. November 2022, 21:23

Code: Alles auswählen

if dies and das and folgendes:
Danke. So hatte ich es zuerst...ewig langer Satz und der ist nicht Handy tauglich. Wie bekomme ich es aber in mehrere Zeilen? Denn der Syntax ist falsch

Code: Alles auswählen

if dies 
and das 
and jenes
and folgendes:
geht sowas? Leider geht es weder mit "," am Satz ende noch mit ":", denn das ist das Ende von "if"...gibt es da einen Trick?
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Handy tauglich ist ein schwieriges Kriterium für Code. Aber das aufteilen auf mehrere Zeilen geht mit \ am Ende der Zeile.

Code: Alles auswählen

if dies \
    and das:
    …
sozo
User
Beiträge: 3
Registriert: Montag 14. November 2022, 20:48

wow, ich Danke Dir! Vier tabs eingespart und nun ist alles wieder links und nicht so weit rechts. Leider verträgt es aber keine Kommentare nach dem "\" nur nach dem ":"

Code: Alles auswählen

if not bought \
        and abstand_aktuell_zu_slow < buy_level_slow \
        and abstand_aktuell_zu_fast < buy_level_fast \
        and symbol0_price < last_ema_slow \
        and profit_since_buy_sy0 < -buy_level_slow-sell_level_slow: #Kommentar erlaubt
    …
Antworten