I've recently started teaching myself Python but have no prior programming experience or formal training. I've successfully created a program that outputs what I wanted it to output, but I'm looking for guidance on design/efficiency. Is there an overall design that would have been more efficient? Any pieces of code that should be re-written to be more stylistically correct? I purposely wrote this program without utilizing a database, but my next goal is to re-write the program to use a database instead of dictionaries.
The goal of this program is to read in 3 files that have a common key (custID). A customer can have multiple orders, but only one email/customer record. File layouts:
names.txt: custID|firstName|lastName|address1|address2|city|state|zip
emails.txt: custID|email
orders.txt: orderID|orderDate|channel|orderAmt|custID
Then, output a file with each order appearing on a new line:
output.txt: custID|firstName|lastName|city|state|email|orderDate|orderAmount
Program:
import re
import os
cust_info = {}
cust_emails = {}
cust_orders = {}
cust_join = {}
#Read Customer file with layout:
#custID|firstName|lastName|address1|address2|city|state|zip
def read_cust_file():
with open('names.txt', 'r') as f:
for line in f:
split_line = re.sub("\s\s+", '|', line).strip().split('|')
cust_info[int(split_line[0])] = "|".join(split_line[1:])
return cust_info
#Read Email file with layout: custID|email
def read_email_file():
with open('emails.txt', 'r') as g:
for line in g:
split_line = re.sub("\s\s+", '|', line).strip().split('|')
cust_emails[int(split_line[0])] = "|".join(split_line[1:])
return cust_emails
#Read Order file with layout: orderID|orderDate|channel|orderAmt|custID
#There can be multiple orders per custID
def read_order_file():
with open('orders.txt', 'r') as f:
for line in f:
split_line = re.sub("\s\s+", '|', line).strip().split('|')
try:
cust_orders.setdefault(int(split_line[4]),[]).append("|".join(
split_line[0:4]))
except KeyError:
pass
return cust_orders
#Join names, emails, and orders together on custID (dict key)
def join_orders():
for key in set(list(cust_info) + list(cust_emails) + list(cust_orders)):
try:
cust_join.setdefault(key,[]).append(cust_info[key])
except KeyError:
pass
try:
cust_join.setdefault(key,[]).append(cust_emails[key])
except KeyError:
pass
try:
cust_join.setdefault(key,[]).append(cust_orders[key])
except KeyError:
pass
return cust_join
#Format output layout:
#custID|firstName|lastName|city|state|email|orderDate|orderAmount
#Each order will be on a separate line, even if a cust made more than 1 order.
def write_output():
output_file = open('output.txt', 'w')
for k, v in cust_join.items():
if len(v) == 3:
for item in v[2]:
split_cust = v[0].split('|')
split_item = item.split('|')
output_file.write("%s|%s|%s|%s|%s|%s|%s|%s\n" % (
k, split_cust[0], split_cust[1], split_cust[4],
split_cust[5], v[1], split_item[1], split_item[3]))
output_file.truncate(output_file.tell() - len(os.linesep))
output_file.close()
def main():
read_cust_file()
read_email_file()
read_order_file()
join_orders()
write_output()
if __name__ == "__main__":
main()
I really appreciate any advice you all can give!