if- Structures

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
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

Eine generelle Frage:
Muessen bei if-structures immer alle Faelle abgedeckt sein? Ich habe momentan das Problem, dass ich in meinem Programm mehrere verschiedene Faelle habe.

Code: Alles auswählen

if check2 == 0 and check1 == 1 and check3 == 0 and check4 == 1 :
    do this
if check2 == 1 and check1 == 0 and check3 == 1 and check4 == 0 :
    do that
    
if check3 == 0 and check4 == 0:
    do something else
eigentlich haette ich aber lieber ein

Code: Alles auswählen

if check2 == 0 and check1 == 1 and check3 == 0 and check4 == 1 :
    do this
if check2 == 1 and check1 == 0 and check3 == 1 and check4 == 0 :
    do that
    
else:
    do something else

der letztere Fall scheint aber nicht zu funktionieren. ALLES im Code ist sonst gleich geblieben.
Vielen Dank im Vorraus,
Peter
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ich weiß nicht genau, auf was du hinaus möchtest, aber suchst du vielleicht einfach nur ``elif``?

Code: Alles auswählen

if check2 == 0 and check1 == 1 and check3 == 0 and check4 == 1 :
    do this
elif check2 == 1 and check1 == 0 and check3 == 1 and check4 == 0 :
    do that  
else:
    do something else
Je nach Anzahl der elif bietet sich aber ein Übergang zu Dictionaries an. Wie sieht denn dein tatsächlicher Code aus?
Das Leben ist wie ein Tennisball.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Moin peter,
peter99 hat geschrieben:Eine generelle Frage:
Muessen bei if-structures immer alle Faelle abgedeckt sein?
Prinzipiell musst Du alle Fälle, die Du unterscheiden möchtest, auch abdecken. Oder was meinst Du mit abdecken?
peter99 hat geschrieben:Ich habe momentan das Problem, dass ich in meinem Programm mehrere verschiedene Faelle habe.

Code: Alles auswählen

if check2 == 0 and check1 == 1 and check3 == 0 and check4 == 1 :
    do this
if check2 == 1 and check1 == 0 and check3 == 1 and check4 == 0 :
    do that
    
else:
    do something else
genau das else gibt es in Python (und zudem auch ein elif, das nur dann geprüft wird, wenn vorherige Bedingungen nicht zutreffen). Hört sich an, als würdest Du das suchen:

Code: Alles auswählen

if not check2 and check1 and not check3 and check4:
    do this
elif check2 and not check1 and check3 and not check4:
    do that
else:
    do something else
Was genau funktioniert nicht? Belommst Du eine Fehlermeldung?

Grüße,
Micha
Diese Nachricht zersört sich in 5 Sekunden selbst ...
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

Hi,
vielen Dank fuer die schnelle Antwort.
Also der Pythoncode ist mit einem CSS-Programm vernetzt und die Ergebnisse werden in einem table ausgegeben.

Code: Alles auswählen

if check2 == 0 and check1 == 1 and check3 == 0 and check4 == 1 :
    do this
if check2 == 1 and check1 == 0 and check3 == 1 and check4 == 0 :
    do that
else:
    do something else
Wenn ich dies als meinen Code angebe, dann printet es mir im Gegensatz zu dem vorherigen nichts mehr aus, auch wenn if check2 == 0 and check1 == 1 and check3 == 0 and check4 == 1 :
eines der ersten beiden Faelle zutrifft.
Ich mage nur die check3 ==0 and check4 ==0 regel generalisieren, aber das funktioniert nicht/liefert ein falsches Ergebnis ohne Fehlermeldung, da es etwas macht, aber eben nicht das gewuenschte;)
Liebe Gruesse,
Peter
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

peter99 hat geschrieben:Also der Pythoncode ist mit einem CSS-Programm vernetzt und die Ergebnisse werden in einem table ausgegeben.
Ich glaube ich stehe auf dem Schlauch, was meinst Du mit "vernetzt"? Könntest Du so etwas wie einen Ablaufplan posten, also welches Prozesselement, mit welchem was austauscht? Nutzt Du das in einem Web-Framework?
Besser noch einen kleinen Ausschnitt richtigen Codes, d.h. was zwischen If ... elif ... else ... steht.

