[WIP] isbn-verifier: implement exercise#890
[WIP] isbn-verifier: implement exercise#890eulercb wants to merge 5 commits intoexercism:masterfrom eulercb:feature/isbn-verifier
Conversation
jamesmcm
left a comment
There was a problem hiding this comment.
Just some notes, overall it looks good.
Perhaps the extra tasks you suggest should be split out in to separate exercises?
| int(isbn[8:9]) * 2) % 11 | ||
|
|
||
| if check_digit == 10: | ||
| return 'X' |
There was a problem hiding this comment.
This is quite a lot of code for a small task, I'd recommend something like:
import string
def verify_isbn(isbn):
handleX = lambda x: 10 if x == 'X' else x
nums = [int(handleX(x)) for x in isbn if x in string.digits+'X']
return(sum([x*(10-ind) for ind, x in enumerate(nums)]) % 11 == 0)| self.assertIs(verify('3598215078X'), False) | ||
|
|
||
| def test_invalid_isbn_without_check_digit(self): | ||
| self.assertIs(verify('3-598-21507'), False) |
There was a problem hiding this comment.
Here you can use AssertTrue and AssertFalse instead of AssertIs.
I.e.:
def test_verify_isbn_example_with_X_spaces(self):
self.assertTrue(isbn_verifier.verify_isbn('955 20 3051 X'))There was a problem hiding this comment.
assertFalse won't fail the test if the tested method returns None in comparison with assertIs
Consider this:
import unittest
tc = unittest.TestCase()
tc.assertFalse(None) # passes
tc.assertIs(None, True) # fails as expectedDo you see the difference, @jamesmcm?
So, I think it's better to use assertIs even if readability suffers a bit
There was a problem hiding this comment.
That's a good point, seems like strange behaviour from the unittest module.
There was a problem hiding this comment.
Yeah, especially considering that bool(None) returns False meaning that None is Falsy
There was a problem hiding this comment.
@m-a-ge, your example code is asserting that None is Falsey, so passing is the expected behaviour - bool(None) is False, so assertFalse(None) should pass (and does).
import unittest
tc = unittest.TestCase()
tc.assertFalse(None) # Passes, since None is Falsey
tc.assertTrue(None) # Fails because None is not Truthy
tc.assertIs(None, False) # Fails because None is not False
tc.assertIs(None, True) # Fails because None is not True
In theory, there's nothing wrong with using assertTrue and assertFalse in exercise tests, but the presence of the latter will cause some tests to pass when no code is implemented, and so these could confuse some people. Using assertIs creates another slight issue, in that it forces learners to return booleans, even though they may expect to be able to use Truthy and Falsey statements instead. I'd consider assertIs the lesser of two evils.
| "uuid": "7961c852-c87a-44b0-b152-efea3ac8555c", | ||
| "slug": "isbn-verifier", | ||
| "core": false, | ||
| "unlocked_by": null, |
There was a problem hiding this comment.
I would consider this a much, much easier difficulty. Perhaps put it after the RNA Transcription exercise?
|
@jamesmcm, the implementation of the two additional tests is fairly simple, so I don't think they should go into a separate exercise. ISBN-10 to ISBN-13: Prepend "978" and calculate the new checksum (by the ISBN-13 method). These tests are clearly quite easy extensions if the checksum calculation is implemented as a separate function to the validation. |
N-Parsons
left a comment
There was a problem hiding this comment.
Looks good overall, but it could do with some additional information in the README (and .meta/hints.md so that it doesn't get lost in future). You also seem to have some extra changes to your config.json that will need to be removed before merging.
I also commented on the choice of function names, but I'd like to hear your thoughts on this.
| "strings", | ||
| "arrays", | ||
| "integers", | ||
| "parsing" |
There was a problem hiding this comment.
Looks like you've accidentally included some changes for a different exercise.
|
|
||
| Which proves that the ISBN is valid. | ||
|
|
||
| ### Submitting Exercises |
There was a problem hiding this comment.
This should be at heading level 2 (## Submitting Exercises).
| pass | ||
|
|
||
|
|
||
| def isbn13_generator_from_isbn10(isbn10): |
There was a problem hiding this comment.
generate_isbn13_from_isbn10 might be a better function name?
| pass | ||
|
|
||
|
|
||
| def isbn_generator(isbn): |
There was a problem hiding this comment.
generate_isbn might be a better function name? I think function names should be more descriptive of what they do than what they are.
| (3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11 = 0 | ||
|
|
||
| Which proves that the ISBN is valid. | ||
|
|
There was a problem hiding this comment.
Could you add something here (and to .meta/hints.md) to explain that we are also expecting implementations of an ISBN10 generator and an ISBN13 generator? It will also need to explain how the conversion from ISBN10 to ISBN13 works, and how to do the ISBN13 checksum calculation.
|
@eulercamposbarros Canonical-data has been updated in /exercism/problem-specifications/#993 |
|
This issue has been automatically marked as |
|
Would it be okay for everyone If I continue from where @jamesmcm left off? |
|
@pheanex Actually the PR was started by @eulercamposbarros. In any case, as this has been closed due to being abandoned, the original author has effectively forfeited his/her claim on the work, so feel free to pick it up! |
A detailed description of this exercise can be found here.
TODO: