[wxPython-users] Many Similar Dialogs For Date Entry
Christopher Barker
Chris.Barker at noaa.gov
Thu Feb 1 16:21:59 PST 2007
Rich,
> Rather than re-inventing the wheel, and having it out of round, =
always a good idea!
> Creating 18 classes, each slightly different from the others is inelegant
> and prone to be a maintenance nightmare. I suppose that one base class wi=
th
> the others inheriting from it might work
yes, that's what OO is about.
However, if what you are looking for is 18 slightly different Panels for =
entering the data, then subclassing could help, but would be a pain =
non-the-less.
What this calls for is dynamic GUI building. This is exactly why I'm not =
a fan of point-an-click GUI builders. In a case like this, you don't =
want to point and click your way to making 18 panels -- you want the =
panels to be generated by code.
I have a simple example of this that I've enclosed. It's a simple Unit =
converter. The Units and conversion factors are defined as data, then a =
Panel for each type of unit (length, velocity, etc) is created on the =
fly. This way I can just add new units to the data, and the whole thing =
just works. There are a couple of oddballs that are still written by =
hand and added in, but most of it works fine.
Your case is more complicated, but the same principle should work, =
define each curve in terms of it's name and parameters required. They =
should be similar enough that you can auto-build a panel to collect the =
data.
-Chris
-- =
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker at noaa.gov
-------------- next part --------------
#!/usr/bin/env python2.4
## there is a pythonw on OS-X, and I add one on Linux, so the #! line can s=
tay the same
import sys
try:
# let's see if it's local (for development)
import UnitConversion as UC
except ImportError:
print "importing installed Unitconversion"
import Hazmat.UnitConversion as UC
=
## This is for bundling up with Py2app or py2exe
## wxversion does not work with those.
if not hasattr(sys, "frozen"):
import wxversion
wxversion.select("2.6")
## Note: it may well work with other versions, but it's been tested on =
2.6.
import wx
class ConverterPanel(wx.Panel):
def __init__(self, parent, id, UnitType):
=
wx.Panel.__init__(self, parent, id, wx.DefaultPosition,style=3Dwx.S=
UNKEN_BORDER)
self.UnitType =3D UnitType
Units =3D UC.GetUnitNames(UnitType)
Units.sort()
=
self.FromUnits =3D wx.Choice(self, wx.ID_ANY, wx.DefaultPosition, w=
x.DefaultSize, Units)
self.FromUnits.SetSelection(0)
self.ToUnits =3D wx.Choice(self, wx.ID_ANY, wx.DefaultPosition, wx.=
DefaultSize, Units)
self.ToUnits.SetSelection(0)
self.InputBox =3D wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPositi=
on, (100,-1))
self.OutBox =3D wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition=
, (100,-1), style =3D wx.TE_READONLY)
=
Grid =3D wx.FlexGridSizer(6, 2, 5, 20)
Grid.Add(wx.StaticText(self, -1, "Convert from:", wx.DefaultPositio=
n, wx.DefaultSize),0,wx.ALIGN_LEFT)
Grid.Add((20, 1), 1) # adding a spacer
Grid.Add(self.InputBox, 0, wx.ALIGN_LEFT)
Grid.Add(self.FromUnits,0, wx.ALIGN_RIGHT)
Grid.Add((20, 20), 1) # adding a spacer
Grid.Add((20, 20), 1) # adding a spacer
Grid.Add(wx.StaticText(self, -1, "Convert To:", wx.DefaultPosition,=
wx.DefaultSize),0,wx.ALIGN_LEFT)
Grid.Add((20, 1), 1) # adding a spacer
Grid.Add(self.OutBox, 0, wx.ALIGN_LEFT)
Grid.Add(self.ToUnits, 0, wx.ALIGN_RIGHT)
Grid.Layout()
OuterBox =3D wx.BoxSizer(wx.VERTICAL)
OuterBox.Add((20, 20), 0)
Label =3D wx.StaticText(self, -1, UnitType, wx.DefaultPosition, wx.=
DefaultSize)
of =3D Label.GetFont()
Font =3D wx.Font(int(of.GetPointSize() * 2), of.GetFamily(), wx.NOR=
MAL, wx.NORMAL)
Label.SetFont(Font)
OuterBox.Add(Label, 0, wx.ALIGN_CENTER)
OuterBox.Add(Grid, 0, wx.ALIGN_CENTER|wx.ALL, 30)
OuterBox.Layout()
self.SetAutoLayout(True)
self.SetSizer(OuterBox)
self.Fit()
self.InputBox.Bind(wx.EVT_TEXT, self.Recalculate)
self.FromUnits.Bind(wx.EVT_CHOICE, self.Recalculate)
self.ToUnits.Bind(wx.EVT_CHOICE, self.Recalculate)
def Recalculate(self,event):
try:
from_string =3D self.InputBox.GetValue()
=
# this is not quite really sigfigs, as all zeros are
# counted, but it looks better it is set to a minimum of 4
# figures and maximum of 7, as there are no more than 7
# digits in the conversion factors
sigfigs =3D min( max(len(from_string.split("e")[0].replace(".",=
"")), 4), 7)
from_val =3D float(from_string)
from_unit =3D self.FromUnits.GetStringSelection()
to_unit =3D self.ToUnits.GetStringSelection()
to_val =3D UC.Convert(self.UnitType, from_unit, to_unit, from_v=
al)
=
format_string =3D "%%.%ig"%sigfigs
self.OutBox.SetValue(format_string%(to_val,))# this displays on=
ly 6 sigfigs...
except ValueError:
self.OutBox.SetValue("")
class LatLongPanel(wx.Panel):
def __init__(self, *args, **kwargs):
kwargs['style'] =3D wx.SUNKEN_BORDER
wx.Panel.__init__(self, *args, **kwargs)
self.TopPanel =3D wx.Panel(self, style =3D wx.TAB_TRAVERSAL|wx.NO_B=
ORDER) =
self.DegreesBox =3D wx.TextCtrl(self.TopPanel, size=3D(80,-1))
self.MinutesBox =3D wx.TextCtrl(self.TopPanel, size=3D(80,-1))
self.SecondsBox =3D wx.TextCtrl(self.TopPanel, size=3D(80,-1))
self.DecimalDegreesBox =3D wx.TextCtrl(self, size=3D(100,-1),style =
=3D wx.TE_READONLY)
self.DegreesMinBox =3D wx.TextCtrl(self, size=3D(100,-1),style =3D =
wx.TE_READONLY)
self.DegMinSecBox =3D wx.TextCtrl(self, size=3D(100,-1),style =3D w=
x.TE_READONLY)
#self.DecimalDegreesBox.Bind(wx.EVT_SET_FOCUS, self.OnDDFocus)
#self.DegreesMinBox.Bind(wx.EVT_SET_FOCUS, self.OnDDFocus)
#self.DegMinSecBox.Bind(wx.EVT_SET_FOCUS, self.OnDDFocus)
DMSSizer =3D wx.GridSizer(2, 3, 1, 5)
DMSSizer.Add(wx.StaticText(self.TopPanel, label=3D"Degrees:"))
DMSSizer.Add(wx.StaticText(self.TopPanel, label=3D"Minutes:"))
DMSSizer.Add(wx.StaticText(self.TopPanel, label=3D"Seconds:"))
DMSSizer.Add(self.DegreesBox, 0, wx.RIGHT, 5)
DMSSizer.Add(self.MinutesBox, 0, wx.RIGHT, 5)
DMSSizer.Add(self.SecondsBox, 0, )
self.TopPanel.SetSizerAndFit(DMSSizer)
OutputSizer =3D wx.FlexGridSizer(3, 2, 5, 5)
OutputSizer.AddGrowableCol(2)
=
OutputSizer.Add(wx.StaticText(self, label=3D"Decimal Degrees:"))
OutputSizer.Add(self.DecimalDegreesBox, 1)
OutputSizer.Add(wx.StaticText(self, label=3D"Deg - Min:"))
OutputSizer.Add(self.DegreesMinBox,1)
OutputSizer.Add(wx.StaticText(self, label=3D"Deg - Min - Sec:"))
OutputSizer.Add(self.DegMinSecBox, 1)
VertBox =3D wx.BoxSizer(wx.VERTICAL)
VertBox.Add((20, 20), 0)
Label =3D wx.StaticText(self, label=3D"Latitude/Longitude")
of =3D Label.GetFont()
Font =3D wx.Font(int(of.GetPointSize() * 2), of.GetFamily(), wx.NOR=
MAL, wx.NORMAL)
Label.SetFont(Font)
VertBox.Add((20, 20), 1)
VertBox.Add(Label, 0, wx.ALIGN_CENTER_HORIZONTAL)
VertBox.Add((20, 20), 1)
VertBox.Add(self.TopPanel, 0, wx.ALL, 10)
VertBox.Add(OutputSizer, 0, wx.ALL|wx.GROW, 0)
VertBox.Add((20, 20), 1)
OuterBox =3D wx.BoxSizer(wx.HORIZONTAL)
OuterBox.Add((1,1), 1)
OuterBox.Add(VertBox, 0)
OuterBox.Add((1,1), 1)
=
self.DegreesBox.Bind(wx.EVT_TEXT, self.Recalculate)
self.MinutesBox.Bind(wx.EVT_TEXT, self.Recalculate)
self.SecondsBox.Bind(wx.EVT_TEXT, self.Recalculate)
self.SetSizerAndFit(OuterBox)
LLC =3D UC.LatLongConverter
def OnDDFocus(self, event=3DNone):
if sys.platform =3D=3D "linux2":
# this is needed on GTK, not on win32
self.DegreesBox.SetFocus()
pass
def Recalculate(self,event):
try:
values =3D []
for box in (self.DegreesBox, self.MinutesBox, self.SecondsBox ):
t =3D box.GetValue()
if t.strip() =3D=3D "":
values.append(0.0)
else:
values.append(float(t))
DecDeg =3D self.LLC.ToDecDeg(*values)
self.DecimalDegreesBox.SetValue(self.LLC.ToDecDeg(DecDeg, ustri=
ng=3DTrue))
self.DegreesMinBox.SetValue(self.LLC.ToDegMin(DecDeg, True) )
self.DegMinSecBox.SetValue(self.LLC.ToDegMinSec(DecDeg, True) )
except ValueError:
self.DecimalDegreesBox.SetValue("")
self.DegreesMinBox.SetValue("")
self.DegMinSecBox.SetValue("")
class ConverterFrame(wx.Frame):
def __init__(self,parent, id, title, position, size):
wx.Frame.__init__(self, parent, id, title, position, size)
## Set up the MenuBar
=
MenuBar =3D wx.MenuBar()
if not sys.platform =3D=3D "darwin":
file_menu =3D wx.Menu()
file_menu.Append(wx.ID_EXIT, "E&xit","Terminate the program")
MenuBar.Append(file_menu, "&File")
help_menu =3D wx.Menu()
help_menu.Append(wx.ID_ABOUT, "&About",
"More information About this program")
MenuBar.Append(help_menu, "&Help")
self.SetMenuBar(MenuBar)
=
wx.EVT_MENU(self, wx.ID_EXIT,self.OnQuit)
wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout)
=
wx.EVT_CLOSE(self, self.OnCloseWindow)
=
MainSizer =3D wx.BoxSizer(wx.HORIZONTAL)
self.MainSizer =3D MainSizer
ButtonSizer =3D wx.BoxSizer(wx.VERTICAL)
self.Panels =3D {}
BiggestSize =3D (0,0)
for UnitType in UC.GetUnitTypes():
# create Panel
Panel =3D ConverterPanel(self, -1, UnitType)
Panel.Show(False)
size =3D Panel.GetBestSize()
BiggestSize =3D ( max(size[0],BiggestSize[0]), max(size[1],Bigg=
estSize[1]) )
=
# create Button
ID =3D wx.NewId()
ButtonSizer.Add(wx.Button(self, ID, UnitType),
0,
wx.EXPAND|wx.ALL,
3)
self.Panels[ID] =3D Panel
### set up the events:
wx.EVT_BUTTON(self, ID, self.OnButtonPress)
## Add the LatLonPanel:
Panel =3D LatLongPanel(self)
Panel.Show(False)
size =3D Panel.GetBestSize()
BiggestSize =3D ( max(size[0],BiggestSize[0]), max(size[1],BiggestS=
ize[1]) )
=
# create Button
ID =3D wx.NewId()
ButtonSizer.Add(wx.Button(self, ID, "Lat-Long"),
0,
wx.EXPAND|wx.ALL,
3)
self.Panels[ID] =3D Panel
### set up the button event:
wx.EVT_BUTTON(self, ID, self.OnButtonPress)
=
ButtonSizer.Layout()
MainSizer.Add(ButtonSizer, 0, wx.ALIGN_TOP|wx.ALL, 6)
## Reset the sizes of all the Panels to match the biggest one
for Panel in self.Panels.values():
Panel.SetSize(BiggestSize)
Panel.SetSizeHintsSz(BiggestSize)
##Add all the Panels
for ID in self.Panels:
CurrentPanel =3D self.Panels[ID]
MainSizer.Add(CurrentPanel, 1, wx.GROW|wx.ALL,4)
MainSizer.Show(CurrentPanel, False)
self.CurrentPanel =3D self.Panels.values()[0]
MainSizer.Show(self.CurrentPanel)
self.SetSizerAndFit(MainSizer)
self.SetSizeHintsSz(self.GetSize(), self.GetSize())
=
def OnButtonPress(self,event):
ID =3D event.GetId()
self.MainSizer.Show(self.CurrentPanel, False)
self.CurrentPanel =3D self.Panels[ID]
self.MainSizer.Show(self.CurrentPanel)
self.MainSizer.Layout()
def OnAbout(self, event):
dlg =3D wx.MessageDialog(self, "This is a small program that \n"
"Provides some handy conversions.\n"
"If you find any errors, or want\n"
"additional units added, tell Chris Barker:\=
n"
"Chris.Barker at noaa.gov",
"About Converter", wx.OK | wx.ICON_INFORMATI=
ON)
dlg.ShowModal()
dlg.Destroy()
=
=
def OnQuit(self,event):
self.Close(True)
=
def OnCloseWindow(self, event):
self.Destroy()
class App(wx.App):
def OnInit(self):
frame =3D ConverterFrame(None,
wx.ID_ANY,
"Unit Converter",
wx.DefaultPosition,
wx.DefaultSize)
=
self.SetTopWindow(frame)
frame.Show(True)
return True
if __name__ =3D=3D "__main__":
app =3D App(0)
app.MainLoop()
=
#### test Lat/longif =
##if __name__ =3D=3D "__main__":
## app =3D wx.App(0)
## frame =3D wx.Frame(None)
## panel =3D LatLongPanel(frame)
## frame.Fit()
## frame.Show()
## app.MainLoop()
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
-------------- next part --------------
#!/usr/bin/env python2.4
__version__ =3D "1.0.0"
ConvertDataUnits =3D {
# All lengths in terms of meter
"Length" : {"meter" : (1.0,["m","meters","metre"]),
"centimeter" : (0.01,["cm", "centimeters"]),
"millimeter" : (0.001,["mm","millimeters"]),
"micron" : (0.000001,["microns"]),
"kilometer" : (1000.0,["km","kilometers"]),
"foot" : (0.3048,["ft", "feet"]),
"inch" : (0.0254,["in","inches"]),
"yard" : (0.9144,[ "yrd","yards"]),
"mile" : (1609.344,["mi", "miles"]),
"nautical mile" : (1852.0,["nm","nauticalmiles"]),
"fathom" : (1.8288,["fthm", "fathoms"]),
"latitude degree": (111120.0,["latitudedegrees"]),
"latitude minute": (1852.0,["latitudeminutes"])
},
# All Areas in terms of square meter
"Area" : {"square meter" : (1.0,["m^2","sq m","squaremeter"]),
"square centimeter": (.0001,["cm^2","sq cm"]),
"square kilometer" : (1e6,["km^2","sq km","squarekilometer"]),
"acre" : (4046.8564,["acres"]),
"square mile" : (2589988.1,["sq miles","squaremile"]),
"square yard" : (0.83612736,["sq yards","squareyards"]),
"square foot" : (0.09290304,["ft^2", "sq foot","square feet"]),
"square inch" : (0.00064516,["in^2", "sq inch","square inches"]),
"hectar" : (10000.0,["hectares"]),
},
# All volumes in terms of cubic meter
"Volume" : {"cubic meter" : (1.0,["m^3","cu m","cubic meter"]),
"cubic centimeter" : (1e-6,["cm^3","cu cm"]),
"barrels (petroleum)" : (.1589873,["bbl","barrels","barrel","bb=
ls",]),
"liter" : (1e-3,["l","liters"]),
"US gallon" : (0.0037854118,["gal","gallons","gallon","us=
gal"]),
"cubic foot" : (0.028316847,["ft^3","cu feet","cubicfeet"]),
"cubic inch" : (16.387064e-6,["in^3","cu inch","cubicinches"=
]),
},
# All Temperature units in K (multiply by, add)
"Temperature" : {"Kelvin" : ((1.0, 0.0),["K","degrees k","degrees k","degr=
ees kelvin","degree kelvin","deg k"]),
"centigrade" : ((1.0, 273.16),["C","degrees c","degree=
s celsius","degree celsius","deg c"]),
"farenheight" : ((0.55555555555555558, (273.16*9/5 - 32) =
),["F","degrees f","degree f","degrees farenheight","deg f"]),
},
# All Mass units in Kg (weight is taken to be mass at standard g)
"Mass" : {"kilograms" : (1.0,["kg","kilogram"]),
"pound" : (0.45359237,["lb","pounds","lbs"]),
"gram" : (.001,["g","grams"]),
"ton" : (907.18474, ["tons","uston"]),
"metric ton" : (1000.0, ["tonnes","metric tons"]),
"slug" : (14.5939, ["slugs"]),
"ounce" : (.028349523, ["oz","ounces"]),
},
# All Time In second
"Time" : {"second" : (1.0,["sec","seconds"]),
"minute" : (60.0,["min","minutes"]),
"hour" : (3600.0,["hr","hours","hrs"]),
"day" : (86400.0,["day","days"]),
},
# All Velocities in meter per second
"Velocity" : {"meter per second" : (1.0,["m/s","meters per second","mps"]),
"centimeter per second" : (.01,["cm/s"]),
"kilometer per hour" : (0.277777,["km/h", "km/hr"]),
"knot" : (0.514444,["knots","kts"]),
"mile per hour" : (0.44704,["mph","miles per hour"]),
"foot per second" : (0.3048,["ft/s", "feet per second", "fee=
t/s"]),
},
# All Discharges in cubic meter per second
"Discharge" : {"cubic meter per second" : (1.0,["m^3/s","cu m/s","cms"]),
"liter per second" : (0.001,["l/s","lps"]),
"cubic foot per second" : (.02831685,["cfs","cu feet/s","=
feet^3/s"]),
"gallon per hour" : (1.0515032833333335e-06,["gal/hr"]),
"gallon per minute" : (6.3090197000000006e-05,["gal/min", "g=
pm"]),
"gallon per second" : ( 0.0037854118,["gal/s"]),
"barrel per hour" : ( 4.4163138888888885e-05,["bbl/hr"]),
},
"Kinematic Viscosity" : {"Stoke": (1.0,["St","stokes"]),
"centistoke": (.01,["cSt","centistokes"]),
"square centimeter per second": (1.0,["cm^2/s"]),
"square meter per second": (10000,["m^2/s"]),
"square inches per second": (6.4516,["in^2/s"]),
#"poise" : (["P"])
},
### Density in g/cc
"Density" : {"grams per cubic centimeter" : (1.0,["g/cm^3"]),
"specific gravity" : (1.0,["S","Spec grav","SG"]),
"kilograms per cubic meter" : (.001,["kg/m^3"]),
"pounds per cubic foot": (0.016018463,["lbs/ft^3"]),
"API" : (1,["api"]),# this is special cased in the code.
},
### Concentration in water in PPM
"Concentration In Water" : {"part per million" : (1.0,["ppm","parts per mi=
llion"]),
"part per billion" : (.001,["ppb", "parts per =
billion"]),
"part per thousand" : (1000,["ppt", "parts per=
thousand"]),
"fraction" : (1e6,["fraction", "mass per mass"]=
),
"percent": (1e4,["%", "parts per hundred", "pe=
r cent"]),
"kilograms per cubic meter": (1000,["kg/m^3","=
kg/m3"]),
"pound per cubic foot": (16018.463, ["lb/ft^3"]=
),
"milligram per liter": (1.0, ["mg/l"]),
"microgram per liter": (0.001, ["ug/l"]),
}
}
def Simplify(String):
"""
Simplify(String)
returns the string with the whitespace and capitalization removed
"""
return "".join(String.lower().split())
def GetUnitTypes():
return ConvertDataUnits.keys()
def GetUnitNames(UnitType):
return ConvertDataUnits[UnitType].keys()
class ConverterClass:
def __init__(self, TypeName, UnitsDict):
self.Name =3D TypeName
self.Synonyms =3D {}
self.Convertdata =3D {}
for PrimaryName, data in UnitsDict.items():
# strip out whitespace and capitalization
Pname =3D Simplify(PrimaryName)
self.Convertdata[Pname] =3D data[0]
self.Synonyms[Pname] =3D Pname
for synonym in data[1]:
self.Synonyms[Simplify(synonym)] =3D Pname
def Convert(self, FromUnit, ToUnit, Value):
"""
Convert(FromUnit, ToUnit, Value)
returns a new value, in the units of ToUnit.
"""
FromUnit =3D Simplify(FromUnit)
ToUnit =3D Simplify(ToUnit)
try:
FromUnit =3D self.Synonyms[FromUnit]
except KeyError:
raise InvalidUnitError(FromUnit, self.Name)
try:
ToUnit =3D self.Synonyms[ToUnit]
except KeyError:
raise InvalidUnitError(ToUnit, self.Name)
return Value * self.Convertdata[FromUnit] / self.Convertdata[ToUnit]
# the special case classes:
class TempConverterClass(ConverterClass):
def Convert(self, FromUnit, ToUnit, Value):
"""
Convert(FromUnit, ToUnit, Value)
returns a new value, in the units of ToUnit.
"""
FromUnit =3D Simplify(FromUnit)
ToUnit =3D Simplify(ToUnit)
try:
FromUnit =3D self.Synonyms[FromUnit]
except KeyError:
raise InvalidUnitError(FromUnit, self.Name)
try:
ToUnit =3D self.Synonyms[ToUnit]
except KeyError:
raise InvalidUnitError(ToUnit, self.Name)
A1 =3D self.Convertdata[FromUnit][0]
B1 =3D self.Convertdata[FromUnit][1]
A2 =3D self.Convertdata[ToUnit][0]
B2 =3D self.Convertdata[ToUnit][1]
#to_val =3D (round((from_val * A1 + B1),13) - round(B2,13))*A2 # ro=
unding to get rid of cancelation error
to_val =3D ((Value + B1)*A1/A2)-B2
return to_val
class DensityConverterClass(ConverterClass):
=
def Convert(self, FromUnit, ToUnit, Value):
"""
Convert(FromUnit, ToUnit, Value)
returns a new value, in the units of ToUnit.
"""
FromUnit =3D Simplify(FromUnit)
ToUnit =3D Simplify(ToUnit)
=
try:
FromUnit =3D self.Synonyms[FromUnit]
except KeyError:
raise InvalidUnitError(FromUnit, self.Name)
try:
ToUnit =3D self.Synonyms[ToUnit]
except KeyError:
raise InvalidUnitError(ToUnit, self.Name)
if FromUnit =3D=3D "api": # another Special case (could I do this t=
he same as temp?)
Value =3D 141.5/(Value + 131.5)
FromUnit =3D "specificgravity"
if ToUnit =3D=3D "api":
ToVal =3D 141.5/(Value * self.Convertdata[FromUnit]) - 131.5
else:
ToVal =3D Value * self.Convertdata[FromUnit] / self.Convertdata=
[ToUnit]
return ToVal
class LatLongConverterClass:
def ToDecDeg(self, d=3D0, m=3D0, s=3D0, ustring =3D False):
"""
DecDegrees =3D ToDecDeg(d=3D0, m=3D0, s=3D0)
=
converts degrees, minutes, seconds to decimal degrees (returned as =
a Float).
"""
if m < 0 or s < 0:
raise ValueError("Minutes and Seconds have to be positive")
if d < 0:
Sign =3D -1
d =3D -d
else:
Sign =3D 1
DecDegrees =3D Sign * (d + m/60.0 + s/3600.0)
if ustring:
return u"%.6f\xb0"%(DecDegrees)
else:
return DecDegrees
def ToDegMin(self, DecDegrees, ustring =3D False):
"""
Converts from decimal (binary float) degrees to:
Degrees, Minutes
If the optional paramter: "ustring" is True,
a unicode string is returned
"""
if DecDegrees < 0:
Sign =3D -1
DecDegrees =3D -DecDegrees
else:
Sign =3D 1
Degrees =3D int(DecDegrees)
DecMinutes =3D (DecDegrees - Degrees + 1e-14) * 60# add a tiny bit =
to avoid rounding issues
if ustring:
return u"%i\xb0 %.3f'"%(Sign*Degrees, DecMinutes)
else:
return (Sign*Degrees, DecMinutes)
def ToDegMinSec(self,DecDegrees, ustring =3D False):
"""
Converts from decimal (binary float) degrees to:
Degrees, Minutes, Seconds
If the optional paramter: "ustring" is True,
a unicode string is returned
"""
if DecDegrees < 0:
Sign =3D -1
DecDegrees =3D -DecDegrees
else:
Sign =3D 1
=
Degrees =3D int(DecDegrees)
DecMinutes =3D (DecDegrees - Degrees + 1e-14) * 60# add a tiny bit =
to avoid rounding issues
Minutes =3D int(DecMinutes)
Seconds =3D round(((DecMinutes - Minutes) * 60), 10 )
if ustring:
return u"%i\xb0 %i' %.2f\""%(Sign*Degrees, Minutes, Seconds)
else:
return (Sign * Degrees, Minutes, Seconds)
=
=
# create the converter objects
LatLongConverter =3D LatLongConverterClass()
Converters =3D {}
for (unittype,data) in ConvertDataUnits.items():
if unittype.lower() =3D=3D 'temperature':
Converters["temperature"] =3D TempConverterClass(unittype, data)
elif unittype.lower() =3D=3D 'density':
Converters["density"] =3D DensityConverterClass(unittype, data)
else:
Converters[Simplify(unittype)] =3D ConverterClass(unittype, data)
def Convert(UnitType, FromUnit, ToUnit, Value):
UnitType=3D Simplify(UnitType)
try:
Converter =3D Converters[UnitType]
except:
raise InvalidUnitTypeError(UnitType)
return Converter.Convert(FromUnit, ToUnit, Value )
### This is used by TapInput
def GetUnitAbbreviation(Units):
# Abbreviation for units is a first element of synonyms list
try:
(UnitType,unit) =3D NameTable[Units]
except KeyError:
raise UnitConversionError("%s is not in UnitConverter Code"%Units)
return(ConvertDataUnits[UnitType][unit][1][0])
class UnitConversionError(Exception):
"""
Exception type for unit conversion errors
perhaps this should be subclassed more, but at the moment, I just pass =
a message back
"""
def __init__(self,message):
self.message =3D message
def __str__(self):
return self.message
class InvalidUnitError(UnitConversionError):
"""
Exception raised when a unit is not in the Unitconversion database
"""
def __init__(self, unit, type =3D ""):
self.unit =3D unit
self.type =3D type
def __str__(self):
return "The unit: %s is not in the list for Unit Type: %s"%(self.un=
it, self.type)
class InvalidUnitTypeError(UnitConversionError):
"""
Exception raised when a unit is not in the Unitconversion database
"""
def __init__(self, unitType):
self.unitType =3D unitType
def __str__(self):
return "The unit type: %s is not in the UnitConversion database"%se=
lf.unitType
=
class MismatchedUnitError(UnitConversionError):
"""
Exception raised when a unit is not in the Unitconversion database
"""
def __init__(self, FromUnit, FromUnitType, ToUnit, ToUnitType):
self.FromUnit =3D FromUnit =
self.FromUnitType =3D FromUnitType
self.ToUnit =3D ToUnit =
self.ToUnitType =3D ToUnitType =
def __str__(self):
#return "a test string"
return "The unit: %s of type %s is not compatible with %s of type =
%s"% \
(self.FromUnit, self.FromUnitType, self.ToUnit, self.ToUnitT=
ype)
=
=
More information about the wxpython-users
mailing list