Skip to content

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

Merged
merged 5 commits into from
Oct 10, 2017
Merged

Conversation

cschlosser
Copy link

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.

@NobbZ
Copy link
Member

NobbZ commented Oct 4, 2017

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
}
]
Copy link
Contributor

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

Copy link
Author

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",
Copy link
Contributor

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.

Copy link
Author

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",
Copy link
Contributor

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?

Copy link
Author

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",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicate description

Copy link
Author

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",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicate description

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

@Insti
Copy link
Contributor

Insti commented Oct 5, 2017

Good exercise. 👍
Needs a few tweaks but is heading in the right direction.

Copy link
Author

@cschlosser cschlosser left a 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",
Copy link
Author

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",
Copy link
Author

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",
Copy link
Author

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",
Copy link
Author

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
}
]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea, added!

@Insti
Copy link
Contributor

Insti commented Oct 5, 2017

Thanks for those changes.
I'm sure it will evolve as it gets implemented and people start solving the exercise, but this seems like a reasonable starting point.


## Bonus tasks

* Generate an valid ISBN-13 from the input ISBN-10 (and maybe verify it again with an derived verifier)
Copy link
Member

@rpottsoh rpottsoh Oct 5, 2017

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.

Copy link
Author

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",
Copy link
Member

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",

Copy link
Author

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.
Copy link
Member

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.

Copy link
Author

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",
Copy link
Member

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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Thanks!

Copy link
Member

@rpottsoh rpottsoh left a 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! 👍

@rpottsoh rpottsoh merged commit 0493308 into exercism:master Oct 10, 2017
{
"description": "X is only valid as a check digit",
"property": "isbn",
"input": "3-598-2X507-0",
Copy link
Member

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",
Copy link
Member

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.

petertseng added a commit that referenced this pull request Nov 2, 2017
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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants