<commit_before>import math
import secrets
from string import ascii_lowercase


class Cipher(object):
    def __init__(self, key=None):
        if not key:
            key = self._random_key()
        if not key.isalpha() or not key.islower():
            raise ValueError("Key must consist only of lowercase letters")
        self.key = key
        self._key = [ord(k)-97 for k in key]

    def encode(self, s):
        key = self._key * math.ceil(len(s)/len(self._key))
        chars = [c for c in s.lower() if c in ascii_lowercase]
        return "".join(self._shift(c, k) for c, k in zip(chars, key))

    def decode(self, s):
        key = self._key * math.ceil(len(s)/len(self._key))
        chars = [c for c in s.lower() if c in ascii_lowercase]
        return "".join(self._shift(c, -k) for c, k in zip(chars, key))

    @staticmethod
    def _shift(char, key):
        return chr(97 + ((ord(char) - 97 + key) % 26))

    @staticmethod
    def _random_key(length=256):
        return "".join(secrets.choice(ascii_lowercase) for _ in range(length))


class Caesar(Cipher):
    def __init__(self):
        super().__init__("d")
<commit_msg>Refactor to reuse the encode method for decoding<commit_after>import math
import secrets
from string import ascii_lowercase


class Cipher(object):
    def __init__(self, key=None):
        if not key:
            key = self._random_key()
        if not key.isalpha() or not key.islower():
            raise ValueError("Key must consist only of lowercase letters")
        self.key = key
        self._key = [ord(k)-97 for k in key]

    def encode(self, s, dirn=1):
        key = self._key * math.ceil(len(s)/len(self._key))
        chars = [c for c in s.lower() if c in ascii_lowercase]
        return "".join(self._shift(c, dirn*k) for c, k in zip(chars, key))

    def decode(self, s):
        return self.encode(s, dirn=-1)

    @staticmethod
    def _shift(char, key):
        return chr(97 + ((ord(char) - 97 + key) % 26))

    @staticmethod
    def _random_key(length=256):
        return "".join(secrets.choice(ascii_lowercase) for _ in range(length))


class Caesar(Cipher):
    def __init__(self):
        super().__init__("d")

{'fraction_non_alphanumeric': 0.12866300366300365, 'fraction_numerical': 0.01098901098901099, 'mean_word_length': 2.6115702479338845, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5501049', 'n_tokens_mistral': 752, 'n_tokens_neox': 709, 'n_words': 215}