Skip to content
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

Hamming: Add a test case to avoid wrong recursion solution #1450

Merged
merged 4 commits into from
Feb 7, 2019
Merged

Hamming: Add a test case to avoid wrong recursion solution #1450

merged 4 commits into from
Feb 7, 2019

Conversation

tqa236
Copy link
Contributor

@tqa236 tqa236 commented Feb 1, 2019

Add an extra test case about one empty strand based on the discussion in exercism/haskell#796 to avoid wrong recursion solution.

Add an extra test case about one empty strand based on the discussion in exercism/haskell#796 to avoid wrong recursion solution.
@rpottsoh rpottsoh changed the title Add a test case to avoid wrong recursion solution Hamming: Add a test case to avoid wrong recursion solution Feb 1, 2019
@cmccandless
Copy link
Contributor

What's interesting about this test case is that is far more likely to fail in Haskell (and other languages that support pattern matching on function parameters) than other languages (that don't). I was trying to think of a solution similar to the example provided in exercism/haskell#796 without using pattern matching... it seems a bit contrived, but possible?

def distance(strandA, strandB):
    if len(strandA) == 0 and len(strandB) == 0:
        return 0
    headA = strandA.pop(0)  # This would raise an unexpected IndexError in the new test case
    headB = strandB.pop(0)
    if len(strandA) != len(strandB):
        raise ValueError()
    return (1 if headA != headB else 0) + distance(strandA, strandB)

Still a good test case though!

I wonder: is test case disallow second strand longer now redundant?

@rpottsoh
Copy link
Member

rpottsoh commented Feb 1, 2019

I wonder: is test case disallow second strand longer now redundant?

Or disallow first strand longer for that matter. Help me understand how these two cases are not enough?

regarding the example code in @cmccandless comment:

Why is the length equality of the strands not checked first before anything else? I am not a FP person so I would like to understand better what is happening in Haskell that makes what looks like a redundant change necessary. Is this an issue that really affects all tracks?

@tqa236
Copy link
Contributor Author

tqa236 commented Feb 1, 2019

In my example Haskell solution in exercism/haskell#796, there is a subtle implicit assumption that both strands are not empty, otherwise, they cannot be divided into (first element : the rest) to do recursion.
This happens before the length check because that's Haskell syntax.

distance (x:xs) (y:ys)

As @sshine mentioned in the issue above, this case affects functional languages more than others. But I don't know enough about the syntax of other functional languages to comment.

And I agree that if this test case is accepted, disallow second strand longer is redundant.

@rpottsoh
Copy link
Member

rpottsoh commented Feb 2, 2019

I think the other two cases should remain, even though see seem redundant. They are not redundant to each other. Perhaps the new case should be stated this way:

"description": "disallow left empty strand",
"property": "distance",
  "input": {
    "strand1": "",
    "strand2": "G"
  },
"expected": {"error": "left and right strands must be of equal length"}

then also add:

"description": "disallow right empty strand",
"property": "distance",
  "input": {
    "strand1": "G",
    "strand2": ""
  },
"expected": {"error": "left and right strands must be of equal length"}

We could also, optionally, change the error message to be more informative. ie. left strand must not be empty and right strand must not be empty

@tqa236
Copy link
Contributor Author

tqa236 commented Feb 2, 2019

Thank you for your review and suggestion. Should I push a new commit to this pull request or wait for some kind of final decisions?

@rpottsoh
Copy link
Member

rpottsoh commented Feb 2, 2019

There is no harm in waiting. It would be interesting to get @petertseng's and @ErikSchierboom's opinions.

@sshine
Copy link
Contributor

sshine commented Feb 3, 2019

Sure,

  1. Fix whitespace
  2. Add the second test case
  3. Name them as @rpottsoh suggested

(A sneeze made me click the wrong button, sorry.)

@sshine sshine closed this Feb 3, 2019
@sshine sshine reopened this Feb 3, 2019
@ErikSchierboom
Copy link
Member

Although I think this particular problem is not that likely to occur in other languages, I don't much mind the addition of the two new test cases. I would go with @rpottsoh' suggestions: adding two new test cases and giving them an error message stating that the input must not be empty.

@sshine
Copy link
Contributor

sshine commented Feb 4, 2019

It is just as likely to occur in Standard ML and Ocaml. So I encouraged @tqa236 to submit this here first.

I would also encourage a lower entry bar for new contributors. :-)

@ErikSchierboom
Copy link
Member

ErikSchierboom commented Feb 4, 2019

I would also encourage a lower entry bar for new contributors. :-)

I'm not entirely sure I understand what you mean by this comment :)

Just to be sure, I think the appropriate action here is the list you mentioned earlier:

  • Fix whitespace
  • Add the second test case
  • Name them as @rpottsoh suggested

Would that work for you @tqa236?

@tqa236
Copy link
Contributor Author

tqa236 commented Feb 4, 2019

It’s ok for me. I will do those 3 tasks you mentioned. Please wait for a few days

@tqa236
Copy link
Contributor Author

tqa236 commented Feb 7, 2019

I updated as you said. Please review it.

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.

I think the error message ought to convey why there is an error with as much useful information as possible.

exercises/hamming/canonical-data.json Outdated Show resolved Hide resolved
exercises/hamming/canonical-data.json Outdated Show resolved Hide resolved
@rpottsoh
Copy link
Member

rpottsoh commented Feb 7, 2019

@ErikSchierboom still OK with PR?

@ErikSchierboom
Copy link
Member

@rpottsoh 👍

@rpottsoh rpottsoh merged commit 4119671 into exercism:master Feb 7, 2019
@ErikSchierboom
Copy link
Member

Thanks @tqa236!

@tqa236 tqa236 deleted the patch-1 branch February 7, 2019 17:20
sshine pushed a commit to exercism/haskell that referenced this pull request Feb 14, 2019
The following solution passes all the current tests but fail on the new ones:

    module Hamming (distance) where

    distance :: String -> String -> Maybe Int
    distance [] []         = Just 0
    distance (x:xs) (y:ys)
      | length(xs) /= length(ys) = Nothing
      | x /= y = fmap (1 + ) (distance xs ys)
      | x == y = distance xs ys

The problem is insufficient pattern matching against an empty strand.

This PR adds two test cases that address the possibility that one strand is
empty and the other one isn't.

This PR addresses exercism/problem-specifications#1450
@sshine
Copy link
Contributor

sshine commented Feb 27, 2019

I would also encourage a lower entry bar for new contributors. :-)

I'm not entirely sure I understand what you mean by this comment :)

Sorry I never got back to this, @ErikSchierboom.

I thought that the discussion of keeping/merging redundant cases might evolve so that it encompassed the original issue, discouraging @tqa236 from finalizing the change on the Haskell track. Similarly, in the hope of a returning contributor, I brought Hamming on the Haskell track up to 2.2.0 in exercism/haskell#797 while waiting for this PR.

I'm sorry if this left an impression of bullying or arguing "too many cooks" when we're generally happy to see people participate in the problem-specifications issues. (I haven't been able to keep up with this participation myself.)

@ErikSchierboom
Copy link
Member

Right, thanks for the explanation! I was just unsure how to interpret said statement, no harm done :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants