-
-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Complex Numbers exercise #528
Conversation
"uuid": "ed6b5073-e3b1-4787-8551-ffffa9e7313d", | ||
"practices": [], | ||
"prerequisites": [], | ||
"difficulty": 6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The core of the exercise isn't that difficult, but relying heavily on operator overloading makes this more challenging
local Complex | ||
|
||
Complex = function(r, i) | ||
local c = { | ||
-- | ||
} | ||
|
||
return setmetatable(c, { | ||
-- | ||
}) | ||
end | ||
|
||
return Complex |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to include a few breadcrumbs here to help lead people in the right direction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could add a document (maybe instructions.append.md) that links to the "Closure based objects" part of https://web.archive.org/web/20240104094707/http://lua-users.org/wiki/ObjectOrientationTutorial
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about the delay. I should be able to do this over the weekend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion. I added an append to introduce closure-based OO and operator overloading.
describe('operations between real numbers and complex numbers', function() | ||
it('add real number to complex number', function() | ||
assert.equal(Complex(6, 2), Complex(1, 2) + Complex(5)) | ||
end) | ||
|
||
it('add complex number to real number', function() | ||
assert.equal(Complex(6, 2), Complex(5) + Complex(1, 2)) | ||
end) | ||
|
||
it('subtract real number from complex number', function() | ||
assert.equal(Complex(1, 7), Complex(5, 7) - Complex(4)) | ||
end) | ||
|
||
it('subtract complex number from real number', function() | ||
assert.equal(Complex(-1, -7), Complex(4) - Complex(5, 7)) | ||
end) | ||
|
||
it('multiply complex number by real number', function() | ||
assert.equal(Complex(10, 25), Complex(2, 5) * Complex(5)) | ||
end) | ||
|
||
it('multiply real number by complex number', function() | ||
assert.equal(Complex(10, 25), Complex(5) * Complex(2, 5)) | ||
end) | ||
|
||
it('divide complex number by real number', function() | ||
assert.equal(Complex(1, 10), Complex(10, 100) / Complex(10)) | ||
end) | ||
|
||
it('divide real number by complex number', function() | ||
assert.equal(Complex(2.5, -2.5), Complex(5) / Complex(1, 1)) | ||
end) | ||
end) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because I chose to use operator overloading this is a little bit awkward. I think it's worth it to introduce operator overloading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's great to get an exercise with "the other" OO style.
local Complex | ||
|
||
Complex = function(r, i) | ||
local c = { | ||
-- | ||
} | ||
|
||
return setmetatable(c, { | ||
-- | ||
}) | ||
end | ||
|
||
return Complex |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could add a document (maybe instructions.append.md) that links to the "Closure based objects" part of https://web.archive.org/web/20240104094707/http://lua-users.org/wiki/ObjectOrientationTutorial
|
||
it('imaginary unit', function() | ||
assert.equal(Complex(-1, 0), Complex(0, 1) * Complex(0, 1)) | ||
end) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get a failure for this:
Failure → ./complex-numbers_spec.lua @ 36
complex-numbers imaginary unit
./complex-numbers_spec.lua:37: Expected objects to be equal.
Passed in:
(table: 0x563a518471c0) {
[i] = 0
[r] = -1 }
Expected:
(table: 0x563a51846650) {
[i] = 0
[r] = -1 }
Should the spec be assert.are.same
because it appears to be checking whether it's actually the same table, rather than whether the table's properties are the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason it uses assert.equal
is because it expects your implementation to define equality via the __eq
metamethod. This lets you define what equality means for your complex type without the tests requiring an identical internal representation for two complex numbers to be considered equal. This also gives you an opportunity to compare floating point values safely (see https://www.reddit.com/r/learnprogramming/comments/9y9gxs/small_lesson_of_the_day_never_check_two_floats/).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason it uses
assert.equal
is because it expects your implementation to define equality via the__eq
metamethod.
Got it. Thanks for the quick response!
No description provided.