How can I tell if x.to_i is really 0 (zero)? - ruby

"0".to_i == 0
also:
"abcdefg".to_i == 0
I want to make sure the string I'm parsing really is just a number (0 included).

Integer("0").zero? rescue false
# => true
Integer("1").zero? rescue false
# => false
Integer("abcdefg").zero? rescue false
# => false

def string_is_integer?(string)
!string.match(/^(\d)+$/).nil? # \d looks for digits
end
def string_is_float?(string)
!string.match(/^(\d)+\.(\d)+$/).nil?
end
def string_is_number?(string)
string_is_integer?(string) || string_is_float?(string)
end
Or, if you don't mind:
def string_is_number?(string)
begin
true if Float(string)
rescue ArgumentError
end || false
end

def is_zero?(string)
(Integer(string) rescue 1).zero?
end
is_zero? "0" #=> true
is_zero? "00000" #=> true
is_zero? "0cat" #=> false
is_zero? "1" #=> false
is_zero? "-0" #=> true
is_zero? "0_000" #=> true
is_zero? "0x00" #=> true
is_zero? "0b00000000" #=> true
Several of these examples illustrate why it's preferable to use Kernel#Integer rather than a regular expression.

First test if the string is integer or not and then match
def is_i?(x)
!!(x =~ /\A[-+]?[0-9]+\z/)
end
def is_zero?(x)
return is_i?(x) && x.to_i == 0
end
# is_zero?("0") will return true
# is_zero?("abcde") will return false
Or you can put these methods in String class like this
class String
def is_i?
!!(self =~ /\A[-+]?[0-9]+\z/)
end
def is_zero?
self.is_i? && self.to_i == 0
end
end
"0".is_zero? # true
"abcde".is_zero? # false

I want to make sure the string I'm parsing really is just a number.
There are two steps involved:
Parsing, i.e. converting the string into a number
Validation, i.e. checking if the string actually is a number
The built-in conversion functions like Integer and Float already perform both steps: they return a numeric result if the string is valid and raise an error otherwise.
Using these functions just for validation and discarding the return value is wasteful. Instead, use the return value and handle the exception, e.g.:
begin
puts 'Enter a number:'
number = Float(gets)
rescue
puts 'Not a valid number'
retry
end
# do something with number
or something like:
def parse_number(string)
Float(string) rescue nil
end
number = parse_number(some_string)
if number
# do something with number
else
# not a number
end

Related

creating my own Enumerable method my_none? for Ruby

I have created my own Enumerable method my_none?. It gives me lint error:
Convert if nested inside else to elsif.
Also two of the test cases are not working. Can anyone help me to resolve these issues?
module Enumerable
def my_each
i = 0
while i < size
yield self[i]
i += 1
end
end
def my_none?
my_each do |item|
if block_given?
return false if yield item
else
return false if item
end
end
true
end
end
%w{ant bear cat}.my_none? { |word| word.length == 5 } #=> true
%w{ant bear cat}.my_none? { |word| word.length >= 4 } #=> false
[].my_none? #=> true
[nil].my_none? #=> true
[nil, false].my_none? #=> true
[nil, false, true].my_none? #=> false
The below two test cases are not working:
%w{ant bear cat}.my_none?(/d/) #=> true > gives me wrong no of argument given 1 expected 0
[1, 3.14, 42].my_none?(Float) #=> false > gives me wrong number of argument
my_none? method, as you defined it, does not accept any arguments. It can only accept block.
I think you meant:
%w{ant bear cat}.my_none?{|e| e =~ /d/ }
[1, 3.14, 42].my_none?(&:to_f)
&:to_f is a way to create a Proc - see this question for more info.
To get rid of the lint errors you can change my_none? implementation to:
def my_none?
my_each do |item|
return false if block_given? && yield(item) || !block_given? && item
end
true
end

Determinate which method returns true in or operator

I have:
def user_validation
first_user_valid? || second_user_valid?
end
and I don't only want to return true/false but also want to return which method returns the true (maybe both?). I do have:
def user_validation
return true if first_user_valid?
return true if second_user_valid?
end
so far. But this does not seem very intuitive to me.
Thanks
You can return an array of responses:
def user_validation
[first_user_valid?, second_user_valid?]
end
This way you can know that the first returned true, and the other false...
# => [true, false]
If i were you, i change the return from boolean to int. Doing that, you can handle which statment returning specifics numbers for that.
Why not call the method itself separately for the different users?
def user_validation(user)
return user_valid?
end
if(user_validation(user_1))
//user_1 is valid
end
if(user_validation(user_2))
//user_2 is valid
end
Just out of curiosity:
result = %w|first_user_valid second_user_valid|.inject(nil) |memo, m|
(memo ||= []) << m.tr('_', ' ') if public_send("#{m}?")
memo
end
if result # at least one is valid
puts result.join ', '
else # none is valid
puts 'None is valid :('
end
Result here might be either nil (falsey), or the string like:
"first user valid, second user valid"
def user_validation
valid = ((which = :first) && first_user_valid?) ||
((which = :second) && second_user_valid?)
which = :neither unless valid
[valid, which]
end
To illustrate:
def first_user_valid?; true; end
def second_user_valid?; true; end
user_validation #=> [true, :first]
def first_user_valid?; false; end
user_validation #=> [true, :second]
def second_user_valid?; false; end
user_validation #=> [false, :neither]
In general, when using ||, you don't want to evaluate the second expression if the first evaluates true, as in some cases that may raise an exception (e.g. division by zero), have undesirable side effects (e.g., deleting a needed file) or initiate a lengthy calculation.

