Skip to content

Rotational Cipher: Exercise Added #460

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 11 commits into from
Apr 3, 2017
9 changes: 9 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@
"topics": [
]
},
{
"slug": "rotational-cipher",
"difficulty": 1,
"topics": [
"strings",
"logic",
"control-flow (loops)"
]
},
{
"slug": "difference-of-squares",
"difficulty": 1,
Expand Down
14 changes: 14 additions & 0 deletions exercises/rotational-cipher/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from string import ascii_lowercase as alpha_lower
from string import ascii_uppercase as alpha_upper
ALPHA_LEN = len(alpha_lower)


def rotate(message, key):
coded_message = ""
for char in message:
if char in alpha_lower:
char = alpha_lower[(alpha_lower.index(char) + key) % ALPHA_LEN]
elif char in alpha_upper:
char = alpha_upper[(alpha_upper.index(char) + key) % ALPHA_LEN]
coded_message += char
return coded_message
2 changes: 2 additions & 0 deletions exercises/rotational-cipher/rotational_cipher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def rotate():
pass
53 changes: 53 additions & 0 deletions exercises/rotational-cipher/rotational_cipher_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import unittest

import rotational_cipher


class RotationalCipher(unittest.TestCase):
Copy link
Contributor

Choose a reason for hiding this comment

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

We try to stick to the canonical test data provided in the x-common repository.

If you are missing a test case that would make sense for all tracks, than it would be best to also add it there.
If you think we need an additional test case that would be python specific it would be good to mark those with a comment (# additional track specific tests) to make it easy to compare it against the common test cases.

def test_rotate_a_by_1(self):
self.assertEqual(rotational_cipher.rotate('a', 1), 'b')

def test_rotate_a_by_26(self):
self.assertEqual(rotational_cipher.rotate('a', 26), 'a')

def test_rotate_a_by_0(self):
self.assertEqual(rotational_cipher.rotate('a', 0), 'a')

def test_rotate_m_by_13(self):
self.assertEqual(rotational_cipher.rotate('m', 13), 'z')

def test_rotate_n_by_13_with_wrap_around_alphabet(self):
self.assertEqual(rotational_cipher.rotate('n', 13), 'a')

def test_rotate_capital_letters(self):
self.assertEqual(rotational_cipher.rotate('OMG', 5), 'TRL')

def test_rotate_spaces(self):
self.assertEqual(rotational_cipher.rotate('O M G', 5),
'T R L')

def test_rotate_numbers(self):
self.assertEqual(
rotational_cipher.rotate(
'Testing 1 2 3 testing',
4),
'Xiwxmrk 1 2 3 xiwxmrk')

def test_rotate_punctuation(self):
self.assertEqual(
rotational_cipher.rotate(
"Let's eat, Grandma!",
21),
"Gzo'n zvo, Bmviyhv!")

def test_rotate_all_letters(self):
self.assertEqual(
rotational_cipher.rotate(
"The quick brown fox jumps"
" over the lazy dog.",
13),
"Gur dhvpx oebja sbk whzcf bire gur ynml qbt.")


if __name__ == '__main__':
unittest.main()
27 changes: 16 additions & 11 deletions exercises/say/say_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
from say import say


# test cases adapted from `x-common//canonical-data.json` @ version: 1.0.0

class SayTest(unittest.TestCase):
def test_zero(self):
self.assertEqual(say(0), "zero")

def test_one(self):
self.assertEqual(say(1), "one")

Expand All @@ -19,6 +24,7 @@ def test_twenty_two(self):
def test_one_hundred(self):
self.assertEqual(say(100), "one hundred")

# additional track specific test
def test_one_hundred_twenty(self):
self.assertEqual(say(120), "one hundred and twenty")

Expand All @@ -31,12 +37,14 @@ def test_one_thousand(self):
def test_one_thousand_two_hundred_thirty_four(self):
self.assertEqual(say(1234), "one thousand two hundred and thirty-four")

# additional track specific test
def test_eight_hundred_and_ten_thousand(self):
self.assertEqual(say(810000), "eight hundred and ten thousand")

def test_one_million(self):
self.assertEqual(say(1e6), "one million")

# additional track specific test
def test_one_million_two(self):
self.assertEqual(say(1000002), "one million and two")

Expand All @@ -48,24 +56,21 @@ def test_1002345(self):
def test_one_billion(self):
self.assertEqual(say(1e9), "one billion")

def test_number_to_large(self):
with self.assertRaises(AttributeError):
say(1e12)

def test_number_negative(self):
with self.assertRaises(AttributeError):
say(-42)

def test_zero(self):
self.assertEqual(say(0), "zero")

def test_987654321123(self):
self.assertEqual(
say(987654321123), ("nine hundred and eighty-seven billion "
"six hundred and fifty-four million "
"three hundred and twenty-one thousand "
"one hundred and twenty-three"))

def test_number_to_large(self):
with self.assertRaises(AttributeError):
say(1e12)

def test_number_negative(self):
with self.assertRaises(AttributeError):
say(-1)


if __name__ == '__main__':
unittest.main()