[Tutor] Please critique my Fraq.py (original) (raw)

Dick Moores rdm at rcblue.com
Mon Jul 19 17:19:38 CEST 2004


Tutors,

This may seem like a silly script to write. But it's just an exercise I set for myself. And it does compute that amazingly close approximation to PI, 355/113:

============================ Maximum denominator: 200 For pi, 355/113 is closest fraction up to maximum denominator of 200 Error is 8.4913678767406e-006 percent

You'll notice that I've had to use this if statement twice in order to enable user to close the program: if choice in ["x", "q"]: break

And also twice: if maximumDenom in ["x", "q"]: break

And this: if minimumError in ["x", "q"]: break

Is there a better way to do this?

How about my variable and constant names?

And all the while loops are "while True:". This OK?

Should the script be a lot more modular?

Thanks, tutors.

Dick Moores

=============================

Frac.py

print """ Enter a decimal number and Frac will calculate a fraction for use as an approximation to the number. You can choose to set a maximum denominator for the fraction, or to set a minimum error for the fraction to satisfy.

 Enter e or E for the mathematical constant 2.7182818284590451,
 and pi or PI for the mathematical constant 3.1415926535897931.

 You may exit the program at any prompt by entering x or q.
 """

import random, time

defaultMinimumError = 0.01 defaultMaximumDenom = 100

def exit(): print "Thank you for using Frac. Frac will now close" time.sleep(1.1) # to provide the user with enough time to read the message

while True: print "If no decimal entered, a random decimal "
"between 0.1 and 1.0 will be chosen." # for exiting via ^C or ^D try: string = raw_input("Decimal: ") except (TypeError, EOFError): break if string in ["x", "q"]: break if string in ["pi", "PI"]: decimal = 3.1415926535897931 elif string in ["E", "e"]: decimal = 2.7182818284590451 elif string == "": while True: decimal = random.random() # permit only 0.1 <= decimal < 1.0 if decimal >= .1: break string = str(decimal) print decimal, "was picked at random for you.\n" else: try: decimal = float(string) except: print "That's not a decimal number! Try again." continue

 while True:
     choice = raw_input("Minimum error (e) or maximum denominator (d)? ")
     if choice in ["x", "q"]:
         break
     elif not (choice in ["e", "d"]):
         print "Enter d or e"
         continue
     else:
         break
 if choice in ["x", "q"]:
         break
 if choice == "d":
     while True:
         print "If no maximum denominator entered, the default is 100"
         maximumDenom = raw_input("Maximum denominator: ")
         if maximumDenom in ["x", "q"]:
             break
         elif maximumDenom == "":
             maximumDenom = defaultMaximumDenom
             print "Maximum denominator is %g by default" % maximumDenom
         else:
             try:
                 maximumDenom = int(maximumDenom)
             except:
                 print "That's not an integer! Try again."
                 continue
         break
     if maximumDenom in ["x", "q"]:
         break
     leastError = 1
     for denom in xrange(1, maximumDenom + 1):
         num = round(decimal * denom)
         error = abs((num / denom - decimal) / decimal)
         if error < leastError:
             leastError = error
             bestDenom = denom
             bestNum = num
         if leastError == 0: # should I have this if statement?
             break

     print "For %s, %d/%d is closest fraction" % (string, 

int(bestNum), bestDenom) print " up to maximum denominator of %d" % maximumDenom print "Error is %.13e percent" % (leastError * 100) print "\n"

 elif choice == "e":
     while True:
         print "If no minimum error entered, the default is %g 

percent" % defaultMinimumError minimumError = raw_input("Minimum error in percent: ") if minimumError in ["x", "q"]: break elif minimumError == "": minimumError = defaultMinimumError print "Minimum error is %g by default" % defaultMinimumError else: try: minimumError = float(minimumError) except: print "That's not a decimal number!" continue break if minimumError in ["x", "q"]: break

     denom = 0
     while True:
         denom += 1
         num = round(decimal * denom)
         error = abs((num / denom - decimal) / decimal) * 100
         if error <= minimumError:
             break
     print "%d/%d is fraction with smallest denominator with error <= 

%.13g percent" % (num, denom, minimumError) print "Actual error is %.13e percent" % error print "\n" exit() ==========End of Frac.py===============



More information about the Tutor mailing list