购物车管理系统--Python基础项目(3)

一、需求

1. 概述

1、购物车管理系统,总共六个模块goods、user、storage、shopping_cart、admin、test_demo;

2、其中goods、user、shopping_cart都重写__str__,storage模块;

3、运用单例类(只能设置一个对象的类)修饰的Storage类中设置goodslist列表,通过for循环把三个列表作为参数初始化goods对象加入goodslist中;

4、主要功能实现是Admin类,其中涉及pickle序列化和反序列化,封装了12个函数。

5、初始化函数逻辑复杂,于是再定义一个私有函数扩充,登录函数设置了校验;

6、添加函数中新创建Goods对象,用于加入购物车字典(key是Goods对象,value是添加数量);删除函数,同理;两函数同时设置序列化写入文本...

2. 框架

仓库类:【信息保存在本地磁盘:程序刚启动时把列表先存储到文件中,之后使用再读取出来】
    商品列表
           商品名称         价格         剩余量    
           Mac电脑         20000      100
           PythonBook    30            200  
           草莓键盘         80            60
           iPhone            7000        70

商品类:

        商品名称   商品价格   商品剩余量

购物车类:

        商品列表:程序初始时,商品列表为空

用户类:

        姓名 

        用户id【这个标识对于每个用户而言是唯一的】

        密码 

        拥有购物车 

        用户登录状态【默认为False 表示没有登录】

操作类
    因为一个程序可能有很多用户,则需要将用户保存在本地
        将注册的用户添加在字典中
                key:用户id 【用户id随机产生即可,从10000~99999中随机产生一个】
                value:对应的用户对象


    行为:
    1. 用户注册——》根据下面信息生成一个用户,并将用户保存在本地
        随机产生 id
        输入姓名和密码  
        创建一个购物车对象

    2. 登录 ——》登录成功返回为 True  否则返回为 False
        输入用户id 检测是否有该用户  没有的话提示注册
        有的话检测用户登录状态 若为 True  提示已登录
        否则 再输入密码进行登录
        不要忘记修改用户的登录状态

    3. 购买商品 ——》验证用户是否登录,没有登录提示登录
        否则,列出仓库中商品名单
                1. Mac电脑      
                2.PythonBook 
                3.草莓键盘
                4.iPhone
        用户输入对应的编号 在仓库中获得对应的商品

        用户输入数量 — 与该商品的的剩余量对比
                > 剩余量:让用户重新输入并提示该商品的剩余量
                <=剩余量:将该商品添加在该用户的购物车中,并将仓库中的数据量做出相应的减少 

        注意:将修改之后的结果同步在本地文件中,时刻保持数据的正确性

    4. 删除购物车的商品——》验证用户是否登录,没有登录提示登录
        否则,请用户输入商品名字 查看该用户的购物车中是否有该商品
        如果没有,提示购物车中没有该商品,否则:
                先选择要删除的商品
                请用户设置删除的数量
                    数量  >=   购物车中商品数量
                        购物车清单中删除该商品
                    否则:
                        购物车清单中做出相应的减少

        注意:将修改之后的结果同步在本地文件中,时刻保持数据的正确性

    5. 结算——》验证用户是否登录 没有登录提示登录
        否则获取该用户的购物车中商品清单,计算总额
        注意: 结算完成 购物车清空
        注意:将修改之后的结果同步在本地文件中,时刻保持数据的正确性

    6. 退出登录———》验证用户是否登录 没有登录提示登录
        否则修改用户登录状态
        注意:将修改之后的结果同步在本地文件中,时刻保持数据的正确性

二、代码解析

1. 商品类

"""
    商品类:
	商品名称   商品价格   商品剩余量
"""
class Goods():
    __slots__ = ("gname","gprice","free_num")
    def __init__(self,gname,gprice,free_num):
        self.gname = gname
        self.gprice = gprice
        self.free_num = free_num

    def __str__(self):
        return f"[商品] 商品名称{self.gname},商品价格{self.gprice},商品剩余量{self.free_num}"
    __repr__ = __str__

game为商品名字

gprice为商品价格

free_num为商品剩余量

2. 购物车类 

"""
    购物车类:
        商品列表:程序初始时,商品列表为空
"""
class Shopping_cart():
    __slots__ = ("shopcar_dict",)
    def __init__(self):
        # 程序初始时,商品列表为空
        # 用字典表示,商品对象作为key,商品数量作为value
        self.shopcar_dict = {}

    def __str__(self):
        return f"[购物车] 商品字典:{self.shopcar_dict}"
    __repr__ = __str__

 字典知识点可参考

https://blog.csdn.net/m0_57975635/article/details/127931233?spm=1001.2014.3001.5501

 3. 用户类