Ruby - return false unless a value is true in which case return the value

If a = false and b = 2 is there a concise way to accomplish this? Using just return a unless b returns 'nil' instead of '2'.
I have
def checkit
return a unless b
b
end
Will this statement call b twice?
A real life case for this is:
def current_user
#current_user ||= authenticate_user
end
def authenticate_user
head :unauthorized unless authenticate_from_cookie
end
def authenticate_from_cookie
.
if user && secure_compare(user.cookie, cookie)
return user
else
return nil
end
end
Try this:
( b == true ) ? a : false
where a is a value you need to return
I do not know why you have false stored in the variable a, so I omitted that. As I understand, you want to pass a value to the method checkit, which should return the value if its boolean value is true (which means everything except values nil and false), and otherwise return the value. In that case, just use this:
def checkit(value)
value || false
end
checkit(1) # => 1
checkit(false) # => false
checkit('value') # => "value"
checkit(nil) # => false

What is the best way to determine if a variable is a number in Ruby? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Test if string is a number in Ruby on Rails
Currently I have this (awful) code:
def is_num(num_given)
begin
num_given.to_i
worked = true
rescue
worked = false
ensure
return worked
end
end
Which I refactored to this:
def is_num(num_given)
num_given.to_i.is_a?(Numeric) rescue false
end
This still just doesn't feel right to me, is there a better way to do this?
Both of these implementations work fine for my purposes, I am just looking for some code euphoria.
something.is_a?(Numeric) is the way to go. Referring to your latter example, there's no need to call to_i on the input.
Note that something.is_a?(Numeric) will not work if you're looking to see if a string is a number...
Here's another solution. It's not very Ruby-like, but that's intentional (e.g., while is faster than str.chars.each in this case).
# is a character between 0 and 9? (based on C's isdigit())
def digit?(c)
o = c.ord
o >= 48 && o <= 57 # '0'.ord, '9'.ord
end
# is a string numeric (i.e., represented as an integer or decimal)?
def numeric?(str)
str = str.to_s unless str.is_a?(String)
l = str.length
i = 0
while i < l
c = str[i]
if c == '.' || c == '-'
i += 1
next
end
return false if !digit?(c)
i += 1
end
true
end
Here are the unit tests. Let me know if I missed a case. For other answerers, just change the subject block to your function.
if $0 == __FILE__
require 'minitest/autorun'
describe :digit? do
%w(- + : ? ! / \ ! # $ ^ & *).each do |c|
it "flunks #{c}" do
digit?(c).must_equal false
end
end
%w(0 1 2 3 4 5 6 7 8 9).each do |c|
it "passes #{c}" do
digit?(c).must_equal true
end
end
end
describe :numeric? do
subject { :numeric? }
%w(0 1 9 10 18 123.4567 -1234).each do |str|
it "passes #{str}" do
method(subject).call(str).must_equal true
end
end
%w(-asdf 123.zzz blah).each do |str|
it "flunks #{str}" do
method(subject).call(str).must_equal false
end
end
[-1.03, 123, 200_000].each do |num|
it "passes #{num}" do
method(subject).call(num).must_equal true
end
end
end
end
The functions you listed won't work:
is_num("a") #=> true
The problem is that they don't raise an error for invalid input. What you want is Integer, which will raise an error which you can rescue:
def is_num(num_given)
!!Integer(num_given) rescue false
end
This works:
irb(main):025:0> is_num("a")
=> false
irb(main):026:0> is_num(5)
=> true
irb(main):027:0> is_num((1..2))
=> false
irb(main):028:0> is_num("3")
=> true
(There may be a more natural way to do this, though.)
You can always use a simple regex:
def is_num(num_given)
num_given =~ /\d+(\.\d+)?/
end

How to check if a variable is a number or a string?

How to check if a variable is a number or a string in Ruby?
There are several ways:
>> 1.class #=> Fixnum
>> "foo".class #=> String
>> 1.is_a? Numeric #=> true
>> "foo".is_a? String #=> true
class Object
def is_number?
to_f.to_s == to_s || to_i.to_s == to_s
end
end
> 15.is_number?
=> true
> 15.0.is_number?
=> true
> '15'.is_number?
=> true
> '15.0'.is_number?
=> true
> 'String'.is_number?
=> false
var.is_a? String
var.is_a? Numeric
The finishing_moves gem includes a String#numeric? method to accomplish this very task. The approach is the same as installero's answer, just packaged up.
"1.2".numeric?
#=> true
"1.2e34".numeric?
#=> true
"1.2.3".numeric?
#=> false
"a".numeric?
#=> false
class Object
def numeric?
Float(self) != nil rescue false
end
end
Print its class, it will show you which type of variable is (e.g. String or Number).
e.g.:
puts varName.class
if chr.to_i != 0
puts "It is number, yep"
end

Resources