
Fraction conversion
I am working on allowing users to input measurements into a field and many will have fractions (eg. 3 5/6, 1/2, 4). Some user entries will just be a Fixnum.
The db table should store all user entered numbers as a integer by multiplying by 12 (eg 3 5/6 => 46, 1/2 => 6, 4 => 48).
How would I go about taking a user entry and converting it to the "entry" x 12 integer for the db?
Many thanks.

You could "split" the numbers by a space and then by a slash. Then do the division to get a float, add to the whole number, and multiply by 12.
I don't know about precision, but if you have a restricted number of possible input variations (i.e. only #/2, #/3, #/4, #/6 and #/12) I think you should be OK.

Ok but how do I convert user input = 3 3/4 to a string or array?


Thanks Regggie... but the case was not solved earlier as one needed to put " " around the user input in your cases. I am trying to avoid a user from having to input "1 1/2" but simply 1 1/2. You have been great and I feel like I am on the 1 yard line but need to get rid of the quotes.

OK I solved my own problem of getting rid of the "" marks.
in the link one would use the following code:
ft = FractionTest.new
number = gets.chomp
ft.test(number)
That way the user does not need to input with ""

The user would not need to put quote (") marks around the entry, and chomp in your "solution" does not remove quote marks:
http://www.rubydoc.org/core/classes...g.html#M000834
What needs to happen is that the input needs to be in the form of a string. Most user inputs will be in the form of a string. For example, try running this code:
Code:
puts "Enter something"
entry = gets
puts "Entry was of the type #{entry.class}"
Run this twice. First entering "1 1/2" and the other just 1 1/2
You'll see that both entries are input into the program as strings. The same is the case with HTML forms. The entry is received via HTTP as a string, with or without quotes.
If chomp has fixed the problem, it appears that a carriage return or end of line character is causing the problem.

Actually, even better try running this version of my program and your see that inputs of 1 1/2 and "1 1/2" both work and both give the same answer.
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
puts "Enter a number"
number_to_test = gets
ft.test(number_to_test)
Actually, playing with that I notice that there is a formatting issue as the gets is recovering the end of line character and that is causing my output to step down a line at this point:
Code:
puts "#{number} contains the number #{parts[1]} "
So 1 1/2 is generating:
1 1/2
contains the number 1
Instead of the intended
1 1/2 contains the number 1
And indeed a chomp fixes that for example by altering the last line to:
Code:
ft.test(number_to_test.chomp)

I have been scouring the web to try to avoid having to ask how to make the fraction conversion in the model. I have the following code and keep getting a "dynamic constant assignment" error:
class Food < ActiveRecord::Base
attr_accessor :quantity
before_save :convert_quantity
private
def convert_quantity
quantity = @quantity
self.quantity = convert(quantity)
end
def FractionConversion
NUMBER_AND_FRACTION = /(\d+)\s+(\d+\/\d+)/
FRACTION_ONLY = /(\d+)\/(\d+)/
NUMBER_ONLY = /(\d+\.*\d*)/
def convert(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
... to the end of the convert