简易ATM+购物车之面条版

一、开发项目模式

  使用瀑布模式

二、要求

简易ATM+购物车之面条版

 三、程序设计

简易ATM+购物车之面条版

 简易ATM+购物车之面条版

 四、目录搭建

简易ATM+购物车之面条版

  start.py为启动文件;settings.py为配置文件;src.py为核心代码;db里面为记录客户信息的;common.py为公用功能的;log位记录日志的

 五、环境搭建

  1、定义好所需功能的函数框架,核心代码用pass代替

  2、把定义的函数写入字典中

func_dic = {
    '1': register,
    '2': login,
    '3': transfer,
    '4': withdrawal,
    '5': recharge,
    '6': check_balance,
    '7': check_flow,
    '8': add_cart,
    '9': check_shopping
}

  3、把函数进行打印,并写好供用户选择的代码,并对其进行判断。通过客户输入的选择序号调用所对应的函数

def run():
    while True:
        print("""
        ==========start==========
        1.注册
        2.登录
        3.转账
        4.提现
        5.充值
        6.查看余额
        7.查看流水
        8.加入购物车
        9.查看购物车
        ==========end==========
        """)
        choice = input('请输入你选择的序号:').strip()
        if not choice:
            continue
        if not choice.isdigit():
            print('你输入的序号不符合规范')
            continue
        func_dic[choice]()

六、启动文件、配置文件和公用文件书写

  1、配置好启动文件。代码运行只能在启动文件中进行

from core import src


if __name__ == '__main__':
    src.run()

  2、配置文件,记录文件路径的

import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

  3、公用文件,记录校验用户是否登录的装饰器

from core import src

def login_aunt(func):

    def inner(*args, **kwargs):
        if src.data_list['is_login']:
            return func(*args, **kwargs)
        else:
            return src.login()
    return inner

七、核心代码书写(代码中所需的模块自行导入,代码中我没写进去)

  1、先定义一个字典,用于记录登录的用户名,以及是否登录,先写False,如果登录则进行更改为True

data_list = {
    'username': None,
    'is_login': False
}

  2、注册功能

    思路书写(仅供参考)

1 获取用户名
2 获取文件路径
3 判断文件是否存在,如果存在返回重新输入
4 获取用户密码
5 把获取到的用户名和密码组织成字典的形式。后续所需的功能在里面增加就可以比如锁定状态、购物车等。
6 组织好的字典写入到文件中

  代码

 1 def register():
 2     print('开始注册')
 3     if data_list['is_login']:
 4         print('账户已经登录')
 5         return
 6     while True:
 7         username = input('请输入你要注册的账户名:').strip()
 8         # 获取文件路径,用于判断文件是否存在
 9         path = settings.BASE_DIR
10         path_file = os.path.join(path, 'db', '%s.json' % username)
11         if os.path.exists(path_file):
12             print('用户已存在')
13             continue
14         pwd = input('请输入你的密码').strip()
15         # 定义一个字典,用于接收用户名和密码以及定义账户余额等其他信息
16         user_dic = {'username': username, 'pwd': pwd, 'account': 10000, 'locked': False, 'shopping_cart': {},
17                     'flow': []}
18         with open(path_file, 'w', encoding='utf8') as f:
19             json.dump(user_dic, f)
20             # 写日志
21             common.write_log('%s注册成功' % username)
22             print('恭喜你,注册成功')
23             break

  3、登录功能

    思路书写

 1 获取用户名
 2 获取文件路径,并进行拼接
 3 判断文件是否存在,如果不存在用户名不存在让重新输入
 4 如果存在,获取用户密码
 5 读取文件的信息,并与用户的密码进行判断,看是否输入正确
 6 读取文件之后可以加入一个判断。如果用户已经锁定了就不能进行接下来的操作了。
 7 如果正确写入则显示登录成功,否则告知用户密码或者用户名输入错误
 8 在用户登录成功的后面记录更改下记录用户登录的名以及状态,并结束循环
 9 因为要锁定账户,所以在函数里定义一个计数器,在输入错误的后面进行计数,当次数累计到三次之后把用户信息中的locked进行更改为真,并写入。
10 因为在全局有定义一个记录用户登录信息的字典。所以可以在开头加入一个判断用户是否登录。如果登录则结束该函数。注册的也加一个

  代码

 1 def login():
 2     print('开始登录')
 3     count = 0
 4     if data_list['is_login']:
 5         print('账户已经登录')
 6         return
 7     while True:
 8         username = input('请输入你的用户名:').strip()
 9         path = settings.BASE_DIR
10         path_file = os.path.join(path, 'db', '%s.json' % username)
11         if not os.path.exists(path_file):
12             print('你输入的账户不存在,请先注册')
13             continue
14         pwd = input('请输入你的密码').strip()
15         if not pwd.isdigit():
16             print('输入的密码不符合规范')
17             continue
18         with open(path_file, 'r', encoding='utf8') as f:
19             data = json.load(f)
20         if data.get('locked'):
21             print('账户已锁定,请联系管理员')
22             break
23         if pwd == data.get('pwd'):
24             # 写日志
25             common.write_log('%s登录成功' % username)
26             print('登录成功')
27             data_list['username'] = username
28             data_list['is_login'] = True
29             break
30         else:
31             print('你输入的账户或密码错误')
32             count += 1
33             if count == 3:
34                 data['locked'] = True
35                 with open(path_file, 'w', encoding='utf8') as f1:
36                     json.dump(data, f1)

  4、转账(加入验证用户是否登录的装饰器)

    思路书写

