halogenandtoast / alchemist Goto Github PK
View Code? Open in Web Editor NEWA scientific conversion library.
A scientific conversion library.
In my code I have usecases like this:
walk_data[:distance] = "2"
walk_data[:distance].to_f.meters.to.feet.to_f
This does not look good at all, maybe we can add functionality that provides automatic string conversion to measurment values? If yes, I will look at the code and try to write implementation for that.
Cheers
test.rb:17:in
'+': coerce must return [x, y] (TypeError) from test.rb:17:in
block in
from test.rb:16:ineach' from test.rb:16:in
find'
from test.rb:16:in `'
totalRAM = 0
hosts = cluster.host.grep(RbVmomi::VIM::HostSystem).find do |host|
totalRAM += host.hardware.memorySize.bytes.to.gigabytes
end
puts "Total RAM (GB): ", totalRAM
Hi!
Maybe I'm missing something, but I get this weird conversion:
2.0.0p247 :014 > 1.kg.to.kg
=> #<Alchemist::Measurement:0x007fbe66c34d68 @value=1000.0, @unit_name=:g, @exponent=1000.0>
2.0.0p247 :015 > 1.kg.to.kg.to_i
=> 1000
I'm getting a no method error when trying to register new units
irb(main):005:0> Alchemist.register(:volume, [:dash, :dashs], 0.125.teaspoons)
NoMethodError: undefined method `register' for Alchemist:Module
from (irb):5
from /usr/local/var/rbenv/versions/2.0.0-p247/bin/irb:12:in `<main>'
As of version 1.6, methods like #round, #floor, #ceil no longer work on converted numbers.
e.g. 10.4.celsius.round
NoMethodError: undefined method `round' for 10.4:Alchemist::Measurement
The specific use case I'm thinking of is averaging. There are simple ways around it, but it might be useful to support this way:
Say you have some input of mixed unit
total = 0.celsius + 32.fahrenheit
If you try to divide by the count:
total / 2
You get NoMethodError: undefined method
unit_name' for 2:Fixnum
from lib/alchemist/measurement.rb:93:in ensure_shared_type!'
If you think it makes sense to support this, I'm happy to look into and doing a pull request.
Example:
5.meter + 2.inches returns 7.meters.
I think either the second operand should be converted to the units of the first, or an exception should be raised.
I'm having a problem with Rails recognizing Alchemist in production on my linode. In development locally everything works smoothly. Even in production locally it works great. I've detailed the problem on Stack Overflow here:
I'm on ruby 1.9.2 and rails 3.2.2
http://stackoverflow.com/questions/10852936/ruby-conversion-gem-errors-with-production-on-rails
Love the look of this gem...
But when I do the following:
(1.foot + 1.foot).to.inches
i get this result:
24.000000000000004
is this as expected? units confuse the *** out of me
thanks
Hi, please excuse me, but I'm having issues performing byte conversion.
Your README.md states:
1.kb.to.b.to_f == 1024.0
This evaluates to false for me:
irb(main):010:0> 1.kb.to.b.to_f
=> 999.9999999999999
1000.meters.to.kilometers is returning 1000. it should be 1
Tested with Ruby 2.0.0p451 and Ruby 2.1.1p76
Alchemist.reset! also does not work, although other class methods do (.setup, .measure).
irb(main):001:0> require 'alchemist'
=> true
irb(main):002:0> Alchemist.register
NoMethodError: undefined method `register' for Alchemist:Module
from (irb):2
from /home/jph/.rbenv/versions/2.0.0-p451/bin/irb:12:in `<main>'
irb(main):003:0> Alchemist.reset!
NoMethodError: undefined method `reset!' for Alchemist:Module
from (irb):3
from /home/jph/.rbenv/versions/2.0.0-p451/bin/irb:12:in `<main>'
I keep wanting to put more and more into Library, this probably means there are some classes that could be extracted.
10.kilometers + 1.mile produces an incorrect measurement.
It is: http://github.com/toastyapps/alchemist
It should be: https://github.com/halogenandtoast/alchemist
Right now, alchemist provides very basic to_s
methods. In the case of a simple measurement, they simply convert the float version of the measurement to a string:
irb(main):003:0> 1.meter.to_s
=> "1.0"
irb(main):004:0> 3.seconds.to_s
=> "3.0"
In the case of compound measurements, they don't even do that much:
irb(main):005:0> 2.meters.per.second.to_s
=> "#<Alchemist::CompoundMeasurement:0x007ff3c18e9060>"
irb(main):006:0>
It'd be awesome if it printed nice strings for these:
=> 1.meter.to_s
"1 meter"
=> 3.seconds.to_s
"3 seconds"
=> 1.s.to_s
"1 second"
=> 30.miles.per.hour
"30 miles/hour"
The way alchemist utilizes method_missing
seems to result in a fairly significant performance hit when numbers are used in certain ways. The problems can crop up even when you're not intending to use alchemist, so this can be quite unexpected. For example, time parsing can become 10x slower just by having alchemist installed.
Without alchemist, parsing 100,000 time strings takes 3.7 seconds
irb(main):001:0> require "time"; require "benchmark"
=> true
irb(main):002:0> puts Benchmark.measure { 100000.times { Time.parse("2012-01-01 01:01:01") } }
3.740000 0.010000 3.750000 ( 3.738171)
With alchemist, parsing 100,000 time strings takes 43 seconds
irb(main):001:0> require "time"; require "benchmark"; require "alchemist"
=> true
irb(main):002:0> puts Benchmark.measure { 100000.times { Time.parse("2012-01-01 01:01:01") } }
42.890000 0.430000 43.320000 ( 43.322304)
This seems to largely stem from something in Time.parse calling to_str
on a bunch of numeric objects. This method doesn't exist, but with alchemist's method_missing
implementation, each to_str
call incurs more of an overhead.
I didn't do further debugging to see if there are similar performance consequences outside of this time parsing example, but it seems like a possibility. After removing alchemist from our app, we saw pretty significant speed increases throughout the computationally heavy parts of our app (Rails requests that were taking 30 seconds to process now take 5 seconds).
I'm unsure of any simple fixes given the current dependency on method_missing
. But I saw you recently started a rewrite branch, so maybe this is something to consider as you rewrite? Sorry I don't have any fixes, but I wanted to file this as an FYI, since anyone dealing with lots of data might be having similar performance problems in their apps without even realizing it.
If anyone's interested, we ended up switching to m9t for our conversions. It isn't quite as syntactically elegant as alchemist, but it doesn't interfere and slow down unrelated aspects of our application, and it also seems to be the fastest conversion library I could find.
Seems that hz.to returns FLOAT Object only. Not sure why (I'm new to ruby) or else I'd help with my own code.
Thanks for the cool library!
Using version 0.1.7
require 'alchemist'
Alchemist.setup
21358.meters.to.kilometers
=> 21358.0
Sometimes to convert a unit to another one you need a third value. What I have in mind is CSS units. For example, if you want to convert inch
to em
you need to provide the relevant font size. I don't have any other use case in mind, but surely there are.
Do you have in mind to allow relative units in alchemist? I have taken a quick look at how your library works, and maybe for relative units something like that could be implemented:
Alchemist.register :distance, [:em] do |value, relevant_font_size|
value/relevant_font_size
end
3.inches.to.em.relative_to(12.inch)
What do you think about it? Would you accept a pull request with it? (I'm not sure I would do it, I'm looking at others gems, too, and I haven't decided yet which one to use)
Thanks a lot. This gems seems really easy to use.
Shouldn't this be miles to meters?
miles = 8 * 1609.344 # converting meters to miles
8.meters.to.miles
Hey There.
Love the Alchemist gem so far.
We're going to be using it as a platform for converting different rates, for example:
Cubic Feet / Minute ---- to ----> Cubic Meters / Hour
Can you suggest a good way to get started.
Many Thanks!
Josh
Haven't looked too closely at this yet, but the tests are failing in Ruby 1.9:
test_temperature(AlchemistTest):
ArgumentError: comparison of Float with Alchemist::NumericConversion failed
/Users/johnduff/development/workspace/alchemist/test/alchemist_test.rb:77:in `test_temperature
I also noticed that in Ruby 1.9 instead of getting:
>> 5.grams
=> #<Alchemist::NumericConversion:0x101227188 @exponent=1.0, @unit_name=:grams, @value=5.0> #ruby 1.8 output
You get:
>> 5.grams
=> 5.0 # ruby 1.9 output
Some things I noticed while working with this gem
>> 22.5.celsius.to.fahrenheit
=> 72.4999999999999
>> 22.5.celsius.to.fahrenheit.round
=> 72 # expected be 73
I believe this is equivalent to:
>> (22.5+273.15)*(9.0/5.0)-459.67
=> 72.4999999999999
However, if the conversion is structured slightly different the floating point anomaly disappears:
>> ((22.5+273.15)-273.15)*(9.0/5.0)+32.0
=> 72.5
This floating point anomaly is not present in larger values
>> 222.5.celsius.to.fahrenheit
=> 432.5
Here are some other examples
>> 72.fahrenheit.to.celsius.to_f.celsius.to.fahrenheit
=> 72.0000000000001
>> 1.fahrenheit.to.celsius.to_f.celsius.to.fahrenheit
=> 1.00000000000006
>> 45.0.celsius.to.fahrenheit.to_f
=> 113.0
>> 45.0.celsius.to.fahrenheit.to_f.truncate
=> 112
I think this would work...
:fahrenheit => [Proc.new{ |t| (t - 32.0) * (5.0/9.0) + 273.15}, Proc.new{ |t| (t - 273.15) * (9.0/5.0) + 32.0 }]
Hello! I added an initializer to my rails app (config/initializers/alchemist.rb
) with the following:
Alchemist.setup('distance')
I'm using alchemist (0.1.5)
undefined method `setup' for Alchemist:Module (NoMethodError)
/Users/mvazquez/work/Jiff3/config/initializers/alchemist.rb:1:in `<top (required)>'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:245:in `load'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:245:in `block in load'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:236:in `load_dependency'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:245:in `load'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/railties-3.2.13/lib/rails/engine.rb:588:in `block (2 levels) in <class:Engine>'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/railties-3.2.13/lib/rails/engine.rb:587:in `each'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/railties-3.2.13/lib/rails/engine.rb:587:in `block in <class:Engine>'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/railties-3.2.13/lib/rails/initializable.rb:30:in `instance_exec'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/railties-3.2.13/lib/rails/initializable.rb:30:in `run'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/railties-3.2.13/lib/rails/initializable.rb:55:in `block in run_initializers'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/railties-3.2.13/lib/rails/initializable.rb:54:in `each'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/railties-3.2.13/lib/rails/initializable.rb:54:in `run_initializers'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/railties-3.2.13/lib/rails/application.rb:136:in `initialize!'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/railties-3.2.13/lib/rails/railtie/configurable.rb:30:in `method_missing'
/Users/mvazquez/work/Jiff3/config/environment.rb:11:in `<top (required)>'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:251:in `require'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:251:in `block in require'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:236:in `load_dependency'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:251:in `require'
/Users/mvazquez/work/Jiff3/spec/spec_helper.rb:10:in `block in <top (required)>'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/spork-1.0.0rc3/lib/spork.rb:24:in `prefork'
/Users/mvazquez/work/Jiff3/spec/spec_helper.rb:3:in `<top (required)>'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:245:in `load'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:245:in `block in load'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:236:in `load_dependency'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:245:in `load'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/spork-1.0.0rc3/lib/spork/test_framework.rb:138:in `block (2 levels) in preload'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/spork-rails-3.2.1/lib/spork/app_framework/rails.rb:8:in `preload'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/spork-1.0.0rc3/lib/spork/test_framework.rb:134:in `block in preload'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/spork-1.0.0rc3/lib/spork.rb:62:in `exec_prefork'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/spork-1.0.0rc3/lib/spork/test_framework.rb:120:in `preload'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/spork-1.0.0rc3/lib/spork/run_strategy/forking.rb:25:in `preload'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/spork-1.0.0rc3/lib/spork/runner.rb:74:in `run'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/spork-1.0.0rc3/lib/spork/runner.rb:10:in `run'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/gems/spork-1.0.0rc3/bin/spork:10:in `<top (required)>'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/bin/spork:19:in `load'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/bin/spork:19:in `<main>'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/bin/ruby_noexec_wrapper:14:in `eval'
/Users/mvazquez/.rvm/gems/ruby-1.9.3-p392@jiff-jiff3/bin/ruby_noexec_wrapper:14:in `<main>'
Thanks!
I'm not sure I understand why anyone would want this kind of behavior:
height = 69.in
height #=> 69.0
height + 1 #=> 70.0
height #=> 70.0
height - 1 #=> 69.0
height #=> 69.0
height * 2 #=> 138.0
height #=> 138.0
height / 2 #=> 69.0
height #=> 69.0
Why are the +
, -
, *
, and /
operators acting like their +=
, -=
, *=
, and /=
counterparts?
I discovered this while I was trying to write a method that takes a height, like 69.in
, and displays it as 5'9"
. Seemed like a straightforward problem:
def display_height(height)
"#{height.to_i/12}'#{height.to_i%12}\""
end
Except that the height variable keeps changing on me. So it looks like the only way around it right now is to set height = height.value.to_i
, which will give me good ol' Fixnum
back instead of an Alchemist::NumericConversion
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.