I kept getting the following error. After some research I assumed this is because my array access was throwing the error due to (mistakenly) having a NIL value.
my_solution.rb:24:in `count_between': undefined method `>=' for nil:NilClass
(NoMethodError) from my_solution.rb:35:in `<main>'
I'm new to reading error codes, so perhaps that's where I went wrong. But it got tunnel vision on line 24, as the error suggested. However I couldn't fix it, so out of desperation I wound up randomly changing the (<=) on line 23 to just (<). This fixed it.
Why did this fix it? My only guess is that originally using (<=) made it iterate "too far" and thus somehow returned NIL?
Why did the error code say it was the element on line 24 causing the issue, when it was actually the element on line 23? I'm new and am trying to be less intimated by error codes, so this was a curious experience.
Thanks for any guidance.
# count_between is a method with three arguments:
# 1. An array of integers
# 2. An integer lower bound
# 3. An integer upper bound
#
# It returns the number of integers in the array between the lower and upper
# bounds,
# including (potentially) those bounds.
#
# If +array+ is empty the method should return 0
# Your Solution Below:
def count_between(list_of_integers, lower_bound, upper_bound)
if list_of_integers.empty?
return 0
else
count = 0
index = 0
##line 23##
while index <= list_of_integers.length
##line24##
if list_of_integers[index] >= lower_bound &&
list_of_integers[index] <= upper_bound
count += 1
index += 1
else
index += 1
end
end
return count
end
end
puts count_between([1,2,3], 0, 100)
The last index that's <= list_of_integers.length is outside of the array, since the first index of an array is 0 and the last is array.length - 1.
The reason your error says line 24 is that line 23 works fine --- it just computes that the value of index is less than or equal to the the length of the array. Once you try and reference the element at that index in the array, however, it's assigned nil - and you can't perform a >= operation on nil.
One thing that might be helpful here is firing up an irb. If you try to reference an element that's out of bounds, you'll just get nil. If you try and perform an operation (that's not listed in nil.methods) on that same reference, it'll throw the error you're seeing.
Related
I have a method called fibs_rec that results in an unexpected output:
def fibs_rec(n)
if n == 1 || n == 0
return 1
else
a = fibs_rec(n-1) + fibs_rec(n-2)
puts a
return a
end
end
fibs_rec(5)
The call fibs_rec(5) should return 1,1,2,3,5 but here is the actual output:
2
3
2
5
2
3
8
Not only is the output incorrect, it lacks a number from the beginning.
Can someone explain why is this happening?
This is correct since your recursion is splitting into two sub-problems every time it recurses. If you want the series to appear properly then you should try doing this via dynamic programming for O(n) time complexity. As is, the first and second position won’t be printed because of the base case in the recursion.
As for the incorrect answer, it seems you have not accounted for the sequence starting with 0 index. Either find 4 index in the function which will give the fifth element or modify your function to work with position instead of index.
I'm new to ruby and I'm wondering why this error comes up. (Sorry for bad formatting)
Error:
rb37: in '%': nil can't be coerced into Fixnum (TypeError)
And also I need help with my question. I'm suppose to come up with a method to run through a list of 1 million ID numbers to find a specific ID using the most efficient way possible (in less than 5min). I've been at this the whole afternoon :(
def exist?(id)
dump = []
employee_list = $employee_list.sort #employee_list is an array of 1 million lines of data, I have to look for a specific "id"
while dump.length < id
dump << employee_list.first
if dump.last != id
if id%dump.last != 0 && dump.last != 1
employee_list.delete_if { |n| n%dump.last == 0 }
#what im doing here is to delete ID from employee_list that are multiples of n
elsif id%dump.last == 0
employee_list.delete_if { |m| m%dump.last == 0 && m!=id }
#deleting multiples of m (excluding id itself)
end
elsif dump.last == id
return true
end
end
return false
end
I honestly have absolutely no idea what your code is trying to do, but here's the problem: you loop until the length of your dump array is greater than the id you are searching. In the loop, you append the first element of the employee_list array to the end of dump. You also delete stuff from employee_list.
Now, depending on how large id is, you are going to loop very often. E.g. imagine id is, say, 1234567890, you are going to loop over a billion times, and you are appending over a billion elements to your dump array. At the same time, you are also constantly deleting stuff from employee_list. It is very likely, that at some point in time, employee_list will become empty, which means that employee_list.first will become nil, you will append nil as the last element of dump, and thus you will try to take the modulus of id and nil in line 9, 10, 12, or 13.
Like I said, I don't actually understand what you are doing at all, so I can't tell you how to fix the problem.
Here's how I would solve the problem:
def exist?(id)
$employee_list.find(id)
end
I am testing whether array elements are greater than or equal to elements of smaller indices.
I get the error message from the subject line if I use the following loop
return true if order.each_index {|i| order[i ] <= order[i+1]}
I understand the last element of my array(order) can't be compared to a non-existant element.
Comparing a value to nil is impossible.
I don't, however understand why the following loop doesn't return the same error
(0...(order.length - 1)).all? do |i|
order[i] <= order[i + 1]
end
It seems that at some point, i = order.length-1
This means order[i+1] is a nil value (order.length)
Apparently not?
No, because three dots ... here (0...(order.length - 1)) mean 'without last element', so last value would be order.length - 2.
You'll encounter the same error if you try (0..(order.length - 1)).
Check Range documentation:
Ranges may be constructed using the s..e and s...e literals
Those created using ... exclude the end value
def large_prime(n)
return [] if n==1
factor = (2..n).find {|x| n % x == 0}
[factor] + large_prime(n/factor)
end
I got this solution from somewhere else. I don't understand the 4th line of code where large_prime is called recursively and appended onto factor.
When I change the first line "return []" and leave out the '[]' after the return, I get an error message for on line 4, that says '+':no implicit conversion of nil into Array.
So why does this code work? Thanks
P.S. I'm obviously a noob and everything is very new to me.
The 3rd line finds the first divisor of n between 2 and n. This line itself does not involve recursion.
I don't really get the code you modified, but it seems to return nil in some case, while the original method always return an Array.
You must return an empty array when passed 1 to terminate the recursion. Any positive argument other than one will result in another call to large_prime, but an argument of 1 results in large_prime simply returning an empty array.
At each level of recursion, the program adds an array with the single factor it found to an array consisting of all factors found for the value n/factor. When the last factor (other than 1) is found, the final call to large_prime is made with an argument of 1, large_prime returns an empty array which is then added to the array containing the last factor, giving an array containing just the last factor. This array is then returned and you have
[next-to-last-factor] + [last-factor], giving a return array of [next-to-last-factor, last-factor] which is added to [next-to-next-to-last-factor] giving [next-to-next-to-last-factor, next-to-last-factor, last-factor]. This is then added to an array [next-to-next-to-next-to-last-factor], giving... lather, rinse, repeat until we reach the largest factor and add it in.
You must return an empty array because you can't add nil to an array in Ruby.
This iteration prints the highest index value.
It works and prints 8 eight times.
- #videos.each_with_index do |video, index|
= index.size
When I add a math operator it doesn't work and gives me this error: wrong number of arguments (1 for 0)
- #videos.each_with_index do |video, index|
= index.size - 1
index in your example is a Fixnum, the index of the element in the enumeration. Fixnum#size returns the number of bytes in the machine representation of a Fixnum. Probably not what you were looking for. It accepts zero arguments which explains the exception you got.
The fact that index.size returns 8 is because you're running on a 64bit architecture and has nothing to do with the size of #videos.
It seems like:
index.size - 1
is being interpreted as:
index.size(-1)
Try adding in parenthesis to force it to be interpreted in the correct way:
(index.size) - 1
or:
index.size() - 1