TheLinuxDuck
12-07-2001, 04:32 PM
Here is my python implementation of kmj's suggestion of a 'material needed' script to determine how much wood is needed to frame a painting or portrait of a specific size.
Me, being the perfectionist and the lover of coding pain, I took it to the next level. (^=
The code also includes a feet/inches parsing algorithm that will allow the user to enter their measures in feet and inches.
The user will enter their frame size as:
2f 3 3/16i x 4f
The code will allow for up to x/64 fractions. Beyond that, it is not accurate, and tends to mung the fractions.
It's lengthy and could prolly have been done in a much cleaner and neater way, but what the heck, I'm learning python...
<STRONG>#!/usr/bin/python
from string import find, splitfields, strip
</STRONG>
#
# A basic exception class to handle ..well.. exceptions
# <STRONG>
class DieException(Exception):
def __init__(self, title, message):
self.title = title
self.message = message
def __str__(self):
return self.title + ": " + `self.message`
def main():
print "Framing Material Needed\n" \
"-----------------------"
quit = 0 </STRONG> # determines when to stop program execution
<STRONG>
try:
while quit == 0:
print 'Please enter the width and height of the painting'
</STRONG>
#
# The getInput routine is fairly simple to use. Give it a prompt
# and a list of acceptable characters. Once the user inputs their
# data, the method examines their input to make sure that it conforms
# to the given acceptable character list. Leave it blank to let them
# enter anything, or put the word 'number', to only allow a number. I
# haven't fully tested the number thing, so it may not work right.
# <STRONG>
temp = getInput('(e.g. 3f 9 3/4i x 4f) ', ' 0123456789fix/')
if temp != '': </STRONG> # returns null on blank input<STRONG>
(paintingWidth, paintingHeight) = convertDimension(temp)
print 'Size given:', convertInches(paintingWidth), 'x', \
convertInches(paintingHeight)
if paintingWidth <= 0.0 or paintingHeight <= 0.0:
print 'That\'s easy! You don\'t need any material!'
else:
print 'Please enter the frame width'
temp = getInput('(e.g. 2 1/4i) ', ' 0123456789fi/')
if temp != '':
frameWidth = convertDimension(temp)[0]
print 'Width given:', convertInches(frameWidth)
if frameWidth <= 0.0:
print 'Whoa, killer! No frame width means no frame!'
else:
print 'Please enter the amount of frame overlap (over painting)'
temp = getInput('(e.g. 1/4i) ', ' 0123456789fi/')
if temp != '':
overlap = convertDimension(temp)[0]
print 'Size given: ', convertInches(paintingWidth), 'x', \
convertInches(paintingHeight)
print 'Width given:', convertInches(frameWidth)
print 'Overlap: ', convertInches(overlap)
if frameWidth <= overlap:
print 'The overlap cannot be more than the actual frame', \
'width, bonehead...'
else:
frameMaterial = 8.0 * (frameWidth-overlap)
frameMaterial += 2 * paintingWidth
frameMaterial += 2 * paintingHeight
print 'To complete this project, you\'ll need', \
convertInches(frameMaterial), 'of frame material'
temp = getInput('Another?(y/N)','yn')
if temp == '' or temp.upper() == 'N':
quit = 1
except DieException, e:
print e
def getInput(message = None, valid = None):
getIquit = 0
while getIquit == 0:
try:
x = raw_input(message)
if x == '?':
print 'Valid input is: ' + valid
else:
if valid == 'number':
retVal = int(x)
else:
if valid is None:
retVal = x
getIquit = 1
else:
findResult = 0
for i in range(len(x)):
found = find(valid.lower(),x.lower()[i])
if found != -1:
findResult += 1
else:
findResult -= 1
if findResult < len(x):
print 'That is not valid input'
else:
retVal = x
getIquit = 1
except ValueError:
print 'That is not a valid number'
except KeyboardInterrupt:
print 'To quit, just press enter'
return retVal
</STRONG>
#
# This function sucks. It does a good job, with what I've tested in it,
# but it's poorly coded. (^=
#<STRONG>
def convertDimension(dimension):
build = ''
wFeet = 0
wInches = 0.0
hFeet = 0
hInches = 0.0
step = 0
for i in range(len(dimension)):
if dimension[i] == 'f':
build = strip(build)
if step == 0:
wFeet = int(build)
else:
hFeet = int(build)
build = ''
elif dimension[i] == 'x':
if step == 0:
step = 1
else:
build = dimension
break
elif dimension[i] == 'i':
build = strip(build)
spaceLoc = find(build, ' ')
if spaceLoc != -1:
if step == 0:
wInches = float(build[0:spaceLoc])
else:
hInches = float(build[0:spaceLoc])
build = build[spaceLoc+1:]
if find(build, '/') == -1:
break;
(one, two) = splitfields(build, '/')
if step == 0:
wInches += float(one)/float(two)
else:
hInches += float(one)/float(two)
else:
if find(build, '/') == -1:
if step == 0:
wInches = float(build)
else:
hInches = float(build)
else:
(one, two) = splitfields(build, '/')
if step == 0:
wInches += float(one)/float(two)
else:
hInches += float(one)/float(two)
build = ''
else:
if dimension[i] == ' ':
if build != '':
build += ' '
else:
build += dimension[i]
if build != '':
s = 'convertDimension received an unknown format: ' + build
raise DieException('UnknownFormatError', s)
wInches += (wFeet*12.0)
hInches += (hFeet*12.0)
return wInches, hInches
def convertInches(fM):
feet = 0
inches = 0
retVal = ''
if fM > 12:
feet = int(fM/12)
fM -= feet * 12
inches = int(fM)
fM -= inches
if feet > 0:
retVal += str(feet) + ' feet '
if inches > 0:
retVal += str(inches) + ' '
 
if fM > 0:
retVal += fraction(float(fM)) + ' '
if inches > 0 or fM > 0:
retVal += 'inches'
return retVal
def fraction(floater):
upper = int((floater*1000000.0)+.5)
lower = 1000000
quit = 0
while quit == 0:
quit = 1
i = 2
while i <= int(upper):
if upper / float(i) == int(upper / float(i)) and \
lower / float(i) == int(lower / float(i)):
upper /= i
lower /= i
quit = 0
i = int(upper)
i += 1
return str(upper) + '/' + str(lower)
if __name__ == '__main__':
main()</STRONG>
Me, being the perfectionist and the lover of coding pain, I took it to the next level. (^=
The code also includes a feet/inches parsing algorithm that will allow the user to enter their measures in feet and inches.
The user will enter their frame size as:
2f 3 3/16i x 4f
The code will allow for up to x/64 fractions. Beyond that, it is not accurate, and tends to mung the fractions.
It's lengthy and could prolly have been done in a much cleaner and neater way, but what the heck, I'm learning python...
<STRONG>#!/usr/bin/python
from string import find, splitfields, strip
</STRONG>
#
# A basic exception class to handle ..well.. exceptions
# <STRONG>
class DieException(Exception):
def __init__(self, title, message):
self.title = title
self.message = message
def __str__(self):
return self.title + ": " + `self.message`
def main():
print "Framing Material Needed\n" \
"-----------------------"
quit = 0 </STRONG> # determines when to stop program execution
<STRONG>
try:
while quit == 0:
print 'Please enter the width and height of the painting'
</STRONG>
#
# The getInput routine is fairly simple to use. Give it a prompt
# and a list of acceptable characters. Once the user inputs their
# data, the method examines their input to make sure that it conforms
# to the given acceptable character list. Leave it blank to let them
# enter anything, or put the word 'number', to only allow a number. I
# haven't fully tested the number thing, so it may not work right.
# <STRONG>
temp = getInput('(e.g. 3f 9 3/4i x 4f) ', ' 0123456789fix/')
if temp != '': </STRONG> # returns null on blank input<STRONG>
(paintingWidth, paintingHeight) = convertDimension(temp)
print 'Size given:', convertInches(paintingWidth), 'x', \
convertInches(paintingHeight)
if paintingWidth <= 0.0 or paintingHeight <= 0.0:
print 'That\'s easy! You don\'t need any material!'
else:
print 'Please enter the frame width'
temp = getInput('(e.g. 2 1/4i) ', ' 0123456789fi/')
if temp != '':
frameWidth = convertDimension(temp)[0]
print 'Width given:', convertInches(frameWidth)
if frameWidth <= 0.0:
print 'Whoa, killer! No frame width means no frame!'
else:
print 'Please enter the amount of frame overlap (over painting)'
temp = getInput('(e.g. 1/4i) ', ' 0123456789fi/')
if temp != '':
overlap = convertDimension(temp)[0]
print 'Size given: ', convertInches(paintingWidth), 'x', \
convertInches(paintingHeight)
print 'Width given:', convertInches(frameWidth)
print 'Overlap: ', convertInches(overlap)
if frameWidth <= overlap:
print 'The overlap cannot be more than the actual frame', \
'width, bonehead...'
else:
frameMaterial = 8.0 * (frameWidth-overlap)
frameMaterial += 2 * paintingWidth
frameMaterial += 2 * paintingHeight
print 'To complete this project, you\'ll need', \
convertInches(frameMaterial), 'of frame material'
temp = getInput('Another?(y/N)','yn')
if temp == '' or temp.upper() == 'N':
quit = 1
except DieException, e:
print e
def getInput(message = None, valid = None):
getIquit = 0
while getIquit == 0:
try:
x = raw_input(message)
if x == '?':
print 'Valid input is: ' + valid
else:
if valid == 'number':
retVal = int(x)
else:
if valid is None:
retVal = x
getIquit = 1
else:
findResult = 0
for i in range(len(x)):
found = find(valid.lower(),x.lower()[i])
if found != -1:
findResult += 1
else:
findResult -= 1
if findResult < len(x):
print 'That is not valid input'
else:
retVal = x
getIquit = 1
except ValueError:
print 'That is not a valid number'
except KeyboardInterrupt:
print 'To quit, just press enter'
return retVal
</STRONG>
#
# This function sucks. It does a good job, with what I've tested in it,
# but it's poorly coded. (^=
#<STRONG>
def convertDimension(dimension):
build = ''
wFeet = 0
wInches = 0.0
hFeet = 0
hInches = 0.0
step = 0
for i in range(len(dimension)):
if dimension[i] == 'f':
build = strip(build)
if step == 0:
wFeet = int(build)
else:
hFeet = int(build)
build = ''
elif dimension[i] == 'x':
if step == 0:
step = 1
else:
build = dimension
break
elif dimension[i] == 'i':
build = strip(build)
spaceLoc = find(build, ' ')
if spaceLoc != -1:
if step == 0:
wInches = float(build[0:spaceLoc])
else:
hInches = float(build[0:spaceLoc])
build = build[spaceLoc+1:]
if find(build, '/') == -1:
break;
(one, two) = splitfields(build, '/')
if step == 0:
wInches += float(one)/float(two)
else:
hInches += float(one)/float(two)
else:
if find(build, '/') == -1:
if step == 0:
wInches = float(build)
else:
hInches = float(build)
else:
(one, two) = splitfields(build, '/')
if step == 0:
wInches += float(one)/float(two)
else:
hInches += float(one)/float(two)
build = ''
else:
if dimension[i] == ' ':
if build != '':
build += ' '
else:
build += dimension[i]
if build != '':
s = 'convertDimension received an unknown format: ' + build
raise DieException('UnknownFormatError', s)
wInches += (wFeet*12.0)
hInches += (hFeet*12.0)
return wInches, hInches
def convertInches(fM):
feet = 0
inches = 0
retVal = ''
if fM > 12:
feet = int(fM/12)
fM -= feet * 12
inches = int(fM)
fM -= inches
if feet > 0:
retVal += str(feet) + ' feet '
if inches > 0:
retVal += str(inches) + ' '
 
if fM > 0:
retVal += fraction(float(fM)) + ' '
if inches > 0 or fM > 0:
retVal += 'inches'
return retVal
def fraction(floater):
upper = int((floater*1000000.0)+.5)
lower = 1000000
quit = 0
while quit == 0:
quit = 1
i = 2
while i <= int(upper):
if upper / float(i) == int(upper / float(i)) and \
lower / float(i) == int(lower / float(i)):
upper /= i
lower /= i
quit = 0
i = int(upper)
i += 1
return str(upper) + '/' + str(lower)
if __name__ == '__main__':
main()</STRONG>