R=U/I mit tkinter (Berechne)?

Fragen zu Tkinter.
Antworten
010010
User
Beiträge: 14
Registriert: Freitag 3. Juni 2016, 20:33

So habe ein kleines Problem mit meiner Aufgabe. Suche nach einer kleinen und leichten lösung. Zur hilfe gibt es auch dierekt meinen Code.

Code: Alles auswählen

## Widerstand

from tkinter import *
import math

win = Tk()
win.title("Wirkwiderstand")
win.geometry("300x200")

a = Label(win, text="R=U/I")
a.pack()

LabelU = Label(text="U=")
LabelU.pack()

U = Entry(win)
U.pack()

LabelI = Label(text="I=")
LabelI.pack()

I = Entry(win)
I.pack()

LabelR = Label(text="R=")
LabelR.pack()

R = Entry(win)
R.pack()

def ber():
	if R=="":
		u=float(U.get())
		i=float(I.get())
		x.configure(text=(u/i))
	if U=="":
		r=float(R.get())
		i=float(I.get())
		x.configure(text=(r*i))
	if I=="":
		r=float(R.get())
		u=float(U.get())
		x.configure(text=(u/r))

B1 = Button(text="Berechnen", command=ber)
B1.pack()

x = Label(text="Ergebnisstelle!")
x.pack()

win.mainloop()
Wie man sehen kann versuche ich einfach nur das Ohmsche Gesetz mit einer Grafikoberfäche zu Programmieren, aber egal wo ich die if Fragen hin packe es will nicht so wie es soll. Hab schon if drei mal mit def dri n stehen gebaut und halt jetzt so das man def hat und die Abfrage einfach in die def packt. Das Problem schein es zu sein das der Die abfrage nicht lösen kann wenn ich auf den Button klicke.

Mir fällt gerade auf das ich keine Erklärung zu meinem Programm hab. Es sind drei Textboxen und je nachdem in welche zwei man Werte ein gibt soll in der dritten automatisch das Ergebnis stehen. Nur in dem man den Button betätigt.
Zuletzt geändert von 010010 am Dienstag 7. Juni 2016, 15:17, insgesamt 2-mal geändert.
BlackJack

@010010: Du vergleichst `Entry`-Objekte mit Zeichenketten. Die ``if``-Bedingungen sind *nie* wahr, weil ein `Entry`-Objekt niemals gleich einer leeren Zeichenkette ist. Du musst die Zeichenkette die der Benutzer eingeben hat vergleichen. Wie man die von einem `Entry`-Objekt bekommt, weisst Du ja schon. Steht ja auch im Quelltext.

Allerdings ist das so ziemlich unsauber mit all diesen grottenschlechten Namen. Einbuchstabige Namen sind in Mathe-/Physikformeln vielleicht eine gute Idee, aber nicht in Programmen. Da soll ein Name dem Leser vermitteln was der Wert bedeutet, ohne das der nachschauen/-lesen oder raten muss wofür eine Abkürzung vielleicht stehen mag. Es verwirrt Dich ja anscheinend selber ein bisschen. `R` ist der Widerstand? Eben nicht, es ist ist ein Texteingabefeld für den Widerstandswert. `ber`? `a`? `x`?

Auf Modulebene sollten nur Definitionen von Konstanten, Funktionen, und Klassen stehen. Weder Variablen noch das Hauptprogramm. Was dann dazu führt, das man objektorientierte Programmierung (OOP) für GUIs braucht.
010010
User
Beiträge: 14
Registriert: Freitag 3. Juni 2016, 20:33

Ah toll das hab ich mir noch nicht näher angesehen.Ich hab eine Lösung in C# mal gehabt die ich auch angewant hatte, aber ich kann C# nicht für Linux nutzen. Ich hatte halt eine Lösung gefunden gehabt die ähnlich war und mit der Ausgangsform alleine geht das auch ohne Probleme. Nur halt nicht mit den Abfragen. Die Formelzeichen lasse ich so stehen, weil die International so gesetzt sind. Jeder der etwas mit E-Technik zu tun hat wird das auch verstehen. Darum geht es mir nicht um einem unwissenden die Rechnung zu vereinfachen. Das soll eh immer noch erst der anfang sein. Da muss noch mehr hin. Komplexe Rechnung wird da auch noch folgen. Hab schon einige Formeln fertig, aber nur als Terminal Preogramm und die will ich halt mit Grafikoberfläche bauen.

