Adding Eighths in Python

Viewed 74

I'm parsing a screenplay .XML file and I need to add the length in eighths of each scene. In film, the scripted length of a scene is measured in eighths and we never reduce that number. Page eighths are used for many different purposes and must remain as such.

So, as I parse my screenplay XML file, each scene heading paragraph element has a child called SceneProperties with an attribute Length the value of which is contained in a string:

<Paragraph Type="Scene Heading" Number="6">
  <SceneProperties Length="1/8" Page="1" Title=""/>

What I need to do is add up the total page eighths of all the scenes in the script. There seem to be two unique aspects to this otherwise simple math: Some of the Length values have a whole number and a fraction separated by a space (like "1 2/8"), and all of the eighths need to remain as eighths. So basically I need to:

from fractions import Fraction

scene_1 = "2/8"
scene_2 = "1 4/8"
Length = Fraction(scene_1) + Fraction(scene_2)
print(Length)
#This doesn't work - I need it to print "1 6/8"

Any ideas how I would go about this?

1 Answers

You should split each of the strings and interpret each part as its own fraction.

from fractions import Fraction

scene_1 = "2/8"
scene_2 = "1 4/8"

def parse_fraction(s):
  return sum(map(Fraction, s.split()))

Length = parse_fraction(scene_1) + parse_fraction(scene_2)
print(Length)

def format_as_eighths(frac):
    number_part, remainder = divmod(frac.numerator, frac.denominator)
    remainder_fraction = Fraction(remainder, frac.denominator)

    if 8 % Length.denominator != 0:
       raise ValueError('Will not fit into a fraction with 8 as the denominator')

    resulting_numerator = remainder_fraction.numerator * (8 // frac.denominator)  # Scale the remainder fraction so it has 8 as its denominator

    result = f"{number_part} {resulting_numerator}/8"
    return result

print(format_as_eighths(Length))
Related