"""
    用户类:
	姓名
    用户id【这个标识对于每个用户而言是唯一的】
    密码     
    拥有购物车  
    用户登录状态【默认为 False 表示没有登录】
"""
from shop_car.shopping_cart import Shopping_cart
class User():
    __slots__ = ("uname","uid","upwd","shopcar","ulogin")
    def __init__(self,uname,uid,upwd):
        self.uname = uname
        self.uid = uid
        self.upwd = upwd
        self.shopcar = Shopping_cart()
        self.ulogin = False

    def __str__(self):
        return f"[用户] 姓名{self.uname},用户id{self.uid},登录状态{self.ulogin}"
    __repr__ = __str__

from shop_car.shopping_cart import Shopping_cart

导入Shooping_cart类用于创建对象作为用户的属性

4. 仓库类 

"""
    仓库类:【信息保存在本地磁盘:程序刚启动时把列表先存储到文件中,之后使用再读取出来】
	商品列表
	       商品名称    	价格      剩余量
		   Mac电脑	   	20000    100
		   PythonBook 	30	  	 200
		   草莓键盘       80       60
		   iPhone		7000	 70
"""
import os,pickle
from shop_car.goods import Goods

path = r"goodslist.txt"

def singleton(cls):
    instance = None
    def getinstance(*args,**kwargs):
        nonlocal instance
        if not instance:
            instance = cls(*args,**kwargs)
        return instance
    return getinstance

@singleton
class Storage():
    __slots__ = ("goodslist",)
    def __init__(self):
        self.__goodsload()

    def __goodsload(self):
        if os.path.exists(path):
            self.get_goodslist()
        else:
            self.goodslist = []
            name_list = ["Mac电脑", "kindle", "book", "手表"]
            price_list = [18888, 500, 60, 1300]
            num_list = [100, 200, 60, 70]
            for i in range(len(name_list)):
                goods = Goods(gname=name_list[i], gprice=price_list[i], free_num=num_list[i])
                self.goodslist.append(goods)
            self.save_goodlist()

    def get_goodslist(self):
        with open(path,"rb") as f:
            self.goodslist = pickle.load(f)

    def save_goodlist(self):
        with open(path,"wb") as f:
            pickle.dump(self.goodslist,f)

系统模块:os

os模块中包含普通的操作系统功能,提供了非常丰富的方法用来处理文件和目录

对象的序列化与反序列化:

1.对象的序列化【写入】和反序列化【读取】通过pickle模块和json模块完成​

2.Python中一切皆对象,可以使用pickle或json模块的类型:数字,字符串,列表,字典。元组,集合,类,函数,模块等

pickle.dump(obj,file)
    obj:需要序列化的对象
    file:需要序列化到的文件对象,注意:必须以位二进制的方式打开文件,wb
pickle.load(file)
    file:需要反序列化到的文件对象,注意:必须以位二进制的方式打开文件,rb

单例设计模式(singleton):

程序运行过程中,确保某一个类只有一个实例【对象】,不管在哪个模块获取这个类的对象,获取到的都是同一个对象。

5、操作类

import os,pickle,string,random
from shop_car.user import User
from shop_car.storage import Storage
from shop_car.goods import Goods

path = r"userdict.txt"

