I have a exercise of the school and i can't resolve it. Can you help me?
The problem is this:
Try using a method that takes two arguments - use the between? method
to determine if the number 2 lies between the numbers 1 and 3.
I tried to find what is the .between? method but í couldn't find it.
I just know that is a method
The method is Comparable#between?, and you can use it like this:
2.between?(1, 3)
# => true
use between? is the easiest way, I found most answers here didn't mention (ruby doc explanation is hard to understand too), using between? does INCLUDE the min and max value.
for example:
irb(main):001:0> 2.between?(1, 3)
=> true
irb(main):002:0> 3.between?(1, 3)
=> true
irb(main):003:0> 1.between?(1, 3)
=> true
irb(main):004:0> 0.between?(1, 3)
=> false
by the way, ruby doc quote (too hard to understand for newbie):
between?(min, max) → true or false Returns false if obj <=> min is
less than zero or if anObject <=> max is greater than zero, true
otherwise.
From "between" ruby documentation:
between?(min, max) → true or false
Returns false if obj <=> min is less than zero or if anObject <=> max is greater than zero, true otherwise.
Uh oh, and of course, it's #=== method for ranges:
( 1..3 ) === 2 #=> true
( 1..3 ) === 4 #=> false
You can use Range#cover? as a solution :
(1..3).cover? 2 #=> true
Related
I was trying to be clever about deterministically picking random stuff, and found this:
irb(main):011:0> Random.new(Random.new(1).rand + 1).rand == Random.new(1).rand
=> true
irb(main):012:0> Random.new(Random.new(5).rand + 1).rand == Random.new(5).rand
=> false
irb(main):013:0> Random.new(Random.new(5).rand + 5).rand == Random.new(5).rand
=> true
For a second, I thought "wow, maybe that's a property of random number generators", but Python and C# fail to reproduce this.
You’re probably going to be disappointed with this one. Let’s take a look at the output of rand:
irb(main):001:0> Random.rand
0.5739704645347423
It’s a number in the range [0, 1). Random.new accepts an integer seed.
irb(main):002:0> Random.new(5.5) == Random.new(5)
true
Mystery solved!
I'm trying to express a condition like this:
if 33.75 < degree <= 56.25
# some code
end
But Ruby gives this error:
undefined method `<=' for true:TrueClass
I'm guessing that one way to do it is something like:
if 33.75 < degree and degree <= 56.25
# code
end
But there is no another, easier way?
Ruby also has between?:
if value.between?(lower, higher)
There are many ways of doing the same things in Ruby.
You can check if value is in the range by use of following methods,
14.between?(10,20) # true
(10..20).member?(14) # true
(10..20).include?(14) # true
But, I would suggest using between than member? or include?. You can find more about it here.
You can express a <= x <= b as (a..b).include? x and a <= x < b as (a...b).include? x.
>> (33.75..56.25).include? 33.9
=> true
>> (33.75..56.25).include? 56.25
=> true
>>
>> (33.75..56.25).include? 56.55
=> false
Unfortunately, there seems no such thing for a < x <= b, a < x < b, ..
UPDATE
You can accomplish using (-56.25...-33.75).include? -degree. But it's hard to read. So I recommend you to use 33.75 < degree and degree <= 56.25.
use between? is the easiest way, I found most answers here didn't mention (ruby doc explanation is hard to understand too), using between? does INCLUDE the min and max value.
for example:
irb(main):001:0> 2.between?(1, 3)
=> true
irb(main):002:0> 3.between?(1, 3)
=> true
irb(main):003:0> 1.between?(1, 3)
=> true
irb(main):004:0> 0.between?(1, 3)
=> false
by the way, ruby doc quote:
between?(min, max) → true or false Returns false if obj <=> min is
less than zero or if anObject <=> max is greater than zero, true
otherwise.
undefined method `<=' for true:TrueClass
means that Ruby is not parsing your if-condition the way you expect it.
Using && and adding parentheses helps!
if (33.75<degree) && (degree<=56.25)
...
end
It's a bad habit to leave out parentheses -- as soon as the expression gets more difficult, you could get a surprising outcome. I've seen this many times in other people's code.
Using and instead of && in Ruby is a very bad idea, see:
https://www.tinfoilsecurity.com/blog/ruby-demystified-and-vs
http://rubyinrails.com/2014/01/30/difference-between-and-and-in-ruby/
You can also use this notation:
(1..5) === 3 # => true
(1..5) === 6 # => false
Adjust value to range?
value = 99
[[value,0].max, 5].min # 5
value = -99
[[value,0].max, 5].min # 0
value = 3
[[value,0].max, 5].min # 3
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does !! mean in ruby?
I'm learning ruby/rails and found a tutorial with the following code example:
def role?(role)
return !!self.roles.find_by_name(role.to_s.camelize)
end
I don't have any idea for what the !! do, neither the !!self do.
I really googled about that, but doesn't find anything.
Can anyone give a short explanation? Thanks in advance.
It's the "not" operator (!) repeated twice, so that it's argument will be coerced to its negated boolean and then its corresponding boolean. Basically, it's a way to coerce any object into its boolean value.
!!false # => false
!!nil # => false
!!true # => true
!!{} # => true
!![] # => true
!!1 # => true
!!0 # => true (Surprised? Only 'false' and 'nil' are false in Ruby!)
It's usually employed to force-cast an arbitrary value into one of true or false.
This is often useful for converting between arbitrary numbers, strings, or potential nil values.
In your example this is extremely inefficient since an entire model is loaded only to be discarded. It would be better written as:
def role?(role)
self.roles.count_by_name(role.to_s.camelize) > 0
end
That query will return a singular value that is used for comparison purposes, the result of which is automatically a boolean.
This confirms that the operation will always return the boolena value
!!1 #gives you true
!!nil #gives you false
In ruby nil, false is consider as false and 0, 0.0 and other objects are consider as true
With Ranges in Ruby you can do 0..5 to include all numbers between and including 0 and 5. You can also do 0...5 to include the same numbers except 5 is not included.
(1..5) === 5
=> true
(1...5) === 5
=> false
(1...5) === 4.999999
=> true
Is there a way to exclude the first number instead of the last to get a result like this?
(1...5) === 1
=> false
(1...5) === 1.00000001
=> true
No, there is no built-in support for such a range. You might want to roll your own Range-like class if this behavior is necessary.
Not natively with a Range. You can mess with its mind but you're better off using an incremented first value. This is ugly but:
[(1..5).to_s].map{ |s| a,b=s.split('..').map{|i| i.to_i}; (1+a .. b) } #=> [2..5]
or
Range.new(*[(1..5).to_s].map{ |s| a,b=s.split('..').map{|i| i.to_i}; [1+a,b] }.flatten) #=> 2..5
or
irb(main):004:0> asdf = (1..5)
=> 1..5
irb(main):005:0> Range.new(asdf.min.succ, asdf.max)
=> 2..5
None seem overly elegant.
Besides just sending first_arg.succ instead of first_arg? No, there is no special support for this.
You could monkey patch Range to add a method to behave the way you want. Ex:
class Range
def exclusive()
Range.new(self.first+1, self.last-1)
end
end
(1..5).exclusive === 5
==>false
(1..5) === 5
==>true
Beware of monkeypatching though, as it changes the functionality of existing classes. There is probably a better way to do it in this case, but given the question, this is an acceptable answer.
How can I get the opposite of a boolean in Ruby (I know that it is converted to 0/1) using a method inline?
say I have the given instance:
class Vote
def return_opposite
self.value
end
end
Which obviously doesn't do anything, but I can't seem to find a method that is simple and short something like opposite() or the like. Does something like this exist and I'm just not looking at the right place in the docs? If one doesn't exist is there a really short ternary that would toggle it from 1 => 0 or 0 => 1?
I like to use this
#object.boolean = !#object.boolean
Boolean expressions are not 0 or 1 in Ruby, actually, 0 is not false
If n is numeric we are swapping 0 and 1...
n == 0 ? 1 : 0 # or...
1 - n # or...
[1, 0][n] # or maybe [1, 0][n & 1] # or...
class Integer; def oh_1; self==0 ? 1:0; end; end; p [12.oh_1, 0.oh_1, 1.oh_1] # or...
n.succ % 2 # or...
n ^= 1
If b already makes sense as a Ruby true or false conditional, it's going to be hard to beat:
!b
These examples differ in how they treat out-of-range input...
You can use XOR operator (exclusive or)
a = true
a # => true
a ^= true
a # => false
a ^= true
a # => true
Edit: See comment by #philomory below.
I believe this is basically an oversight in the boolean classes (TrueClass and FalseClass) in Ruby.
You can negate any object:
nil.! => true
false.! => true
true.! => false
0.! => false
1.! => false
a.! => false (all other objects)
But you cannot in-place negate the boolean objects:
a.!! => does not compile
I guess this would call for trouble with the compiler's grammar.
The best you can do, is thus:
a = a.!
If you just want to access the opposite of the value, use ! as some people have said in the comments. If you want to actually change the value, that would be bool_value = !bool_value. Unless I've misunderstood your question. Which is quite possible.
In order to toggle a boolean data in rails you can do this vote.toggle!(:boolean)
If you want to toggle boolean (that is false and true) , that would be as simple as just use ! as others has stated.
If you want to toggle between 0 and 1 , I can only think of something naive as below :)
def opposite
op = {0=>1,1=>0}
op[self.value]
end
In a Rails app, I use this method to toggle a post between paused and active, so ! (not) is my preferred method.
def toggle
#post = Post.find(params[:id])
#post.update_attributes paused: !#post.paused?
msg = #post.paused? ? 'The post is now paused.' : 'The post is now active.'
redirect_to :back, notice: msg
end
I think that using a ternary can be interesting :
check = false
check == true ? check = false : check = true