changeset 9:46e1c1e6b564

Added from_key_sheet constructor and tests.
author Brian Neal <bgneal@gmail.com>
date Wed, 27 Nov 2013 19:15:17 -0600
parents 9e44ad188f4a
children cb053e95105e
files purple/machine.py purple/tests/test_machine.py
diffstat 2 files changed, 71 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/purple/machine.py	Wed Nov 27 18:31:48 2013 -0600
+++ b/purple/machine.py	Wed Nov 27 19:15:17 2013 -0600
@@ -116,4 +116,48 @@
 
         self.alphabet = alphabet
 
+    @classmethod
+    def from_key_sheet(cls, switches, alphabet=None):
+        """This class method allows one to construct a Purple97 using
+        a shorthand notation used by US codebreakers.
 
+        switches: must be a string of the form 'a-b,c,d-ef' where
+            a - starting position of the sixes switch (1-25)
+            b - starting position of the twenties switch #1 (1-25)
+            c - starting position of the twenties switch #2 (1-25)
+            d - starting position of the twenties switch #3 (1-25)
+            e - which switch is the fast switch (1-3)
+            f - which switch is the middle switch (1-3)
+
+        Example: '9-1,24,6-23'
+
+        Note that the starting positions here are 1-based since that is the
+        notation the US codebreakers seemed to have used.
+
+        alphabet: the daily alphabet, same format as in the __init__ function
+
+        """
+        try:
+            sixes, twenties, speed = switches.split('-')
+        except ValueError:
+            raise Purple97Error('invalid switches string (-)')
+
+        twenties = twenties.split(',')
+        if len(twenties) != 3:
+            raise Purple97Error('invalid twenties position')
+
+        try:
+            switches_pos = [int(s) - 1 for s in [sixes] + twenties]
+        except ValueError:
+            raise Purple97Error('switch positions must be numeric')
+
+        if len(speed) != 2:
+            raise Purple97Error('invalid switch speed settings')
+
+        try:
+            fast_switch, middle_switch = int(speed[0]), int(speed[1])
+        except ValueError:
+            raise Purple97Error('switch speed settings must be numeric')
+
+        return cls(switches_pos, fast_switch, middle_switch, alphabet)
+
--- a/purple/tests/test_machine.py	Wed Nov 27 18:31:48 2013 -0600
+++ b/purple/tests/test_machine.py	Wed Nov 27 19:15:17 2013 -0600
@@ -64,3 +64,30 @@
         self.assertRaises(Purple97Error, Purple97, alpha)
         alpha = 'M' * 26
         self.assertRaises(Purple97Error, Purple97, alpha)
+
+    def test_from_key_sheet(self):
+
+        Purple97.from_key_sheet('9-1,2,3-23')
+        Purple97.from_key_sheet('1-1,1,1-13')
+        Purple97.from_key_sheet('25-25,25,25-31')
+        Purple97.from_key_sheet('5-20,7,18-21', alphabet=string.ascii_uppercase)
+
+    def test_bad_from_key_sheet(self):
+
+        self.assertRaises(SteppingSwitchError, Purple97.from_key_sheet, '0-1,2,3-13')
+        self.assertRaises(SteppingSwitchError, Purple97.from_key_sheet, '26-1,2,3-13')
+        self.assertRaises(SteppingSwitchError, Purple97.from_key_sheet, '1-1,0,3-13')
+        self.assertRaises(SteppingSwitchError, Purple97.from_key_sheet, '1-1,2,26-13')
+        self.assertRaises(SteppingSwitchError, Purple97.from_key_sheet, '1-1,2,26-03')
+        self.assertRaises(SteppingSwitchError, Purple97.from_key_sheet, '1-1,2,26-00')
+        self.assertRaises(SteppingSwitchError, Purple97.from_key_sheet, '1-1,2,26-14')
+
+        self.assertRaises(Purple97Error, Purple97.from_key_sheet, 'bad string')
+        self.assertRaises(Purple97Error, Purple97.from_key_sheet, '1-2-1,2,26-14')
+        self.assertRaises(Purple97Error, Purple97.from_key_sheet, 'a-9,2,20-13')
+        self.assertRaises(Purple97Error, Purple97.from_key_sheet, '1-a,2,20-13')
+        self.assertRaises(Purple97Error, Purple97.from_key_sheet, '1-9,a,20-13')
+        self.assertRaises(Purple97Error, Purple97.from_key_sheet, '1-9,2,a-13')
+        self.assertRaises(Purple97Error, Purple97.from_key_sheet, '1-9,2,20-a3')
+        self.assertRaises(Purple97Error, Purple97.from_key_sheet, '1-9,2,20-1a')
+        self.assertRaises(Purple97Error, Purple97.from_key_sheet, '1-9,2,20-123')