2011-12-30 18 views
8

Tôi có một cơ sở dữ liệu đã được tạo và được sử dụng bởi một công ty kiến ​​trúc. Tất cả các phép đo được lưu trữ ở định dạng như sau: 15-3/4 "12 '6-3/4".Làm thế nào để chuyển đổi một phép đo được hiển thị trong một định dạng kiến ​​trúc thành một điểm nổi?

Có cách nào để chuyển đổi các loại phép đo này thành điểm nổi trong Python không? Hoặc là có một thư viện ở đó cung cấp chức năng này?

Tương tự, bạn sẽ chuyển đổi từ điểm động sang định dạng trên như thế nào?

+1

Tất nhiên có một cách. Nhưng đó là những giá trị với các đơn vị, do đó, chuyển đổi trực tiếp sang điểm động cũng sẽ yêu cầu xác định đơn vị ngụ ý mà nó sẽ được. bạn cũng có thể mất độ chính xác. – Keith

+1

Ngoài ra, Django chỉ là một khuôn khổ web, do đó, nó thực sự không có bất cứ điều gì để làm với điều này. Bây giờ bạn có thể tạo một đối tượng, khi được xâu chuỗi tạo ra định dạng đó. Sau đó, bạn chỉ có thể sử dụng bất kỳ mẫu nào. – Keith

+0

Cảm ơn Keith ... Tôi đã xóa phần Django. – Clayton

Trả lời

3

Tùy thuộc vào cách thường xuyên các mẫu đang có, bạn có thể sử dụng str.partition để làm phân tích cú pháp:

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 
+0

Điều này sẽ không hoạt động nếu số ở dạng phân số inch như '3/4 '' Có thể bạn sẽ chỉ muốn gắn bó với rpartition – Abhijit

+0

@Abhijit Đã chỉnh sửa để sử dụng rpartition cho sự tách biệt int/frac.Cảm ơn –

+0

Điều này làm việc tuyệt vời ... Cảm ơn Raymond! – Clayton

0

kiến ​​trúc để dấu chấm động:

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) 

Nó thực sự tàn bạo, nhưng tôi đã không làm việc với Python trong một thời gian; Tôi không nghi ngờ có một cách sạch hơn nhiều để làm điều này, nhưng nó không xử lý thiếu chân độc đáo. Nó hiện luôn luôn mong đợi inch, mặc dù, do đó, các phép đo như 12' sẽ phải là 12' 0" để được phân tích cú pháp chính xác.

1

Hãy xem xét mã tự nhận xét sau. Tôi cố gắng để giữ trong đơn giản

>>> 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)  

Acid Test

>>> 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 

Chuyển đổi từ phao để Kiến trúc sẽ dễ dàng như bạn không phải đi nỗi đau để phân tích cú pháp

>>> 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) 

Acid Kiểm tra

>>> 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" 
>>> 

Lưu ý *** Điều quan trọng của nó là giữ cho biểu diễn dạng float trong mẫu số thấp nhất (inch) hoặc mẫu số đại diện cao nhất (feet). Tôi đã chọn mức cao nhất trong trường hợp này. Nếu bạn wan't để hạ nó, bạn có thể nhân nó bằng 12.


Cập nhật để phục vụ làm tròn Request (Không chắc chắn nếu đây là thanh lịch nhưng hiện các công việc)

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) 
+0

Mỗi bình luận của @ Keith, tôi sẽ thêm đơn vị này và biến phao thành một cấu trúc hoặc lớp với một phao và một đơn vị. –

+0

@ JesseSmith, Bạn chỉ cần chuyển đổi nó thành chuỗi và thêm đơn vị. Đối với ex 'str (Arch2Float ('12 \ '6-3/4"')) + 'ft'' – Abhijit

+0

@ Abhijit, giải pháp này hoạt động là tốt. Tôi đã kết hợp @RaymondHettinger với hàm 'Float2Arch' của bạn. đề nghị làm tròn giá trị trả về để một đầu vào như thế này ** 18,33 ** trả về ** 18 '4 "**? – Clayton

Các vấn đề liên quan