Skip to content

Commit

Permalink
Add crypto-square.json
Browse files Browse the repository at this point in the history
Mentioned in exercism#190, but I don't see that this has its own issue

Currently 18 tracks implement this exercise. I did [a
survey](https://gist.github.com/IanWhitney/4912b100cca0b02a5c3ce21096a3e673)
of their test suites and found that they fell into two types:

Type One: Test Just Encoding
--

- [python](https://github.com/exercism/xpython/blob/master/exercises/crypto-square/crypto_square_test.py)
- [lisp](https://github.com/exercism/xlisp/blob/master/exercises/crypto-square/crypto-square-test.lisp)
- [go](https://github.com/exercism/xgo/blob/master/exercises/crypto-square/crypto_square_test.go)
- [elixir](https://github.com/exercism/xelixir/blob/master/exercises/crypto-square/crypto_square_test.exs)

Are the tracks that followed this approach. Just an `encode` method (or
some alias) is implemented and tested.

Type Two: Test Intermediate Methods
--

The remaining 14 tracks followed this style. There's not a lot of
variation between these suites.
[Ruby](https://github.com/exercism/xruby/blob/master/exercises/crypto-square/crypto_square_test.rb) is a good, representative example.

In these test suites several methods are implemented and tested:

- `normalized_plaintext`
- `size`
- `plaintext_segments`
- `ciphertext`
- `normalized_ciphertext'

Again, exact method names may vary.

In implementing this json file I followed the second type. I did this
for a few reasons:

*It's already the majority*: With 14 of 18 tracks already implementing
tests like this, there is some value in following the crowd.

*I think it's the best approach*: This one is more subjective,
obviously. My problem with the Test Just Encoding approach is that
there's a huge gap between starting the exercise and getting a useful
passing test. Students have to implement the full algorithm to get
tests passing.

By breaking the steps down in to smaller methods, each with their own
tests, the lag time between starting to code and getting a passing test
is smaller. And the tests are ordered so that each new method builds on
the methods already built.

The downside of this approach, I think, is that we're doing a lot of the
design up front. In the Test Just Encoding approach students can
implement the algorithm using as many methods as they want. In the Test
Intermediate Methods approach, students end up locked to the methods
defined in the test suite.

In this case I think the trade off is worth it.

But that's just my opinion. My kata group also worked through this
exercise. 3 people did it in Test Just Encoding languages (Elixir and
Python). 2 people did it in Test Intermediate Methods languages (Ruby
and Javascript).

Their opinions largely mirrored mine. Those that used Just Encoding
found it a lot of work to get the 2nd test to pass (since the first test
encodes an empty string). But once they got the 2nd test to pass, all
tests passed.

Those who used the Intermediate Methods approach found the steps between
tests easer to manage and though that this approach was better for
learning.

Though, as an argument for Just Encoding, the Python people were
impressed at the variety of designs people used to solve the problem.
And our Elixir programmer liked that they could make up their own mind
about internal implementations.

A suggested middle ground was to have one exercise offer a Intermediate
Methods test suite, while a later exercise could cover similar ground
with a more free-form Just Encoding test suite.

Removed Tests
---

I dropped one set of tests that existed in the Test Intermediate Methods
approach: `size`. I didn't see a reason for this method. I don't see it
being used as part of a 'real' crypto library (though if your real
crypto library is using Crypto Square then you probably have other
problems). And I didn't see that testing it offered any useful tests not
already provided by the `plaintext_segments` tests.

Tweaked Method Names
---

Method naming varies between current implementations and the Readme.
I've tried to use method names that follow the readme.

My methods

- normalized_plaintext
- plaintext_segments
- encoded
- ciphertext

Terms used in the Readme

- 'input is normalized'
- 'plaintext in a rectangle'
- 'encoded text'
- 'cyphertext' or 'encoded text chunks'

`plaintext_segments` is the method name that deviates most from the
readme. It comes from the current implementations and I could not think
of a better name. Names = hard.
  • Loading branch information
whit0694 committed May 11, 2016
1 parent 3dee37b commit bd29436
Showing 1 changed file with 82 additions and 0 deletions.
82 changes: 82 additions & 0 deletions crypto-square.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"normalized_plaintext": {
"description": "the spaces and punctuation are removed from the English text and the message is downcased",
"cases" : [
{
"description": "Lowercase",
"plaintext": "Hello",
"expected": "hello"
},
{
"description": "Remove spaces",
"plaintext": "Hi there",
"expected": "hithere"
},
{
"description": "Remove punctuation",
"plaintext": "@1, 2%, 3 Go!",
"expected": "123go"
}
]
},
"plaintext_segments": {
"description": "The plaintext should be organized in to a rectangle. The size of the rectangle (`r x c`) should be decided by the length of the message, such that `c >= r` and `c - r <= 1`, where `c` is the number of columns and `r` is the number of rows.",
"cases" : [
{
"description": "empty plaintext results in an empty rectangle",
"plaintext": "",
"expected": "[]"
},
{
"description": "4 character plaintext results in an 2x2 rectangle",
"plaintext": "Ab Cd",
"expected": "[ab, cd]"
},
{
"description": "9 character plaintext results in an 3x3 rectangle",
"plaintext": "This is fun!",
"expected": "[thi, sis, fun]"
},
{
"description": "54 character plaintext results in an 8x7 rectangle",
"plaintext": "If man was meant to stay on the ground, god would have given us roots.",
"expected": "[ifmanwas, meanttos, tayonthe, groundgo, dwouldha, vegivenu, sroots]"
}
]
},
"encoded": {
"description": "The coded message is obtained by reading down the columns going left to right.",
"cases" : [
{
"description": "empty plaintext results in an empty encode",
"plaintext": "",
"expected": ""
},
{
"description": "Non-empty plaintext results in the combined plaintext_segments",
"plaintext": "If man was meant to stay on the ground, god would have given us roots.",
"expected": "imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau"
}
]
},
"ciphertext": {
"description": "Output the encoded text in chunks. Phrases that fill perfect squares `(r X r)` should be output in `r`-length chunks separated by spaces. Imperfect squares will have `n` empty spaces. Those spaces should be distributed evenly across the last `n` rows.",
"cases" : [
{
"description": "empty plaintext results in an empty ciphertext",
"plaintext": "",
"expected": ""
},
{
"description": "9 character plaintext results in 3 chunks of 3 characters",
"plaintext": "This is fun!",
"expected": "tsf hiu isn"
},
{
"description": "54 character plaintext results in 7 chunks, the last two padded with spaces",
"plaintext": "If man was meant to stay on the ground, god would have given us roots.",
"expected": "imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau"
}
]
}
}

0 comments on commit bd29436

Please sign in to comment.