[Tutor] Please critique my Fraq.py
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