2. Instruction
This assignment requires you to create an e-commerce system which allows customers to login to the system, perform some shopping operations like purchasing products, viewing order history and showing user consumption reports. Besides, admin users need to be created
to manage the whole system, who are able to create/delete/view customers, products and all the orders. Except for the management part, admin users can view the statistical figures about this system. Since the whole system is executed in the command line system, it is better to design a well-formatted interface and always show proper messages to guide users to use your system. In this assignment, we use the open source data from data.world, which contains 9 files of products. All the product’s data should be retrieved from these files.
In this assignment, we are going to decouple the relationship between various classes. As you can see from the image below, we have four main parts and when using the system, end users only need to interact with the IOInterface class. The Main Control class handles the main business logic. The operation classes use the model classes as templates to manipulate the data reading/writing. With this design pattern, the input() and print() functions only exist in the I/O interface class. No other classes have these functions. The file reading/writing operations happen in the operation classes, which simulate the database activities.
效果图:
代码:
operation_customer.py
import operation_user
import time
class CustomerOperation:
def validate_email(self, user_email):
if not (user_email.find("@") != -1 and user_email.find(".") != -1):
return False
if user_email.find("@") > user_email.find("."):
return False
if user_email.find("@") == 0 or user_email.find(".") == 0:
return False
if user_email.find("@") == len(user_email) - 1 or user_email.find(".") == len(user_email) - 1:
return False
return True
def validate_mobile(self, user_mobile):
if not (user_mobile.isdigit() and (user_mobile.startswith("04") or user_mobile.startswith("03")) and len(
user_mobile) == 10):
return False
return True
def register_customer(self, user_name, user_password, user_email, user_mobile):
ou = operation_user.UserOperation()
if not (ou.validate_username(user_name) and ou.validate_password(
user_password) and self.validate_email(user_email) and self.validate_mobile(user_mobile)):
return False
if ou.check_username_exist(user_name):
return False
user_id = ou.generate_unique_user_id()
user_register_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
user_password = ou.encrypt_password(user_password)
user_info = {"user_id": user_id, "user_name": user_name, "user_password": user_password,
"user_role": "customer", "user_email": user_email, "user_mobile": user_mobile,
"user_register_time": user_register_time}
with open("data/users.txt", "a") as f:
f.write(str(user_info) + "\n")
return True
def update_profile(self, attribute_name, value, customer_object):
ou = operation_user.UserOperation()
if attribute_name == "user_name":
if not ou.validate_username(value):
return False
if ou.check_username_exist(value):
return False
customer_object.set_name(value)
elif attribute_name == "user_password":
if not ou.validate_password(value):
return False
value = ou.encrypt_password(value)
customer_object.set_password(value)
elif attribute_name == "user_email":
if not self.validate_email(value):
return False
customer_object.set_email(value)
elif attribute_name == "user_mobile":
if not self.validate_mobile(value):
return False
customer_object.set_mobile(value)
else:
return False
print(customer_object)
with open("data/users.txt", "r") as f:
lines = f.readlines()
with open("data/users.txt", "w") as f:
for line in lines:
if line.find(customer_object.get_id()) != -1:
line = str(customer_object) + "\n"
f.write(line)
return True
def delete_customer(self, customer_id):
is_deleted = False
with open("data/users.txt", "r") as f:
lines = f.readlines()
with open("data/users.txt", "w") as f:
for line in lines:
if line.find(customer_id) == -1:
f.write(line)
else:
is_deleted = True
return is_deleted
def get_customer_list(self, page_number):
customer_list = []
with open("data/users.txt", "r") as f:
lines = f.readlines()
total_page = len(lines) // 10 + 1
if page_number > total_page:
return None
for line in lines[(page_number - 1) * 10:page_number * 10]:
customer_list.append(eval(line))
return customer_list, page_number, total_page
def delete_all_customers(self):
with open("data/users.txt", "w", encoding='utf-8') as f:
f.write("")
def create_a_customer(self, customer_info):
with open("data/users.txt", "a") as f:
f.write(str(customer_info) + "\n")
operation_product.py
import csv
import os
import matplotlib.pyplot as plt
class ProductOperation:
def extract_products_from_files(self, filename):
data = []
file_list = os.listdir(filename)
for file in file_list:
file_dir = filename + '/' + file
with open(file_dir, encoding='utf-8') as csvf:
csv_render = csv.reader(csvf)
for row in csv_render:
# find current_price in title
pro_current_price = row[3]
# find raw_price in title
pro_raw_price = row[4]
# find discount in title
pro_discount = row[7]
# find likes_count in title
pro_likes_count = row[8]
# find name in title
pro_name = row[2]
# find model in title
pro_model = row[20]
# find category in title
pro_category = row[0]
# find id in title
pro_id = row[21]
# add to data
data.append(
{"pro_id": pro_id, "pro_model": pro_model, "pro_category": pro_category, "pro_name": pro_name,
"pro_current_price": pro_current_price, "pro_raw_price": pro_raw_price,
"pro_discount": pro_discount, "pro_likes_count": pro_likes_count})
with open("data/products.txt", "w", encoding='utf-8') as f:
for line in data:
f.write(str(line) + "\n")
def get_product_list(self, page_number):
product_list = []
with open("data/products.txt", "r", encoding='utf-8') as f:
lines = f.readlines()
total_page = len(lines) // 10 + 1
if page_number > total_page:
return None
for line in lines[(page_number - 1) * 10:page_number * 10]:
product_list.append(eval(line))
return product_list, page_number, total_page
def delete_product(product_id):
has_deleted = False
with open("data/products.txt", "r") as f:
lines = f.readlines()
with open("data/products.txt", "w") as f:
for line in lines:
product = eval(line)
if product["pro_id"] != product_id:
f.write(line)
else:
has_deleted = True
return has_deleted
def get_product_list_by_keyword(keyword):
pro_list = []
with open("data/products.txt", "r") as f:
lines = f.readlines()
for line in lines:
pro_name = eval(line)["pro_name"]
if keyword.lower() in pro_name.lower():
# create a product object
pro_obj = eval(line)
pro_list.append(pro_obj)
return pro_list
def get_product_by_id(self, product_id):
with open("data/products.txt", "r") as f:
lines = f.readlines()
for line in lines:
pro_obj = eval(line)
if pro_obj["pro_id"] == product_id:
return pro_obj
return None
def generate_category_figure(self):
with open("data/products.txt", "r", encoding='utf-8') as f:
lines = f.readlines()
category_dict = {}
for line in lines:
pro_obj = eval(line)
if pro_obj["pro_category"] not in category_dict:
category_dict[pro_obj["pro_category"]] = 1
else:
category_dict[pro_obj["pro_category"]] += 1
# in descending order
# in descending order
category_dict = sorted(category_dict.items(), key=lambda x: x[1], reverse=True)
a = [i[0] for i in category_dict]
b = [i[1] for i in category_dict]
plt.bar(a, b)
plt.savefig("data/figure/category.png")
plt.close()
def generate_discount_figure(self):
with open("data/products.txt", "r", encoding='utf-8') as f:
lines = f.readlines()
discount_dict = {"<30": 0, "30-60": 0, ">60": 0}
for line in lines:
pro_obj = eval(line)
if pro_obj["pro_discount"] != "" and pro_obj["pro_discount"].isdigit():
if float(pro_obj["pro_discount"]) < 30:
discount_dict["<30"] += 1
elif float(pro_obj["pro_discount"]) <= 60:
discount_dict["30-60"] += 1
else:
discount_dict[">60"] += 1
plt.pie(discount_dict.values(), labels=discount_dict.keys(), autopct='%1.1f%%')
plt.savefig("data/figure/discount.png")
plt.close()
def generate_likes_count_figure(self):
with open("data/products.txt", "r", encoding='utf-8') as f:
lines = f.readlines()
likes_count_dict = {}
for line in lines:
pro_obj = eval(line)
c = 1
if pro_obj["pro_likes_count"] == 'false':
c = 0
if pro_obj["pro_category"] not in likes_count_dict:
likes_count_dict[pro_obj["pro_category"]] = c
else:
likes_count_dict[pro_obj["pro_category"]] += c
likes_count_dict = sorted(likes_count_dict.items(), key=lambda x: x[1])
a = [i[0] for i in likes_count_dict]
b = [i[1] for i in likes_count_dict]
plt.bar(a, b)
plt.savefig("data/figure/likes_count.png")
plt.close()
def generate_discount_likes_count_figure(self):
with open("data/products.txt", "r", encoding='utf-8') as f:
lines = f.readlines()
discount_dict = {}
likes_count_dict = {}
for line in lines:
pro_obj = eval(line)
if pro_obj["pro_discount"] != "":
if pro_obj["pro_discount"].isdigit():
discount_dict[pro_obj["pro_id"]] = float(pro_obj["pro_discount"])
else:
discount_dict[pro_obj["pro_id"]] = 0
c = 1
if pro_obj["pro_likes_count"] == 'false':
c = 0
likes_count_dict[pro_obj["pro_id"]] = c
plt.scatter(discount_dict.values(), likes_count_dict.values())
plt.savefig("data/figure/discount_likes_count.png")
plt.close()
def delete_all_products(self):
with open("data/products.txt", "w", encoding='utf-8') as f:
f.write("")