Rails: Currency to Number - ruby-on-rails

I have some forms on my site where after a user enters currency values those inputs are put into a calculator.
The input needs to be either floats or integers but I want it so that if they enter '$200,000' or '200000' it will both result in '200000.0' after clicking submit. (sort of the opposite of number_to_currency)
I was thinking something like
text = text.gsub(/[$,]/, '').to_f
or better yet take out all non digit characters but this will result in an unintentional zero in the output.
I also would like to format the result in the view so that if the resulting float has nothing after the decimal eg 200.00 then it will round up to 200. Otherwise it will round to 2 decimal place
Most preferably I would like it to work like the presence validator before the form actually submits.
What's the best way to go about implementing this? I'm thinking there is something obvious I've missed.

For the second part, you could do this:
# after converting text to a float
text.modulo(1) == 0 ? text.to_i : sprintf("%.2f", text)
For example, if text = 200000.0, we get 200000 using the above.
On the other hand, if text = 200000.1, we get 200000.10 using the above.

Related

Printing a number with either one decimal place or none

Is there a simple way to print a number with either one decimal place or none?
I've searched the net for a method to do that but all of them try to always have a zero after the decimal point..
I want 3.0 to be printed as just 3, and 3.5 to be printed as 3.5.
I tried print('{:.1f}'.format(num)) but this prints 3.0
You have not specified the programming language, so I will provide an answer in pseudocode.
Using if-else
printWithOneOrNoDecimals(n)
if (isNumberInteger(n))
printWithoutDecimals(n)
else
printNumberWithOneDecimal(n)
isNumberInteger(n)
return round(n) == n
The method round(n) should round the number, for example 2.4 to 2. Because 2.4 != 2, isNumberInteger(2.4) would return false and the else statement is exectuted.
Now you can define different formats for printing numbers with or without decimal in printNumberWithOneDecimal and printWithoutDecimals.
Using “right trim” or “right strip”
Another way to achieve the result is to first make the number a string (maybe formatting it to have one decimal) and then “trimming” or “stripping” it from the right, first “all” zeros (in your case at most one) and then the decimal point (if any on the right). Note: trim or strip methods do not give an error if there’s nothing to trim/strip.
I guess that in Python it would be:
'{:.1f}'.format(num).rstrip('0').rstrip('.')
Happy coding, good luck!

Rails: Split text including dollar end euro

