It's not unusual for early implementations of code to be excessive or unrefined.
The important thing is to refactor as necessary.
http://en.wikipedia.org/wiki/Code_refactoring
Your early implementations and final versions will improve over time if you learn more about Python, plan what you want your code to do, decompose data and functions, study other implementations, and ask for feedback.
In terms of code elegance and readability, I don't see the number of lines as a major consideration. In fact, multiple lines are usually preferable to a bunched up one liner.
In terms of comments, there are a few guidelines. You want to avoid useless comments. You don't need to comment every line of code. You don't need to comment obvious code. "#Sets c to a + b." is a useless comment.
How can you tell which code is obvious and which isn't? That is tricky, but I'd ask myself this question: "If I forgot this code, could I look at it and figure out what it does quickly?"
If you think you couldn't, you should add some useful comments explaining what it does.
Useful comments most often give the big picture of what code does. E.g. a useful comment for "c = math.sqrt(a ** 2 + b ** 2)" would be "Calculates the hypotenuse."
Let me offer you my implementation.
##The MIT License
##
##Copyright (c) 2011 Larry Haskins
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in
##all copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
##THE SOFTWARE.
#Python 3.1
import string
__all__ = ['rot']
#Case gnostic Caeser cipher tools.
#http://en.wikipedia.org/wiki/Caesar_cipher
UPPERCASE_OFFSET = 65
LOWERCASE_OFFSET = 97
ciphers = dict()
def shift(char, n):
"""Returns Caesar shift n of char."""
ordinal = ord(char)
#Caesar shift works only for letters.
if not char.isalpha():
raise ValueError(
"chr({ordinal}) not in alphabet!".format(**locals())
)
if char.islower():
offset = LOWERCASE_OFFSET
else:
offset = UPPERCASE_OFFSET
letter_value = ordinal - offset
raw_value = letter_value + n
new_value = raw_value % 26
new_ordinal = new_value + offset
new_letter = chr(new_ordinal)
return new_letter
def cipher(n):
"""Returns Caeser cipher for shift n."""
if n in ciphers:
return ciphers[n]
else:
cipher = dict()
for char in string.ascii_letters:
cipher[char] = shift(char, n)
global ciphers
ciphers[n] = cipher
return cipher
def translate(text, n):
"""Translates text using cipher(n)."""
cipher_ = cipher(n)
ciphertext = []
for char in text:
try:
ciphertext.append(cipher_[char])
except KeyError:
ciphertext.append(char)
return ''.join(ciphertext)
def rot(text):
"""Returns ROT13 of text.
http://en.wikipedia.org/wiki/ROT13"""
return translate(text, 13)
if __name__ == '__main__':
#USAGE:
#Caesar cipher shift 3 encryption and decryption.
plaintext = 'the quick brown fox jumps over the lazy dog'
ciphertext = translate(plaintext, 3)
assert ciphertext == 'wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj'
assert translate(ciphertext, -3) == 'the quick brown fox jumps over the lazy dog'
print('How can you tell an extrovert from an introvert at NSA?')
#ROT13
print(rot("Va gur ryringbef, gur rkgebireg ybbxf ng gur BGURE thl'f fubrf."))