# Methods Exercises - Expert Solution

UPDATED: originally had a question regarding running code in Atom, but was making a simple save error. Now have a question on expert problem.

Hi there Dillon! Would you mind posting a screenshot of the error youâ€™re getting when you run bundle exec rspec ? That would probably help me (or, realistically, someone way more qualified than me ) diagnose whatâ€™s going on.

careless error with saving by me, thanks for the response though @paolospeirn Paolo! I tried to remove the post but doesnâ€™t look like I can, so I suppose Iâ€™ll change it to ask another question. On the last problem (the expert one), I solved it a different way at first:

def int_remainder_without_modulo(i_dividend, i_divisor)
quotient = i_dividend / i_divisor
i_dividend - (quotient * i_divisor).round
end

This solves the first two tests, however for the third it throws this error:

int_remainder_without_modulo
knows 8 mod 3 is 2
knows 5 mod 6 is 5
doesn't use the % operator (FAILED - 1)

Failures:

1) methods.rb int_remainder_without_modulo doesn't use the % operator
Failure/Error: i_dividend - (quotient * i_divisor)
#<Double "Integer"> received unexpected message :- with (2)
# ./lib/methods.rb:108:in `int_remainder_without_modulo'
# ./spec/methods_spec.rb:144:in `block (3 levels) in <top (required)>'

Finished in 0.01838 seconds (files took 0.1471 seconds to load)
27 examples, 1 failure

Failed examples:

rspec ./spec/methods_spec.rb:141 # methods.rb int_remainder_without_modulo doesn't use the % operator

which Iâ€™m having trouble deciphering. It sounds like it thinks Iâ€™m using a modulo in my code, but Iâ€™m not sure. Let me know if you encountered/solved this.

Thanks!

1 Like

@dtluther: Hello Dillon! This is a really interesting question, so I decided to do some debugging.
I think your solution is valid, there is nothing wrong with it. However, I just worked my way out to pass the rspec.
You donâ€™t have to follow my instruction, but Iâ€™ll show you how I would debug your code and fix it.

• So you passed the first two test, but fail the last one

Letâ€™s look at the Rspec file :

describe "int_remainder_without_modulo" do
it "knows 8 mod 3 is 2" do
expect(int_remainder_without_modulo(8, 3)).to be(2)
end

it "knows 5 mod 6 is 5" do
expect(int_remainder_without_modulo(5, 6)).to eq(5)
end

it "doesn't use the % operator" do
a = double("Integer", :/ => 1, :to_f => 2.0)
int_remainder_without_modulo(a, 2)
end
end
• If you look at the 2 first tests (ignore the 3rd test) : itâ€™s passing 8 and 3 (1st test), 5 and 6 (2nd test)
• And the parameters in the int_remainder_without_modulo method are i_dividend and i_divisor
• So it tells us that the type of i_dividend and i_divisor is Integer
• Letâ€™s do some debugging
def int_remainder_without_modulo(i_dividend, i_divisor)
quotient = i_dividend / i_divisor
byebug # <---------- Bye Bug is right HERE
i_dividend.to_f.round - (quotient * i_divisor)
end

## Now look at the 3rd test: â€śdoesnâ€™t use the % operatorâ€ť

• And letâ€™s debug the Rspec file (not method.rb file). Remember to remove the â€śbyebugâ€ť line in method.rb file, and run spec on the 3rd test (line 142)
it "doesn't use the % operator" do
a = double("Integer", :/ => 1, :to_f => 2.0)
byebug # <---------- Bye Bug is right HERE
int_remainder_without_modulo(a, 2)
end

• You will see that a is passing to i_dividend and 2 is passing to i_divisor.
• Well, we know for sure that i_divisor is Integer type because number 2 is Integer
• But what about a? Well, itâ€™s a Double type. REALLY?
• You can learn learn about Integer, Float, Double, â€¦ . Just google : primitive data types.
• You also see that what number is divisible by a , it still give us a same result 1
• Ex: a/2 = a/123 = a/456 = a/2.35 = 1
• Because a has a key (word) â€ś/â€ť, and â€ś/â€ť 's value is 1 --> a/(any number) = 1 (Integer type)
• It tells us that at this line: int_remainder_without_modulo(a, 2), instead of passing a 2, you pass anything you want like: (a,123) because a/(any nunber) always give us 1
• Usually in Ruby, division with a Float type will give you a Float type. In this case, itâ€™s a test
â€“> So itâ€™s a fake â€śDoubleâ€ť

## Now look at your code and letâ€™s do some debugging on 3rd test

• Remember to remove â€śbyebugâ€ť line in the Rspec file, and only run rspec for the 3 test
def int_remainder_without_modulo(i_dividend, i_divisor)
quotient = i_dividend / i_divisor
byebug # <---- Bye Bug is right HERE
i_dividend - (quotient * i_divisor).round
end

• Well this is what we kinda expect. i_dividend.classâ€™s type is Double, because that â€śaâ€ť in the 3rd test (Rspec file), its type is Double (fake Double), and â€śaâ€ť is passing to the parameter i_dividend.
• However, we passed first 2 tests, but failed this 3rd test. The reason is the first 2 tests, i_dividend received Integer types, and the 3rd test, i_dividend received this fake Double type.
• Also, you see that quotient is Integer type, and its value is 1.
• To guarantee that your code will pass the rspec, your code should able to handle the case for that fake Double type
# Assume the arguments are integers.
• Iâ€™m so sorry for whoever wrote this test, when I look at the rspec file, I just didnâ€™t trust it
• And Iâ€™m sorry, this may be the bug in rspec.
• I think the test is meant to test only for â€śnot to use % operatorâ€ť,and they give us a hint to use the helper function
• Well, you can figure it our how to use the hint
• But, itâ€™s more fun to fix your code
# HINT: Use dec_remainder_of_two_integers as a helper method

## How would we fix this problem?

• Well, a few things we should know about Ruby are:
• Variables donâ€™t have type
• Everything decimal number are Float type by default including Double (itâ€™s different in other languages like Java, C,â€¦)
• So Float, Double are the same thing, just call it Float
• To fix this, itâ€™s pretty easy, all you have to do is convert this fake Double to Float
def int_remainder_without_modulo(i_dividend, i_divisor)
quotient = i_dividend / i_divisor
i_dividend.to_f - (quotient * i_divisor).round
end

#### Pass the 3rd test, but fail the 1st test

• So it tells us that we need to handle the case for both Integer and that fake Double
• So How would we fix this?
• convert i_dividend to float and convert it to Integer.
• You can use â€śroundâ€ť method to round a number and convert to Integer type

# All Tests Passed

def int_remainder_without_modulo(i_dividend, i_divisor)
quotient = i_dividend / i_divisor
i_dividend.to_f.round - (quotient * i_divisor)
end

• Btw, you may notice that I remove the round method for (quotient * i_divisor)
• Because we know that quotient and i_divisor are always Integer type:
• First 2 tests: passing 2 Integer numbers --> quotient = i_dividend / i_divisor is Integer
• 3rd Test: passing a fake Double type â€śaâ€ť, and whenever a/(any number) = quotient = i_dividend / i_diviso always give us a number 1 which is an Integer type.