[Tutor] Is there a "better" way to do this?

Alan Gauld alan.gauld at freenet.co.uk
Thu Dec 23 00:16:20 CET 2004


> procedural programming to object oriented.   Is this a good approach
for
> such a check?  It seems to me this is more work then needed.

Its a valid approach but whether its the best approach depends on
what else you intend to do. For example will there be multiple
types of greeting? or several instances of greeting? Or will
you use this same greeting in many programs? I suspect not
because the menu is embedded, but if you could parameterise
the init method, then you could pass the menu string in along
with high and low values and then you might have a reusable
text menu class?

class Menu:
   def __init__(self, menu, prompt, high, low=1):
      # lots of self assignments here

   def opening(self):
      print self.menu
      self.choice = raw_input(self.prompt)

   def validateChoice(self):
      # this method overriden in subbclasses if need be...
      return self.low < int(self.choice) < self.high

But thats just soome personal musings. Comments on
your code follow:

> class greating:

Its conventional to make class names start with a capital letter,
instances with a lower. Python doesn't case but its easier on
the reader...

>     def __init__(self):
>         self.OK = False
>         self.lowValue = 1
>         self.highValue = 6
>
>     def opening(self):
>         print """
>         Please choose from the following options.
>         1) - Normal Unit test with static data.
>         2) - Normal Unit test with missing data.
>         3) - Integration test with current DTG.
>         4) - Integration test with missing data.
>         5) - Clean directory
>         6) - Exit
>         """
>         self.choice = raw_input("Choice(1-6) ")

See comments above about making menu a configurable item.

>     def check(self):
>         try:
>             self.choice = int(self.choice)
>         except ValueError:
>             print "Please enter a number from ",self.lowValue," to
> ",self.highValue
>             pass

pass does nothing. It is only used to indicate that something
should go here sometime. But since you are doing something,
you don't need pass here. Maybe you meant return?

>         if self.choice > self.highValue or self.choice <
self.lowValue:
>             print "You have entered an invalid entry. Please try
again"

python allows a shortened version of this like

if x < value < y:   # checks that value is between x and y.

>         else:
>             self.OK = True

As well as printing the errors you probably want to set self.OK
to False in the other cases. Just because you did it in the init()
is not enough, if you call opening() more than once and the user
types valid input first time but not second time OK will be set
to True when it should be False.

The way you use it in the test case is OK but in other scenarios...

> a = greating()
>
> while a.OK != True:
>     a.opening()
>     a.check()

Try this test loop instead:

while a.choice not in '123456':   # ie an invalid value
   a.opening()
   a.check()

OOPS! IT won;t work because a.choice doesn't exist until
after calling a.opening().

This is one reason you are better to initialise all
instance variables in the init method IMHO.

HTH

Alan G
Author of the Learn to Program web tutor
http://www.freenetpages.co.uk/hp/alan.gauld



More information about the Tutor mailing list