I’m working on Bubble Sort with the proc added and I can’t seem to find the gap in my logic. This is my second version where I now have a sorted? helper method which I think makes it cleaner, but I’m now worried that’s where my possible logic gap is hiding. I think I’m struggling with allowing the sorted? method to pass both an ascending and descending array. I tried to mitigate the issue by separating the while loop into two loops in the helper method but that might be superfluous.

When I run the rspec in terminal it doesn’t pass the last 3 tests, and only passes the first two as a result of the first line of code in bubble_sort!, so I think it’s definitely a larger logic problem that I’m missing.

def sorted?(arr)

i = 0

if arr[0] > arr[1]

while i < arr.length - 1

return false if arr[i] < arr[i+1]

i += 1

end

else

while i < arr.length - 1

return false if arr[i] > arr[i+1]

i += 1

end

end

true

end

def bubble_sort!(&prc)

return self if self.length <= 1

while sorted?(self) == false

self.each do |idx|

if block_given?

if prc.call(self[idx], self[idx + 1]) == 1

self[idx],self[idx+1] = self[idx+1],self[idx]

end

else

if self[idx] > self[idx + 1]

self[idx],self[idx+1] = self[idx+1],self[idx]

end

end

end

end

self

end

def bubble_sort(&prc)

self.dup.bubble_sort!(&prc)

end

Thanks for any help or advice!

Hi Ellen,

One of the things that will be helpful along the way is really getting into the error messages in the tests- they’ll steer you in the right direction!

I just copied your code over and ran the tests to see what’s going on.

It gives us a few errors, notably, `undefined method '>' for nil:NilClass`

and `comparison of Integer with nil failed`

. These are both referring to the line `if self[idx] > self[idx + 1]`

. Essentially, the first time, nil is in the first spot, the second time nil is in the second spot. You’ll want to rethink some parts of your code to prevent that from happening so that you’re only comparing the integers in the array.

I would suggest wrtiting the code to work without a block first and then we can refactor it to work with a block.

The other major thing to think about is in your sorted method, you have the same while loop written twice. Can you find a spot to put it so that you only have to write it once? It will make your code much easier to read. Once you have your code working without a block, you may be able to refactor your sorted method too!

Let me know how it goes!

Thank you so much for your help! I created a bubble_sort that doesn’t take a block and it works, and I refactored my sorted? method using that working bubble sort. I then went back to try to reconvert it to use a block and am now only running into one error: Failure/Error: num2**2 <=> num1**2

NoMethodError:

undefined method `**’ for nil:NilClass**

I believe this is a result of the block, when I tried to research what it means similar errors seemed to have to do with declaring variables and using syntactic sugar (=+). I’m not sure where it actually needs the code to be fixed since the '’ method isn’t in my code. Although it seems similar to the previous error you mentioned where nil was being compared to an Integer except I believe I fixed that by using .each_index in place of the .each method.

Here is my bubble sort without block:

def sorted?(arr)

i = 0

while i < arr.length - 1

if arr[0] > arr[1]

return false if arr[i] < arr[i+1]

i += 1

else

return false if arr[i] > arr[i+1]

i += 1

end

end

true

end

def bubble_sort!(arr)

return arr if arr.length <= 1

while sorted?(arr) == false

arr.each_index do |idx|

if (arr[idx] <=> arr[idx + 1]) == 1

arr[idx],arr[idx+1] = arr[idx+1],arr[idx]

end

end

end

arr

end

Here is my slightly changes block version:

def bubble_sort!(&prc)

return self if self.length <= 1

while sorted?(self) == false

self.each_index do |idx|

if block_given?

if prc.call(self[idx], self[idx + 1]) == 1

self[idx],self[idx+1] = self[idx+1],self[idx]

end

else

if (self[idx] <=> self[idx + 1]) == 1

self[idx],self[idx+1] = self[idx+1],self[idx]

end

end

end

end

self

end

Thank you again!!

num2 and num1 are the variables in the block tests and if one of them is nil, it might be leading to the invalid comparison. It;s probably num2, since it’s before the method `<=>`

. Are you passing integers in every time? If you haven’t used byebug yet, this is a great time to try it out!

Just type `require "byebug"`

at the top of your ruby file. Then type `byebug`

in the definition you want to debug.

When we run the rspec, it will enter debugging mode when it comes across the byebug in your code.

You can type `s`

or `step`

to move to the next line, `n`

or `next`

to move to the next block of code, and `c`

or `continue`

to skip to the next byebug.

You can type in the name of any variable to see what it is at that moment and type `display #{variable_name}`

to see a running update.

Thank so much! Byebug was very helpful, every time I reached the end of my do loop I’d compare the last element to a non-existent nil one at idx+1. The nil error makes so much more sense now, thanks again for your help!

1 Like