I'm using Rails and Nokogiri and I'm trying to parse some website.
This is where I'm stuck:
doc.css('#example > li:nth-child(1)').each do |node|
money = node.xpath('//*ul/li/div/span').text
end
It returns something like:
$100,000£230,000$40,000$9,000€600$800,000
I want to split those items, save them to the database and finally hand them to the view.
So, in the view, I want it to appear like:
(1)$100,000
(2)£230,000
(3)$40,000
(4)$9,000
(5)€600
(6)$800,000
I tried to split those items by this code below.
money = node.xpath('//*ul/li/div/span').text.split(/[$€£]/)
but the result looks like this:
["", "100,000", "230,000", "40,000", "9,000", "600", "800,000"]
And I don't know which item is in Dollar, Euro, or Pond.
Is there any good way to solve this problem?
you're almost there,
just use the positive lookahead :)
irb(main):005:0> "$100,000£230,000$40,000$9,000€600$800,000".split(/(?=[$£€])/)
=> ["$100,000", "£230,000", "$40,000", "$9,000", "€600", "$800,000"]
It needs a regular expression. This works:
"$100,000£230,000$40,000$9,000$600$800,000".scan(/([^\d][0-9,]+)/)
=> [["$100,000"],
["£230,000"],
["$40,000"],
["$9,000"],
["$600"],
["$800,000"]]
The regex contains these parts:
[^\d]: A character class matching a single non-digit. This will match the currency symbol.
`[0-9,]+': Another character class, this time repeating (the '+'). It matches the numeric part (0-9) plus the thousand's separator.

Proper way to display the result of large calculations?

When performing calculations on large numbers, how does one properly output the result in the right String format for the end user to see? I've tried the different format specifiers for NSString and compared the results to what the iOS Calculator app shows and some of the results aren't the same. Ideally it would match the iOS Calculator results exactly.
I know it needs to be displayed in decimal format until the number is sufficiently large, and at that point it needs to be shown in scientific notation. Therefore I thought %g was the right specifier. But it doesn't match the built-in calculator for the same calculation.
[NSString stringWithFormat:#"%g", calcResult] //where calcResult is a double
Some examples:
123456.7 * 1 should display as 123456.7 but it is displayed as 123457 (puzzling!)
123456789 * 1 should display as 123456789 but it's displayed as 1.23457e+08
123456789 * 123456789 should display as 1.524158e+16 but it's displayed as 1.52416e+16
Also, how does one get the comma (or period depending on locale) to appear in the result? Are there additional specifiers one can use to get the exact format the iOS Calculator shows?

How to convert Float to String with out getting E in blackberry

Any way to convert Float to string with out getting E (exponent).
String str = String.valueOf(floatvalue);
txtbox.settext(str);
and i am using NumericTextFilter.ALLOW_DECIMAL in my textField which allow decimal but not E.
i am getting like this 1.3453E7 but i want it something like 1.34538945213 due to e i am not able to set my value in edit text.
so any way to get value with out e.
I'm not 100% sure I understand what number you're trying to format. In the US (my locale), the number 1.3453E7 is not equal to the number 1.34538945213. I thought that even in locales that used the period, or full stop (.) to group large numbers, you wouldn't have 1.34538945213. So, I'm guessing what you want here.
If you just want to show float numbers without the E, then you can use the Formatter class. It does not, however, have all the same methods on BlackBerry that you might expect on other platforms.
You can try this:
float floatValue = 1.3453E7f;
Formatter f = new Formatter();
String str = f.formatNumber(floatValue, 1);
text.setText(str);
Which will show
13453000.0
The 1 method parameter above indicates the number of decimal places to show, and can be anything from 1 to 15. It can't be zero, but if you wanted to display a number without any decimal places, I would assume you would be using an int or a long for that.
If I have misunderstood your problem, please post a little more description as to what you need.
I'll also mention this utility class that apparently can be used to do more numeric formatting on BlackBerry, although I haven't tried it myself.
Try this:
Double floatValue = 1.34538945213;
Formatter f = new Formatter();
String result = f.format("%.11f", floatValue);
Due to the floating point presentation in java, the float value 1.34538945213 has not the same representation as the double value 1.34538945213. So, if you want to get 1.34538945213 as output, you should use a double value and format it as shown in the example.

Dynamically generate short URLs for a SQL database?

My client has database of over 400,000 customers. Each customer is assigned a GUID. He wants me to select all the records, create a dynamic "short URL" which includes this GUID as a parameter. Then save this short url to a field on each clients record.
The first question I have is do any of the URL shortening sites allow you to programatically create short urls on the fly like this?
TinyUrl allow you to do it (not widely documented), for example:
http://tinyurl.com/api-create.php?url=http://www.stackoverflow.com/
becomes http://tinyurl.com/6fqmtu
So you could have
http://tinyurl.com/api-create.php?url=http://mysite.com/user/xxxx-xxxx-xxxx-xxxx
to http://tinyurl.com/64dva66.
The guid doesn't end up being that clear, but the URLs should be unique
Note that you'd have to pass this through an HTTPWebRequest and get the response.
You can use Google's URL shortner, they have an API.
Here is the docs for that: http://code.google.com/apis/urlshortener/v1/getting_started.html
This URL is not sufficiently short:?
http://www.clientsdomain.com/?customer=267E7DDD-8D01-4F38-A3D8-DCBAA2179609
NOTE: Personally I think your client is asking for something strange. By asking you to create a URL field on each customer record (which will be based on the Customer's GUID through a deterministic algorithm) he is in fact essentially asking you to denormalize the database.
The algorithm URL shortening sites use is very simple:
Store the URL and map it to it's sequence number.
Convert the sequence number (id) to a fixed-length string.
Using just six lowercase letter for the second step will give you many more (24^6) combinations that the current application needs, and there's nothing preventing the use of a larger sequence at some point in time. You can use shorter sequences if you allow for numbers and/or uppercase letters.
The algorithm for the conversion is a base conversion (like when converting to hex), padding with whatever symbol represents zero. This is some Python code for the conversion:
LOWER = [chr(x + ord('a')) for x in range(25)]
DIGITS = [chr(x + ord('0')) for x in range(10)]
MAP = DIGITS + LOWER
def i2text(i, l):
n = len(MAP)
result = ''
while i != 0:
c = i % n
result += MAP[c]
i //= n
padding = MAP[0]*l
return (padding+result)[-l:]
print i2text(0,4)
print i2text(1,4)
print i2text(12,4)
print i2text(36,4)
print i2text(400000,4)
print i2text(1600000,4)
Results:
0000
0001
000c
0011
kib9
4b21
Your URLs would then be of the form http://mydomain.com/myapp/short/kib9.

Resources