Probleme mit Radiobutton.

Fragen zu Tkinter.
Antworten
MrMelone
User
Beiträge: 5
Registriert: Dienstag 23. Dezember 2014, 15:19

Hallo!

Ich bin Python-Anfänger und habe ein Problem mit meinen Radiobuttons. Ich weiß nicht was ich falsch mache, ich kann durch diese Buttons keine Eingrezung in meinem Programm bekommen, sodass ich durch If-Anweisungen verschiedene Rechnung durchführen kann. Ich hoffe auf Hilfe von euch! Danke.

Hier der Quelltext.

Code: Alles auswählen

from tkinter import *

# Das Hauptfenster
Hauptfenster = Tk()
Hauptfenster.title("Schneelasten - Rechner")

v = IntVar()
value = IntVar()
x = IntVar()
sk = float()

# Zeile 0: Die Grafik wird in das Hauptfenster geladen und positioniert.
bild = PhotoImage(file = "Zonen.gif")
Label(image = bild).grid(row = 0, column = 0, columnspan = 3)

# Zeile 1: Auswahl der Schneelastzone

Label(Hauptfenster, 
      text="Schneelastzone :",).grid(row = 1, column = 0, sticky = "e")
Radiobutton(Hauptfenster, 
            text="Zone 1",
            variable=v, 
            value=1).grid(row = 1, column = 1, sticky = "w")
Radiobutton(Hauptfenster, 
            text="Zone 1a",
            variable=v, 
            value=2).grid(row = 1, column = 1, sticky = "e")
Radiobutton(Hauptfenster, 
            text="Zone 2",
            variable=v, 
            value=3).grid(row = 2, column = 1, sticky = "w")
Radiobutton(Hauptfenster, 
            text="Zone 2a",
            variable=v, 
            value=4).grid(row = 2, column = 1, sticky = "e")
Radiobutton(Hauptfenster, 
            text="Zone 3",
            variable=v, 
            value=5).grid(row = 3, column = 1, sticky = "w")


# Zeile 2: Eingabe von der Höhe über dem Meeresspiegel
Label(text = "Höhe über dem Meeresspiegel :").grid(row = 4, column = 0, sticky = "e")
Meeresspiegel = Entry(width = 10)
Meeresspiegel.grid(row = 4, column = 1, sticky = "we")
Label(text = " in m").grid(row = 4, column = 2, sticky = "w")

# Zeile 3: Eingabe der Dachneigung
Label(text = "Dachneigung :").grid(row = 5, column = 0, sticky = "e")
Dachneigung = Entry(width = 10) 
Dachneigung.grid(row = 5, column = 1, sticky = "we")
Label(text = " in °").grid(row = 5, column = 2, sticky = "w")

# Zeile 4: Abfrage zum Schneefanggitter
Label(text = "Schneefanggitter ?").grid(row = 6, column = 0, sticky = "e")
Radiobutton(Hauptfenster, 
            text="Ja",
            variable=x, 
            value=1).grid(row = 6, column = 1, sticky = "w")
Radiobutton(Hauptfenster, 
            text="Nein",
            variable=x, 
            value=2).grid(row = 6, column = 1, sticky = "e")

# Die Funktion für den Knopf "berechnen!"
def berechnen():
    
        # Eingabe 
        Zone = int(value.get())
        ms = float(Meeresspiegel.get())
        dn = float(Dachneigung.get())
        SF = float(x.get())
        # Verarbeitung
        if value==1 and ms<=400:
            sk=0.65

        elif value==1 and ms>=400:
            sk = 0.19+0.91*((ms+140)/760)**2

        elif value==2 and ms<=400:
            sk = 0.81

        elif value==2 and ms>=400:
            sk = (0.19+0.91*((ms+140)/760)**2)*1.25

        elif value==3 and ms<=285:
            sk = 0.85

        elif value==3 and ms>=285:
            sk = 0.25+1.91*((ms+140)/760)**2

        elif value==4 and ms<=285:
            sk = 1.06

        elif value==4 and ms>=285:
            sk = (0.25+1.91*((ms+140)/760)**2)*1.25

        elif value==5 and ms<=255:
            sk = 1.1

        else: value==5 and ms>=255
        sk = 0.31+2.91*((ms+140)/760)**2
        
            
        # Ausgabe
        LA.config(text = "Zu erwartende Schneelast = %.2f kN/m²"%sk)
        

         
