Skip to content

Add anagram generator#464

Merged
kotp merged 1 commit intoexercism:masterfrom
fredrb:anagram_generator
Oct 20, 2016
Merged

Add anagram generator#464
kotp merged 1 commit intoexercism:masterfrom
fredrb:anagram_generator

Conversation

@fredrb
Copy link
Copy Markdown
Contributor

@fredrb fredrb commented Oct 18, 2016

#396 - Anagram exercise generator

Comment thread exercises/anagram/anagram_test.rb Outdated
detector = Anagram.new('diaper')
assert_equal [], detector.match(%w(hello world zombies pants))
# skip
assert_equal [], Anagram.new("diaper").match(["hello", "world", "zombies", "pants"])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

indentation should be 2 spaces, you've got 3 here.

Comment thread lib/anagram_cases.rb Outdated
end

def work_load
actual = "Anagram.new(\"#{subject}\").match(#{candidates})"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If you use single quotes around #{subject} you don't need to escape the quotes.

Comment thread lib/anagram_cases.rb Outdated
end

def show_comment
comment.nil? ? '' : "# #{comment}\n\t\t"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

\t is the wrong character to be using.
Ideally there would be no formatting characters in this file.
Perhaps you can find a solution that leaves the formatting in the template file and the logic in this file?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I was enforcing this because I didn't want a blank line in the generated file if there are no comments for the test case. But it makes sense that no formatting should be done here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There are other ways to achieve the same effect.

Comment thread exercises/anagram/anagram_test.rb Outdated
def test_detects_unicode_anagrams
skip
# These words don't make sense, they're just greek letters cobbled together.
assert_equal ["ΒΓΑ", "γβα"], Anagram.new("ΑΒΓ").match(["ΒΓΑ", "ΒΓΔ", "γβα"])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Use spaces rather than tabs for indentation.

Comment thread exercises/anagram/anagram_test.rb Outdated
assert_equal [], detector.match(['eagle'])
def test_detects_multiple_anagrams
skip
assert_equal ["stream", "maters"], Anagram.new("master").match(["stream", "pigeon", "maters"])
Copy link
Copy Markdown
Contributor

@Insti Insti Oct 18, 2016

Choose a reason for hiding this comment

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

You're enforcing an ordering here which is not specified in the readme.
['matters','stream'] would also be a valid result.

Comment thread exercises/anagram/anagram_test.rb Outdated
assert_equal ['tan'], anagrams
def test_detects_simple_anagram
skip
assert_equal ["tan"], Anagram.new("ant").match(["tan", "stand", "at"])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why have you changed from the old 3 line "detector, anagrams, assertion" format?

Comment thread exercises/anagram/anagram_test.rb Outdated
assert_equal [], detector.match(['last'])
def test_detects_anagram
skip
assert_equal ["inlets"], Anagram.new("listen").match(["enlists", "google", "inlets", "banana"])
Copy link
Copy Markdown
Contributor

@Insti Insti Oct 18, 2016

Choose a reason for hiding this comment

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

This is a personal preference of mine and not something that needs changing if you have a different opinion, but I'd rather see single quotes around strings that don't require interpolation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed. But both the expected and matched lists come from the canonical json file.

@Insti
Copy link
Copy Markdown
Contributor

Insti commented Oct 18, 2016

Travis CI is failing because the example solution does not pass all the tests:

  1) Failure:
AnagramTest#test_detects_unicode_anagrams [/tmp/anagram.oOJIjvdSpC/anagram_test.rb:87]:
Expected: ["ΒΓΑ", "γβα"]
  Actual: ["ΒΓΑ"]

@Insti
Copy link
Copy Markdown
Contributor

Insti commented Oct 18, 2016

Thanks @fredrb ❤️ It's great to see people contributing new generators.
You've covered all the important functionality and the things to change are are mostly just minor stylistic and consistency issues.

Great work.

@Insti
Copy link
Copy Markdown
Contributor

Insti commented Oct 18, 2016

Expected: ["ΒΓΑ", "γβα"]
Actual: ["ΒΓΑ"]

I see you've raised an issue about this in x-common.
That was the right thing to do.

@fredrb
Copy link
Copy Markdown
Contributor Author

fredrb commented Oct 18, 2016

Thanks for the review @Insti. I fixed most of the things you pointed out and left a comment on others. I'll check the issue with the greek letters in x-common then, if it gets fixed, I'll re-generate the files here.

Comment thread exercises/anagram/anagram_test.rb Outdated
assert_equal ["gallery", "regally", "largely"], Anagram.new("allergy").match(["gallery", "ballerina", "regally", "clergy", "largely", "leading"])
skip

assert_equal ["gallery", "regally", "largely"].sort, Anagram.new('allergy').match(["gallery", "ballerina", "regally", "clergy", "largely", "leading"]).sort
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You didn't address my other question:

Why have you changed from the old 3 line "detector, anagrams, assertion" format?

That would help avoid situations like this where you end up with one really long line.