Ich habe Dich anfangs so verstanden, dass wenn Du die drei if-Anweisungen des ersten Codestücks ausführst, der Inhalt des dritten if-Blocks ausgeführt wird. Wenn Du die dritte if-Anweisung durch ein "else" ersetzt, wird der dritte Block nicht mehr ausgeführt.

Aber ich denke, ich weiß was Dein Problem ist: wenn nur einer der drei Blöcke ausgeführt werden darf, dann MUSST Du als zweites "elif" verwenden. Andernfalls bezieht sich "else" nur auf das direkt davor geschriebene "if":

1. if: block 1
2. if: block 2
else: block 3

Wenn Bedingung 1 erfüllt ist, wird block 1 ausgeführt, wenn nicht passiert nichts
Wenn Bedingung 2 erfüllt ist, wird block 2 ausgeführt, wenn nicht wird block 3 ausgeführt - auch dann, wenn Block 1 schon ausgeführt wurde.
Im letzten Fall wird die wahrscheinlich in Block 1 gesetzte CSS-Eigenschaft wieder überschrieben und es sieht so aus, als ob nur das else ausgeführt wird. Das gilt nur, wenn Bedingung 1 erfüllt ist. Wenn Bedingung zwei erfüllt ist, geht der Interpreter nicht in den else-Block.

Gruß,
Micha
Diese Nachricht zersört sich in 5 Sekunden selbst ...
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

Ich habe ein GUI-interface von dme as Pythonprogramm seine inputs nimmt, calculiert und anschliessend das Ergebnis in einem table printet. also so etwas wie:

Code: Alles auswählen

 if check2 == 1 and check1 == 0 and check3 == 1 and check4 == 0 :
        numbers = range(int(minnumber), int(maxnumber)+1, 1)
        Q = range(1, Qin + 1, 1)
        Qout, Vebitout, fieldout, numberout = [], [], [], []
        for j in numbers:
            diffE = E - 600
            E_average = (600 + E)/2
            v_averge = sqrt(2*E_average*1.602177*10**(-16)/1.6726*10**27)
            c = 299792458.0
            beta_average = v_averge/c
            T_average = sin(pi*geff/(beta_average*Lambda))/(pi*geff/(beta_average*Lambda))*sin(pi*betaS/(2*beta_average))
            for i in Q:
                Vebit = 12*A/i
                fieldreal = diffE*A/(27.98*i*float(j)*T_average*cos(phi))
                listfields = [fieldreal]* int(j)
                if fieldreal < maximumf and fieldreal > minimumf and Vebit < Vebitmax and all(t < u for t, u in zip(listfields, cavmaxreal)):
                    Qout.append(i)
                    len(Qout)
                    table.setCellText(len(Qout) - 1 , 0, str(i))
                    table.setCellText(len(Qout) - 1 , 1, str(Vebit))
                    table.setCellText(len(Qout) - 1 , 2, str(j))
#take Ein so it is displayed in the unit you entered
                    table.setCellText(len(Qout) - 1, 3, str(Ein))
und

Code: Alles auswählen

 if check3 == 0 and check4 == 0:
   # else:
  # to refresh the content
        table.setContent([[" ", " ", " ", " "]])
        table1.setContent([[" ", " ", " ", " ", " ", " "]])
        for i in range(1, 7):
            display.getWidget("cav" + str(i)).setValue(0)
Das ist wahrscheinlich nicht ueberaus hilfreich, aber ich glaube das Ziel dahinter wird ca. klar oder.
Vielen Dank
Peter
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hallo Peter,

