[Tutor] Please take another look at my frac.py
Dick Moores
rdm at rcblue.com
Mon Aug 2 03:04:02 CEST 2004
Danny Yoo will be disappointed, I'm sure. His kind post of Fri, 23 Jul
2004 15:26:36 -0700 (PDT) tried to show me how to shorten the program by
consolidating the functions that get user input, but I was unable to
implement his suggestions. But I have made the program a lot more modular.
If there's some more work needed, please tell me.
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 can exit the program at any prompt by entering 0 (zero).
"""
import random, time
def exit():
print "Thank you for using Frac. Frac will now close."
time.sleep(1.1)
def getDecimalFromUser():
while True:
print "If nothing entered, a random decimal " \
"between 0.1 and 1.0 will be chosen."
string = raw_input("Decimal: ")
if string in ["pi", "PI"]: decimal = 3.1415926535897931
elif string in ["E", "e"]: decimal = 2.7182818284590451
elif string == "":
decimal = getRandomDecimal()
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
break
return decimal
def getRandomDecimal():
decimal = random.uniform(0.1, 1.0)
return decimal
def getChoiceFromUser():
while True:
choice = raw_input("Minimum error (e) or maximum denominator (d)? ")
if not (choice in ['d', 'D', 'e', 'E', '0']):
print "Enter d or e"
continue
break
return choice
def getMaxDenomFromUser():
while True:
print "If no maximum denominator entered, the default is 100"
maxDenom = raw_input("Maximum denominator: ")
if maxDenom == "":
maxDenom = 100
print "Maximum denominator is %g by default" % maxDenom
else:
try:
maxDenom = int(maxDenom)
except:
print "That's not an integer! Try again."
continue
break
return maxDenom
def getMinimumErrorFromUser():
while True:
print "If no minimum error entered, the default is %g percent" % .01
minimumError = raw_input("Minimum error in percent: ")
if minimumError == "":
minimumError = .01
print "Minimum error is %g by default" % .01
else:
try:
minimumError = float(minimumError)
except:
print "That's not a decimal number!"
continue
break
return minimumError
def bestFracForMaxDenom(decimal, maxDenom):
leastError = 1
for denom in xrange(1, maxDenom + 1):
num = round(decimal * denom)
error = abs((num / denom - decimal) / decimal)
if error < leastError:
leastError = error
bestDenom = denom
bestNum = num
# leastError is a float; should I have this if statement?
if leastError == 0:
break
return int(bestNum), bestDenom, leastError
def bestFracForMinimumError(decimal, minimumError):
denom = 0
while True:
denom += 1
num = round(decimal * denom)
error = abs((num / denom - decimal) / decimal) * 100
if error <= minimumError:
break
return int(num), denom, error
while True:
decimal = getDecimalFromUser()
if decimal == 0:
break
choice = getChoiceFromUser()
if choice == "0":
break
if choice == "d":
maxDenom = getMaxDenomFromUser()
if maxDenom == 0:
break
bestNum, bestDenom, leastError = bestFracForMaxDenom(decimal,
maxDenom)
print "\n For a decimal of %s, %d/%d," % (str(decimal), bestNum,
bestDenom)
print "which is equal to %s, is the closest fraction" %
(str(float(bestNum)/bestDenom))
print "up to a maximum denominator of %d" % maxDenom
print "Error is %.13e percent" % (leastError * 100)
print "====================================="
print
else:
minimumError = getMinimumErrorFromUser()
if minimumError == 0:
break
num, denom, error = bestFracForMinimumError(decimal, minimumError)
print "\n For a decimal of %s, %d/%d," % (str(decimal), num, denom)
print "which is equal to %s, is the closest fraction" %
(str(float(num)/denom))
print "with smallest denominator and error <= %.13g percent" %
minimumError
print "Actual error is %.13e percent" % error
print "============================================"
print
exit()
===========end fraq.py=========================
More information about the Tutor
mailing list