Comment thread lib/anagram_cases.rb Outdated

def show_comment
comment.nil? ? '' : "# #{comment}\n\t\t"
comment.nil? ? '' : "# #{comment}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Try moving the comment outputing into the work_load, this should allow you to avoid empty lines.

Comment thread lib/anagram_cases.rb
def work_load
actual = "Anagram.new('#{subject}').match(#{candidates})"
"assert_equal #{expected}.sort, #{actual}.sort"
end
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A suggestion:

  def work_load
    expectation = "expected = #{expected}"
    actual = "actual = Anagram.new('#{subject}').match(#{candidates})"
    assertion = "assert_equal expected.sort, actual.sort"

    indent_lines(
    [
      show_comment,
      expectation,
      actual,
      assertion
    ].compact )
  end

  def indent_lines(lines, indent_level = 2)
    lines.join("\n" + ' '*2*indent_level)
  end

Although the formatting of the indent_lines method call could be improved.

@fredrb
Copy link
Copy Markdown
Contributor Author

fredrb commented Oct 18, 2016

@Insti, I implemented the changes you suggested, could you please review again?
Our tests are failing because exercism/problem-specifications#414 is still pending.

Comment thread lib/anagram_cases.rb Outdated

private

def ident_lines(code, ident = 2)
Copy link
Copy Markdown
Contributor

@Insti Insti Oct 19, 2016

Choose a reason for hiding this comment

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

"indent" is missing an 'n'

Copy link
Copy Markdown
Contributor

@Insti Insti left a comment

Choose a reason for hiding this comment

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

This is really nice.

I think the multi-line work_load makes it much clearer what is going on.

I really like what you've done in anagram_cases using small methods and simplifying the whole thing.

Great work.

@Insti
Copy link
Copy Markdown
Contributor

Insti commented Oct 19, 2016

exercism/problem-specifications#414 has now been merged.

Comment thread exercises/anagram/anagram_test.rb Outdated
anagrams = detector.match(%w(tan stand at))
assert_equal ['tan'], anagrams
anagrams = detector.match(["tan", "stand", "at"])
assert_equal ["tan"].sort, anagrams.sort
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

(This is an 'in an ideal world' type issue please don't think that you have to do this.)

Based on the principle that we want to make the test cases as nice as possible for people and would prefer generator complexity over test case complexity.
It could be nice to omit the .sort when there is only one element, and pre-sort the 'expected' arrays that have multiple elements.

Comment thread lib/anagram_cases.rb Outdated
end

def assert
"assert_equal #{expected}.sort, anagrams.sort"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

"ideal world" suggestion: (see my other comment)

assert_equal #{expected.sort}, anagrams#{expected.size > 1 ? '.sort' : ''}

or something more elegant.


# Test data version:
# <%= sha1 %>
class AnagramTest < Minitest::Test<% test_cases.each do |test_case| %>
Copy link
Copy Markdown
Contributor

@Insti Insti Oct 19, 2016

Choose a reason for hiding this comment

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

Can we move the <% .. %> down to the next line?

@fredrb
Copy link
Copy Markdown
Contributor Author

fredrb commented Oct 19, 2016

Good idea omiting the .sort when expected list has either a single value or it's empty. If you check the test class, only two test cases ended up with anagrams.sort 👍

@Insti
Copy link
Copy Markdown
Contributor

Insti commented Oct 19, 2016

I think this is ready to go now, I'll just wait a bit and give @kotp a chance to look over it before merging.

Thanks for your work on this and your responsiveness to feedback, I think we've ended up with a really nice generator AND nice test cases. Great work. ❤️

@fredrb
Copy link
Copy Markdown
Contributor Author

fredrb commented Oct 19, 2016

@Insti It was a pleasure! Thanks for the code reviews and suggestions

@kotp
Copy link
Copy Markdown
Member

kotp commented Oct 19, 2016

@fredrb can you squash these commits into one or (if you think it makes sense) 2 commits. It makes it easier to review, and gives structure to the commit message when it comes in, as to what you would like communicate in the log.

I end up doing it locally, to review, but it is nice to give you a chance to cultivate the commit, as I may miss something.

Copy link
Copy Markdown
Member

@kotp kotp left a comment

Choose a reason for hiding this comment

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

The changes all together look really good.

There are trailing whitespace that ends up in the generated test file on or around line 9. We would want to not do that.

@fredrb fredrb force-pushed the anagram_generator branch from 4604fe3 to af734a7 Compare October 19, 2016 23:54
@fredrb
Copy link
Copy Markdown
Contributor Author

fredrb commented Oct 19, 2016

Squashed them into one, @kotp. Also made the small fix for the trailing whitespace.

@kotp kotp merged commit f646982 into exercism:master Oct 20, 2016
@kotp
Copy link
Copy Markdown
Member

kotp commented Oct 20, 2016

Thank you @fredrb

@Insti Insti removed the in progress label May 19, 2017
@Insti Insti removed the ready label Jun 8, 2017
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.

3 participants