Here is the table http://en.wikipedia.org/wiki/File:Vigen%C3%A8re_square_shading.svg
How can I implement this table in Python? What is the way(s) for this?
And any clue about how can I check for example Row: L & Column G becomes R welcome.
I like to use the standard library where possible to avoid rolling my own code and inadvertently leaving things out (like accidentally misplacing or forgetting a letter.)
import string
import collections
def vigsquare(printable=False):
'''
Returns a string like a vigenere square,
printable joins each row with a newline so it's literally square
printable=False (defaul) joins without newlines for easier
searching by row and column index
'''
alpha = string.ascii_uppercase
rotater = collections.deque(alpha)
vigsquare_list = []
for i in xrange(26):
vigsquare_list.append(''.join(rotater))
rotater.rotate(-1)
if printable:
return '\n'.join(vigsquare_list)
else:
return ''.join(vigsquare_list)
and
def vigenere(row, column):
'''
Return a character from a vigenere square by
row and column letter.
vigenere('L', 'G') returns 'R'
'''
alpha = string.ascii_uppercase
rowindex = alpha.find(row)
columnindex = alpha.find(column)
return vigsquare()[rowindex*26 + columnindex]
print vigsquare(printable=True)
vigenere('L', 'G')
gives you:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
BCDEFGHIJKLMNOPQRSTUVWXYZA
CDEFGHIJKLMNOPQRSTUVWXYZAB
DEFGHIJKLMNOPQRSTUVWXYZABC
EFGHIJKLMNOPQRSTUVWXYZABCD
FGHIJKLMNOPQRSTUVWXYZABCDE
GHIJKLMNOPQRSTUVWXYZABCDEF
HIJKLMNOPQRSTUVWXYZABCDEFG
IJKLMNOPQRSTUVWXYZABCDEFGH
JKLMNOPQRSTUVWXYZABCDEFGHI
KLMNOPQRSTUVWXYZABCDEFGHIJ
LMNOPQRSTUVWXYZABCDEFGHIJK
MNOPQRSTUVWXYZABCDEFGHIJKL
NOPQRSTUVWXYZABCDEFGHIJKLM
OPQRSTUVWXYZABCDEFGHIJKLMN
PQRSTUVWXYZABCDEFGHIJKLMNO
QRSTUVWXYZABCDEFGHIJKLMNOP
RSTUVWXYZABCDEFGHIJKLMNOPQ
STUVWXYZABCDEFGHIJKLMNOPQR
TUVWXYZABCDEFGHIJKLMNOPQRS
UVWXYZABCDEFGHIJKLMNOPQRST
VWXYZABCDEFGHIJKLMNOPQRSTU
WXYZABCDEFGHIJKLMNOPQRSTUV
XYZABCDEFGHIJKLMNOPQRSTUVW
YZABCDEFGHIJKLMNOPQRSTUVWX
ZABCDEFGHIJKLMNOPQRSTUVWXY
and
'R'
There was another solution that looked interesting here, but I didn't trust it because I didn't understand it, so I'll unittest my code and the other code to see if it's reliable.
def vig_2(row, col):
return string.ascii_uppercase[(ord(row) + ord(col)) % 26]
And unittested comparing both approaches. The second one (borrowed from NPE, to whom I now owe an upvote) is likely to be more performant if it is correct.:
import unittest
class VigTestCase(unittest.TestCase):
def test_vigenere(self):
self.assertEqual(vigenere('L', 'G'), 'R')
def test_vigsquare(self):
self.assertEqual(vigsquare(printable=False), 'ABCDEFGHIJKLMNOPQRSTUVWXYZBCDEFGHIJKLMNOPQRSTUVWXYZACDEFGHIJKLMNOPQRSTUVWXYZABDEFGHIJKLMNOPQRSTUVWXYZABCEFGHIJKLMNOPQRSTUVWXYZABCDFGHIJKLMNOPQRSTUVWXYZABCDEGHIJKLMNOPQRSTUVWXYZABCDEFHIJKLMNOPQRSTUVWXYZABCDEFGIJKLMNOPQRSTUVWXYZABCDEFGHJKLMNOPQRSTUVWXYZABCDEFGHIKLMNOPQRSTUVWXYZABCDEFGHIJLMNOPQRSTUVWXYZABCDEFGHIJKMNOPQRSTUVWXYZABCDEFGHIJKLNOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMNPQRSTUVWXYZABCDEFGHIJKLMNOQRSTUVWXYZABCDEFGHIJKLMNOPRSTUVWXYZABCDEFGHIJKLMNOPQSTUVWXYZABCDEFGHIJKLMNOPQRTUVWXYZABCDEFGHIJKLMNOPQRSUVWXYZABCDEFGHIJKLMNOPQRSTVWXYZABCDEFGHIJKLMNOPQRSTUWXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVWYZABCDEFGHIJKLMNOPQRSTUVWXZABCDEFGHIJKLMNOPQRSTUVWXY')
def test_vig2(self):
for i in string.ascii_uppercase:
for j in string.ascii_uppercase:
self.assertEqual(vig_2(i, j), vigenere(i, j))
unittest.main()
...
----------------------------------------------------------------------
Ran 3 tests in 0.038s
OK
So it looks like NPE had a very good solution!