Convert fraction string to decimal

I am getting the size of “MEP Fabrication Hangers” and I need this as a number to then do math and whatever else to it.

However I can’t seem to be able to convert it.

I thought there was a custom node that could handle this but I couldn’t find it.

You’ll have to break down the string into its feet, inches, and fractional parts to convert it back to a number. It won’t read that format of string. Python is definitely the best way to handle this, but it’s possible with nodes and a bit of effort.

You could also check and see if that parameter also stores the value numerically. If it does, that’s way easier.

EDIT: Don’t know how I missed it the first time… Springs has Fraction.ToFeet that does this, but it doesn’t seem to handle feet with fractional inches. If you need that functionality, you can probably add it yourself with a little effort.

That is a good node to remember, but yeah mine are all inches only. I have a limited number of hanger sizes so I just went manual on it.

Interesting. Not sure why it didn’t work for you. Might be something in an updated version.
image

There’s probably extra syntax to handle in imperial, but for basic whole/fraction conversion this could work:

myNumbers = ["1 1/4\"", "1 1/2\"", "2 1/2\"", "3 1/2\"", "1/2\"", "3/4\"", "1\"", "10\""]

def fractionToNumber(string):
    # Split at the space
    string = string.replace("\"", "")
    splitStrings = string.split(" ")
    # If we have one string...
    if len(splitStrings) == 1:
        # If it is a fraction
        if "/" in string:
            product, quotient = string.split("/")
            return int(product)/int(quotient)
        # Else it is a number
        else:
            return int(string)
    # Otherwise we have two strings...
    else:
        # Assign the parts
        whole, fraction = splitStrings
        # Handle the fraction
        product, quotient = fraction.split("/")
        # Return the total
        return int(whole) + int(product)/int(quotient)

for n in myNumbers:
    print(fractionToNumber(n))
1 Like

Oh, so thats how you write the inch symbol in code, with a back slash symbol! Definitely writing this down.

Here’s the python code that converts Feet & Fractional Inches to Decimal Feet.

import re

def feet_inches_to_decimal(feet, inches):
    """
    Converts feet and fractional inches to a decimal value.
    
    Args:
        feet (int): The number of feet.
        inches (float): The inches, including fractional inches.
    
    Returns:
        float: The decimal value of the feet and inches.
    """
    decimal_feet = feet + (inches / 12)
    return decimal_feet

def convert_feet_inches_to_decimal(input_str):
    """
    Converts a string representation of feet and inches to a decimal value.
    
    Args:
        input_str (str): A string in the format 'Feet\'-Inches"' (e.g. '3\'-6 1/2"').
    
    Returns:
        float: The decimal value of the feet and inches.
    """
    # Split the input string into feet and inches
    parts = input_str.split('-')
    feet = int(parts[0][:-1])
    inches_str = parts[1][:-1]
    
    # Parse the fractional inches
    inches_pattern = r'(\d+) (\d+)/(\d+)'
    match = re.match(inches_pattern, inches_str)
    if match:
        whole_inches = int(match.group(1))
        numerator = int(match.group(2))
        denominator = int(match.group(3))
        fractional_inches = whole_inches + (numerator / denominator)
    else:
        fractional_inches = float(inches_str)
    
    # Convert to decimal feet
    decimal_feet = feet_inches_to_decimal(feet, fractional_inches)
    
    return decimal_feet

# Input: Connect a string to IN[0] in the format 'Feet\'-Inches"' (e.g. '3\'-6 1/2"')
input_str = IN[0]

# Process the input and calculate the result
decimal_feet = convert_feet_inches_to_decimal(input_str)

# Output: The result will be available at OUT
OUT = decimal_feet

Alternative is to use the internal utilities for parsing
Edit Requires IronPython to work

import clr

clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *

clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager


def ffi_to_unit(ffi_str, to_unit=UnitTypeId.Feet):
    parse = UnitFormatUtils.TryParse(units, SpecTypeId.Length, ffi_str)
    if parse[0]:
        return UnitUtils.Convert(parse[1], UnitTypeId.FeetFractionalInches, to_unit)


doc = DocumentManager.Instance.CurrentDBDocument
units = doc.GetUnits()

MM = UnitTypeId.Millimeters

OUT = ffi_to_unit(IN[0]) if isinstance(IN[0], str) else [ffi_to_unit(i) for i in IN[0]]
2 Likes

More recent versions of Dynamo also have utility nodes
image

1 Like

Finally, you can use the ForgeUnits assembly (Revit 2023+) from Dynamo to parse strings, including arithmetic equations.

import clr
import os
import sys
import sysconfig

# Set up ForgeUnits assembly path
src_dir = sysconfig.get_config_var("srcdir")  # Revit install path
dyn_path = os.path.join(src_dir, "AddIns\DynamoForRevit")
sys.path.append(dyn_path)

clr.AddReference("ForgeUnitsCLR")
from ForgeUnitsCLR import UnitsEngine
from SchemasCLR import SchemaUtility

clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import UnitTypeId


def units_engine(schema_path):
    ue = UnitsEngine()
    SchemaUtility.addDefinitionsFromFolder(schema_path, ue)
    ue.resolveSchemas()
    return ue


schema_path = os.path.join(dyn_path, "unit")
ue = units_engine(schema_path)

MM = UnitTypeId.Millimeters.TypeId
FT = UnitTypeId.Feet.TypeId

OUT = ue.parse(MM, IN[0])

image

1 Like