Search code examples
pythonpython-2.7minimize

Minimizing lines of code


I have a few lines of code for making a rotated string for a Caesar cipher and just for fun I am trying to condense them into one. Obviously this is pointless since it is completely unreadable but I'm curious. Still, I can't quite figure out how to do it. Here's what I have tried so far

s = 'abcdefghijklmnopqrstuvwxyz'
rot = raw_input('Enter Rotation or Key: ')
s = s[-int(rot):] + s[:-int(rot)] if rot.isdigit() else rot.lower()+ ''.join([j for i in s for j in rot.lower() if j == i]) # This is the only line I want condensed
print s

Here is the readable version which actually works

s = 'abcdefghijklmnopqrstuvwxyz'
rot = raw_input('Enter Rotation or Key: ')
if rot.isdigit():                        #I only want from here
    s = s[-int(rot):] + s[:-int(rot)]
else:
    for i in rot.lower():
        s = s.replace(i,'')
    s = rot.lower() + s                  #To here condensed into one line
print s

rot is the amount to rotate the alphabet or the key for a keyed version of a Caesar cipher. You should be able to just run the code as is and see exactly what's wrong

I know this is bad code but I find this kind of code interesting since the language supports linking so many if/else/for/lambda/whatever together into a single line.


Solution

  • You can rewrite the else case using reduce (it’s functools.reduce in Python 3):

    if rot.isdigit():
        s = s[-int(rot):] + s[:-int(rot)]
    else:
        s = rot.lower() + reduce(lambda x, y: x.replace(y, ''), rot.lower(), s)
    

    And then you can combine it to one line:

    s = s[-int(rot):] + s[:-int(rot)] if rot.isdigit() else rot.lower() + reduce(lambda x, y: x.replace(y, ''), rot.lower(), s)
    

    But you’re absolutely right: It makes no sense to write it like this. It’s really unreadable.


    Since you’re using Python 2, you can actually use str.translate here too, to remove the characters in rot from s. This uses the deletechars parameter of that function:

    s = rot.lower() + s.translate(None, rot.lower())
    

    Your one-line expression is then a little bit shorter:

    s = s[-int(rot):] + s[:-int(rot)] if rot.isdigit() else rot.lower() + s.translate(None, rot.lower())