如何将建筑格式的测量值转换为浮点数?
我有一个数据库,是一个建筑公司创建并使用的。所有的测量数据都以这样的格式存储:15-3/4" 和 12' 6-3/4"。
有没有办法在Python中把这些测量值转换成浮点数?或者有没有什么库可以提供这样的功能?
同样的,怎样才能把浮点数转换成上面的格式呢?
3 个回答
0
从建筑单位转换到浮点数:
import re
regex = re.compile('(\d+\' )*(\d+)-(\d+)\/(\d+)"')
regex.sub(lambda m: str((int((m.group(1) or '0').split("'")[0]) * 12)
+ int(m.group(2)))
+ ('%.2f' % (int(m.group(3)) / float(m.group(4))))[1:], measurement)
这真是太糟糕了,不过我有一段时间没用Python了;我相信肯定有更简单的方法来做到这一点,但这个方法确实很好地处理了没有英尺的情况。不过,它总是期待输入为英寸,所以像12'
这样的测量值必须写成12' 0"
才能正确解析。
1
考虑一下下面这段自我注释的代码。我尽量让它简单易懂。
>>> from fractions import Fraction
>>> def Arch2Float(num):
#First Partition from Right so that the Feet and Unit always
#Remains aligned even if one of them is absent
ft,x,inch=num.rpartition("\'")
#Convert the inch to a real and frac part after stripping the
#inch (") identifier. Note it is assumed that the real and frac
#parts are delimited by '-'
real,x,frac=inch.strip("\"").rpartition("-")
#Now Convert every thing in terms of feet which can then be converted
#to float. Note to trap Error's like missing or invalid items, its better
#to convert each items seperately
result=0
try:
result = int(ft.strip("\'"))
except ValueError:
None
#Convert the real inch part as a fraction of feet
try:
result += Fraction(int(real),12)
except ValueError:
None
#Now finally convert the Fractional part using the fractions module and convert to feet
try:
result+=Fraction(frac)/12
except ValueError:
None
return float(result)
酸性测试
>>> print Arch2Float('15-3/4"') # 15-3/4" (without ft)
1.3125
>>> print Arch2Float('12\' 6-3/4"') #12' 6-3/4"
12.5625
>>> print Arch2Float('12\'6-3/4"') #12'6-3/4" (without space)
12.5625
>>> print Arch2Float('3/4"') #3/4" (just the inch)
0.0625
>>> print Arch2Float('15\'') #15' (just ft)
15.0
>>> print Arch2Float('15') #15 (without any ascent considered as inch)
1.25
把浮点数转换成架构会很简单,因为你不需要费心去解析。
>>> def Float2Arch(num):
num=Fraction(num)
ft,inch=Fraction(num.numerator/num.denominator),Fraction(num.numerator%num.denominator)/num.denominator*12
real,frac=inch.numerator/inch.denominator,Fraction(inch.numerator%inch.denominator,inch.denominator)
return '{0}\' {1}-{2}"'.format(ft,real,frac)
酸性测试
>>> print Float2Arch(Arch2Float('12\' 6-3/4"'))
12' 6-3/4"
>>> print Float2Arch(Arch2Float('15-3/4"'))
1' 3-3/4"
>>> print Float2Arch(Arch2Float('12\'6-3/4"'))
12' 6-3/4"
>>> print Float2Arch(Arch2Float('3/4"'))
0' 0-3/4"
>>> print Float2Arch(Arch2Float('15\''))
15' 0-0"
>>> print Float2Arch(Arch2Float('15'))
1' 3-0"
>>>
注意*** 保持浮点数的表示很重要,要么用最小的单位(英寸),要么用最大的单位(英尺)。在这个例子中,我选择了最大的单位,英尺。如果你想用更小的单位,可以把它乘以12。
更新以满足四舍五入的请求 (不确定这是否优雅,但能完成任务)
def Float2Arch(num):
num=Fraction(num)
ft,inch=Fraction(num.numerator/num.denominator),Fraction(num.numerator%num.denominator)/num.denominator*12
real,frac=inch.numerator/inch.denominator,Fraction(inch.numerator%inch.denominator,inch.denominator)
for i in xrange(1,17):
if Fraction(frac) < Fraction(1.0/16*i): break
frac=Fraction(1.0/16*i)
if frac>= 1:
real+=1
frac=0
return '{0}\' {1}-{2}"'.format(ft,real,frac)
5
根据模式的规律性,你可以使用 str.partition 来进行解析:
def architectural_to_float(text):
''' Convert architectural measurements to inches.
>>> for text in """15-3/4",12' 6-3/4",3/4",3/4',15',15",15.5'""".split(','):
... print text.ljust(10), '-->', architectural_to_float(text)
...
15-3/4" --> 15.75
12' 6-3/4" --> 150.75
3/4" --> 0.75
3/4' --> 9.0
15' --> 180.0
15" --> 15.0
15.5' --> 186.0
'''
# See http://stackoverflow.com/questions/8675714
text = text.replace('"', '').replace(' ', '')
feet, sep, inches = text.rpartition("'")
floatfeet, sep, fracfeet = feet.rpartition('-')
feetnum, sep, feetdenom = fracfeet.partition('/')
feet = float(floatfeet or 0) + float(feetnum or 0) / float(feetdenom or 1)
floatinches, sep, fracinches = inches.rpartition('-')
inchesnum, sep, inchesdenom = fracinches.partition('/')
inches = float(floatinches or 0) + float(inchesnum or 0) / float(inchesdenom or 1)
return feet * 12.0 + inches