Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can ruby have a range starting with a Float?

Tags:

ruby

I'm a beginner in ruby, trying to use it to help me analyse biological data. I need to try and match a set of data (numbers in an array) to another with a certain specificity (e.g number+/- 0.25) I have come up with this (so far) to change one data set into ranges, instead of numbers:

def range(arr)
  c = []
  arr.each do |b|
    b = (b-0.25..b+0.25)
    b = b.to_a
    c << b
  end
  c = c.flatten
  return c
end

the code gives the desired array, however I always get

TypeError: can't iterate from Float.

how can I fix that?

Background

this is a sample of my practical data:

119.0456 119.0714 119.0721 119.0737 120.0772 130.0746 131.0737 136.0721 140.0951 143.0697 154.038 154.0744 154.1108 155.0949 156.054 169.053 170.1422 171.0646 171.0686 174.0644 174.0795 180.0539 182.1059

I need to match it to a theoretical set, which I need to generate withtin a tolerance of 0.002 I am working on the code step by step to generate my theoretical set, since I'm still new to coding, and just wanted to know how to create a range of +/- 0.002 around my theoretical set to match it to the practical one.

like image 505
Mokhtar Avatar asked May 19 '26 07:05

Mokhtar


1 Answers

Can ruby have a range starting with a Float?

Yes, you can create ranges with floats:

r = 0.25..0.75
#=> 0.25..0.75

But you can't use Range#each to traverse it, because each relies on succ (e.g. Integer#succ) and Float doesn't implement that method.

Instead, you can use Range#step with takes an explcit increment value:

r.step(0.1) { |f| puts f }

Output:

0.25
0.35
0.45
0.55
0.65
0.75

Just for fun, let's see what happens if we utilize Float#next_float:

class Float
  alias succ next_float
end

r = 0.25..0.75

r.each { |f| puts f }

Output:

0.25
0.25000000000000006
0.2500000000000001
0.25000000000000017
0.2500000000000002
0.2500000000000003
0.25000000000000033
0.2500000000000004
0.25000000000000044
0.2500000000000005
0.25000000000000056
0.2500000000000006
...

the code gives the desired array, however I always get

TypeError: can't iterate from Float.

how can I fix that

You could build an array of ranges instead:

def range(arr)
  arr.map { |b| b-0.25..b+0.25 }
end

range [1, 2, 3]
#=> [0.75..1.25, 1.75..2.25, 2.75..3.25]
like image 191
Stefan Avatar answered May 20 '26 22:05

Stefan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!