Kannsrt du mir mal ein Beispiel für eine Lösuung meines Problem zeigen?

mfg
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

010010 hat geschrieben:Ich hab eine Lösung in C# mal gehabt die ich auch angewant hatte, aber ich kann C# nicht für Linux nutzen.
Mono kennst du?
the more they change the more they stay the same
010010
User
Beiträge: 14
Registriert: Freitag 3. Juni 2016, 20:33

Ja natürlich kenn ich mono, aber das ist nicht so schön. Ich will das jetzt in Python lösen und komme nicht auf einen grünen Zweig. Will C# nicht benutzen. Das kann ich nur, weil ich es im Abitur brauchte.
BlackJack

@010010: Du hast Die Lösung selber schon in Deinem Programm stehen. Du willst die Eingabe gegen eine leere Zeichenkette prüfen. Und Du wandelst die Eingabe in Gleitkommawerte um. Das eine machst Du falsch, das andere machst Du richtig.

Bei den Namen geht es nicht darum irgendwem Rechnungen zu vereinfachen, sondern Lesern des Quelltextes das Verständnis zu erleichtern. Denn die Namen sind ja *falsch*. `R` ist nicht der Widerstand in dem Programm. Und `x` steht nicht für einen Wert aus ℝ, wie man das aus der Mathematik erwarten würde.
010010
User
Beiträge: 14
Registriert: Freitag 3. Juni 2016, 20:33

Ah jetzt kann ich mir da schon etwas mehr drunter vorstellen. Warum schreibst du das nicht dierekter. Das erinnert mich sonst an meinen SAS Lehrer. Der hat mir auch nur so ne wage aussage geben und gesagt du machst das schon. :D
BlackJack

@010010: Sternchen-Importe sollte man vermeiden. Gerade bei `tkinter` holt man sich cirka 190 Namen in das Modul die man nicht alle braucht und wo die Gefahr von Namenskollisionen besteht.

`math` wird importiert, aber nicht verwendet.

Bei allen `Label`-Exemplaren und beim `Button` wurde vergessen das Eltern-Widget zu übergeben.

Einiges wird unnötigerweise an Namen gebunden.

Mal sauberer aber ungetestet:

Code: Alles auswählen

import tkinter as tk
from functools import partial

 
def on_calculate(voltage_entry, current_entry, resistance_entry, result_label):
    try:
        voltage = float(voltage_entry.get())
    except ValueError:
        voltage = None
    
    try:
        current = float(current_entry.get())
    except ValueError:
        current = None
    
    try:
        resistance = float(resistance_entry.get())
    except ValueError:
        resistance = None

    if resistance is None:
        result = voltage / current
    elif voltage is None:
        result = resistance * current
    elif current is None:
        result = voltage / resistance
    
    result_label['text'] = result


def main():
    root = tk.Tk()
    root.title('Wirkwiderstand')
     
    tk.Label(root, text='R=U/I').pack()
     
    tk.Label(root, text='U=').pack()
    voltage_entry = tk.Entry(root)
    voltage_entry.pack()
     
    tk.Label(root, text='I=').pack()
    current_entry = tk.Entry(root)
    current_entry.pack()
     
    tk.Label(root, text='R=').pack()
    resistance_entry = tk.Entry(root)
    resistance_entry.pack()
     
    calculate_button = tk.Button(root, text='Berechnen')
    calculate_button.pack()
     
    result_label = tk.Label(root, text='Ergebnisstelle!')
    result_label.pack()
    
    calculate_button['command'] = partial(
        on_calculate,
        voltage_entry,
        current_entry,
        resistance_entry,
        result_label,
    )
    root.mainloop()


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