tobyclemson-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2007-Jul-27 13:50 UTC
Number formatter
Hi, Does anyone know if the reverse of the rails 20.kilobytes (megabytes/ gigabytes etc.) exists? I have lots of values in my model that are stored as bytes and I''d like to easily convert them to a MB or GB approximation (say 1 decimal place) with *B as a suffix after the number. I also need to do the same for decimal numbers in terms of thousands and millions. I could write something to do it but I wondered if there was an easier way? Also if I did write a class to deal with it where in the rails directory structure should it go? helpers? Thanks, Toby --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
gene.tani-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2007-Jul-27 14:00 UTC
Re: Number formatter
On Jul 27, 6:50 am, "tobyclem...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org" <tobyclem...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi, > > Does anyone know if the reverse of the rails 20.kilobytes (megabytes/ > gigabytes etc.) exists? I have lots of values in my model that are > stored as bytes and I''d like to easily convert them to a MB or GB > approximation (say 1 decimal place) with *B as a suffix after the > number. > > I also need to do the same for decimal numbers in terms of thousands > and millions. > > I could write something to do it but I wondered if there was an easier > way? > > Also if I did write a class to deal with it where in the rails > directory structure should it go? helpers? > > Thanks, > Tobyhttp://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Numeric/Bytes.html --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
tobyclemson-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2007-Jul-27 14:08 UTC
Re: Number formatter
I am aware of the ruby extensions that will go in one direction but those don''t work in the other direction. All my values are bytes already and I want to convert those to kilo/mega/giga bytes etc. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> Also if I did write a class to deal with it where in the rails > directory structure should it go? helpers?You could put it there if you think you''re unlikely to use it anywhere other than just this app, else I tend to put things like this into their own file in lib. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
that was a fun little exercise... here''s how i interpreted your need: class Numeric def to(unit, places=1) units = { :b => 1, :kb => 1024**1, :mb => 1024**2, :gb => 1024**3, :tb => 1024**4, :pb => 1024**5, :eb => 1024**6} unitval = units[unit.to_s.downcase.to_sym] "#{sprintf("%.#{places}f", self / unitval)} #{unit.to_s.upcase}" end # to end puts 1024.to(:kb) # 1.0 KB puts 20000.0.to(:kb) # 19.5 KB puts 123456789.to(:mb) # 117.0 MB puts 123456789.to(''MB'') # 117.0 MB puts 123456789.to(:MB) # 117.0 MB puts 123456789.to(:mb, 0) # 117 MB puts 345678912345.4.to(:gb, 3) # 321.939 GB --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
tobyclemson-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2007-Jul-27 15:12 UTC
Re: Number formatter
Thanks that''s great - I did something similar in the end except mine didn''t have the ability to choose, it just went to the smallest that wasn''t less than zero. I think I''ll combine the two! On Jul 27, 3:56 pm, jemminger <jemmin...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> that was a fun little exercise... here''s how i interpreted your need: > > class Numeric > def to(unit, places=1) > units = { :b => 1, > :kb => 1024**1, > :mb => 1024**2, > :gb => 1024**3, > :tb => 1024**4, > :pb => 1024**5, > :eb => 1024**6} > unitval = units[unit.to_s.downcase.to_sym] > "#{sprintf("%.#{places}f", self / unitval)} #{unit.to_s.upcase}" > end # to > end > > puts 1024.to(:kb) # 1.0 KB > puts 20000.0.to(:kb) # 19.5 KB > puts 123456789.to(:mb) # 117.0 MB > puts 123456789.to(''MB'') # 117.0 MB > puts 123456789.to(:MB) # 117.0 MB > puts 123456789.to(:mb, 0) # 117 MB > puts 345678912345.4.to(:gb, 3) # 321.939 GB--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
tobyclemson-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:> I could write something to do it but I wondered if there was an easier > way? > > Also if I did write a class to deal with it where in the rails > directory structure should it go? helpers? > > Thanks, > TobyI would just stick in in the core extensions as it''s very unlikely to conflict with anything and it''s "in the spirit" of how rails extends the core. I don''t think you will find the reverse anywhere as the implementation is trivial irb(main):001:0> require ''rubygems'' => true irb(main):002:0> gem ''activesupport'' => true irb(main):003:0> require ''active_support'' => true irb(main):004:0> module ActiveSupport::CoreExtensions::Numeric::Bytes irb(main):005:1> def to_megabytes irb(main):006:2> self/1.megabyte irb(main):007:2> end irb(main):008:1> end => nil irb(main):009:0> num = 6.megabytes => 6291456 irb(main):010:0> num.to_megabytes => 6 HTH. ilan -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
You can use number_to_human_size(size, precision=1) from ActionView::Helpers::NumberHelper (http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#M000524) Adam On 7/27/07, Ilan Berci <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > tobyclemson-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote: > > > I could write something to do it but I wondered if there was an easier > > way? > > > > Also if I did write a class to deal with it where in the rails > > directory structure should it go? helpers? > > > > Thanks, > > Toby > > I would just stick in in the core extensions as it''s very unlikely to > conflict with anything and it''s "in the spirit" of how rails extends the > core. > > I don''t think you will find the reverse anywhere as the implementation > is trivial > > irb(main):001:0> require ''rubygems'' > => true > irb(main):002:0> gem ''activesupport'' > => true > irb(main):003:0> require ''active_support'' > => true > irb(main):004:0> module ActiveSupport::CoreExtensions::Numeric::Bytes > irb(main):005:1> def to_megabytes > irb(main):006:2> self/1.megabyte > irb(main):007:2> end > irb(main):008:1> end > => nil > irb(main):009:0> num = 6.megabytes > => 6291456 > irb(main):010:0> num.to_megabytes > => 6 > > HTH. > > ilan > > -- > Posted via http://www.ruby-forum.com/. > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
tobyclemson-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:> Does anyone know if the reverse of the rails 20.kilobytes (megabytes/ > gigabytes etc.) exists? I have lots of values in my model that are > stored as bytes and I''d like to easily convert them to a MB or GB > approximation (say 1 decimal place) with *B as a suffix after the > number.This reply is over a year old, but I thought I''d archive the information in this thread. While ActionView in rails does have a helper for this, it requires you to supply the number of decimal places. What follows is my own code (as a Ramaze helper) that (by default) automatically determines the number of decimal places based on the size of the answer. For example: [ 1500 12_000 130_000 1_400_000 ].each do |bytes| puts nice_bytes( b ) end #=> 1.46kB #=> 11.7kB #=> 127kB #=> 1.34MB module Ramaze::Helper::NiceBytes K = 2.0**10 M = 2.0**20 G = 2.0**30 T = 2.0**40 def nice_bytes( bytes, max_digits=3 ) value, suffix, precision = case bytes when 0...K [ bytes, ''b'', 0 ] else value, suffix = case bytes when K...M : [ bytes / K, ''kB'' ] when M...G : [ bytes / M, ''MB'' ] when G...T : [ bytes / G, ''GB'' ] else [ bytes / T, ''TB'' ] end used_digits = case value when 0...10 : 1 when 10...100 : 2 when 100...1000 : 3 end leftover_digits = max_digits - used_digits [ value, suffix, leftover_digits > 0 ? leftover_digits : 0 ] end "%.#{precision}f#{suffix}" % value end end -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Gavin Kistner wrote:> While ActionView in rails does have a helper for this, it requires you > to supply the number of decimal places. What follows is my own code (as > a Ramaze helper) that (by default) automatically determines the number > of decimal places based on the size of the answer.I just found this thread an Rails'' number_to_human_size does exactly what you want as far as I can see, so there is no need to write your own function it seems? http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#M001656 -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Michael Hasenstein wrote:> Gavin Kistner wrote: >> While ActionView in rails does have a helper for this, it requires you >> to supply the number of decimal places. What follows is my own code (as >> a Ramaze helper) that (by default) automatically determines the number >> of decimal places based on the size of the answer. > > > I just found this thread an Rails'' number_to_human_size does exactly > what you want as far as I can see, so there is no need to write your own > function it seems? > > http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#M001656If you read the part of what I wrote that you quoted again, I think you''ll find that Rails'' method does not do the same thing when no precision parameter is supplied. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> If you read the part of what I wrote that you quoted again, I think > you''ll find that Rails'' method does not do the same thing when no > precision parameter is supplied.So what is so difficult or bad about giving it that one parameter :precision => 2 that you feel you have to roll your own lengthy function? I still don''t understand, but I would like to. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Michael Hasenstein wrote:> I still don''t understand, but I would like to.Okay, now I do. But I still think a new function is not necessary. The only difference in behavior without the precision parameter is that the Rails function defaults to 1. Output of your example using the Rails function: 1.5 KB (your function: 1.46) 11.7 KB 127 KB 1.3 MB (your function: 1.34) That looks very acceptable to me and a lot of people. Of course, do what you want, the only reason I post is because when *I* found this thread looking for such a functionality I copied your code, and only then realized there''s a function already. I respond to let others know right away who find this through Google. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Michael Hasenstein wrote:> That looks very acceptable to me and a lot of people. Of course, do what > you want, the only reason I post is because when *I* found this thread > looking for such a functionality I copied your code, and only then > realized there''s a function already. I respond to let others know right > away who find this through Google.I think it''s excellent that you recorded for the record the simplest case for others to follow. To be clear, here''s the output I want (and have): [ 1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789, 1234567890 ].each{ |bytes| puts nice_bytes( bytes ) } #=> 1b #=> 12b #=> 123b #=> 1.21kB #=> 12.1kB #=> 121kB #=> 1.18MB #=> 11.8MB #=> 118MB #=> 1.15GB With the exception of bytes, I get two decimal places when there are less than 10 of the amount, one decimal place with less than a hundred, and no decimal places for hundreds. Windows does this, and I actually like it. Although unrelated to real significant figures, it''s similar: there are ~always 3 digits displayed. As the number grows in magnitude, I am less interested in the details of the exact decimals. When working with a large number of files all in the same rough range, this lets me automatically visually display them in a way that allows them to be compared and distinguished, without too much detail. *shrug* Not a big deal. As you say, most people will find the rails method suits their needs. BTW, here''s updated 1.9 compatible code for the function: K = 2.0**10 M = 2.0**20 G = 2.0**30 T = 2.0**40 def nice_bytes( bytes, max_digits=3 ) value, suffix, precision = case bytes when 0...K [ bytes, ''b'', 0 ] else value, suffix = case bytes when K...M then [ bytes / K, ''kB'' ] when M...G then [ bytes / M, ''MB'' ] when G...T then [ bytes / G, ''GB'' ] else [ bytes / T, ''TB'' ] end used_digits = case value when 0...10 then 1 when 10...100 then 2 when 100...1000 then 3 end leftover_digits = max_digits - used_digits [ value, suffix, leftover_digits > 0 ? leftover_digits : 0 ] end "%.#{precision}f#{suffix}" % value end -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Gavin Kistner wrote:> #=> 1b > #=> 12b > #=> 123b[...]> [ bytes, ''b'', 0 ]Ack! That''s twice now that I''ve pasted code in there with the incorrect lowercase ''b'' for bytes. Should be: [ bytes, ''B'', 0 ] and thus #=> 1B #=> 12B #=> 123B -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Bah. One, final, 1.9-compatible post that also handles the edge case of values in the range 1000...1024 of a value correctly. K = 2.0**10 M = 2.0**20 G = 2.0**30 T = 2.0**40 def nice_bytes( bytes, max_digits=3 ) value, suffix, precision = case bytes when 0...K [ bytes, ''b'', 0 ] else value, suffix = case bytes when K...M then [ bytes / K, ''kB'' ] when M...G then [ bytes / M, ''MB'' ] when G...T then [ bytes / G, ''GB'' ] else [ bytes / T, ''TB'' ] end used_digits = case value when 0...10 then 1 when 10...100 then 2 when 100...1024 then 3 end leftover_digits = max_digits - used_digits [ value, suffix, leftover_digits > 0 ? leftover_digits : 0 ] end "%.#{precision}f#{suffix}" % value end [ 1, 12, 123, 1022, 1024, 1234, 12345, 123456, 2**19.99, 2**20, 1234567, 12345678, 123456789, 1234567890 ].each{ |bytes| puts nice_bytes( bytes ) } #=> 1b #=> 12b #=> 123b #=> 1022b #=> 1.00kB #=> 1.21kB #=> 12.1kB #=> 121kB #=> 1017kB #=> 1.00MB #=> 1.18MB #=> 11.8MB #=> 118MB #=> 1.15GB -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Gavin Kistner wrote:> Bah. One, final, 1.9-compatible post that also handles the edge case of > values in the range 1000...1024 of a value correctly.Thanks for the effort! Why don''t you submit it to Rails so that they replace their version with yours? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---