def internal_ord(c): c = c.lower() internal_ord = ord(c) - ord("a") if(internal_ord < 0 or internal_ord > 25): raise ValueError("'{}' is an unsupported character".format(c)) return internal_ord def internal_chr(i): return chr(ord("a") + i) def encode_or_keeps_space(c): if(c == " "): return (False, c) return (True, internal_ord(c)) def prepare_string(s): return (encode_or_keeps_space(c) for c in s) def _caesar(s, K): for encode, i in prepare_string(s): if(encode): yield internal_chr((i + K) % 26) else: yield i def caesar(s, K): return "".join(_caesar(s, K))