From d872515343bd19cc3780ce8a9b118d3848c11363 Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 11:43:02 -0500 Subject: [PATCH 01/14] Initial commit --- src/ch07/c2_safe_cracker.py | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/ch07/c2_safe_cracker.py diff --git a/src/ch07/c2_safe_cracker.py b/src/ch07/c2_safe_cracker.py new file mode 100644 index 0000000..05df8f1 --- /dev/null +++ b/src/ch07/c2_safe_cracker.py @@ -0,0 +1,11 @@ +"""Use hill-climbing algorithm to solve a lock combination. + +Solve a lock combination by randomly changing a tumbler's values one +by one and noting whether the safe had a response. If so, lock the +tumbler at that value and continue randomly changing tumbler values. + +Previously, a locked tumbler can still be changed, but the safe wouldn't +respond so, the change would be discarded. This improves upon the algorithm by +removing the locked tumbler from the pool of tumblers to randomly change. + +""" From 7eac1bdcba2bde2b47a3c36fa819e7edf45a4c97 Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 12:13:26 -0500 Subject: [PATCH 02/14] Add compare --- src/ch07/c2_safe_cracker.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/ch07/c2_safe_cracker.py b/src/ch07/c2_safe_cracker.py index 05df8f1..6e17b4d 100644 --- a/src/ch07/c2_safe_cracker.py +++ b/src/ch07/c2_safe_cracker.py @@ -9,3 +9,20 @@ removing the locked tumbler from the pool of tumblers to randomly change. """ + + +def compare(combo: list, attempt: list) -> int: + """Compare items in two lists and count number of matches. + + Compare each element in **combo** with **attempt** and return + the number of matches. + + Args: + combo (list): Integers of safe combination. + attempt (list): Integers of guessed safe combination. + + Returns: + Number of combination matches between **combo** and **attempt**. + + """ + return sum(1 for i, j in zip(combo, attempt) if i == j) From 8c62783875a965e1e16492cd51313a188edf0f76 Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 12:13:35 -0500 Subject: [PATCH 03/14] Initialize TestSafeCracker with test_compare --- tests/test_chapter07.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/test_chapter07.py b/tests/test_chapter07.py index ed6466c..0e758b6 100644 --- a/tests/test_chapter07.py +++ b/tests/test_chapter07.py @@ -5,6 +5,7 @@ from io import StringIO import src.ch07.c1_breed_rats as breed_rats +import src.ch07.c2_safe_cracker as safe_cracker class TestBreedRats(unittest.TestCase): @@ -321,5 +322,36 @@ def test_main(self, mock_stdout, mock_random, mock_time): self.assertEqual(mock_stdout.getvalue(), file_data) +class TestSafeCracker(unittest.TestCase): + """Test Safe Cracker.""" + + def test_compare(self): + """Test compare.""" + list1 = [8] + list2 = [8] + test = safe_cracker.compare(list1, list2) + self.assertEqual(test, 1) + list1 = [8, 9] + list2 = [8] + test = safe_cracker.compare(list1, list2) + self.assertEqual(test, 1) + list1 = [8, 9] + list2 = [8, 8] + test = safe_cracker.compare(list1, list2) + self.assertEqual(test, 1) + list1 = [8, 9] + list2 = [8, 9] + test = safe_cracker.compare(list1, list2) + self.assertEqual(test, 2) + list1 = [8, 9, 7, 4, 5, 9, 0] + list2 = [8, 8, 6, 3, 5, 8, 1] + test = safe_cracker.compare(list1, list2) + self.assertEqual(test, 2) + list1 = [8, 9, 7, 4, 5, 9, 0] + list2 = [8, 9, 7, 4, 5, 9, 0] + test = safe_cracker.compare(list1, list2) + self.assertEqual(test, 7) + + if __name__ == '__main__': unittest.main() From 630d09449711d2d120aba67a39fd15c189d90ee0 Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 14:01:12 -0500 Subject: [PATCH 04/14] Add crack_safe --- src/ch07/c2_safe_cracker.py | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/ch07/c2_safe_cracker.py b/src/ch07/c2_safe_cracker.py index 6e17b4d..8e1c56a 100644 --- a/src/ch07/c2_safe_cracker.py +++ b/src/ch07/c2_safe_cracker.py @@ -9,6 +9,7 @@ removing the locked tumbler from the pool of tumblers to randomly change. """ +import random def compare(combo: list, attempt: list) -> int: @@ -26,3 +27,48 @@ def compare(combo: list, attempt: list) -> int: """ return sum(1 for i, j in zip(combo, attempt) if i == j) + + +def crack_safe(combo: str) -> tuple: + """Crack a safe combination with a hill-climbing algorithm. + + Solve a lock combination by randomly changing a tumbler's values one + by one and noting whether the safe had a response. If so, lock the + tumbler at that value, remove it from the pool of tumblers, and + continue randomly changing tumbler values. + + Args: + combo (str): String of numbers representing combination of safe. + + Returns: + Tuple with string of solved combination and number of attempts. + + """ + # Convert combo to list. + combo = [int(i) for i in combo] + + # Make initial guess and compare. + best_guess = [0] * len(combo) + best_guess_match = compare(combo, best_guess) + + count = 0 + tumblers = list(range(len(combo))) + + # Evolve guess. + while best_guess != combo: + # Crossover. + guess = best_guess.copy() + + # Mutate. + lock_tumbler = random.choice(tumblers) + guess[lock_tumbler] = random.randint(0, len(combo) - 1) + + # Compare and select. + guess_match = compare(combo, guess) + if guess_match > best_guess_match: + best_guess = guess.copy() + best_guess_match = guess_match + tumblers.remove(lock_tumbler) + print(guess, best_guess) + count += 1 + return ''.join([str(i) for i in best_guess]), count From 8cc9c7a3888b16896ad2b677c256c8702c19c0f3 Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 14:01:41 -0500 Subject: [PATCH 05/14] Initial commit --- tests/data/ch07/safe_cracker.txt | 110 +++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 tests/data/ch07/safe_cracker.txt diff --git a/tests/data/ch07/safe_cracker.txt b/tests/data/ch07/safe_cracker.txt new file mode 100644 index 0000000..fe5fcd3 --- /dev/null +++ b/tests/data/ch07/safe_cracker.txt @@ -0,0 +1,110 @@ +[0, 0, 0, 0, 0, 0, 0, 0, 0, 5] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 8, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 0, 0, 0, 5] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 0, 0, 0, 9] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 6, 0, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 9, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 2, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 0, 0, 3, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 8, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 7, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 9, 0, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 2, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 0, 8, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 0, 0, 0, 1] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 5, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 1, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 6, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 0, 6, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 4, 0, 0, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 8, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 4, 0, 0, 0, 0, 0, 0] [0, 0, 0, 4, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 4, 9, 0, 0, 0, 0, 0] [0, 0, 0, 4, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 4, 0, 0, 0, 4, 0, 0] [0, 0, 0, 4, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 4, 0, 0, 0, 0, 0, 0] [0, 0, 0, 4, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 4, 0, 8, 0, 0, 0, 0] [0, 0, 0, 4, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 4, 0, 0, 0, 5, 0, 0] [0, 0, 0, 4, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 4, 0, 0, 0, 0, 3, 0] [0, 0, 0, 4, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 4, 0, 4, 0, 0, 0, 0] [0, 0, 0, 4, 0, 0, 0, 0, 0, 0] +[0, 0, 5, 4, 0, 0, 0, 0, 0, 0] [0, 0, 0, 4, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 4, 0, 0, 0, 0, 6, 0] [0, 0, 0, 4, 0, 0, 0, 0, 0, 0] +[0, 7, 0, 4, 0, 0, 0, 0, 0, 0] [0, 0, 0, 4, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 4, 9, 0, 0, 0, 0, 0] [0, 0, 0, 4, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 4, 0, 0, 0, 0, 0, 3] [0, 0, 0, 4, 0, 0, 0, 0, 0, 3] +[0, 0, 0, 4, 0, 0, 1, 0, 0, 3] [0, 0, 0, 4, 0, 0, 0, 0, 0, 3] +[0, 0, 0, 4, 0, 0, 0, 0, 0, 3] [0, 0, 0, 4, 0, 0, 0, 0, 0, 3] +[0, 0, 0, 4, 0, 0, 6, 0, 0, 3] [0, 0, 0, 4, 0, 0, 0, 0, 0, 3] +[0, 0, 0, 4, 0, 0, 8, 0, 0, 3] [0, 0, 0, 4, 0, 0, 0, 0, 0, 3] +[0, 0, 0, 4, 0, 3, 0, 0, 0, 3] [0, 0, 0, 4, 0, 0, 0, 0, 0, 3] +[0, 0, 0, 4, 0, 0, 9, 0, 0, 3] [0, 0, 0, 4, 0, 0, 0, 0, 0, 3] +[0, 0, 0, 4, 0, 1, 0, 0, 0, 3] [0, 0, 0, 4, 0, 0, 0, 0, 0, 3] +[0, 0, 0, 4, 0, 0, 0, 0, 0, 3] [0, 0, 0, 4, 0, 0, 0, 0, 0, 3] +[8, 0, 0, 4, 0, 0, 0, 0, 0, 3] [8, 0, 0, 4, 0, 0, 0, 0, 0, 3] +[8, 0, 0, 4, 0, 0, 0, 3, 0, 3] [8, 0, 0, 4, 0, 0, 0, 0, 0, 3] +[8, 0, 0, 4, 0, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 0, 9, 4, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 4, 4, 0, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 0, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 2, 0, 4, 0, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 3, 4, 0, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 8, 4, 0, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 0, 9, 2, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 0, 9, 8, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 8, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 0, 9, 5, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 9, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 8, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 0, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 0, 9, 0, 0, 8, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 2, 0, 4, 0, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 6, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 4, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 4, 0, 4, 0, 9, 0, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 0, 4, 0, 9, 9, 0, 0, 3] [8, 0, 0, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 7, 4, 0, 9, 0, 0, 0, 3] [8, 0, 7, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 7, 4, 0, 9, 0, 0, 7, 3] [8, 0, 7, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 7, 4, 2, 9, 0, 0, 0, 3] [8, 0, 7, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 7, 4, 0, 9, 0, 0, 7, 3] [8, 0, 7, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 7, 4, 0, 9, 0, 9, 0, 3] [8, 0, 7, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 7, 4, 0, 9, 2, 0, 0, 3] [8, 0, 7, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 7, 4, 0, 9, 0, 0, 0, 3] [8, 0, 7, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 7, 4, 0, 9, 4, 0, 0, 3] [8, 0, 7, 4, 0, 9, 0, 0, 0, 3] +[8, 0, 7, 4, 0, 9, 0, 2, 0, 3] [8, 0, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 2, 7, 4, 0, 9, 0, 2, 0, 3] [8, 0, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 4, 7, 4, 0, 9, 0, 2, 0, 3] [8, 0, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 0, 7, 4, 0, 9, 8, 2, 0, 3] [8, 0, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 2, 7, 4, 0, 9, 0, 2, 0, 3] [8, 0, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 7, 9, 0, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 7, 9, 0, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 2, 9, 0, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 7, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 3, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 4, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 3, 9, 0, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 7, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 6, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 7, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 9, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 3, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 3, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 8, 9, 0, 2, 0, 3] [8, 9, 7, 4, 0, 9, 0, 2, 0, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 1, 3] [8, 9, 7, 4, 0, 9, 0, 2, 1, 3] +[8, 9, 7, 4, 9, 9, 0, 2, 1, 3] [8, 9, 7, 4, 0, 9, 0, 2, 1, 3] +[8, 9, 7, 4, 0, 9, 9, 2, 1, 3] [8, 9, 7, 4, 0, 9, 0, 2, 1, 3] +[8, 9, 7, 4, 0, 9, 5, 2, 1, 3] [8, 9, 7, 4, 0, 9, 0, 2, 1, 3] +[8, 9, 7, 4, 3, 9, 0, 2, 1, 3] [8, 9, 7, 4, 0, 9, 0, 2, 1, 3] +[8, 9, 7, 4, 7, 9, 0, 2, 1, 3] [8, 9, 7, 4, 0, 9, 0, 2, 1, 3] +[8, 9, 7, 4, 4, 9, 0, 2, 1, 3] [8, 9, 7, 4, 0, 9, 0, 2, 1, 3] +[8, 9, 7, 4, 0, 9, 6, 2, 1, 3] [8, 9, 7, 4, 0, 9, 0, 2, 1, 3] +[8, 9, 7, 4, 0, 9, 0, 2, 1, 3] [8, 9, 7, 4, 0, 9, 0, 2, 1, 3] +[8, 9, 7, 4, 0, 9, 4, 2, 1, 3] [8, 9, 7, 4, 0, 9, 0, 2, 1, 3] +[8, 9, 7, 4, 5, 9, 0, 2, 1, 3] [8, 9, 7, 4, 5, 9, 0, 2, 1, 3] From c4607b932cd37f1296644b6df1ddf3d8215f86d9 Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 14:02:06 -0500 Subject: [PATCH 06/14] Add setUpClass to TestSafeCracker --- tests/test_chapter07.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_chapter07.py b/tests/test_chapter07.py index 0e758b6..8a9596d 100644 --- a/tests/test_chapter07.py +++ b/tests/test_chapter07.py @@ -325,6 +325,11 @@ def test_main(self, mock_stdout, mock_random, mock_time): class TestSafeCracker(unittest.TestCase): """Test Safe Cracker.""" + @classmethod + def setUpClass(cls): + """Configure attributes for use in this class only.""" + cls.random = Random() + def test_compare(self): """Test compare.""" list1 = [8] From c49098ea3f7e3c690d0e7cd37a35d38805662561 Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 14:02:35 -0500 Subject: [PATCH 07/14] Add test_crack_safe to TestSafeCracker --- tests/test_chapter07.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/test_chapter07.py b/tests/test_chapter07.py index 8a9596d..ed1ad0e 100644 --- a/tests/test_chapter07.py +++ b/tests/test_chapter07.py @@ -357,6 +357,26 @@ def test_compare(self): test = safe_cracker.compare(list1, list2) self.assertEqual(test, 7) + @unittest.mock.patch('src.ch07.c2_safe_cracker.random') + @unittest.mock.patch('sys.stdout', new_callable=StringIO) + def test_crack_safe(self, mock_stdout, mock_random): + """Test crack_safe.""" + # Patch random to use non-random seed. + self.random.seed(211) + mock_random.choice._mock_side_effect = self.random.choice + mock_random.randint._mock_side_effect = self.random.randint + + combo = '8974590213' + test, count = safe_cracker.crack_safe(combo) + self.assertEqual(count, 110) + self.assertEqual(combo, test) + + # Test sys.stdout output. + with open(os.path.normpath('tests/data/ch07/safe_cracker.txt'), + 'r') as file: + file_data = ''.join(file.readlines()) + self.assertEqual(mock_stdout.getvalue(), file_data) + if __name__ == '__main__': unittest.main() From c2127bdc5e1d6eeb8e9b56081d6dae30364925b3 Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 14:09:51 -0500 Subject: [PATCH 08/14] Fix punctuation in module docstring --- src/ch07/c2_safe_cracker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch07/c2_safe_cracker.py b/src/ch07/c2_safe_cracker.py index 8e1c56a..babd8fd 100644 --- a/src/ch07/c2_safe_cracker.py +++ b/src/ch07/c2_safe_cracker.py @@ -5,7 +5,7 @@ tumbler at that value and continue randomly changing tumbler values. Previously, a locked tumbler can still be changed, but the safe wouldn't -respond so, the change would be discarded. This improves upon the algorithm by +respond, so the change would be discarded. This improves upon the algorithm by removing the locked tumbler from the pool of tumblers to randomly change. """ From c9ae13da7230b0f93f26ed08286400c78c93d5c5 Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 14:10:02 -0500 Subject: [PATCH 09/14] Add main --- src/ch07/c2_safe_cracker.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/ch07/c2_safe_cracker.py b/src/ch07/c2_safe_cracker.py index babd8fd..402b97d 100644 --- a/src/ch07/c2_safe_cracker.py +++ b/src/ch07/c2_safe_cracker.py @@ -9,6 +9,7 @@ removing the locked tumbler from the pool of tumblers to randomly change. """ +import time import random @@ -72,3 +73,27 @@ def crack_safe(combo: str) -> tuple: print(guess, best_guess) count += 1 return ''.join([str(i) for i in best_guess]), count + + +def main(): + """Demonstrate safe cracker. + + Use default combination to demonstrate :func:`crack_safe` and display time + (in seconds) it took to run. + + """ + start_time = time.time() + + combination = '6822858902' + print(f'Combination: {combination}') + guess, count = crack_safe(combination) + print(f'\nCracked! {guess} ') + print(f'in {count} tries!') + + end_time = time.time() + duration = end_time - start_time + print(f'\nRuntime for this program was {duration:.5f} seconds.') + + +if __name__ == '__main__': + main() From 97df86ba7eef0936c0248dbea55afcf687c46f86 Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 14:14:21 -0500 Subject: [PATCH 10/14] Initial commit --- tests/data/ch07/main/safe_cracker.txt | 127 ++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 tests/data/ch07/main/safe_cracker.txt diff --git a/tests/data/ch07/main/safe_cracker.txt b/tests/data/ch07/main/safe_cracker.txt new file mode 100644 index 0000000..01a80a1 --- /dev/null +++ b/tests/data/ch07/main/safe_cracker.txt @@ -0,0 +1,127 @@ +Combination: 6822858902 +[0, 0, 0, 5, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 0, 3, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 6, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +[0, 0, 0, 0, 0, 0, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 6, 0, 0, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 0, 0, 0, 0, 0, 3, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 7, 0, 0, 0, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 0, 0, 0, 6, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 0, 6, 0, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 5, 0, 0, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 0, 0, 0, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 0, 0, 3, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 0, 0, 0, 0, 6, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 6, 0, 0, 0, 0, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 0, 0, 0, 0, 0, 1, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 0, 1, 0, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 0, 0, 7, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 5, 0, 0, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 8, 0, 0, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 0, 0, 0, 0, 0, 0, 2] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2] +[0, 0, 0, 0, 0, 0, 8, 0, 0, 2] [0, 0, 0, 0, 0, 0, 8, 0, 0, 2] +[0, 0, 0, 0, 7, 0, 8, 0, 0, 2] [0, 0, 0, 0, 0, 0, 8, 0, 0, 2] +[0, 0, 0, 0, 0, 0, 8, 0, 7, 2] [0, 0, 0, 0, 0, 0, 8, 0, 0, 2] +[0, 9, 0, 0, 0, 0, 8, 0, 0, 2] [0, 0, 0, 0, 0, 0, 8, 0, 0, 2] +[0, 0, 0, 0, 0, 0, 8, 0, 0, 2] [0, 0, 0, 0, 0, 0, 8, 0, 0, 2] +[0, 0, 7, 0, 0, 0, 8, 0, 0, 2] [0, 0, 0, 0, 0, 0, 8, 0, 0, 2] +[0, 0, 0, 0, 0, 0, 8, 0, 8, 2] [0, 0, 0, 0, 0, 0, 8, 0, 0, 2] +[5, 0, 0, 0, 0, 0, 8, 0, 0, 2] [0, 0, 0, 0, 0, 0, 8, 0, 0, 2] +[0, 0, 0, 7, 0, 0, 8, 0, 0, 2] [0, 0, 0, 0, 0, 0, 8, 0, 0, 2] +[0, 0, 2, 0, 0, 0, 8, 0, 0, 2] [0, 0, 2, 0, 0, 0, 8, 0, 0, 2] +[0, 0, 2, 0, 0, 8, 8, 0, 0, 2] [0, 0, 2, 0, 0, 0, 8, 0, 0, 2] +[0, 0, 2, 0, 9, 0, 8, 0, 0, 2] [0, 0, 2, 0, 0, 0, 8, 0, 0, 2] +[0, 0, 2, 0, 0, 0, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 0, 0, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 0, 9, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 0, 0, 8, 9, 3, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 2, 2, 0, 0, 0, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 0, 9, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 0, 0, 8, 9, 4, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 0, 0, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 0, 0, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 1, 0, 0, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 0, 1, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 5, 0, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 3, 2, 0, 0, 0, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 0, 9, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 1, 0, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 0, 6, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 3, 0, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 0, 0, 0, 8, 9, 1, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[0, 0, 2, 4, 0, 0, 8, 9, 0, 2] [0, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[6, 0, 2, 0, 0, 0, 8, 9, 0, 2] [6, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[6, 0, 2, 3, 0, 0, 8, 9, 0, 2] [6, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[6, 7, 2, 0, 0, 0, 8, 9, 0, 2] [6, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[6, 0, 2, 0, 0, 4, 8, 9, 0, 2] [6, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[6, 0, 2, 0, 0, 0, 8, 9, 0, 2] [6, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[6, 0, 2, 3, 0, 0, 8, 9, 0, 2] [6, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[6, 0, 2, 0, 0, 9, 8, 9, 0, 2] [6, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[6, 0, 2, 0, 0, 0, 8, 9, 0, 2] [6, 0, 2, 0, 0, 0, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 0, 8, 9, 0, 2] [6, 8, 2, 0, 0, 0, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 4, 8, 9, 0, 2] [6, 8, 2, 0, 0, 0, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 3, 8, 9, 0, 2] [6, 8, 2, 0, 0, 0, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 6, 0, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 4, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 8, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 6, 0, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 9, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 5, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 6, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 6, 0, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 8, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 9, 0, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 4, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 3, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 7, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 1, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 9, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 4, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 9, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 3, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 5, 0, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 2, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 4, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 8, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 1, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 9, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 5, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 4, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 4, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 1, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 0, 5, 8, 9, 0, 2] [6, 8, 2, 0, 0, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 3, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 8, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 9, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 4, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 8, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 6, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 3, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 4, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 6, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 6, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 8, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 7, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 8, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 7, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 7, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 3, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 7, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 7, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 7, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 4, 8, 5, 8, 9, 0, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 4, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 6, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 0, 8, 5, 8, 9, 6, 2] [6, 8, 2, 0, 8, 5, 8, 9, 0, 2] +[6, 8, 2, 2, 8, 5, 8, 9, 0, 2] [6, 8, 2, 2, 8, 5, 8, 9, 0, 2] + +Cracked! 6822858902 +in 121 tries! + +Runtime for this program was 55545.00000 seconds. From 87155a71d1657960e149b1c9c6e839a481f5bf6d Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 14:14:38 -0500 Subject: [PATCH 11/14] Add test_main to TestSafeCracker --- tests/test_chapter07.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/test_chapter07.py b/tests/test_chapter07.py index ed1ad0e..169476a 100644 --- a/tests/test_chapter07.py +++ b/tests/test_chapter07.py @@ -377,6 +377,25 @@ def test_crack_safe(self, mock_stdout, mock_random): file_data = ''.join(file.readlines()) self.assertEqual(mock_stdout.getvalue(), file_data) + @unittest.mock.patch('src.ch07.c2_safe_cracker.time') + @unittest.mock.patch('src.ch07.c2_safe_cracker.random') + @unittest.mock.patch('sys.stdout', new_callable=StringIO) + def test_main(self, mock_stdout, mock_random, mock_time): + """Test main.""" + # Patch out variances. + self.random.seed(111) + mock_random.choice._mock_side_effect = self.random.choice + mock_random.randint._mock_side_effect = self.random.randint + mock_time.time.side_effect = [12345, 67890] + + safe_cracker.main() + + # Test sys.stdout output. + with open(os.path.normpath('tests/data/ch07/main/safe_cracker.txt'), + 'r') as file: + file_data = ''.join(file.readlines()) + self.assertEqual(mock_stdout.getvalue(), file_data) + if __name__ == '__main__': unittest.main() From 238eb19db8f0bbb54f5f3c8b66a0bf202c5d2df1 Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 14:15:24 -0500 Subject: [PATCH 12/14] Add c2_safe_cracker --- docs/source/src.ch07.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/source/src.ch07.rst b/docs/source/src.ch07.rst index 6885a5b..3801c32 100644 --- a/docs/source/src.ch07.rst +++ b/docs/source/src.ch07.rst @@ -12,6 +12,14 @@ src.ch07.c1\_breed\_rats module :undoc-members: :show-inheritance: +src.ch07.c2\_safe\_cracker module +--------------------------------- + +.. automodule:: src.ch07.c2_safe_cracker + :members: + :undoc-members: + :show-inheritance: + Module contents --------------- From 65b4757a34d517c38309affec4748e84f915760c Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 14:46:11 -0500 Subject: [PATCH 13/14] [skip ci] Reword compare docstring --- src/ch07/c2_safe_cracker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch07/c2_safe_cracker.py b/src/ch07/c2_safe_cracker.py index 402b97d..d1ec9a3 100644 --- a/src/ch07/c2_safe_cracker.py +++ b/src/ch07/c2_safe_cracker.py @@ -16,7 +16,7 @@ def compare(combo: list, attempt: list) -> int: """Compare items in two lists and count number of matches. - Compare each element in **combo** with **attempt** and return + Compare each tumbler in **combo** with **attempt** and return the number of matches. Args: @@ -24,7 +24,7 @@ def compare(combo: list, attempt: list) -> int: attempt (list): Integers of guessed safe combination. Returns: - Number of combination matches between **combo** and **attempt**. + Number of tumbler matches between **combo** and **attempt**. """ return sum(1 for i, j in zip(combo, attempt) if i == j) From e7acfc8bc68e99c9bd8ea2869adbb4848eb89c5d Mon Sep 17 00:00:00 2001 From: JoseALermaIII Date: Sun, 13 Oct 2019 14:46:11 -0500 Subject: [PATCH 14/14] Reword compare docstring --- src/ch07/c2_safe_cracker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch07/c2_safe_cracker.py b/src/ch07/c2_safe_cracker.py index 402b97d..d1ec9a3 100644 --- a/src/ch07/c2_safe_cracker.py +++ b/src/ch07/c2_safe_cracker.py @@ -16,7 +16,7 @@ def compare(combo: list, attempt: list) -> int: """Compare items in two lists and count number of matches. - Compare each element in **combo** with **attempt** and return + Compare each tumbler in **combo** with **attempt** and return the number of matches. Args: @@ -24,7 +24,7 @@ def compare(combo: list, attempt: list) -> int: attempt (list): Integers of guessed safe combination. Returns: - Number of combination matches between **combo** and **attempt**. + Number of tumbler matches between **combo** and **attempt**. """ return sum(1 for i, j in zip(combo, attempt) if i == j)