Ruby division infinity/NaN should return 0 - ruby

I am having an application on Ruby On Rails.
In application I want to override parent class of division in Ruby.
For handling below exceptions.
I Googled everywhere. I want to override ruby division method in application.
So that for below results it should return zero.
0.0 / 0
=> NaN
1.0 / 0
=> Infinity
ZeroDivisionError: divided by 0
I can handle it by changing code everywhere while divide operation. But I want to save my time by overriding the method itself.

You do not need a special method or to extend the float class as other answers state.
Ruby provides you a method on the Float class for this called .finite?
http://ruby-doc.org/core-1.9.3/Float.html#method-i-finite-3F
finite? → true or false
Returns true if flt is a valid IEEE floating point number (it is not infinite, and nan? is false).
if value.finite? == false
value = 0
else
value = value
end
The above example is a bit verbose.

Very similar to: How can I redefine Fixnum's + (plus) method in Ruby and keep original + functionality?
class Float
alias_method :old_div, :/
def /(y)
return NAN if self == y && y == 0.0
return INFINITY if self == 1.0 && y == 0.0
self.old_div(y)
end
end
I know the code above might not be what you exactly want. Feel free to customize it the way you want =)

Overriding the division of Fixnum, Decimal, etc. is possible, but might not be the best solution for you. You would need to override methods in several classes, and they might have some very nasty side-effects (remember - these methods are not called only from your code!!)
I would suggest you write some helper module, which will implement this new behavior, and that you would call it instead of /:
module WeirdMath
self.div(n1, n2)
result = n1 / n2
result.nan? || result.infinite? ? 0 : result
rescue
0
end
end
WeirdMath.div(0.0, 0) # => 0
WeirdMath.div(1.0, 0) # => 0
WeirdMath.div(3.0, 2) # => 1.5

Related

how to check if an argument is an integer and if not return nil

how would I write this in ruby " check if something is an integer, if not return nil. otherwise divide it by 2 and return the result. I
don't understand how to get it to check if it's not an integer and return nil. to write it in a function
def halve(x) x / 2 end
In Ruby, you can use instance_of? to check if the object is an instance of a given class and is_a? which returns true if the given class is the class of the object, or if the given class is one of the superclasses of the object.
In Ruby polymorphism or duck-typing is preferred, in this example, I would argue that one of those methods is a great choice too. IMHO is_a? is more idiomatic than instance_of? in Ruby but that depends on your specific use case.
def halve(x)
if x.is_a?(Integer)
x / 2.0
else
nil
end
end
Note that I change x / 2 to x / 2.0 because imagine x = 3 then x / 2 would return 1 but x / 2.0 will return 1.5. See the docs of Integer#/ for details.
def halve(x)
x.is_a?(Integer) ? x.fdiv(2) : nil
end
#is_a?(obj) returns true if the argument passed is the class of that object. You can also use #kind_of?(obj).
#fdiv(n) returns float. 1.fdiv(2) will return 0.5 (might be what you want) unlike 1 / 2 which returns 0.

Inject double ampersand operator