mir ist noch etwas eingefallen und um nicht doppelt zu posten, habe ich es an meinen letzten Post gehängt. :-(
Hast Du das gesehen? Kurz: wenn Du drei Bedingungen hast, von deren Anweisungsblöcken nur einer ausgeführt werden darf, dann musst Du

if (Bedingung1): ...
elif (Bedingung2): ...
else: ...

verwenden.

Gruß
Diese Nachricht zersört sich in 5 Sekunden selbst ...
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

danke, das wars! vielen dank!!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@peter99: Hui... sorry, aber der Code sieht *grausam* aus und Deine Bedingungen schreien auch nach einer *Datenstruktur*!

Man sollte Namen niemals nummerieren; denn wenn man das tut, will man eigentlich eine Collection verwenden, idR. dann eine Liste.

Bei Dir bietet sich das doch ganz einfach an:

Code: Alles auswählen

checks = [1, 0, 1, 0]

checks == [1, 0, 1, 0]
> True

checks == [1, 0, 1, 1]
> False
Sollten das eher Wahrheitswerte sein, so verwende doch besser die Literale ``True`` und ``False`` statt 0 und 1!

Je nach Anzahl der Bedingungen kann man auch auf die if...elif...else-Kaskaden verzichten und ein Dispatching über ein Dictionary o.ä. aufbauen. Sollte es nur diese drei Möglichkeiten geben, geht es auch so.

In Deinem Code scheinst Du zu viel zu vermischen! Ich sehe da von der Hierarchie her (if, for, for, if) - das ist zu viel in *einer* Funktion; mal ganz unabhängig davon, dass Berechnungen und GUI miteinander offenbar vermischt sind. Lagere mehr Code in separate Funktionen aus. Z.B. hast Du eine Funktion, die sich um den Ablauf (also die Auswertung der Bedingungen) kümmert, dann jeweils eine Berechnungsfunktion aufruft und das Ergebnis an eine Funktion weiterreicht, die von der GUI-Seite her die neuen Wert setzt.

Deine Namen an sich sind ziemlich nichtssagend... was ist denn "Q"? Ok, je nach Domäne und Problem kann man auch mal Buchstaben verwenden (Physik o.ä.), aber generell solltest Du aussagekräftige Namen verwenden. Bei ``table`` sehe ich auch wieder einen nummerierten Namen ``table1``... da weißt Du doch sicher bald nicht mehr, welcher Name was repräsentiert!?

Auch wenn Du das jetzt irgend wie zum Laufen gebracht hast, wirst Du spätestens in einigen Tagen / Wochen an dem Code verzweifeln, weil Du ihn nicht mehr durchschaust.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

vielen Dank, ich bin ein Python-Neuling. Q repraesentiert eine Ladung, es handelt sich um ein physikalisches Problem. Der code ist zurzeit ziemlich schlimm und gerade das versuche ich zu verbessern.
Also vielen Dank fuer die Hinweise!
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

ich verstehe nicht 100%-ig, was du damit meinst. die checks sind im GUI checkboxen, die den wert 0 oder 1 haben, je nachdem ob sie geklickt wurden oder nicht. also werden die werte der checkboxen eingelesen und je nachdem, was fuer entscheidungen der user getroffen hat, gehe ich dann einen verschiedenen pfad im programm.
ich koennte eine liste checks = [check1, check2, check3, check4] machen und dann checken, ob.. z.B. checks == [0,0,1,0] ist, meinst du das?
Lg, Peter
BlackJack

@peter99: Das mit den durchnummerierten `check*`\s sind wieder schlechte Namen. Wenn man verstehen will was die Bedingungen beim ``if`` bedeuten, muss man doch wissen was die einzelnen Checkboxen *bedeuten*. In der GUI werden die doch sicher mit vernünfigen Namen beschriften sein, und nicht einfach mit Ziffern.
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

hmmm, ja, schon, ich habe nur sehr viele inputs und ich muss wissen, dass es eine checkbox ist. werde drueber nachdenken. am ende, wenn alles fertig ist, werd ich nochmal alle namen durchgehen
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@peter99: Du mußt nicht wissen, daß es eine Checkbox ist, sondern was es ist. Aus dem "Was" ergibt sich automatisch, daß nur Ja/Nein sinnvolle Werte sind, die Darstellung kann man dann mit einer Checkbox machen.
Antworten