[Tutor] Function problem

Bob Gailer bgailer at alum.rpi.edu
Sat Nov 6 04:35:17 CET 2004


At 11:35 AM 11/5/2004, Eri Mendz wrote:
>Hello All,
>
>First off, thanks again to all who answered my loop problem Re: 
>'IndexError....'. I got it understood now.
>
>The problem of my script below is in the proceed function: if Y is
>selected, instead of staying in the option menu, the program just shows 
>the option menu then exits. ditto in the 'really quit program' prompt: i 
>expect to go to main menu if i select N but again program exits. can you 
>guys point me to my error? this is just a simple script but it took me 
>some time to figure out on my own; its a good learning exercise nevertheless.
>
>what to do to improve the program further, e.g., make it simple but
>efficient? i love to hear your good advise.
>
>#!/usr/bin/env python
># filename: tempConvert.py
># description: temperature conversion program
># Author: Eri Mendz
># Fri Nov  5 13:53:16 AST 2004
>
>import sys
>
>def print_options():
>     print '''
>     THIS IS A TEMPERATURE CONVERSION PROGRAM.
>     Options:
>     [C] - convert to Celsius
>     [F] - convert to Fahrenheit
>     [P] - print options
>     [Q] - quit
>     '''
>print_options()
>
>def f2c(ctemp):
>     return (9/5.0)*ctemp + 32
>
>def c2f(ftemp):
>     return (ftemp - 32) * 5/9.0
>
>def proceed():
>     proceed = raw_input("do another conversion? [Y|N]: ")
>     if proceed == 'y' or proceed =='Y':
>         print_options()
>     else:
>         confirmQuit()
>
>def confirmQuit():
>     ask = raw_input("Really quit program? [Y|N]: ")
>     if ask == 'y' or ask == 'Y' or ask == 'ye' or ask == 'yes':
>         sys.exit("bye")
>     else:
>         print_options()
>
># begin
>while 1:
>     choice = raw_input("select options: ")
>     if choice == 'c' or choice == 'C':
>         try:
>             getftemp = int(raw_input("enter fahrenheit temperature: "))
>             print "temp in C is: ", c2f(getftemp)
>             proceed()
>         except ValueError:
>             print "error: not a valid input!"
>         break
>     elif choice == 'f' or choice == 'F':
>         try:
>             getctemp = int(raw_input("enter centigrade temperature: "))
>             print "temp in F is: ", f2c(getctemp)
>             proceed()
>         except ValueError:
>             print "error: not a valid input!"
>         break
>     elif choice =='p' or choice == 'P':
>         print_options()
>     elif choice =='q' or choice == 'Q':
>         confirmQuit()
>     else:
>         print "invalid option"
>
>print "bye"

Since I enjoy OOP I thought I'd see what your program might look like using 
classes. Here's a cut at it:

import sys
class Menu:
   input_prompt = ''
   def prompt(self):
     print '[%s] - %s' % (self.__class__.__name__, self.menu_prompt)
   def act(self):
     if self.input_prompt:
       try:
         inp = raw_input(self.input_prompt)
         self.act_on_input(inp)
       except KeyboardInterrupt:
         pass

class Numeric(Menu):
   def act_on_input(self, inp):
     try:
       inp = int(inp)
       print self.output_prompt % self.convert(inp)
     except ValueError:
       print 'Input must be numeric.'

class Character(Menu):
   pass

class C(Numeric):
   menu_prompt = 'convert to Celsius'
   input_prompt = 'enter fahrenheit temperature: '
   output_prompt = 'temp in C is %s'
   def convert(self, ctemp):
     return (9/5.0)*ctemp + 32

class F(Numeric):
   menu_prompt = 'convert to Fahrenheit'
   input_prompt = 'enter centigrade temperature: '
   output_prompt = 'temp in F is %s'
   def convert(self, ftemp):
     return (ftemp - 32) * 5/9.0

class P(Character):
   menu_prompt = 'print options'
   def act_on_input(self, inp):
     print_options()

class Q(Character):
   menu_prompt = 'quit'
   input_prompt = 'Really quit program? [Y|N]: '
   def act_on_input(self, inp):
     if 'YES'.startswith(inp.upper()):
       sys.exit("bye")
     else:
       print_options()

menu = [C(), F(), P(), Q()]

def print_options():
     print '''
     THIS IS A TEMPERATURE CONVERSION PROGRAM.
     Options:    '''
     for item in menu:
       item.prompt()

print_options()
while 1:
   choice = raw_input("select option: ").upper()
   for item in menu:
     if item.__class__.__name__ == choice:
       item.act()
       break
   else:
     print "invalid option"
print "bye"

What I like about this is that all the information for a choice is packaged 
in the class definition, and there is minimal redundant code.

Bob Gailer
bgailer at alum.rpi.edu
303 442 2625 home
720 938 2625 cell 



More information about the Tutor mailing list