1 输入被转账的账户
2 获取文件路径
3 判断被转账用户是否存在
4 对输入的转账金额进行判断,然后再转换成整型
5 读取自己的账户信息
6 比较转账金额和被转帐金额大小。
7 小于,返回信息,
8 大于,读取对方账户的信息,然后金额增加,写入
9 自己账户的信息中金额减少,然后写入

  代码

 1 @common.login_aunt
 2 def transfer():
 3     print('开始转账')
 4     while True:
 5         to_user = input('请输入你要转账的用户名:').strip()
 6         path = settings.BASE_DIR
 7         to_path_file = os.path.join(path, 'db', '%s.json' % to_user)
 8         if not os.path.exists(to_path_file):
 9             print('此用户不存在,请重新输入')
10             continue
11         money = input('请输入你要转账的金额').strip()
12         if not money:
13             print('输入的金额不符合规范')
14             continue
15         if not money.isdigit():
16             print('输入的金额不符合规范')
17             continue
18         money = int(money)
19         from_path_file = os.path.join(path, 'db', '%s.json' % data_list['username'])
20         with open(from_path_file, 'r', encoding='utf8') as f:
21             from_user = json.load(f)
22         if from_user['account'] >= money:
23             from_user['account'] -= money
24             now_time = time.strftime('%Y-%m-%d %X')
25             from_user['flow'].append('%s给%s转了%s钱' % (now_time, to_user, money))
26             with open(from_path_file, 'w', encoding='utf8') as f1:
27                 json.dump(from_user, f1, ensure_ascii=False)
28             with open(to_path_file, 'r', encoding='utf8') as f2:
29                 to_user_money = json.load(f2)
30                 to_user_money['account'] += money
31                 now_time = time.strftime('%Y-%m-%d %X')
32                 to_user_money['flow'].append('%s%s转了%s钱' % (now_time, data_list['username'], money))
33                 with open(to_path_file, 'w', encoding='utf8') as f3:
34                     json.dump(to_user_money, f3, ensure_ascii=False)
35                     # 写日志
36                     common.write_log('%s转账成功' % data_list['username'])
37                 print('转账成功')
38                 break
39         else:
40             print('余额不足')

  5、提现

    思路书写

1 获取用户提现金额
2 对输入的金额进行判断。把输入的金额转为整型类型
3 获取文件路径,并进行拼接
4 读取用户信息
5 判断用户原有金额是否大于提现金额加上手续费
6 如果小于,证明钱不够。返回重新输入
7 大于,原有金额减去提取金额加上手续费
8 把更新之后的金额写入文件中

   代码

 1 @common.login_aunt
 2 def withdrawal():
 3     print('开始提现')
 4     while True:
 5         money = input('请输入你要提现的金额').strip()
 6         if not money.isdigit():
 7             print('你输入的金额不符合规范,请重新输入')
 8             continue
 9         if not money:
10             continue
11         money = int(money)
12         path = settings.BASE_DIR
13         path_file = os.path.join(path, 'db', '%s.json' % data_list['username'])
14         with open(path_file, 'r', encoding='utf8') as f:
15             data = json.load(f)
16         if data['account'] >= money * 1.05:
17             data['account'] -= money * 1.05
18             now_time = time.strftime('%Y-%m-%d %X')
19             data['flow'].append('%s提现了%s钱' % (now_time, money))
20             with open(path_file, 'w', encoding='utf8') as f1:
21                 json.dump(data, f1, ensure_ascii=False)
22                 # 写日志
23                 common.write_log('%s提现成功' % data_list['username'])
24                 print('提现成功')
25                 break
26         else:
27             print('余额不足')
28             continue

  6、充值

    思路书写

1 获取用户充值金额
2 对输入的金额进行判断,并进行数据转换
3 获取目录,并进行拼接
4 读取文件信息
5 文件中的金额加上充值的金额,并写入文件中

  代码

 1 @common.login_aunt
 2 def recharge():
 3     print('开始充值')
 4     while True:
 5         money = input('请输入你要充值的金额').strip()
 6         if not money.isdigit():
 7             print('输入的金额不符合规范')
 8             continue
 9         money = int(money)
