I have a dynamically generated table that multiplies price * qty. Some of the prices are in partial cents. For example
if the price of an item is 0.0375 I can display that in my table as
number_to_currency(0.0375,:precision => 4)
=> $0.0375
but on quantities where the price is a standard 2 decimal number I get
number_to_currency(33.95,:precision => 4)
=> $39.9500
I need a way to trim the trailing zeroes of a decimal value. Keep in mind that the output is in a Model.each block so I'm uncertain I can modify the precision parameter conditionally.
Try to specify strip_insignificant_zeros option:
number_to_currency(33.95, precision: 4, strip_insignificant_zeros: true)
It should remove zeros after decimal separator. Here is description of this option.
The default for this method is 2. So you simply need
number_to_currency(33.95)
http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#method-i-number_to_currency
number_to_currency(33.95,:precision => 2)
Since number_to_currency returns a String, you can use .remove(/0+$/) to remove any trailing zeros:
number_to_currency(33.95,:precision => 4).remove(/0+$/)
Try using round before number_to_currency:
number_to_currency(33.95.round(4)) # $33.95
number_to_currency(0.0375.round(4)) # $0.0375
Related
Following problem. I have decimal numbers in my Google Sheets that I get from a website.
The numbers have 3 digits after the decimal point or they have no comma in there. I need the numbers without a comma and adding Zero after 1,2 => 1200 or 1,22 => 1220 and 2 should be 2.
Say if a number looks like this on the website:
1,200
1,220
1,222
12,220
2
I get the data via Google spreadsheet with the formula =IMPORTDATA("API_LINK")
There is the problem that the zeros that I don't want to lose are automatically deleted by =IMPORTDATA
Means I get that copied into the table like this :
1,2
1,22
1,222
12,22
2
My question is, how do I get the numbers to be automatically converted with another formula or even with a script that looks like this:
1,2 => 1200
1,22 => 1220
1,222 => 1222
12,22 => 12220
2 => 2
So normal numbers should be normal and decimals should be converted.
The formula what I tried but is only working for 1,222 => 1222. The other looke like this 1,2 => 43862 and 1,22 => 1,22 also 12,22 => 12,22.
=IFERROR(VALUE(SUBSTITUTE(A2;",";"."));VALUE(SUBSTITUTE(A2;".";",")))
I tried even to change the settings in the sheet but isn't working at all.
It would be very nice if someone could help me with that.
If your import is removing final zeros, this indicates that what winds up in your sheet is most likely text and not a number at all.
It is always easier to help if you share a sample sheet with full editing permissions. However, given what I know from your post, try this:
=IF(A2="","",VALUE(A2&IFERROR(REPT("0",3-(LEN(A2)-FIND(",",A2))))))
This would also work as an array formula with slight modification (i.e., it could "solve" a whole column with one formula rather than dragging a formula down). For instance, if your raw data were in A2:A, you could put the following array formula in B2 (assuming column B is completely blank below B2):
=ArrayFormula(IF(A2:A="","",VALUE(A2:A&IFERROR(REPT("0",3-(LEN(A2:A)-FIND(",",A2:A)))))))
try:
=ARRAYFORMULA(SUBSTITUTE(TO_TEXT(IMPORTDATA("API_LINK")), ",", ))
You also can use format patterns.
You can define how many digits wants in the decimal side with TEXT function. In this case, always three digits even zeros:
##.000
Then, once you have the number you want, you can remove the decimal separator with the SUBSTITUTE funtion.
Finally you got:
SUBSTITUTE(TEXT(YOURNUMBER;"##.000");",";"")
More info in this google site.
how would I extract the last part of the string with a regex? The last part of the string will always be a 3 digit number as well.
"/gdc/md/vin06hdpq8442qocut9aoih8q5j5k43u/obj/185"
Something like: /\d+$/ should get all digits at the end of the string
Just slice the last 3 chars :
str = "/gdc/md/vin06hdpq8442qocut9aoih8q5j5k43u/obj/185"
p str[-3,3] # => "185"
There are a number of different ways you can accomplish this.
You can use regular expressions to match either all trailing digits (/\d+$/), or just the last three trailing digits (/\d{3}$/), depending on what behaviour you want in case the string for some reason has more digits than you expected:
str.match(/\d+$/)[0]
#=> "185"
str.match(/\d{3}$/)[0]
#=> "185"
Another option is to split the string into an array, using / as the separator, and then grabbing the last element (which will contain everything past the last /.)
str.split("/").last
#=> "185"
Or you can use the fact that substrings can be accessed using indices, much like arrays, and use it to grab the last three digits:
str[-3, 3]
#=> "185"
Unless you're doing this thousands of times inside a loop, any performance difference will be insignificant, so you can go for the option that is offer the most robustness and legibility.
Note that in all four cases, you will be returned a string, so if you intend to use this number as an integer, you'll need to first convert it using #to_i.
Or a combination of both with str[/\d{3}$/]
or maybe str[-3..-1]
So many ways to skin that string :)
I am facing an issue with Ruby BigDecimal on my Rails 4 app.
I have a "price" attribute in a Thing model, which class is BigDecimal. Whenever I create or update a Thing, I would like to save the "price" attribute with strictly two decimal digits (e.g. "0.00", "10.00", "10.10", "10.01").
But it saves, by default, only one decimal digit if two are not necessary. Here what I insert and what it saved currently :
"0" => "0.0" (instead of "0.00")
"10" => "10.0" (instead of "10.00")
"10.1" => "10.1" (instead of "10.10")
"10.01" => "10.01" (OK)
I don't just want to display the "price" attribute with two decimals (which can be done using "%.2f" % price), I want to save the "price" attribute with two decimal digits in my database. Any way to do so ?
Thanks a lot for your help.
What you are describing seems to me to be purely for display purposes. I don't know of any way to save a decimal to a DB with a specific amount of decimals that don't actually add precision unless you save them as a string.
Seems to me you would be best off creating a method on the Thing model that will return price formatted how you want.
I'm storing numbers such as
2,000
5,000
10,000
in a database with an 'integer column'. When I display them on the app, they're showing up like
2.0
5.0
Is there a column type I can use to make them show up "as is." I tried string before but string doesn't sort well.
Integers should come out like integers. If you try to insert "2,000" internally rails is effectively doing to do a to_i on it which will be 2. (try this on irb "2,000".to_i and "2_000".to_i to see how ruby deals with integer conversions).
Now if you insert 2000 and you get 2000.0 that is not natural or expected for an integer column. I suspect there is some post processing going on on the attribute or that your database is decimal/float column.
Rails Console =>
"2,000".to_i => 2
"2_000".to_i => 2000
helper.number_to_currency(2000) => "$2,000.00"
to fix this, I entered the number in the database without the comma. Then the numbers showed up on the app like 10000.0 and I used number_to_currency to change the number to make it look like a dollar value
In Ruby, you can also enter in integers like this
10_000
5_000
2_000
I'd like to generate a comment preview. I have #comments, which has 1 or comment comment items.
How can I take up to 5 comments. Combine them into a single string, spaced apart. And then take the first 100 characters? Where if there is less than 100 characters it won't break?
Thanks
Use the truncate Rails helper:
truncate(#comments.take(5).join(" "), :length => 100)
With truncate you can put a "..." at the end or make sure to not split a word (by using :separator)
(Note that it would be best to move some of the snippet-creation logic to the model)
(Suppose that the content/body of the comment is accessible via :content)
#comments[0...5].map(&:content).join(' ').first(100)
It won't break if it's less than 100 characters.
But can't you only retrieve the first 5 comments from the db instead of retrieving all the comments and then keeping only 5 of those?
It would be much more efficient.
For instance:
#post.comments.select(:content).limit(5).map(&:content).join(' ').first(100)