-
-
Notifications
You must be signed in to change notification settings - Fork 554
Add isbn-verifier exercise #924
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
Conversation
There should be at least a rough description of how a ISBN-10 is structured and how the checksum is calculated. |
What is an ISBN comprised of and when is an ISBN valid.
"input": "3-598-21507-XA", | ||
"expected": false | ||
} | ||
] |
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.
Test suggestion: Valid ISBN for which the check digit should be 0
but is X
to catch solutions that convert X
to 0
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.
Great idea, added!
"expected": false | ||
}, | ||
{ | ||
"description": "valid character in isbn", |
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.
This description is confusing.
Maybe: "X is only valid as a checkdigit."
Also make sure that this ISBN would be valid if 10 was used in place of X in the calculation.
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.
Good idea, thanks!
"expected": true | ||
}, | ||
{ | ||
"description": "isbn without separating dashes", |
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.
This description is the same as the last, what is this test testing differently?
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 X is the checkdigit
"expected": false | ||
}, | ||
{ | ||
"description": "isbn without check digit", |
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.
duplicate description
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.
Updated.
"expected": false | ||
}, | ||
{ | ||
"description": "too long isbn", |
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.
duplicate description
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.
Updated
Good exercise. 👍 |
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.
Thank you for your feedback, any further review is quite welcome!
"expected": true | ||
}, | ||
{ | ||
"description": "isbn without separating dashes", |
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 X is the checkdigit
"expected": false | ||
}, | ||
{ | ||
"description": "valid character in isbn", |
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.
Good idea, thanks!
"expected": false | ||
}, | ||
{ | ||
"description": "isbn without check digit", |
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.
Updated.
"expected": false | ||
}, | ||
{ | ||
"description": "too long isbn", |
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.
Updated
"input": "3-598-21507-XA", | ||
"expected": false | ||
} | ||
] |
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.
Great idea, added!
Thanks for those changes. |
|
||
## Bonus tasks | ||
|
||
* Generate an valid ISBN-13 from the input ISBN-10 (and maybe verify it again with an derived verifier) |
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.
Change all an
's to a
.
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.
Done
"expected": false | ||
}, | ||
{ | ||
"description": "check digit should be 0 but is X to prevent solutions to use X as 0", |
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.
How about?:
"description": "check digit of X should not be used for 0",
This test is essentially the same as:
"description": "invalid isbn check digit",
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 improved description.
Yes indeed but X is in a bit of a special position for ISBN so I think it doesn't hurt to add some extra tests for this.
@@ -15,7 +15,7 @@ The following number block is to identify the publisher. Since this is a three d | |||
The last digit in the ISBN is the check digit which is used to detect read errors. | |||
|
|||
The first 9 digits in the ISBN have to be between 0 and 9. | |||
The check digit can additionally be an 'X' to allow 10 to be a valid check digit as well. | |||
The check digit can additionally be a 'X' to allow 10 to be a valid check digit as well. |
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.
@christophschlosser my apologies. I was not clear on when an
should be a
. In this instance an
is OK. An is used when the next word starts with a vowel or starts with a vowel sound. In this instance 'X' starts with a vowel sound, e
in this instance.
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.
No problem @rpottsoh . TIL. I uploaded a new commit where this is fixed.
@@ -79,7 +79,7 @@ | |||
"expected": false | |||
}, | |||
{ | |||
"description": "check digit should be 0 but is X to prevent solutions to use X as 0", | |||
"description": "check digit of X should not be used for 0", |
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!
@@ -30,6 +30,6 @@ It's getting even trickier since the check-digit of an ISBN-10 can be 'X'. | |||
|
|||
## Bonus tasks | |||
|
|||
* Generate an valid ISBN-13 from the input ISBN-10 (and maybe verify it again with an derived verifier) | |||
* Generate a valid ISBN-13 from the input ISBN-10 (and maybe verify it again with a derived verifier) |
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!
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 making these changes and more importantly, thanks for providing a new exercise for Exercism! 👍
{ | ||
"description": "X is only valid as a check digit", | ||
"property": "isbn", | ||
"input": "3-598-2X507-0", |
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.
An implementation that unconditionally treats X as 10 will still reject this ISBN:
3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 10 * 5 + 5 * 4 + 0 * 3 + 7 * 2 + 0 * 1 = 299, and 299 is not divisible by 11.
If the intention of this test is to ensure that an implementation only treats X as 10 in the check digit position, then a case such as "3-598-2X507-9" is needed.
{ | ||
"description": "too long isbn", | ||
"property": "isbn", | ||
"input": "3-598-21507-XA", |
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.
An implementation that would potentially attempt to checksum ISBNs that are too long would still reject this input because it would see that the "A" is invalid.
If the intention of this case is to ensure that an implementation does in fact reject ISBNs that are too long, at the very least a valid character should be used instead of A.
If one wanted to be thorough, one might have to include three different cases here, respectively checking for implementations that try to checksum:
- all 11 resulting digits (with a coefficient of 11 on the leftmost one, naturally)
- the 10 rightmost digits
- the 10 leftmost digits
by providing a too-long ISBN that has a valid check digit under each respective scheme.
isbn-verifier 1.1.0 "X is only valid as a check-digit" #924 (comment) An implementation that unconditionally treats X as 10 will still reject the ISBN 3-598-2X507-0 3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 10 * 5 + 5 * 4 + 0 * 3 + 7 * 2 + 0 * 1 = 299, and 299 is not divisible by 11. If the intention of this test is to ensure that an implementation only treats X as 10 in the check digit position, then a case such as 3-598-2X507-9 is needed. The following may be run in a terminal to ensure that this ISBN does sum to a multiple of 11 under such a mistaken implementation: ruby -e 'p "3-598-2X507-9".delete(?-).chars.reverse.map.with_index { |c, i| (c == ?X ? 10 : Integer(c)) * (i + 1) }.sum % 11' "too long isbn" #924 (comment) An implementation that would potentially attempt to checksum ISBNs that are too long would still reject this input because it would see that the "A" is invalid. If the intention of this case is to ensure that an implementation does in fact reject ISBNs that are too long, at the very least a valid character should be used instead of A. If one wanted to be thorough, one might have to include three different cases here, respectively checking for implementations that try to checksum: * all 11 resulting digits (with a coefficient of 11 on the leftmost one, naturally) * the 10 rightmost digits * the 10 leftmost digits by providing a too-long ISBN that has a valid check digit under each respective scheme. This is not done in this PR because it has not yet become apparent through submissions that such three cases are necessary (submissions that unconditionally attempt to checksum using any of the three schemes listed).
This was an starter exercise in my CS class.
The exercise is really simple, depending on how much your language supports converting types and string manipulation but it can be blown up into a full grown exercise with the bonus tasks.
This teaches you some simple string manipulation combined with basic numerical calculations.
You also get to use the three datatypes of number, string and bool.