## Programming Praxis – Feet And Inches

In today’s Programming Praxis exercise, our goal is to convert a decimal length value to the fractions used by carpenters. Let’s get started, shall we?

Some imports:

```import Data.Ratio
import Text.Printf```

To get proper rounding we first multiply by 32 and then see how many feet, inches and fractions of an inch there are.

```toCarpenter :: RealFrac a => a -> (Int, Int, Ratio Int)
toCarpenter l = (feet, div r 32, mod r 32 % 32) where
(feet, r) = divMod (round \$ l * 32) (32 * 12)```

Formatting the text is a unfortunately a tad unwieldy due to the number of special cases.

```feetAndInches :: RealFrac a => a -> String
feetAndInches l = case toCarpenter l of
(0,0,0) -> "0 feet 0 inches"
(f,i,t) -> showUnit "foot" "feet" (f % 1) ++
(if f > 0 && (i%1 + t) > 0 then " " else "") ++
showUnit "inch" "inches" (i % 1 + t)
where
showUnit _ _ 0 = ""
showUnit s m n = printf "%s %s" (showVal n) \$ if n <= 1 then s else m
showVal v | d == 1    = show n
| v < 1     = printf "%d/%d" n d
| otherwise = printf "%d and %d/%d" (div n d) (mod n d) d
where (n,d) = (numerator v, denominator v)```

Some tests to see if everything is working properly:

```main :: IO ()
main = do print \$ feetAndInches 0       == "0 feet 0 inches"
print \$ feetAndInches 0.2785  == "9/32 inch"
print \$ feetAndInches 1.6895  == "1 and 11/16 inches"
print \$ feetAndInches 11.9999 == "1 foot"
print \$ feetAndInches 12.2785 == "1 foot 9/32 inch"
print \$ feetAndInches 71.9999 == "6 feet"
print \$ feetAndInches 72      == "6 feet"
print \$ feetAndInches 72.3492 == "6 feet 11/32 inch"
print \$ feetAndInches 72.9999 == "6 feet 1 inch"
print \$ feetAndInches 73      == "6 feet 1 inch"
print \$ feetAndInches 73.0135 == "6 feet 1 inch"
print \$ feetAndInches 73.0185 == "6 feet 1 and 1/32 inches"
print \$ feetAndInches 73.8218 == "6 feet 1 and 13/16 inches"```