I have an inject call
[2,4,6].inject(true) { |res, val| res && val % 2 == 0 }
and want to send the && operator to inject as in inject(0, :+). How can I do that?
You can't because && and ||, unlike other operators, are not syntacic sugar for methods (i.e. there is no method called && or ||), so you can't reference them using a symbol.
However you can avoid using inject to compute the logical conjunction or disjunction of an array of boolean values, replacing it with all? or any? respectively, because for any array the following conditions hold:
ary.inject(true) { |res, b| res && b } == ary.all?
ary.inject(false) { |res, b| res || b } == ary.any?
So, for example, the code you posted could be rewritten as:
[2,4,6].map(&:even?).all?
# => true
Update: obviously my latter example is not the right way to express this computation, falsetru's answer is much faster:
require 'fruity'
compare(
-> { (0..1000).map(&:even?).all? },
-> { (0..1000).all?(&:even?) }
)
Running each test 1024 times. Test will take about 2 seconds.
Code 2 is faster than Code 1 by 111x ± 10.0
How about using Enumerable#all?
[2,4,6].all? &:even?
# => true
[2,4,6,5].all? &:even?
# => false
If you want to use inject, you need to define an instance method.
class Object
def is_even(val)
self && val % 2 == 0
end
end
[2,4,6].inject(true, :is_even) # => true
[1,2,4,6,5].inject(true, :is_even) # => false
'&&' is not a method, hence you can't inject it. However you can inject & method.
[2,4,6,5].map(&:even?).inject(true, :&)
Which will do the same
NOTE: This however should not be done, as it is extremely risky and might cause unexpected consequences (if run on collection containing at least one non-boolean (true, false, nil) value). You should always use any? or all? methods instead.
inject(0, :+) would add all the elements of the array, regardless of what the content of the elements are (odd, even, etc).
If you want to inject(true, &:&&) (I know this doesn't work), your array should be an array of boolean values for your question to make sense, which would be the same as: [true, false].all?
important:
you can't pass both block arg and actual block which means you can't check if it's even inject an && at the same time.
If you insist, try this out:
[2,4,6].inject(true, & lambda { |x,y| x && y })
=> 6
This is the equivalent of what you're asking for (which I still don't totally understand)

Ruby - modifying classes

