A friend of mine wanted help learning to program, so he gave me all the programs that he wrote for his previous classes. The last program that he wrote was an encryption program, and after rewriting all his programs in Python, this is how his encryption program turned out (after adding my own requirements).
#! /usr/bin/env python
################################################################################
"""\
CLASS INFORMATION
-----------------
Program Name: Program 11
Programmer: Stephen Chappell
Instructor: Stephen Chappell for CS 999-0, Python
Due Date: 17 May 2010
DOCUMENTATION
-------------
This is a simple encryption program that can encode and decode messages."""
################################################################################
import sys
KEY_FILE = 'Key.txt'
BACKUP = '''\
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO\
PQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
_@/6-UC'GzaV0%5Mo9g+yNh8b">Bi=<Lx [sQn#^R.D2Xc(\
Jm!4e${lAEWud&t7]H\`}pvPw)FY,Z~?qK|3SOfk*:1;jTrI''' #`
################################################################################
def main():
"Run the program: loads key, runs processing loop, and saves key."
encode_map, decode_map = load_key(KEY_FILE)
try:
run_interface_loop(encode_map, decode_map)
except SystemExit:
pass
save_key(KEY_FILE, encode_map)
def run_interface_loop(encode_map, decode_map):
"Shows the menu and runs the appropriate command."
print('This program handles encryption via a customizable key.')
while True:
print('''\
MENU
====
(1) Encode
(2) Decode
(3) Custom
(4) Finish''')
switch = get_character('Select: ', tuple('1234'))
FUNC[switch](encode_map, decode_map)
def get_character(prompt, choices):
"Gets a valid menu option and returns it."
while True:
sys.stdout.write(prompt)
sys.stdout.flush()
line = sys.stdin.readline()[:-1]
if not line:
sys.exit()
if line in choices:
return line
print(repr(line), 'is not a valid choice.')
################################################################################
def load_key(filename):
"Gets the key file data and returns encoding/decoding dictionaries."
plain, cypher = open_file(filename)
return dict(zip(plain, cypher)), dict(zip(cypher, plain))
def open_file(filename):
"Load the keys and tries to create it when not available."
while True:
try:
with open(filename) as file:
plain, cypher = file.read().split('\n')
return plain, cypher
except:
with open(filename, 'w') as file:
file.write(BACKUP)
def save_key(filename, encode_map):
"Dumps the map into two buffers and saves them to the key file."
plain = cypher = str()
for p, c in encode_map.items():
plain += p
cypher += c
with open(filename, 'w') as file:
file.write(plain + '\n' + cypher)
################################################################################
def encode(encode_map, decode_map):
"Encodes message for the user."
print('Enter your message to encode (EOF when finished).')
message = get_message()
for char in message:
sys.stdout.write(encode_map[char] if char in encode_map else char)
def decode(encode_map, decode_map):
"Decodes message for the user."
print('Enter your message to decode (EOF when finished).')
message = get_message()
for char in message:
sys.stdout.write(decode_map[char] if char in decode_map else char)
def custom(encode_map, decode_map):
"Allows user to edit the encoding/decoding dictionaries."
plain, cypher = get_new_mapping()
for p, c in zip(plain, cypher):
encode_map[p] = c
decode_map[c] = p
################################################################################
def get_message():
"Gets and returns text entered by the user (until EOF)."
buffer = []
while True:
line = sys.stdin.readline()
if line:
buffer.append(line)
else:
return ''.join(buffer)
def get_new_mapping():
"Prompts for strings to edit encoding/decoding maps."
while True:
plain = get_unique_chars('What do you want to encode from?')
cypher = get_unique_chars('What do you want to encode to?')
if len(plain) == len(cypher):
return plain, cypher
print('Both lines should have the same length.')
def get_unique_chars(prompt):
"Gets strings that only contain unique characters."
print(prompt)
while True:
line = input()
if len(line) == len(set(line)):
return line
print('There were duplicate characters: please try again.')
################################################################################
# This map is used for dispatching commands in the interface loop.
FUNC = {'1': encode, '2': decode, '3': custom, '4': lambda a, b: sys.exit()}
################################################################################
if __name__ == '__main__':
main()
For all those Python programmers out there, your help is being requested. How should the formatting (not necessarily the coding by altered to fit Python's style guide? My friend does not need to be learning things that are not correct. If you have suggestions on the code, feel free to post them to this wiki as well.
EDIT: For those interested, here is the original code source in C that my friend gave me for translation.
/******************************************************************************
CLASS INFORMATION
-----------------
Program Name: Program 11 - Encodes/Decodes
Programmer: Evgnto nAl.Wi a
Instructor: fsSP21 .C emgr2rCHoMal4 gyia ro-rm n ,
Date Due: MAY 4, 2010
PLEDGE STATEMENT
----------------
I pledge that all of the code in this program is my own _original_ work for
the spring 2010 semester. None of the code in this program has been copied
from anyone or anyplace unless I was specifically authorized to do so by my
CS 214 instructor. This program has been created using properly licensed
software.
Signed: ________________________________
DOCUMENTATION
-------------
This program Encodes and decodes a program. It also gives you the option of
making your own code.
******************************************************************************/
#include <stdio.h>
#define ENCODE 1
#define DECODE 2
#define OWNCODE 3
#define QUIT 4
void printPurpose();
void encode(char input[], char code1[]);
void decode(char input[], char code1[]);
void ownCode();
int main()
{
char charIn;
char code1[100] = "";
char input[100] = "";
int a;
int b;
int closeStatus;
int number;
a = 0;
b = 0;
FILE *code;
printPurpose();
if (!(code = fopen("code.txt", "r")))
{
printf("Error opening code.txt for reading");
return 100;
}
while ((charIn = fgetc(code)) != '\n')
{
input[a] = charIn;
a++;
}
while ((charIn = fgetc(code)) != EOF)
{
code1[b] = charIn;
b++;
}
scanf("%d", &number);
while (number != QUIT)
{
if (number == ENCODE)
encode(input, code1);
else if (number == DECODE)
decode(input, code1);
else if (number == OWNCODE)
ownCode();
printf("\n\n");
printPurpose();
scanf("%d", &number);
}
printf("Thank you for using my program Mr. Halsey!!!!!!!!\n");
closeStatus = fclose(code);
if (closeStatus == EOF)
{
printf("File close error.\n");
return 201;
}
else
printf("Exit successfully.\n");
return 0;
}
/******************************************************************************
Prints the purpose of the program
******************************************************************************/
void printPurpose()
{
printf("This program Encodes, Decodes, and allows you to make your own");
printf("code.\n");
printf("Enter a 1 to Encode\n");
printf("Enter a 2 to Decode\n");
printf("Enter a 3 to make your own code\n");
printf("Enter a 4 to Quit\n");
}
/******************************************************************************
Encodes the sentence entered
******************************************************************************/
void encode(char input[], char code1[])
{
char sentence[100] = "";
char x;
char y;
int index;
int index2;
index = 0;
printf("Enter your sentence\n");
gets(sentence);
gets(sentence);
printf("Your encoded message is >");
for (index2 = 0; (y = sentence[index2]) != '\0'; index2++)
{
while ((x = input[index]) != y)
index++;
if (x == y)
printf("%c", code1[index]);
else
printf("error");
index = 0;
}
return;
}
/******************************************************************************
Decodes the sentence entered
******************************************************************************/
void decode(char input[], char code1[])
{
char encodedMessage[100] = "";
char x;
char y;
int index1;
int index2;
index2 = 0;
printf("Enter encoded message\n");
gets(encodedMessage);
gets(encodedMessage);
printf("Your decoded message is >");
for (index1 = 0; (y = encodedMessage[index1]) != '\0'; index1++)
{
while (( x = code1[index2]) != y)
index2++;
if (x == y)
printf("%c", input[index2]);
else
printf("error");
index2 = 0;
}
return;
}
/******************************************************************************
Reads in your code and encodes / decodes
******************************************************************************/
void ownCode()
{
char charactersUsed[50] = "";
char codeUsed[50] = "";
char sentence[50] = "";
int index1;
int index2;
int number;
int x;
int y;
index2 = 0;
y = 0;
printf("Enter the characters you want to use.\n");
printf("Use less than 50 characters and DO NOT REPEAT the characters.\n");
gets(charactersUsed);
gets(charactersUsed);
printf("Enter the code for the characters.\n");
gets(codeUsed);
printf("\nEnter 1 to encode and 2 to decode or 3 to return to main menu.\n");
scanf("%d", &number);
while (number != OWNCODE)
{
if (number == ENCODE)
{
printf("Enter your sentence.\n");
gets(sentence);
gets(sentence);
printf("Your encoded message is > ");
for (index1 = 0; (y = sentence[index1]) != '\0'; index1++)
{
while (( x = charactersUsed[index2]) != y)
index2++;
if (x == y)
printf("%c", codeUsed[index2]);
else
printf("error");
index2 = 0;
}
}
else if (number == DECODE)
{
printf("Enter your encoded sentence.\n");
gets(sentence);
gets(sentence);
printf("Your decoded message is > ");
for (index1 = 0; (y = sentence[index1]) != '\0'; index1++)
{
while (( x = codeUsed[index2]) != y)
index2++;
if (x == y)
printf("%c", charactersUsed[index2]);
else
printf("error");
index2 = 0;
}
}
printf("\nEnter 1 to encode and 2 to decode or 3 to return to main menu.\n");
scanf("%d", &number);
}
return;
}