# Zeile 4: Der Knopf "berechnen!"
b1 = Button(text = "berechnen!", command = berechnen)
b1.grid(row = 7, column = 1, columnspan = 1, sticky = "nsew")

# Zeile 5: Ausgabe von A
LA = Label()
LA.grid(row = 8, column = 1, sticky = "w")

         
Hauptfenster.mainloop()

Ich habe hier nun versucht den Wert sk auszugeben. Dieser müsste sich eigentlich aufgrund der verschiedenen Werte ändern.
BlackJack

@MrMelone: Es wäre nett wenn Du jetzt auch noch verraten würdest wo das Problem liegt dann muss man das nicht raten oder mühsam selber herausfinden.

Du berechnest in den verschiedenen ``elif``-Zweigen eventuell einen Wert für `sk` der aber niemals irgendwo verwendet wird weil kurz vor der Ausgabe in dem Label grundsätzlich ohne irgendwelche Bedingungen `sk` neu berechnet wird und damit dann natürlich immer dieser Wert nach der dort angegeben Formel zum tragen kommt. Das ``else`` sieht sehr merkwürdig aus, denn alles was in *dem* Zweig gemacht wird ist ein Wahrheitswert zu berechnen der für nichts verwendet wird. Der wird nicht einmal an einen Namen gebunden.

Edit: Es wird auch niemals einer der ``elif``-Zweige ausgeführt weil die Bedingungen niemals erfüllt werden können. Schau Dir mal genau an was Du da vergleichst. Was ist `value` für ein Datentyp? Und wie sollte der jemals mit einer Zahl verglichen wahr sein können?
MrMelone
User
Beiträge: 5
Registriert: Dienstag 23. Dezember 2014, 15:19

Vielen Dank für deine Anteilnahme. Ich wollte nur durch die 5 Radiobuttons diese verschieden it Anweisungen ansteuern und dachte das sich der Wert value für jeden angesteuerten Button ändert. Ich wollte praktisch für jede Zone eine andere Rechnung benutzen.Das Problem mit der Ausgabe verstehe ich nicht ganz, aber danke für deinen Hinweis. Dafür ist das Forum ja da. Ich hoffe auf deine Hilfe. Hab Nachsicht ich bin Anfänger. :)
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@MrMelone: nochmal nachgefragt, weil es aus Deiner Antwort nicht klar hervorgeht: Du verstehst was in Zeile 101 und in Zeile 102 jeweils passiert? Falls nicht, vereinfache Dein Problem soweit, bis Du es verstanden hast. Dazu solltest Du die eigentliche Berechnung in eine eigene Funktion `schneelast` auslagern, die als Parameter nur Zahlen (also Zone, Meeresspiegel und was sie sonst noch braucht) bekommt, so dass man sie auch unabhängig von der GUI benutzen kann.
BlackJack

@MrMelone: Der Wert von `value` ändert sich nie. Noch mal die Frage: Welchen *Datentyp* hat `value`. Tipp: Das ist *keine* Zahl.
MrMelone
User
Beiträge: 5
Registriert: Dienstag 23. Dezember 2014, 15:19

Ich weiß jetzt nicht ob ich auf dem Holzweg befinde, aber kann es sein das es sich um die variable v handelt? Also das alle Buttons den Wert v haben. Müsste ich also für jeden Button eine andere variable einfügen? Hoffe ihr haltet mich nicht komplett für begriffsstutzig ^^
BlackJack

