# Thread: Displaying fractions in Ruby

1. ## Displaying fractions in Ruby

I'd like to be able to store fractions in the database, so that people can type things such as 1/2 or 1 1/3. Given the fractions I am interested in (half, quarter, third) I will just store the numbers as integer twelvths.

Example: if I wanted 1 1/2 store 18, if I wanted 3 2/3 store as 44 etc.

So then how would I format to display 1 1/2 and 3 2/3 etc. in views?

2. Here's the first solution using a whopping case statement for the fractional part. This is not ideal, but it gives an idea of what's going on in order to understand the second better solution.

Code:
```def frac(num)
str = (num / 12).to_s
frac = num % 12
frac_str = case frac
when 0 then ''
when 1 then '1/12'
when 2 then '1/6'
when 3 then '1/4'
when 4 then '1/3'
when 5 then '5/12'
when 6 then '1/2'
when 7 then '7/12'
when 8 then '2/3'
when 9 then '3/4'
when 10 then '5/6'
when 11 then '11/12'
end
return [str, frac_str].join(' ')
end```
I use division and modulus in the first 2 lines to find the whole number and fractional bits. Then I use a case statement on the fractional part to map to a nice string representation. The return statement uses a join to avoid having messy if/then/else statements in the event the number is divisible by 12.

Here's the second solution that gets rid of the massive case statement by utilising the mathematical concept known as the greatest common divisor.

Code:
```def frac(num)
str = (num / 12).to_s
common_divisor = 12.gcd(num % 12)
frac_str = if common_divisor == 12
nil
else
[num % 12 / common_divisor, 12 / common_divisor].join('/')
end
return [str, frac_str].compact.join(' ')
end```
The first line is the same as the first code sample. The second line tells me the greatest common divisor of the modulus and 12. Then I use the GCD to normalise the numerator and denominator provided the number doesn't doesn't divide by 12 entirely. There's a little bit of trickery/ugliness in the code to make sure the string formatting looks appropriate on the way out.

I hope this helps!

3. If all you want to do is allow users multiple ways of inputting information, I'd use regular expressions to determine the user input format and deal with it. You should then be able to store the number in a standard format thereby removing the complication of storing twelfths and allowing the user to enter any fraction.

Here a sample script that uses a class to shows how you can do that:
Code:
```class FractionTest
NUMBER_AND_FRACTION = /(\d+)\s+(\d+\/\d+)/
FRACTION_ONLY = /(\d+)\/(\d+)/
NUMBER_ONLY = /(\d+\.*\d*)/

def test(number)
case number
when NUMBER_AND_FRACTION
number_and_fraction(number)
when FRACTION_ONLY
fraction_only(number)
when NUMBER_ONLY
number_only(number)
else
puts "no match"
end
puts "--------------"
end

private

def number_and_fraction(number)
parts = number.match(NUMBER_AND_FRACTION)
result = parts[1].to_f + process_fraction(parts[2])
puts "#{number} contains the number #{parts[1]} "
puts "and the fraction #{parts[2]} "
puts "and is equal to #{result}."
end

def fraction_only(number)
result = process_fraction(number)
puts "#{number} contains the fraction #{number} "
puts "and is equal to #{result}."
end

def number_only(number)
result = number.match(NUMBER_ONLY)[0].to_f
puts "#{number} contains the number #{number}"
puts "and is equal to #{result}."
end

def process_fraction(fraction)
parts = fraction.match(FRACTION_ONLY)
numerator = parts[1].to_f
denominator = parts[2].to_f
return numerator / denominator
end

end

ft = FractionTest.new

ft.test("1 1/2")
ft.test("1/2")
ft.test("1")
ft.test("4.34")```

4. Reggie, that was really helpful on the fractions thanks. I am a relatively new coder so I will go thru it with a fine tooth comb. Quick follow up question:

Should I store the inputs in my table (Quantity Column) as a integer or a float?

Do I take the input from users in the view as a text as:

<p>
Measurement Quantitybr />
<&#37;= f.text_field :quantity %>
</p>

Many thanks again.

5. Originally Posted by cberry1971
Should I store the inputs in my table (Quantity Column) as a integer or a float?
It is always best to store the data in the format that best matches the data itself. As the numbers you are storing contain a decimal component, integer would not be appropriate.

Float is the obvious solution. However, you should be aware that Float stores numbers as bits rather than as base 10 decimals, and you can get small quirks transferring back and forth between the float and the decimal system your human users will use. For many situations (for me the vast majority) float is perfectly satisfactory. However, if precise accuracy is required, you should consider using a decimal field.

Originally Posted by cberry1971
Do I take the input from users in the view as a text
Yes. The nature of web forms is that data passed from the client browser to the server, is passed as text. However, Rails (and in particular ActiveRecord) is clever enough to automatically convert the text into the correct format for the field when data is inserted into the database, if you use the built-in functions to do that. So you shouldn't have to worry about it.

6. Originally Posted by cberry1971
Should I store the inputs in my table (Quantity Column) as a integer or a float?
Store the number as an integer multiple of 1/12. So 1/6 would be stored as 2 I.e. 2/12.

Float will produce rounding errors in special cases.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•