PEP 8
The Style Guide for Python Code has many guidelines all Python programs should follow. Marc mentioned one (parameters and variables should be snake_case
not bumpyWords
.
Another is with regard to keyword parameters: the =
should not be surrounded with spaces when used for keywords. Instead of declaring the function like:
def caesar(inputString, rotation = 1):
...
it should be:
def caesar(input_string, rotation=1):
...
Type hints
Although Python is a not a strongly typed language, it is useful to pretend it is, and provide the expected types for the function parameters and return values. I’ll repeat that: expected types. The declarations actually don’t enforce anything, and are mostly ignored by the Python interpreter, but other tools (pylint, pyflakes, pychecker, mypy, ...) can read in the code and look for inconsistencies based on the declared types.
When using type hints, you do end up putting a space around the =
sign for the function’s keyword parameters:
def caesar(input_string: str, rotation: int = 1) -> str:
...
Docstrings
Python allows the author to include built-in documentation for functions using a """docstrings"""
immediately after the function declaration.
def caesar(input_string: str, rotation: int = 1) -> str:
"""
Encrypt an input string using a “Caesar Cipher”, where each
alphabetic character is replaced by the alphabetic character
`rotation` characters after it, wrapping around from `z` back
to `a`.
"""
...
Bugs
As others have noted, the program has bugs which happen when a rotation larger than 25 is used, or non-lowercase letters is given as input.
Efficiency
When translating longer texts, the method used is inefficient. For instance, when translating "stackoverflow"
, the translation for the letter “o” is computed more than once.
For translation of longer blocks of text, it would be more efficient to determine the translation key once, ahead of time, and then simply looking up the correct translation for each character.
def caesar(input_string: str, rotation: int = 1) -> str:
"""
Encrypt an input string using a “Caesar Cipher”, where each
alphabetic character is replaced by the alphabetic character
`rotation` characters after it, wrapping around from `z` back
to `a`.
"""
key = {}
for ch in string.ascii_lowercase:
key[ch] = chr((ord(ch) - ord('a') + rotation) % 26 + ord('a')
return ''.join(key.get(ch, ch) for ch in input_string)
Python actually has a built-in translation function for this purpose. Once the key
has been created, a translation table may be generated, and used.
def caesar(input_string: str, rotation: int = 1) -> str:
"""
Encrypt an input string using a “Caesar Cipher”, where each
alphabetic character is replaced by the alphabetic character
`rotation` characters after it, wrapping around from `z` back
to `a`.
"""
key = {}
for ch in string.ascii_lowercase:
key[ch] = chr((ord(ch) - ord('a') + rotation) % 26 + ord('a')
translation_table = str.maketrans(key)
return input_string.translate(translation_table)
Ideally, this translation_table
would only be created once, and could be reused for other translations.