class Admin():
    __slots__ = ("userdict",)
    def __init__(self):
        self.__loaduserdict()

    def __loaduserdict(self):
        if os.path.exists(path):
            with open(path,"rb") as f:
                self.userdict = pickle.load(f)
        else:
            self.userdict = {}

    # save_userdict
    def save_userdict(self):
        with open(path, "wb") as f:
            pickle.dump(self.userdict, f) #!!!

    # 获取uid
    def __get_uid(self):
        while True:
            uid = str(random.randint(1,1000))
            if uid not in self.userdict:
                return uid

    # 校验名称和密码
    def check_name(self,uname):
        result = True
        if len(uname) in range(1,13):
            for ch in uname:
                if ch not in string.ascii_letters + string.digits: #!!!
                    result = False
                    break
        else:
            result = False
        return result

    def check_pwd(self,upwd):
        if len(upwd) in range(1,5):
            if upwd.isdigit():
                return True
        return False

    # 注册
    def user_register(self):
        uname = input("请输入用户名【必须由数字或字母组成,长度为6~12位】:")
        upwd = input("请输入密码【必须由数字组成,长度为4位】:")
        uid = self.__get_uid()
        if self.check_name(uname) and self.check_pwd(upwd):
            user = User(uname=uname, uid=uid, upwd=upwd)
            self.userdict[uid] = user
            self.save_userdict()
            print(f"注册用户成功,您的id为{uid}")
        else:
            print("输入错误!")

    # 登录
    def user_login(self):
        uid = input("请输入你的id:")
        if uid not in self.userdict:
            print(f"您输入的id{uid}不存在")
            return
        user = self.userdict[uid] #!!!
        if user.ulogin:
            print("已经登入~~")
            return user
        for _ in range(1, 4):
            uname = input("请输入用户名:")
            upwd = input("请输入密码:")
            if user.uname == uname and user.upwd == upwd:
                user.ulogin = True
                self.save_userdict()
                print("登录成功~~")
                return user
            else:
                print("输入错误超过三次~~")

    # 添加商品
    def add_goods(self):
        user = self.user_login() # !!!
        if not user:
            print("还未登录,请先登录")
            return
        print("""
                0.Mac电脑
                1.kindle
                2.book
                3.手表""")
        num = input("请输入想加入购物车的商品:")
        storage = Storage()
        if num.isdigit():
            num = int(num)
            if num in range(4):
                goods = storage.goodslist[num] # !!!
                shop_num = int(input(f"该商品还剩{goods.free_num},请输入您要购买的数量:"))
                if shop_num < 0:
                    print("输入有误~~")
                else:
                    while shop_num > goods.free_num:
                        num = int(input(f"商品剩余量为:{goods.free_num},请重新输入需要购买的数量:"))
                    else:
                        ugoods = Goods(gname=goods.gname, gprice=goods.gprice, free_num=shop_num)
                        for shop_good in user.shopcar.shopcar_dict:
                            if shop_good.gname == ugoods.gname:
                                user.shopcar.shopcar_dict[ugoods] += shop_num
                                break
                        else:
                            user.shopcar.shopcar_dict[ugoods] = shop_num
                        goods.free_num -= shop_num
                        storage.save_goodlist()
                        self.save_userdict()
                        print(f"商品{ugoods.gname}添加成功~~")
            else:
                print(f"该商品不存在")
        else:
            print("输入有误~~")

    # 删除商品
    def del_goods(self):
        user = self.user_login()  # !!!
        if not user:
            print("还未登录,请先登录")
            return
        ugoods = None
        sgoods = None
        name = input("请输入你要删除的商品名称:")
        for goods in user.shopcar.shopcar_dict:
            if goods.gname == name:
                ugoods = goods
        if not ugoods:
            print(f"商品{name}不存在")
            return
        storage = Storage()
        for goods in storage.goodslist:
            if goods.gname == name:
                sgoods = goods
        num = int(input(f"请输入需要删除{name}的数量:"))
        if num < 0:
            print(f"{num}有误~~")
        else:
            if num > ugoods.free_num:
                user.shopcar.shopcar_dict.pop(ugoods)
                sgoods.free_num += ugoods.free_num #!!!
            else:
                ugoods.free_num -= num
                user.shopcar.shopcar_dict[ugoods] = ugoods.free_num
                sgoods.free_num += num
            storage.save_goodlist()
            self.save_userdict()
            print("商品删除成功")

    # 计算总额
    def total_goods(self):
        user = self.user_login()  # !!!
        if not user:
            print("还未登录,请先登录")
            return
        total = 0
        for goods,num in user.shopcar.shopcar_dict.items():
            total += goods.gprice*num
        print(f"该商品的总额为{total}")
        user.shopcar.shopcar_dict.clear() # !!!
        self.save_userdict()

    def user_logout(self):
        user = self.user_login()
        if user:
            user.ulogin = False
            self.save_userdict()
            print("注销登录~~")

1. 初始化函数逻辑复杂,所以可以在初始化函数中定义一个封装函数(用于初始化)

2. 获取用户id函数(运用random.randint()函数),并用while True:死循环控制

3. 注册函数中调用校验用户名和密码函数,并创建用户类对象加入用户字典中

4. 登入函数通过用户id号,验证是否存在;且赋值用户类对象,通过对象属性判断是否登录

5. 添加函数先通过登入函数判断是否登录,再创建仓库类对象(此为单例类对象)...

6.测试类

from shop_car.admin import Admin

def main():
    admin = Admin()
    print("欢迎登录购物车管理系统".center(50,"="))
    while True:
        print("""
                1.用户注册
                2.用户登录
                3.购买商品
                4.删除商品
                5.结算购物车
                6.退出登录
                7.退出系统""")
        choice = int(input("请选择功能:"))
        if choice == 1:
            admin.user_register()
        elif choice == 2:
            admin.user_login()
        elif choice == 3:
            admin.add_goods()
        elif choice == 4:
            admin.del_goods()
        elif choice == 5:
            admin.total_goods()
        elif choice == 6:
            admin.user_logout()
        elif choice == 7:
            print("欢迎再次登录~~")
            break
        else:
            print("输入错误了嗷~~")

if __name__ == "__main__":
    main()

三、运行与测试

购物车管理系统--Python基础项目(3)_第1张图片

你可能感兴趣的:(Python--全栈开发,Python--基础语法,Python--项目,python,pycharm,开发语言)