import string, collections, re

def generate_key(rot):
    return zip(string.ascii_lowercase, string.ascii_uppercase[rot:] + string.ascii_uppercase[:rot])

def get_ciphertext_letters_by_frequency(ciphertext):
    ciphertext_nopunc = re.sub(r"\W+", "", ciphertext)
    letter_freqs = collections.Counter(ciphertext_nopunc)
    print(letter_freqs)
    return [i[0] for i in letter_freqs.most_common()]

def decipher(ciphertext, rot):
    key = generate_key(rot)
    for x, y in key:
        print(f"key[x] is {x}; key[y] is {y}")
        ciphertext = ciphertext.replace(x, y)
        print("ciphertext is now:",ciphertext)
    return ciphertext

def frequency_analysis(ciphertext):
    print("\n==================")
    print("Frequency Analysis")
    print("==================\n")
    most_common_letter = get_ciphertext_letters_by_frequency(ciphertext)[0]
    rot = (ord('e') - ord(most_common_letter)) % 26
    print("rot is:",rot)
    print(decipher(ciphertext, rot), "\n")

if __name__ == "__main__":
    ciphertext = "dvvkzecfssprkkve"
    print("Original Ciphertext: ", ciphertext)
    ciphertext = ciphertext.lower()
    print("Lowercase ciphertext: ", ciphertext)

    print("\nPerforming a Statistical Letter Frequency Analysis")
    frequency_analysis(ciphertext)