10         path = settings.BASE_DIR
11         path_file = os.path.join(path, 'db', '%s.json' % data_list['username'])
12         with open(path_file, 'r', encoding='utf8') as f:
13             data = json.load(f)
14         data['account'] += money
15         now_time = time.strftime('%Y-%m-%d %X')
16         data['flow'].append('%s充值了%s钱' % (now_time, money))
17         with open(path_file, 'w', encoding='utf8') as f1:
18             json.dump(data, f1, ensure_ascii=False)
19             # 写日志
20             common.write_log('%s充值成功' % data_list['username'])
21             print('充值成功')
22             break

  7、查看余额

 1 @common.login_aunt
 2 def check_balance():
 3     print('开始查看余额')
 4     while True:
 5         path = settings.BASE_DIR
 6         path_file = os.path.join(path, 'db', '%s.json' % data_list['username'])
 7         with open(path_file, 'r', encoding='utf8') as f:
 8             data = json.load(f)
 9             print(data['account'])
10             break

  8、查看流水(流水可以在转账,充值,提现成功的后面进行添加然后写入文件中)

@common.login_aunt
def check_flow():
    print('开始查看流水')
    while True:
        path = settings.BASE_DIR
        path_file = os.path.join(path, 'db', '%s.json' % data_list['username'])
        with open(path_file, 'r', encoding='utf8') as f:
            data = json.load(f)
        if data['username'] == data_list['username']:
            print(data['flow'])
            break
        else:
            print('输入的用户名错误')
            continue

  9、加入购物车

    思路书写

 1 定义商品,列表
 2 循环取值,枚举
 3 获取商品序号
 4 判断输入的序号是为空不,是否是小数。
 5 如果不是,返回输入不对
 6 如果对,转换输入序号的类型。
 7 在外面定义一个大字典,用于接受加入购物车的商品
 8 取出商品的名称和价格
 9 判断商品名称在不在外面的大字典中,如果不在就把商品名称写入字典中
10 如果在取出大字典中的count值加1
11 在输入商品序号的地方加入一个退出键
12 如果退出,获取文件根目录,拼接文件路径到db目录下为用户名.json结尾的文件。读取文件
13 把购物车里的数据赋值给用户文件中的购物信息,然后再写入

  代码

 1 @common.login_aunt
 2 def add_cart():
 3     print('添加购物车')
 4     # 定义一个全局变量,用于接受添加的购物车
 5     shopping_cra = {}
 6     while True:
 7         # 定义商品
 8         commodity = [
 9             ['water', 10],
10             ['drinks', 20],
11             ['bread', 30]
12         ]
13         # 通过枚举的方式得到商品和价格以及商品序号
14         for k, v in enumerate(commodity):
15             print('%s %s %s' % (k, v[0], v[1]))
16         number = input('请输入商品序号(q to quit):').strip()
17         if number.isdigit():
18             number = int(number)
19             commodity_name = commodity[number][0]
20             commodity_price = commodity[number][1]
21             if commodity_name not in shopping_cra:
22                 shopping_cra[commodity_name] = {'price': commodity_price, 'count': 1}
23             else:
24                 shopping_cra[commodity_name]['count'] += 1
25                 print('请继续购物')
26         elif number == 'q':
27             if shopping_cra:
28                 path = settings.BASE_DIR
29                 path_file = os.path.join(path, 'db', '%s.json' % data_list['username'])
30                 with open(path_file, 'r', encoding='utf8') as f:
31                     data = json.load(f)
32                 data['shopping_cart'] = shopping_cra
33 
34                 with open(path_file, 'w', encoding='utf8') as f1:
35                     json.dump(data, f1)
36                     # 写日志
37                     common.write_log('%s添加购物车成功' % data_list['username'])
38                     print('购物车添加成功')
39                     break
40         else:
41             print('输入的不符合规范')

  10、查看流水

 1 @common.login_aunt
 2 def check_shopping():
 3     print('开始查看购物车')
 4     while True:
 5         path = settings.BASE_DIR
 6         path_file = os.path.join(path, 'db', '%s.json' % data_list['username'])
 7         with open(path_file, 'r', encoding='utf8') as f:
 8             data = json.load(f)
 9         if data['username'] == data_list['username']:
10             print(data['shopping_cart'])
11             break
12         else:
13             print('输入的用户名错误')
14             continue

  11、日志功能

    日志功能我是写在公用文件中。然后在核心代码中添加记录即可(登录、注册等都可以)

 1 import logging
 2 import os
 3 from conf import settings
 4 logging.basicConfig(
 5     # 1、日志输出位置:1、终端 2、文件
 6     # filename='access.log', # 不指定,默认打印到终端
 7     filename=os.path.join(settings.BASE_DIR, 'log', 'log.log'),
 8 
 9     # 2、日志格式
10     format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
11 
12     # 3、时间格式
13     datefmt='%Y-%m-%d %H:%M:%S %p',
14 
15 
16     # 4、日志级别
17     # critical => 50
18     # error => 40
19     # warning => 30
20     # info => 20
21     # debug => 10
22     level=10,
23 )
24 
25 # 二:输出日志
26 # logging.debug('调试debug')
27 # logging.info('消息info')
28 # logging.warning('警告warn')
29 # logging.error('错误error')
30 # logging.critical('严重critical')
31 
32 def write_log(info):
33     logging.debug(info)

简易ATM+购物车之面条版

 

上一篇:测试用例方法


下一篇:ATM项目的实现