@MrMelone: Oh, da hätten wir dann das nächste Problem: Der Zustand von `value` wird nirgends verändert. Ist mir vorher noch gar nicht aufgefallen.

Ich würde mich da mal Sirius3 anschliessen: Fang noch mal von vorne an und zwar mit einer Funktion welche die Schneelast berechnet. Ganz ohne GUI. Und dann testest Du die mit den verschiedenen Werten, möglichst so das alle Fälle abgedeckt sind, und vielleicht am besten auch automatisiert, also mit einer Funktion die diese Funktion aufruft und mit händisch nachgerechneten Ergebnissen vergleicht. Und wenn das läuft, *dann* kann man sich Gedanken darüber machen eine GUI da drauf zu setzen.
MrMelone
User
Beiträge: 5
Registriert: Dienstag 23. Dezember 2014, 15:19

Frohes Neues euch allen,

habe nun nochmal ganz von vorne angefangen und versucht eine Funktion zubauen die die berechnung der "Schneelast" durchführt. Soweit funktioniert auch alles.
Habe nur nun das Problem das ich die Variable sk die ich ausgerechnet habe nicht in die nächste Berechnung stecken kann. Ich bekomme es nicht hin das "errechnete" sk in die andere Berechnung einzubinden. :cry:

Hier mein Quelltext:

Code: Alles auswählen

Zone = float(input("In welcher Zone Befinden sie sich?"))
Meeresspiegel = float(input("Höhe über dem Meeresspiegel?"))
sk = float()
Dachneigung = float(input("Bitte geben sie die Dachneigung ein:"))


def schneelast(sk):
    
    if Zone==1 and Meeresspiegel < 400:
        sk=0.65
    
    if Zone==1 and Meeresspiegel > 400:
        sk = 0.19+0.91*((Meeresspiegel+140)/760)**2
    
    if Zone==1.1 and Meeresspiegel < 400:
        sk=0.81
    
    if Zone==1.1 and Meeresspiegel > 400:
        sk = (0.19+0.91*((Meeresspiegel+140)/760)**2)*1.25

    if Zone==2 and Meeresspiegel < 400:
        sk=0.8
    
    if Zone==2 and Meeresspiegel > 400:
        sk = 0.25+1.91*((Meeresspiegel+140)/760)**2

    if Zone==2.1 and Meeresspiegel < 400:
        sk=1.06

    if Zone==2.1 and Meeresspiegel > 400:
        sk = (0.25+1.91*((Meeresspiegel+140)/760)**2)*1.25

    if Zone==3 and Meeresspiegel < 400:
        sk=1.1

    if Zone==3 and Meeresspiegel > 400:
        sk = 0.31+2.91*((Meeresspiegel+140)/760)**2

    else: 
        print("Da ist etwas schief gegangen!")

if 30 < Dachneigung > 0:
    0.8*sk
    print(sk)

if 30 < Dachneigung < 60:
    (0.8 * (60 - Dachneigung)/30) * sk
    print(sk)

if Dachneigung > 60:
    0*sk
    print(sk)
Ich hoffe wie immer auf eure Hilfe!
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@MrMelone: Erklär doch mal in Worten, was hier passiert:

Code: Alles auswählen

if 30 < Dachneigung > 0:
    0.8*sk
    print(sk)
In specifications, Murphy's Law supersedes Ohm's.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@MrMelone: In eine Funktion geht was rein, das nennt sich Argumente, und es kommt was raus, das nennt sich Rückgabewert.
Was soll bei Deiner Funktion "schneelast" reingehen? Auf keinen Fall "sk", weil das wird ja drin berechnet. Raus geht auch nix, weil es kein "return" gibt. Rauskommen sollte aber, na Du weißt ja selber, was Du da berechnest.
Am besten Du lernst das Kapitel über Funktionen nochmal in Deinem Lieblingstutorial.
Dann kannst Du auch gleich nochmal nachschlagen, wie denn das ist mit if und else.
Achso, aufrufen sollte man Funktionen auch noch.
MrMelone
User
Beiträge: 5
Registriert: Dienstag 23. Dezember 2014, 15:19