I wrote simple method which checks if a number is Armstrong number.
But now I want to modify default Number class putting method.
So, I have code:
def is_an(number)
(number.to_s.split(//).map(&:to_i).inject{|x,y|x+y**(number.size-1)}) == number ? true : false
end
p is_an(153)
I want to use it as method: 153.is_a?
So, how I do this?
class Number
def is_an
??? How to use object data over here? ???
end
end
Thx a lot for reading.
Incorporating #mikej's answer, plus replacing number with self:
class Fixnum
def is_an
digits = self.to_s.split(//).map(&:to_i)
digits.inject(0) { |x,y| x+y**digits.size } == self
end
end
But I would suggest a name change, to make it more Ruby like. Instead of #is_an, which isn't very descriptive, how about #armstrong? then you can call:
153.armstrong?
Not an answer to your original question, but there are a couple of small bugs in your code. You need to pass 0 to the inject to use as an initial value. Otherwise, inject takes the first value from the list as the initial value. Your current code seems to work for 153 because 1^3 == 1 but it would return false for 370, for example, when it should return true.
Also, the size method on Fixnums doesn't return the number of digits in a number.
Finally, a minor point: the ? true : false isn't needed because the value of the ... == number expression is already the required boolean value. So a possible updated method would be:
def is_an(number)
digits = number.to_s.split(//).map(&:to_i)
digits.inject(0) { |x,y| x+y**digits.size } == number
end

A float subclass that can be evaluated to false (fuzzy logic) in Ruby

I need a class that can represent probabilities. It can be represented like a float between 0 and 1, and anything below 0.5 should evaluate to false. (or it can be between 1 and -1, anything negative is false)
p = A.probability()
puts p # will output 0.3
if(p)
puts 'success'
else
puts 'failure'
end
# will outputs 'failure'
From this post it seems to suggest it is possible: every object has a boolean value... Most objects in Ruby will have a boolean value of true. Only two objects have a boolean value of false. Just that I need to set this boolean value somehow. So is this possible?
I wanted to do something similar, but unfortunately this is not possible in Ruby.
The only two objects that have a boolean value of false are false itself and nil. A few weeks ago I had a an internet chat (IRC) discussion with Brixen, one of the main developers of rubinius, and he explained it pretty well. My understanding is that when Ruby decides whether an object is true or not, it does NOT call any methods on (i.e. send any messages to) the object, it simply looks at the pointer it has to the object to see whether the pointer itself is equal to false or nil. Since it doesn't call any methods on the object, there is no way for you to change the behavior.
The best you can do is something like this:
p = A.probability()
puts p # => 0.3
if p.to_bool
puts 'success'
else
puts 'failure'
end
There is no "cast to boolean" operator because, as David notes, falsiness is hard wired for false and nil and anything that isn't "falsy" is true. However, there is a logical negation operator so you can do it if you don't mind an explicit cast to boolean:
class P
attr_accessor :p
def !#
p < 0.5
end
end
And then:
>> p = P.new
>> p.p = 0.75
=> puts 'Pancakes!' if(!!p)
Pancakes!
>> p.p = 0.25
>> puts 'Pancakes!' if(!!p)
# No pancakes for you
All the double bangs might be a bit ugly but, on the upside, it might make people notice that something a little non-standard is going on.
First of all, you do not need a Float subclass. Those interested in subclassing Numeric types can see Katzuda's answer.
The simple way to achieve what you want to achieve is to simply use a method:
class P
def initialize p; #p = p
raise "outta range" unless 0 <= #p and #p <= 1 end
def success?; SUCC <= #p end
def fail?; not success? end
end
p = P.new 0.3
p.success? # => false
p.fail? # => true
q = P.new 0.7
q.success? # => true
q.fail? # => false
Remember, for these kind of circumstances, Ruby has methods.

Ruby round float to_int if whole number

In ruby, I want to convert a float to an int if it's a whole number. For example
a = 1.0
b = 2.5
a.to_int_if_whole # => 1
b.to_int_if_whole # => 2.5
Basically I'm trying to avoid displaying ".0" on any number that doesn't have a decimal. I'm looking for an elegant (or built-in) way to do
def to_int_if_whole(float)
(float % 1 == 0) ? float.to_i : float
end
One simple way to it would be:
class Float
def prettify
to_i == self ? to_i : self
end
end
That's because:
irb> 1.0 == 1
=> true
irb> 1 == 1.0
=> true
Then you could do:
irb> 1.0.prettify
=> 1
irb> 1.5.prettify
=> 1.5
A one liner sprintf...
sprintf("%g", 5.0)
=> "5"
sprintf("%g", 5.5)
=> "5.5"
This is the solution that ended up working the way I want it to:
class Float
alias_method(:original_to_s, :to_s) unless method_defined?(:original_to_s)
def is_whole?
self % 1 == 0
end
def to_s
self.is_whole? ? self.to_i.to_s : self.original_to_s
end
end
This way I can update the is_whole? logic (I seems like tadman's is the most sophisticated) if needed, and it ensures that anywhere a Float outputs to a string (eg, in a form) it appears the way I want it to (ie, no zeros on the end).
Thanks to everybody for your ideas - they really helped.
I'm don't know much about Ruby.
But this is a display issue. I would be extremely surprised if the libraries you are using don't have a way to format a number when you convert it to a string.
There might not be a catch-all formatting option that does exactly what you want but you could set up a method that returns true if the float is the float representation of a whole number and false otherwise. Inside a formatting routine that you create (so you only have to do this in once place) just change the formatting based on if this is true or false.
This discusses how to control the number of digits that appear after the decimal when displaying a number.
Watch out for the intricacies of floating point representations. Math might say the answer is 3 but you may get 3.000000000000000000001. I'd suggest using a delta to see if the number is almost an integer number.
If you are using rails you can use helper number_to_rounded with option strip_insignificant_zeros, for example:
ActiveSupport::NumberHelper.number_to_rounded(42.0, strip_insignificant_zeros: true)
or like this:
42.0.to_s(:rounded, strip_insignificant_zeros: true)
Although I'd tend to agree with the above post, if you must do this:
(float == float.floor) ? float.to_i : float
Here's my horribly hacktastic implementation provided for educational purposes:
class Float
def to_int_if_whole(precision = 2)
("%.#{precision}f" % self).split(/\./).last == '0' * precision and self.to_i or self
end
end
puts 1.0.to_int_if_whole # => 1
puts 2.5.to_int_if_whole # => 2.5
puts 1.9999999999999999999923.to_int_if_whole # => 2
The reason for using the sprintf-style call is that it handles floating point approximations much more reliably than the Float#round method tends to.
I don't know much about Ruby either.
But in C++, I'd do this:
bool IsWholeNumber( float f )
{
const float delta = 0.0001;
int i = (int) f;
return (f - (float)i) < delta;
}
And then I'd format the output precision based on that.

Resources