my cryptogram program

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Mon May 15 20:50:26 EDT 2006


John Salerno a écrit :
> Alrighty, here is what I've come up with. Any suggestions for tweaks or 
> speed-boosting efficiency? Just kidding. :)

Too late ! You asked for it, you get it !-)

> Maybe the weakest part is how the code is determined (just shuffling the 
> letters in the alphabet). Perhaps there's a better way? Although it 
> seems effective to me....
> 
> 
> import string
> import random
> import itertools
> 
> def convert_quote(quote):
>     coded_quote = make_code(quote)
>     author = coded_quote.split('|')[1]
>     quote = coded_quote.split('|')[0]
>     return quote, author

def convert_quote(quote):
   return make_code(quote).split('|', 1)

> 
> def make_code(original):
>     original_letters = make_set(original)
>     new_letters = list(string.ascii_uppercase)
>     while True:
>         random.shuffle(new_letters)
>         trans_letters = ''.join(new_letters)[:len(original_letters)]
>         if test_code(original_letters, trans_letters):
>             trans_table = string.maketrans(original_letters, trans_letters)
>             break
>     return original.translate(trans_table)
> 
> def make_set(original):
>     original_set = set(original)
>     punc_space = string.punctuation + string.whitespace
>     for char in punc_space:
>         if char in original_set:
>             original_set.remove(char)
>     return ''.join(original_set)

PUNCT_SPACE_SET = set(string.punctuation + string.whitespace)
def make_set(original):
   return ''.join(set(original) - PUNCT_SPACE_SET)

<splitting-hairs>
BTW, the name make_set is a bit misleading, since the function returns a 
string... FWIW, some other functions could benefit from better naming too:
- convert_quote() takes a "<quote>|<author>" string and returns a 
(<coded_quote>, <coded_author>) pair (given the name, I would expect a 
"<coded_quote>| <coded_author>" string as output)
- make_code() doesn't actually 'make a code' - it really encrypt it's input
</splitting-hairs>

> 
> def test_code(original_letters, trans_letters):
>     for pair in itertools.izip(original_letters, trans_letters):
>         if pair[0] == pair[1]:
>             return False
>     return True

If you really want "speed-boosting efficiency", you may try this instead:
def test_code(original_letters, trans_letters)
     # assert len(original_letters) == len(trans_letters), \
     #    "original_letters and trans_letters should be of equal len"
     for i in range(original_letters):
         if original_letters[i] == trans_letters[i]:
             return False
     return True

> if __name__ == '__main__':
>     print convert_quote("The past is not dead. In fact, it's not even 
> past.|William Faulkner")

My 2 cents...



More information about the Python-list mailing list