Vielen Dank für die Antworten!

Ganz langsam steig ich dahinter und ich komme mir so langsam vor als ob ich ein ganz schönes Brett vor dem Kopf hatte. :roll:
Habe das ganze jetzt mal verändert und verkürzt. Mir wird immernoch für sk 0 angegeben.

Code: Alles auswählen

Zone = float(input("In welcher Zone Befinden sie sich?"))
Meeresspiegel = float(input("Höhe über dem Meeresspiegel?"))
sk = float()


def skf(Zone,Meeresspiegel):
    
    if Zone==1 and Meeresspiegel < 400:
        sk=0.65
        
    elif Zone==1 and Meeresspiegel > 400:
        sk = 0.19+0.91*((Meeresspiegel+140)/760)**2
        
    elif Zone==1.1 and Meeresspiegel < 400:
        sk=0.81
        
    elif Zone==1.1 and Meeresspiegel > 400:
        sk = (0.19+0.91*((Meeresspiegel+140)/760)**2)*1.25

    elif Zone==2 and Meeresspiegel < 400:
        sk=0.8
        
    elif Zone==2 and Meeresspiegel > 400:
        sk = 0.25+1.91*((Meeresspiegel+140)/760)**2

    elif Zone==2.1 and Meeresspiegel < 400:
        sk=1.06

    elif Zone==2.1 and Meeresspiegel > 400:
        sk = (0.25+1.91*((Meeresspiegel+140)/760)**2)*1.25

    elif Zone==3 and Meeresspiegel < 400:
        sk=1.1

    elif Zone==3 and Meeresspiegel > 400:
        sk = 0.31+2.91*((Meeresspiegel+140)/760)**2

    else: 
        print("Da ist etwas schief gegangen!")
        
    return sk

skf(Zone,Meeresspiegel)
print(sk)
@sirius3 Ist die Funktion den nun korrekt Beschrieben, alsp sind die Parameter nun richtig angegeben. Muss hinter jeder If - Anweisung ein neues return gesetzt werden oder recht es dies am Ende der Funktion zu setzten?

In der Shell funktionierts jetzt.
BlackJack

@MrMelone: In Zeile 3 setzt Du `sk` auf 0.0, denn das ist der Rückgabewert vom Aufruf von `float()` und in Zeile 44 gibst Du diese 0.0 dann aus. Lass Zeile 3 am besten ganz weg und binde `sk` auf Modulebene an den Rückgabwert Deiner Funktion. Im Moment rufst Du die nämlich auf und ignorierst was die zurück gibt, was nicht sinvoll ist.

Die Zonen würde ich nicht in Zahlen umwandeln, denn das sind keine, vor allem keine Gleitkommazahlen. Im Original, also der DIN-Vorschrift, wird die zweite Gliederungsebene ja auch mit Buchstaben und nicht mit Ziffern angegeben.

Eine Berechnungsfunktion sollte nicht gleichzeitig Ausgaben für den Benutzer beinhalten. Im ``else``-Zweig sollte eine Ausnahme ausgelöst werden. Das passiert ja sowieso in dem Fall eine Zeile später, nämlich ein `NameError` weil `sk` nicht definiert wurde.

Ich würde da wahrscheinlich auch Daten rausziehen und die den Zonen zuordnen, also zum Beispiel die Werte für <400 und die Werte aus der ja im Grunde immer gleichen Formel für >400. Und führ die Funktion mal für irgendeine Zone und *genau* 400 Meter aus. Da sollte Dir was auffallen. ;-)

Edit: Ich denke dass da immer 400 Meter in jeder Zone als Grenzwert genommen werden könnte falsch sein. Das solltest Du mal nachprüfen.

Hier hat jemand wohl die gleiche Aufgabe: http://www.python-forum.de/viewtopic.php?f=1&t=35329
Antworten