I'm new to programming. I wrote the following code in python. It's a cmd based address book.
import os
from reportlab.pdfgen import canvas
from cryptography.fernet import Fernet
p_d_D = {}
d_D = {}
dd = {}
file_path = os.path.join(os.path.expanduser('~'), 'Desktop', str(os.path.basename(__file__)) + '__database.txt') # The
# Location of dict database stored in the users HDD
data = {}
key = b'kXDB2gXHHwOoVC6FCwKjDhCa3JW0vRiKkHv3iBuPhx0=' # Secret key value
# for Fernet encryption
# Loads the decrypted dict into the memory (data gets the decrypted values)
def make_eval2():
make_eval()
global dd
global data
decrypt_dict()
data = eval(str(dd))
# A function that encrypts or decrypts dict and stores into dict db
def encrypt_dict(write=False, decrypt=False):
l = []
for k, v in data.items():
for i in v:
if decrypt is False:
a = encrypt_decrypt(i)
else:
a = encrypt_decrypt(i, decrypt=True)
l.append(a)
ch = [l[x:x + 4] for x in range(0, len(l), 4)]
for it in ch:
d_D.setdefault(it[0], (it[0], it[1], it[2], it[3]))
if write is True:
write_read_data('w', text=str(d_D))
global p_d_D
p_d_D = d_D.copy()
d_D.clear()
# Decrypts the dict data and stores into dict dd
def decrypt_dict():
l = []
global data
global dd
if len(data) < 1:
print('No entry')
else:
for k, v in data.items():
for i in v:
a = encrypt_decrypt(i, decrypt=True)
l.append(a)
ch = [l[x:x + 4] for x in range(0, len(l), 4)]
for it in ch:
dd.setdefault(it[0], (it[0], it[1], it[2], it[3]))
# A function that does the actual enc. or dec. of provided dict values
def encrypt_decrypt(x, decrypt=False):
global key
f = Fernet(key)
x_en = x.encode()
if decrypt is False:
a = f.encrypt(x_en).decode()
return a
else:
a = f.decrypt(x_en).decode()
return a
# Initial file maker that creates an empty dict db
def make_dict_file_to_write():
global file_path
if os.path.exists(file_path):
pass
else:
open(file_path, 'w')
# Loads the dict db from HDD to dict data (into the memory)
def make_eval():
global data
x = write_read_data('r', read=True)
if x == '':
pass
else:
data = eval(x)
# A modified writing function for writing and reading to/from files
def write_read_data(mode, **kwargs):
global file_path
read = kwargs.get('read', False)
text = kwargs.get('text', None)
with open(file_path, mode) as f_to_w_read:
if 'read' in kwargs:
if read is True:
return f_to_w_read.read()
else:
return None
if 'text' in kwargs:
if text is not None and mode == 'w':
x = f_to_w_read.write(str(text))
return x
return None
# Returns the user given entries as encrypted values in the form of a tuple
def get_contact_details():
a = ''
tags = ['name', 'address', 'cell-number', 'email']
for tag in tags:
x = input('Please enter contact %s: ' % tag)
a += x.lower() + ','
name, address, cell, email = a.rstrip(',').split(',')
h_name, h_address, h_cell, h_email = encrypt_decrypt(name), encrypt_decrypt(address), encrypt_decrypt(cell), \
encrypt_decrypt(email)
return h_name, h_address, h_cell, h_email
# Adds a new contact entry to the dict db in HDD
def add_contact():
make_eval()
contact = get_contact_details()
data.setdefault(contact[0], contact)
write_read_data('w', text=str(data))
clear_dict()
print('New contact added\r\n')
# Prints requested entry into a PDF file in the current folder
# It is a part of search_contact() function
def print_data(x):
if x in data.keys():
xx = ('Name: %s\r\nAddress: %s\r\nCell-number : %s\r\nEmail: %s\r\n' % (data[x][0].capitalize(), data[x][1].
capitalize(),
data[x][2].capitalize(),
data[x][3].lower()))
print(xx)
file_name = '%s\'s contact information' % x.capitalize()
c = canvas.Canvas(file_name + '.pdf', pagesize='A4')
t = c.beginText()
t.setFont('Times-Bold', 12)
t.setTextOrigin(30, 700)
t.textLines(file_name + ' :\r\n')
t.textLines(xx)
c.drawText(t)
c.showPage()
c.save()
print('Document will be printed after quitting\r\n')
# Prints all the entries of the dict db into readable format
def print_all():
make_eval()
if len(data) < 1:
print('No entry')
else:
encrypt_dict(decrypt=True)
global p_d_D
for k, v in p_d_D.items():
print('Name: %s\r\nAddress: %s\r\nCell-number : %s\r\nEmail: %s\r\n' % (v[0].capitalize(),
v[1].capitalize(),
v[2], v[3].lower()))
p_d_D.clear()
# Allows a requested entry to be printed out in the PDF format
def search_contact():
make_eval2()
search_item = input('Enter the full name of the person you wish to search: \r\n').lower()
if search_item in data.keys():
print_data(search_item)
clear_dict()
else:
print('No match found\r\n')
# Part of edit_contact() function, which provides different editing choices to the user
def choice_edit():
while True:
choiceEdit = input('Press "A" to change address\nPress "C" '
'to change cell-number\nPress "E" to change email\nPress "Q" '
'to quit without editing\n').lower()
if choiceEdit == 'a' or choiceEdit == 'c' or choiceEdit == 'e' or choiceEdit == 'q':
return choiceEdit
print('Not correct option\r\n')
# Part of edit_contact() function
def do_it_again():
while True:
try:
doAgain = int(input('Press 1 to edit again\nPress 2 to save and quit\r\n'))
if doAgain == 1 or doAgain == 2:
return doAgain
print('Not correct option\r\n')
except ValueError:
print('Select an integer\r\n')
# Part of edit_contact() function
def print_try(x=None):
xx = input('Enter new %s\r\n' % x).lower()
return xx
# Stores the updated dict to the dict db
def update(f, c):
x = tuple(f) # Converts the list X into a tuple
data.update({(c, x)}) # Updates data dict
encrypt_dict(write=True)
# Part of edit_contact() function which gives the option to store edited data or re-edit a requested entry
def next_gen(list_x, edit_pointer, edit_name, print_call=''):
list_x[edit_pointer] = print_try(x=print_call)
update(list_x, edit_name)
doooAgain = do_it_again()
if doooAgain == 1:
edit_contact()
if doooAgain == 2:
update(list_x, edit_name)
clear_dict()
# Edits an stored entry on request
def edit_contact():
make_eval2() # Decrypts the dict to readable format
var_edit_name = input('Enter the contact name that you with to edit: \r\n').lower()
if var_edit_name in data.keys():
z = list(data[var_edit_name]) # Converts the tuple into a list to allow edits
cho_edit = choice_edit()
if cho_edit == 'a':
next_gen(z, 1, var_edit_name, print_call='address')
elif cho_edit == 'c':
next_gen(z, 2, var_edit_name, print_call='cell-number')
elif cho_edit == 'e':
next_gen(z, 3, var_edit_name, print_call='email')
elif cho_edit == 'q':
update(z, var_edit_name)
clear_dict()
else:
print('Please select a correct option\r\n')
edit_contact()
else:
print('No such name found\r\n')
# Clears the memories of all the dicts
def clear_dict():
global dd, data, p_d_D, d_D
dd.clear()
data.clear()
p_d_D.clear()
d_D.clear()
# Deletes an entry
def delete_contact():
make_eval2() # Decrypts the dict to readable format
var_del_name = input('Enter the contact name that you with to delete: \r\n').lower()
if var_del_name in data.keys():
data.pop(var_del_name, None)
encrypt_dict(write=True) # Encrypts the dict to unreadable format and stores it in the dict database
clear_dict() # Clears the memories of all the dicts
else:
print('No such name found\r\n')
# Initially checks if the dict db is empty or not
def initial_emptyness_checker():
make_eval()
if len(data) < 1:
print('Address book is currently empty\r\n')
else:
return True
# Allows to quit from the app
def quit_here():
make_eval()
write_read_data('w', text=str(data))
quit()
# Provides options to the user to choose a set of action
def option_switcher():
options = {
1: add_contact,
2: search_contact,
3: delete_contact,
4: edit_contact,
5: print_all,
6: quit_here
}
xx = ['Add contract', 'Search', 'Delete', 'Edit', 'Print all entries', 'Quit']
c = 1
for i in xx:
print('Option %d: %s' % (c, i))
c += 1
try:
select = int(input('\nPlease select an option \r\n'))
if 1 <= select < 7:
options[select]()
else:
print('Options 1-6\r\n')
except ValueError:
print('Invalid option\r\n')
option_switcher()
def main():
print('Welcome to AddressBookEXtREM V1 by AJ\r\n')
make_dict_file_to_write()
initial_emptyness_checker()
while True:
option_switcher()
if __name__ == '__main__':
main()
The above app allows a user to make contact lists and store them in the hard disk. Moreover, it provides security to the stored database file via encryption. User can anytime update or delete or edit stored contacts. Moreover, it provides the user to print out the searched item into a PDF file. The code is pretty long. I hope someone could suggest me to make it shorter or more efficient.