how best to check a value? (if/else or try/except?)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • John Salerno

    how best to check a value? (if/else or try/except?)

    My code is below. The main focus would be on the OnStart method. I want
    to make sure that a positive integer is entered in the input box. At
    first I tried an if/else clause, then switched to try/except. Neither is
    perfect yet, but I was wondering which I should try for in the first
    place. I figure I need to check for an emptry string, non-numeric
    strings (maybe these are the same check), 0 and negative numbers (which
    might also fall into the category of 'anything but a number' because of
    the negative sign).

    Thanks.

    -------------------------------

    import wx


    class MyTimer(wx.Fram e):

    def __init__(self):
    wx.Frame.__init __(self, None, wx.ID_ANY, 'Timer',
    style=wx.DEFAUL T_FRAME_STYLE ^
    wx.RESIZE_BORDE R ^ wx.MAXIMIZE_BOX )
    panel = wx.Panel(self)

    mainSizer = wx.BoxSizer(wx. VERTICAL)
    inputSizer = wx.BoxSizer(wx. HORIZONTAL)

    self.progress = wx.Gauge(panel, wx.ID_ANY, 100, size=(300, 20))
    self.status = wx.StaticText(p anel, wx.ID_ANY, 'Enter a time.')
    prompt = wx.StaticText(p anel, wx.ID_ANY, 'Time to wait:')
    self.input = wx.TextCtrl(pan el, wx.ID_ANY, size=(20, 20))
    self.start = wx.Button(panel , wx.ID_ANY, 'Start')
    self.reset = wx.Button(panel , wx.ID_ANY, 'Reset')
    self.reset.Disa ble()
    self.timer = wx.Timer(self)

    mainSizer.Add(s elf.progress, flag=wx.ALIGN_C ENTER | wx.ALL ^
    wx.BOTTOM,
    border=10)
    mainSizer.Add(s elf.status, flag=wx.ALIGN_C ENTER | wx.ALL,
    border=10)
    mainSizer.Add(i nputSizer, flag=wx.ALIGN_C ENTER | wx.BOTTOM,
    border=10)
    inputSizer.Add( prompt, flag=wx.ALIGN_C ENTER)
    inputSizer.Add( self.input, flag=wx.ALIGN_C ENTER | wx.LEFT |
    wx.RIGHT,
    border=5)
    inputSizer.Add( self.start, flag=wx.ALIGN_C ENTER)
    inputSizer.Add( self.reset, flag=wx.ALIGN_C ENTER)

    self.Bind(wx.EV T_TEXT_ENTER, self.OnStart, self.input)
    self.Bind(wx.EV T_BUTTON, self.OnStart, self.start)
    self.Bind(wx.EV T_TIMER, self.OnTimer, self.timer)
    self.Bind(wx.EV T_BUTTON, self.OnReset, self.reset)

    panel.SetSizer( mainSizer)
    mainSizer.Fit(s elf)

    def OnStart(self, event):
    try:
    self.time = int(self.input. GetValue())
    self.minutes_pa ssed = 1
    self.minutes_re maining = self.time - 1
    self.start.Disa ble()
    self.input.Disa ble()
    self.reset.Enab le()
    self.status.Set Label('%s minute(s) remaining.' % self.time)
    self.timer.Star t(1000)
    except ValueError:
    wx.MessageBox(' Enter a valid time.', 'Invalid time entered',
    wx.OK | wx.ICON_ERROR)
    self.input.Clea r()

    def OnReset(self, event):
    if self.timer.IsRu nning():
    self.timer.Stop ()
    self.input.Clea r()
    self.input.Enab le()
    self.start.Enab le()
    self.reset.Disa ble()
    self.status.Set Label('Enter a new time.')
    self.progress.S etValue(0)
    self.minutes_pa ssed = 1

    def OnTimer(self, event):
    if self.minutes_re maining != 0:
    self.progress.S etValue(self.mi nutes_passed * (100.0 /
    self.time))
    self.status.Set Label('%s minute(s) remaining.' %
    self.minutes_re maining)
    self.minutes_pa ssed += 1
    self.minutes_re maining -= 1
    else:
    self.timer.Stop ()
    self.progress.S etValue(self.mi nutes_passed * (100.0 /
    self.time))
    self.status.Set Label('%s minute(s) have elapsed.' % self.time)
    wx.Sound.Play(w x.Sound(r'C:\Wi ndows\Media\not ify.wav'))


    class MyApp(wx.App):

    def OnInit(self):
    frame = MyTimer()
    self.SetTopWind ow(frame)
    frame.Show()
    return True


    if __name__ == '__main__':
    app = MyApp(False)
    app.MainLoop()
  • Nick Vatamaniuc

    #2
    Re: how best to check a value? (if/else or try/except?)

    John,

    The way I do it is, is I ask myself 'is there a more common (basic)
    base between the code paths or do they both have about a 50/50 chance
    on average?' or 'will one code path be taken during an error and the
    other one during the normal processing?'. If there is a clear single
    common/usual/basic case or I try to detect an error I use 'try/except',
    if it could go either way on average I use 'if'.

    In general in Python we follow the 'it is better to ask forgiveness
    than to ask permission'. In other words if you don't know if a piece
    of data you have is a function and is callable you just call it and if
    it raises an exception then you'll know it's not. This is the opposite
    of C where you have to spend a good deal of time validating your input
    arguments before you can safely continue.

    That said, Python is also a practical language and quite often if you
    do just one check then an 'if' may take 2 lines (if no need for else)
    while a try/except will take 4 lines. So just apply common sense. For
    example, I want to find out if I can call f then do some stuff if that
    is the case:
    try:
    f(arg)
    #...do stuff because f is callable...
    except TypeError:
    pass
    # ... if f is not callable, then I don't care...

    But of course it is much shorter to do:
    if callable(f):
    #...do stuff because f is callable...

    Hope this helps,
    Nick Vatamaniuc





    John Salerno wrote:
    My code is below. The main focus would be on the OnStart method. I want
    to make sure that a positive integer is entered in the input box. At
    first I tried an if/else clause, then switched to try/except. Neither is
    perfect yet, but I was wondering which I should try for in the first
    place. I figure I need to check for an emptry string, non-numeric
    strings (maybe these are the same check), 0 and negative numbers (which
    might also fall into the category of 'anything but a number' because of
    the negative sign).
    >
    Thanks.
    >
    -------------------------------
    >
    import wx
    >
    >
    class MyTimer(wx.Fram e):
    >
    def __init__(self):
    wx.Frame.__init __(self, None, wx.ID_ANY, 'Timer',
    style=wx.DEFAUL T_FRAME_STYLE ^
    wx.RESIZE_BORDE R ^ wx.MAXIMIZE_BOX )
    panel = wx.Panel(self)
    >
    mainSizer = wx.BoxSizer(wx. VERTICAL)
    inputSizer = wx.BoxSizer(wx. HORIZONTAL)
    >
    self.progress = wx.Gauge(panel, wx.ID_ANY, 100, size=(300, 20))
    self.status = wx.StaticText(p anel, wx.ID_ANY, 'Enter a time.')
    prompt = wx.StaticText(p anel, wx.ID_ANY, 'Time to wait:')
    self.input = wx.TextCtrl(pan el, wx.ID_ANY, size=(20, 20))
    self.start = wx.Button(panel , wx.ID_ANY, 'Start')
    self.reset = wx.Button(panel , wx.ID_ANY, 'Reset')
    self.reset.Disa ble()
    self.timer = wx.Timer(self)
    >
    mainSizer.Add(s elf.progress, flag=wx.ALIGN_C ENTER | wx.ALL ^
    wx.BOTTOM,
    border=10)
    mainSizer.Add(s elf.status, flag=wx.ALIGN_C ENTER | wx.ALL,
    border=10)
    mainSizer.Add(i nputSizer, flag=wx.ALIGN_C ENTER | wx.BOTTOM,
    border=10)
    inputSizer.Add( prompt, flag=wx.ALIGN_C ENTER)
    inputSizer.Add( self.input, flag=wx.ALIGN_C ENTER | wx.LEFT |
    wx.RIGHT,
    border=5)
    inputSizer.Add( self.start, flag=wx.ALIGN_C ENTER)
    inputSizer.Add( self.reset, flag=wx.ALIGN_C ENTER)
    >
    self.Bind(wx.EV T_TEXT_ENTER, self.OnStart, self.input)
    self.Bind(wx.EV T_BUTTON, self.OnStart, self.start)
    self.Bind(wx.EV T_TIMER, self.OnTimer, self.timer)
    self.Bind(wx.EV T_BUTTON, self.OnReset, self.reset)
    >
    panel.SetSizer( mainSizer)
    mainSizer.Fit(s elf)
    >
    def OnStart(self, event):
    try:
    self.time = int(self.input. GetValue())
    self.minutes_pa ssed = 1
    self.minutes_re maining = self.time - 1
    self.start.Disa ble()
    self.input.Disa ble()
    self.reset.Enab le()
    self.status.Set Label('%s minute(s) remaining.' % self.time)
    self.timer.Star t(1000)
    except ValueError:
    wx.MessageBox(' Enter a valid time.', 'Invalid time entered',
    wx.OK | wx.ICON_ERROR)
    self.input.Clea r()
    >
    def OnReset(self, event):
    if self.timer.IsRu nning():
    self.timer.Stop ()
    self.input.Clea r()
    self.input.Enab le()
    self.start.Enab le()
    self.reset.Disa ble()
    self.status.Set Label('Enter a new time.')
    self.progress.S etValue(0)
    self.minutes_pa ssed = 1
    >
    def OnTimer(self, event):
    if self.minutes_re maining != 0:
    self.progress.S etValue(self.mi nutes_passed * (100.0 /
    self.time))
    self.status.Set Label('%s minute(s) remaining.' %
    self.minutes_re maining)
    self.minutes_pa ssed += 1
    self.minutes_re maining -= 1
    else:
    self.timer.Stop ()
    self.progress.S etValue(self.mi nutes_passed * (100.0 /
    self.time))
    self.status.Set Label('%s minute(s) have elapsed.' % self.time)
    wx.Sound.Play(w x.Sound(r'C:\Wi ndows\Media\not ify.wav'))
    >
    >
    class MyApp(wx.App):
    >
    def OnInit(self):
    frame = MyTimer()
    self.SetTopWind ow(frame)
    frame.Show()
    return True
    >
    >
    if __name__ == '__main__':
    app = MyApp(False)
    app.MainLoop()

    Comment

    • John McMonagle

      #3
      Re: how best to check a value? (if/else or try/except?)

      On Thu, 2006-07-27 at 20:44 +0000, John Salerno wrote:
      My code is below. The main focus would be on the OnStart method. I want
      to make sure that a positive integer is entered in the input box. At
      first I tried an if/else clause, then switched to try/except. Neither is
      perfect yet, but I was wondering which I should try for in the first
      place. I figure I need to check for an emptry string, non-numeric
      strings (maybe these are the same check), 0 and negative numbers (which
      might also fall into the category of 'anything but a number' because of
      the negative sign).
      >
      Have a look at using a wx.Validator in your wx.TextCtrl.


      Syntax for wx.TextCtrl:

      wx.TextCtrl(par ent, id, value="", pos=wx.DefaultP osition,
      size=wx.Default Size, style=0, validator=wx.De faultValidator,
      name=wx.TextCtr lNameStr)

      This will enable you to automagically check the TextCtrl if it's empty,
      has wrong data type, does not meet a prescribed condition (eg: no
      negative numbers) and do something if it does not pass validation (eg:
      colour the background of the TextCtrl red, initiate a system beep, etc).

      Regards,

      John



      --
      This message has been scanned for viruses and
      dangerous content by MailScanner, and is
      believed to be clean.

      Comment

      • John Salerno

        #4
        Re: how best to check a value? (if/else or try/except?)

        John McMonagle wrote:
        Have a look at using a wx.Validator in your wx.TextCtrl.
        Ah, good thinking! I wasn't even considering another option like that,
        which probably makes more sense anyway!

        Comment

        • John Salerno

          #5
          Re: how best to check a value? (if/else or try/except?)

          Nick Vatamaniuc wrote:
          John,
          >
          The way I do it is, is I ask myself 'is there a more common (basic)
          base between the code paths or do they both have about a 50/50 chance
          on average?' or 'will one code path be taken during an error and the
          other one during the normal processing?'. If there is a clear single
          common/usual/basic case or I try to detect an error I use 'try/except',
          if it could go either way on average I use 'if'.
          Thanks, that's something good to think about. This issue came up once
          before and I remember someone saying something like "you're using a
          try/except statement, but i wouldn't really consider that situation
          'exceptional'", so thinking of it in your terms might help a lot.

          Comment

          Working...