diff --git a/src/ideaCollisionGenerator.py b/src/ideaCollisionGenerator.py index 406ac5f..6c98bcd 100644 --- a/src/ideaCollisionGenerator.py +++ b/src/ideaCollisionGenerator.py @@ -3,27 +3,34 @@ import os class IdeaCollisionGenerator: - def __init__(self): + def __init__(self, numKeywords=10): + # keywords are matched in pairs, so the count has to be even + if numKeywords < 2 or numKeywords % 2 != 0: + raise ValueError("numKeywords must be a positive even number") + self.numKeywords = numKeywords self.keywords = [] self.pairs = [] self.ideas = [] + def ordinal(self, n): + # 1st, 2nd, 3rd, 4th ... 11th, 12th, 13th ... 21st, 22nd, 23rd + if n % 100 in (11, 12, 13): + suffix = "th" + elif n % 10 == 1: + suffix = "st" + elif n % 10 == 2: + suffix = "nd" + elif n % 10 == 3: + suffix = "rd" + else: + suffix = "th" + return str(n) + suffix + def getKeywords(self): - # get 10 keywords from user - numKeywords = 10 - for i in range(numKeywords): - if i == 0: - keyword = input("Enter 1st keyword: ") - self.keywords.append(keyword) - elif i == 1: - keyword = input("Enter 2nd keyword: ") - self.keywords.append(keyword) - elif i == 2: - keyword = input("Enter 3rd keyword: ") - self.keywords.append(keyword) - else: - keyword = input("Enter " + str(i+1) + "th keyword: ") - self.keywords.append(keyword) + # get keywords from user + for i in range(self.numKeywords): + keyword = input("Enter " + self.ordinal(i+1) + " keyword: ") + self.keywords.append(keyword) # randomize keywords random.shuffle(self.keywords) diff --git a/tests/test_ideaCollisionGenerator.py b/tests/test_ideaCollisionGenerator.py index 9d8cbf2..22ada0f 100644 --- a/tests/test_ideaCollisionGenerator.py +++ b/tests/test_ideaCollisionGenerator.py @@ -38,6 +38,41 @@ def recordingInput(prompt): self.assertEqual(prompts[3], "Enter 4th keyword: ") self.assertEqual(prompts[9], "Enter 10th keyword: ") + def testPromptsAreCorrectPastTwenty(self): + generator = IdeaCollisionGenerator(numKeywords=24) + prompts = [] + + def recordingInput(prompt): + prompts.append(prompt) + return "keyword" + + with mock.patch("builtins.input", recordingInput): + with mock.patch("random.shuffle"): + generator.getKeywords() + + self.assertEqual(prompts[20], "Enter 21st keyword: ") + self.assertEqual(prompts[21], "Enter 22nd keyword: ") + self.assertEqual(prompts[22], "Enter 23rd keyword: ") + + def testKeywordCountIsConfigurable(self): + generator = IdeaCollisionGenerator(numKeywords=4) + with mock.patch("builtins.input", side_effect=["a", "b", "c", "d"]): + with mock.patch("random.shuffle"): + generator.getKeywords() + self.assertEqual(generator.keywords, ["a", "b", "c", "d"]) + + def testKeywordCountDefaultsToTen(self): + self.assertEqual(IdeaCollisionGenerator().numKeywords, 10) + + def testOddKeywordCountIsRejected(self): + # createPairs() needs an even count, so it is refused up front + with self.assertRaises(ValueError): + IdeaCollisionGenerator(numKeywords=3) + + def testNonPositiveKeywordCountIsRejected(self): + with self.assertRaises(ValueError): + IdeaCollisionGenerator(numKeywords=0) + def testKeywordsAreShuffled(self): generator = IdeaCollisionGenerator() with mock.patch("builtins.input", side_effect=[str(i) for i in range(10)]): @@ -54,6 +89,19 @@ def testEmptyKeywordsAreAccepted(self): self.assertEqual(generator.keywords, [""] * 10) +class TestOrdinal(unittest.TestCase): + def testSuffixes(self): + generator = IdeaCollisionGenerator() + expected = { + 1: "1st", 2: "2nd", 3: "3rd", 4: "4th", 10: "10th", + 11: "11th", 12: "12th", 13: "13th", 14: "14th", + 21: "21st", 22: "22nd", 23: "23rd", 24: "24th", + 101: "101st", 111: "111th", 112: "112th", 113: "113th", 121: "121st", + } + for n, text in expected.items(): + self.assertEqual(generator.ordinal(n), text) + + class TestCreatePairs(unittest.TestCase): def testPairsAdjacentKeywords(self): generator = IdeaCollisionGenerator()