Luhn: Update testcase to avoid wrong solution #1480
Luhn: Update testcase to avoid wrong solution #1480petertseng merged 5 commits intoexercism:masterfrom tqa236:tqa236-patch-1
Conversation
coriolinus
left a comment
There was a problem hiding this comment.
Not having convenient access to a Java dev environment, I've rewritten your example in Python, as directly as possible:
>>> def isValid(candidate):
... number = candidate.replace(' ', '')
... if number == '0':
... return False
... digits = [ord(c) - 48 for c in number]
... return sum(2*digits[i] - (9*(1 if digits[i] >= 5 else 0)) if i % 2 == 0 else digits[i] for i in range(len(digits))) % 10 == 0
...I've confirmed that where the old test case correctly returned False by accident, the new test case will incorrectly return True, failing the test case.
>>> isValid("055a 444 285")
False
>>> isValid("055b 444 285")
TrueIt's not a perfectly general solution, but it's an elegant way to stop this particular wrong algorithm from succeeding. I like it.
|
I also don't have access to running Java so I'll have to rely on others' help for the answer to the question: What does it do to |
|
Using the previous Python def of >>> isValid(':9')
TrueGiven that the expected value of this case is |
|
It seems that this solution is already be ruled out by that test case. My mistake. Given that the range of |
|
That means the interesting thing about these two cases I won't stand in the way if the decision is instead to ignore this recommendation and merge this PR as it currently stands. |
|
I agree that we should update the description to better describe the test, do you have any suggestions? By the way, is it possible to add a comment in a test about the intent of that test? It is not easy to recognize just by looking at the file. Just in case there's a wrong solution with a similar approach that passes, we know we should update the test suite to a more rigorous version. |
I have a hard time finding a short description for the cases. Even though it is not a requirement that it be short, #1198 seems to imply there are benefits. I'll try:
Open question, do we need to mention "ascii value offset from the value of 0" or is "ascii value" sufficient
it is possible. see an example in problem-specifications/exercises/largest-series-product/canonical-data.json Lines 107 to 120 in d28d6a5 see the formal spec in andproblem-specifications/canonical-schema.json Lines 62 to 67 in d28d6a5 |
|
I updated the descriptions based on your suggestion. I also grouped them together to reflect the fact that they address the same problem. |
| "Convert non-digits to their ascii value and then offset them by 48 sometimes accidently return the correct result.", | ||
| "This test is designed to avoid that solution." | ||
| ], | ||
| "description": "using ascii value for doubled non-digit isn't allow", |
There was a problem hiding this comment.
I think for grammar, allow should be allowed here, and in the other test case as well
| { | ||
| "description": "strings with non-digits is invalid", | ||
| "comments": [ | ||
| "Convert non-digits to their ascii value and then offset them by 48 sometimes accidently return the correct result.", |
There was a problem hiding this comment.
spelling accidently -> accidentally
| { | ||
| "description": "strings with non-digits is invalid", | ||
| "comments": [ | ||
| "Convert non-digits to their ascii value and then offset them by 48 sometimes accidently return the correct result.", |
There was a problem hiding this comment.
"accidentally return the correct result" might be easy to misinterpret, or require careful thinking before a reader can determine whether the sentence is true. Can I suggest "accidentally declare an invalid string to be valid" so that requires less brainpower? my feeble mind was having a hard time figuring things out
|
Thank you for the review. I made a new commit based on your suggestion. |
petertseng
left a comment
There was a problem hiding this comment.
I think I have one last comment, that these two have been swapped.
I plan to approve after the two descriptions are swapped, or someone tells me I got mixed up. I do not plan to wait long after that to merge it. So, if other reviewers have some things to say, you should say them soon.
| "Convert non-digits to their ascii values and then offset them by 48 sometimes accidentally declare an invalid string to be valid.", | ||
| "This test is designed to avoid that solution." | ||
| ], | ||
| "description": "using ascii value for doubled non-digit isn't allowed", |
There was a problem hiding this comment.
can you double-check me on this one? I think in this case, the b is in a non-doubled position, and in the latter case the : is in a doubled position. So these two test case descriptions should be switched, right?
Or did I get them mixed up
|
You're correct. I fix that in the new commit. |
petertseng
left a comment
There was a problem hiding this comment.
this PR makes the purposes of these test cases clearer, a good improvement.
* luhn: Updated the exercise to the version 1.6.1 Relevant PRs: - exercism/problem-specifications#1420 - exercism/problem-specifications#1480 - exercism/problem-specifications#1500 - exercism/problem-specifications#1523 * luhn: Fixed the 'exercise' util generated comments in the test suite
Changes included: 1. exercism/problem-specifications#1480: 1.4.0 to 1.5.0: Change "055a 444 285" test into "055b 444 285" for subtle reasons. New test name: using ascii value for doubled non-digit isn't allowed 2. exercism/problem-specifications#1500: 1.5.0 to 1.6.0: Add test case: valid number with an odd number of spaces 3. exercism/problem-specifications#1635: 1.6.0 to 1.7.0: Add test case: invalid long number with an even remainder
The change might seem trivia at first. It isn't. Here's a solution that passes all the test in Java
In this solution, after I remove all the whitespaces, I convert all characters to the ascii number and subtract them to 48 (the ascii code of 0) to get the digits. Then I check with the list I receive and it passes all test cases. I didn't remove invalid characters at all.
The problem is that the ascii code of the invalid characters automatically make the valid number becomes invalid, so no need to remove them.
With the new test case, the sum is 90, and it should still be false because if the invalid character.