Seite 1 von 1

Frage zu SpinCtrl

Verfasst: Donnerstag 24. November 2011, 08:57
von schwedenmann
Hallo

Habe folgendes Demoprogramm modifiziert
[url][http://wiki.wxpython.org/AnotherTutoria ... inCtrl/url] spinctrl.py

hier meine Modifikation

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
# spinctrl.py
 
import wx
class MyDialog(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(350, 310))
        wx.StaticText(self, -1, 'Zinseszins - Endkapitalberechnung ', (20,20))
        wx.StaticText(self, -1, 'Anfangskapital: ', (20, 80))
        wx.StaticText(self, -1, 'Laufzeit: ',  (20, 100))
        wx.StaticText(self, -1, 'Zinssatz: ',  (20, 125))
        wx.StaticText(self, -1, 'Zinszahlungen: ',  (20, 150))
        wx.StaticText(self, -1, 'Endkapital: ', (20, 225))
        
        self.SetBackgroundColour('Orange')
        self.endkapital =  wx.StaticText(self, -1, '', (225, 225))
        self.sk = wx.SpinCtrl(self, -1, '',  (150, 75), (60, -1))
        self.sk.SetRange(-459, 1000)
        self.sk.SetValue(0)
        self.lz = wx.SpinCtrl(self, -1, '', (150, 100), (60, -1))
        self.lz.SetRange(0, 50)
        self.lz.SetValue(0)
        self.zs = wx.SpinCtrl(self, -1, '', (150, 125), (60, -1))
        self.zs.SetRange(0, 20)
        self.zs.SetValue(0)
        self.zz = wx.SpinCtrl(self, -1, '', (150, 150), (60, -1))
        self.zz.SetRange(0, 20)
        self.zz.SetValue(0)
 
        compute_btn = wx.Button(self, 1, 'Berechnen', (70, 250))
        compute_btn.SetFocus()
        clear_btn = wx.Button(self, 2, 'Beenden', (185, 250))
 
        self.Bind(wx.EVT_BUTTON, self.OnCompute, id=1)
        self.Bind(wx.EVT_BUTTON, self.OnClose, id=2)
        self.Bind(wx.EVT_CLOSE, self.OnClose)
 
    def OnCompute(self, event):
         startkapital = self.sk.GetValue()
         laufzeit = self.lz.GetValue()
         zinssatz = self.zs.GetValue()
         zinszahlungen = self.zz.GetValue()
         cels = startkapital * (1 + zinssatz/(100*zinszahlungen))**(laufzeit*zinszahlungen)
         self.endkapital.SetLabel(str(cels))
 
    def OnClose(self, event):
         self.Destroy()
 
class MyApp(wx.App):
     def OnInit(self):
         dlg = MyDialog(None, -1, 'Zinseszins.py')
         dlg.Show(True)
         dlg.Centre()
         return True
 
app = MyApp(0)
app.MainLoop()
Das Programm gibt mir immer nur den Wert der Eingabe von startkapital (sk) zurück, wo liegt der Fehler

Re: Frage zu SpinCtrl

Verfasst: Donnerstag 24. November 2011, 09:56
von BlackJack
@schwedenmann: Rechnen mit ganzen Zahlen:

Code: Alles auswählen

In [86]: 100 * (1 + 7 / (100 * 42))**(23 * 42)
Out[86]: 100

In [87]: (1 + 7 / (100 * 42))**(23 * 42)
Out[87]: 1

In [88]: (1 + 7 / (100 * 42))
Out[88]: 1

In [89]: 7 / (100 * 42)
Out[89]: 0
Du musst halt dafür sorgen, dass die Berechnungen mit Gleitkommazahlen ausgeführt werden.

Sonstige Anmerkungen: Statisches, pixelgenaues Layout ist kaputtes Design. Das verwendet man heutzutage nicht mehr. `wx` bietet verschiedene Sizer um das GUI-Layout dynamisch zu gestalten und damit unabhängig von Anzeigegrösse, Display-Auflösung, Schriftarten- und Grössen, und so weiter, zu machen.

Statt -1 bei IDs sollte man `wx.ID_ANY` nehmen, damit dem Leser eher klar ist, was das Argument bedeutet.

Man darf nicht selber irgendwelche festen IDs verwenden! Es gibt IDs die von `wx` schon mit einer Bedeutung vorbelegt sind. Da können „interessante“ Sachen passieren wenn man einfach so welche nimmt, von denen man nicht weiss ob sie nicht schon eine Bedeutung haben. Garantiert unbenutzte kann man mit `wx.NewId()` erstellen. Das ist aber meistens gar nicht nötig. Man kann oft auch einfach `wx.ID_ANY` nehmen und dann bei anderen Methoden statt einer ID das Objekt selbst übergeben. Oder man verwendet eine vorgegebene ID falls man eine passende findet. Zum Beispiel `wx.ID_EXIT` für eine Schaltfläche, die das Programm beendet. Wenn man dort dann noch als Text eine leere Zeichenkette verwendet, werden Standard-Icon und Beschriftung für die Aktion verwendet:

Code: Alles auswählen

        compute_btn = wx.Button(self, wx.ID_APPLY, '', (70, 250))
        compute_btn.SetFocus()
        clear_btn = wx.Button(self, wx.ID_EXIT, '', (185, 250))
        
        self.Bind(wx.EVT_BUTTON, self.OnCompute, compute_btn)
        self.Bind(wx.EVT_BUTTON, self.OnClose, clear_btn)
Attributnamen wie `sk`, `lz`, `zs`, oder `zz` gehen ja mal gar nicht.

Man sollte Dialoge nicht selber platzieren. Das kann Anwender gehörig nerven wenn Fenster nicht da erscheinen wo freier Platz auf dem Desktop ist, sondern unbedingt in der Mitte aufgehen wollen. Wenn man das haben möchte, dann kann man das als Anwender der Fensterverwaltung mitteilen.

Die Grenzwerte für die Zahleneingabe solltest Du noch einmal überdenken. Die kann man auch so setzen, dass ein `ZeroDivisionError` vermieden wird.

Re: Frage zu SpinCtrl

Verfasst: Donnerstag 24. November 2011, 10:34
von schwedenmann
Hallo

Danke.

Hab jetzt erstmal so geändert

Code: Alles auswählen

def OnCompute(self, event):
         startkapital = float(self.sk.GetValue())
         laufzeit = int(self.lz.GetValue())
         zinssatz = float(self.zs.GetValue())
         zinszahlungen = float(self.zz.GetValue())
         cels = round (startkapital * (1 + zinssatz/(100*zinszahlungen))**(laufzeit*zinszahlungen), 2)
         self.endkapital.SetLabel(str(cels))
Kann man das so stehen lassen, oder sollte man flot int andrs handhaben?

Zu den aboluten px-Angabne, das sind jetzt meine ersten Anfänge mit GUIprogrammierung, ist nur eine Übung, damit ich den GrundAufbau bei wxPython verstehen lerne.

Zu den Attributen lz, sk etc., sollen, müsen das komplette Wörter, ev. sogar groß geschrieben sein ?

Re: Frage zu SpinCtrl

Verfasst: Donnerstag 24. November 2011, 10:38
von deets
Nein, nicht grossgeschrieben - lies dir mal PEP8 durch, das sind Hinweise, wie Python-Code formatiert sein sollte.

Re: Frage zu SpinCtrl

Verfasst: Donnerstag 24. November 2011, 18:19
von Dav1d
Das kommt darauf an, ich persönlich würde für lokale Variabeln der PEP-8 auf jeden Fall folgen, bei Funktionen/Methoden scheiden sich die Geister, laut PEP8 lautet deine Funktion "on_compute" und nach wxPython-Konvention so wie du sie genannt hast, "OnCompute".