SitePoint Sponsor 

User Tag List
Results 1 to 6 of 6
Thread: Displaying fractions in Ruby
Hybrid View

Apr 20, 2009, 04:35 #1
 Join Date
 Apr 2009
 Location
 Marin CA
 Posts
 17
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
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?

Apr 20, 2009, 05:53 #2
 Join Date
 Apr 2009
 Location
 Australia
 Posts
 8
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
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
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
I hope this helps!

Apr 20, 2009, 08:15 #3
 Join Date
 Feb 2006
 Location
 Worcs. UK
 Posts
 404
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
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")

Apr 20, 2009, 09:23 #4
 Join Date
 Apr 2009
 Location
 Marin CA
 Posts
 17
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
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 />
<%= f.text_field :quantity %>
</p>
Many thanks again.

Apr 21, 2009, 00:36 #5
 Join Date
 Feb 2006
 Location
 Worcs. UK
 Posts
 404
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
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.
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 builtin functions to do that. So you shouldn't have to worry about it.

Apr 21, 2009, 00:46 #6
 Join Date
 Apr 2009
 Location
 Australia
 Posts
 8
 Mentioned
 0 Post(s)
 Tagged
 0 Thread(s)
Bookmarks