import string import random import pandas # Functions go here def make_statement(statement, decoration): """Emphasises headings by adding decoration at the start and end""" return f"{decoration * 3} {statement} {decoration * 3}" def string_check(question, valid_answers=('yes', 'no'), num_letters=1): """Checks that users enter the full word or the 'n' letters of a word from a list of valid responses""" while True: response = input(question).lower() for item in valid_answers: # check if the response is the entire word if response == item: return item # check if it's the first letter elif response == item[:num_letters]: return item print(f"Please choose an option from {valid_answers}") def not_blank(question): """Checks that a user response is not blank""" while True: response = input(question) if response != "": return response print("Sorry, this can't be blank. Please try again.\n") def int_check(question, low, high): """Checks users enter an integer between two values""" error = f"Oops - please enter an integer between {low} and {high}." while True: try: # Change the response to an integer and check that it's more than zero response = int(input(question)) if low <= response <= high: return response else: print(error) except ValueError: print(error) def instructions(): make_statement("Instructions", "🎲") print('''Thank you for using this decoding program! First, select whether you want to encode or decode. If you want to disguise a message using the Caesar Cipher, select encode. If you have an already encoded message that you want to understand, select decode. Then enter your message and the number of letters you want it to be shifted by. Please do not attempt to copy and paste long messages into the program as they may end the dialogue. Instead, try decoding paragraph by paragraph. When you are done using the program, type 'xxx' into the enter message section. The program will record the messages you have encoded/decoded, what they were shifted by and how many times you have used the program. Once you have entered the exit code ('xxx'), the program will display your user history and write the data as a text file.''') def cipher(code_message, key, code_type): coded_message = "" for letter in code_message: if letter in alphabet: if key == "add": new_position = alphabet.index(letter) + shift_number else: new_position = alphabet.index(letter) - shift_number new_position = new_position % len(alphabet) coded_message = coded_message + alphabet[new_position] elif letter in upper_alphabet: if key == "add": new_position = upper_alphabet.index(letter) + shift_number else: new_position = upper_alphabet.index(letter) - shift_number new_position = new_position % len(upper_alphabet) coded_message = coded_message + upper_alphabet[new_position] else: coded_message = coded_message + letter print(f"This is your {code_type} message:", coded_message) return coded_message # initialise alphabet + enc_dec alphabet = list(string.ascii_lowercase) upper_alphabet = list(string.ascii_uppercase) messages_encoded = 0 messages_decoded = 0 cipher_types = ('encode', 'decode', 'xxxxx') # lists to hold message information all_messages = [] all_shift_numbers = [] all_decoded = [] all_encoded = [] caesar_cipher_dict = { 'Message': all_messages, 'Shift Number': all_shift_numbers, } # Main routine goes here make_statement("Caesar Cipher Program", "⚖") print() want_instructions = string_check("Do you want to see the instructions? ") if want_instructions == "yes": instructions() print() while True: # ask user for their message (and check it's not blank) print() message = not_blank("What is your message? ") # if message is exit code, break out of loop if message == "xxx": break # Add messages to the all messages list all_messages.append(message) # Ask for their shift_number shift_number = int_check("How many letters would you like to shift your message by? ", 1, 260) # Add shift_numbers to the shift_numbers list all_shift_numbers.append(shift_number) # ask user for cipher type (encode / decode / enc / dec) cipher_type = string_check("Type of cipher (encode/decode): ", cipher_types, 3) if cipher_type == 'encode': cipher_encode = cipher(message, "add", "encoded") messages_encoded += 1 all_encoded.append(cipher_encode) prior_message = string_check("Do you want to decode your prior message? ") if prior_message == "yes": cipher_decode = cipher(cipher_encode, "minus", "decoded") messages_decoded += 1 all_decoded.append(cipher_decode) elif cipher_type == 'decode': cipher_decode = cipher(message, "minus", "decoded") messages_decoded += 1 all_decoded.append(cipher_decode) prior_message = string_check("Do you want to encode your prior message? ") if prior_message == 'yes': cipher_encode = cipher(cipher_decode, "add", "encoded") # encode_returned = encode(cipher_decode_returned) messages_encoded += 1 all_encoded.append(cipher_encode) else: break # End of CC Loop # create dataframe / table from dictionary caesar_cipher_frame = pandas.DataFrame(caesar_cipher_dict) # messages encoded and decoded messages_encoded_string = f"You encoded {messages_encoded} messages. These messages were {all_encoded}." messages_decoded_string = f"You decoded {messages_decoded} messages. These messages were {all_decoded}." # uses all_uses_string = f"You used the program {messages_decoded + messages_encoded} times" # choose a random favourite message favourite = random.choice(all_messages) # Output movie frame without index caesar_cipher_string = caesar_cipher_frame.to_string(index=False) # favourite announcement fav_message_string = f"Our favourite message you encoded/decoded is '{favourite}'! Good job." # Additional strings / Headings heading_string = make_statement("Caesar Cipher Program", "⚖") user_details_heading = make_statement("User History and Details", "📖") final_statement_string = make_statement("Thank you for using our Caesar Cipher program. We hope you use it again in " "the future.", "💕") # List of strings to be outputted / written to file to_write = [heading_string, "\n", user_details_heading, caesar_cipher_string, "\n", messages_encoded_string, messages_decoded_string, "\n", all_uses_string, fav_message_string, "\n", final_statement_string] # Print area print() for item in to_write: print(item) # create file to hold data (add .txt extension file_name = "write_experiment" write_to = "{}.txt".format(file_name) text_file = open(write_to, "w+", encoding="utf-8") # write the item to file for item in to_write: text_file.write(item) text_file.write("\n")