• python从入门到实践:项目1-ATM取款机(完成代码)


    目录

    一、项目视图分析

    二、文件结构分析

    三、完整代码

    1.start.py

    2.conf

    -settings.py

    3.core

    -src.py

    -admin.py

    4.interface

     -user_interface.py

    -shop_interface.py

    -bank_interface.py

    -admin_interface.py

    5.db

    -db_handler.py

    6.lib

    -common.py

    7.log

    8.readme


    一、项目视图分析

    通过上图,我们可以看到,一个完整的项目,基本包括三个部分:用户视图层、接口层、数据处理层,其中,用户视图层是用来接收用户的数据输入的,比如:有户名,密码;接口层是要接收用户视图层传来的数据,然后做判断:名字是否存在、密码是否正确,这就要求接口层调用数据处理层的方法;数据处理层就需要接收接口层的参数,把接口层需要的增、删、改、查的数据结果返回给接口层,接口层再把判断的结果返回给用户层。

    二、文件结构分析

    文件主要有以下几个部分:conf(setting.py-参数配置,比如:日志文件的配置、路径等)、core(src.py\admin.py-用户视图层,分为图通用户和管理员)、interface(接口层,里面有很多接口:用户接口,购物接口,银行接口,管理员接口,分这么细是为了“解耦合”)、db(用户数据存放;数据处理层:主要负责数据的增、删、改、查)、lib(公共方法:比如登录功能的装饰器)、log(日志文件)、readme(文档说明)、strat启动

    三、完整代码

    1.start.py

    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2022/09/02 14:59
    4. @Author : Rice
    5. @CSDN : C_小米同学
    6. @FileName: start.py
    7. '''
    8. '''
    9. 程序的入口
    10. '''
    11. import sys
    12. import os
    13. #添加解释器的环境变量
    14. sys.path.append(
    15. os.path.dirname(__file__)
    16. )
    17. #导入用户视图层
    18. from core import src
    19. # 开始执行项目函数
    20. if __name__ == '__main__':
    21. # 1.先执行用户视图层
    22. src.run()

    2.conf

    -settings.py

    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2022/09/02 14:49
    4. @Author : Rice
    5. @CSDN : C_小米同学
    6. @FileName: settings.py
    7. '''
    8. '''
    9. 存放配置信息
    10. '''
    11. import os
    12. #获取项目根目录路劲
    13. BASE_PATH = os.path.dirname(
    14. os.path.dirname(__file__)
    15. )
    16. # 获取user_data文件夹目录路径
    17. USER_DATA_PATH = os.path.abspath(os.path.join(BASE_PATH, 'db','user_data'))
    18. #USER_DATA_PATH2 = os.path.join(BASE_PATH, 'db','user_data').replace('\\','/')
    19. username = 'rice'
    20. user_path = os.path.abspath(os.path.join(USER_DATA_PATH, f'{username}.json')).replace('\\','/')
    21. """
    22. logging配置
    23. """
    24. BASE_PATH2 = os.path.dirname(os.path.dirname(__file__))
    25. logfile_dir = os.path.abspath(os.path.join(BASE_PATH2,'log')).replace('\\','/')
    26. logfile_name = 'atm.log'
    27. #如果不存在定义的日志目录就创建一个
    28. if not os.path.isdir(logfile_dir):
    29. os.mkdir(logfile_dir)
    30. #log文件的全路径
    31. logfile_path = os.path.join(logfile_dir, logfile_name).replace('\\','/')
    32. standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
    33. '[%(levelname)s][%(message)s]'
    34. simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
    35. test_format = '%(asctime)s] %(message)s'
    36. # 3、日志配置字典
    37. LOGGING_DIC = {
    38. 'version': 1,
    39. 'disable_existing_loggers': False,
    40. 'formatters': {
    41. 'standard': {
    42. 'format': standard_format
    43. },
    44. 'simple': {
    45. 'format': simple_format
    46. },
    47. },
    48. 'filters': {},
    49. 'handlers': {
    50. # 打印到终端的日志
    51. 'console': {
    52. 'level': 'DEBUG',
    53. 'class': 'logging.StreamHandler', # 打印到屏幕
    54. 'formatter': 'simple'
    55. },
    56. # 打印到文件的日志,收集info及以上的日志
    57. 'default': {
    58. 'level': 'DEBUG',
    59. 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,日志轮转
    60. 'formatter': 'simple',
    61. # 可以定制日志文件路径
    62. # BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # log文件的目录
    63. # LOG_PATH = os.path.join(BASE_DIR,'a1.log')
    64. 'filename': logfile_path, # 日志文件
    65. 'maxBytes': 1024 * 1024 * 5, # 日志大小 5M
    66. 'backupCount': 5,
    67. 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
    68. },
    69. },
    70. 'loggers': {
    71. # logging.getLogger(__name__)拿到的logger配置
    72. '': {
    73. 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
    74. 'level': 'DEBUG', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
    75. 'propagate': True, # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
    76. },
    77. },
    78. }
    79. if __name__ == '__main__':
    80. print(user_path)

    3.core

    -src.py

    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2022/09/02 14:51
    4. @Author : Rice
    5. @CSDN : C_小米同学
    6. @FileName: src.py
    7. '''
    8. '''
    9. 用户视图层
    10. '''
    11. from interface import user_interface
    12. from lib import common
    13. from interface import bank_interface
    14. from interface import shop_interface
    15. #全局变量,记录用户是否已登录
    16. login_user = None
    17. # 1.注册功能
    18. def register():
    19. while True:
    20. # 1)让用户输入用户名和密码校验
    21. username = input('请输入用户名:').strip()
    22. password = input('请输入密码:').strip()
    23. re_password = input('请确认密码:').strip()
    24. #可以输入自定义的金额
    25. # 小的逻辑错误:比如两次密码是否一致
    26. if password == re_password:
    27. #2)调用接口层的注册接口,将用户名与密码交给接口层来进行处理
    28. #一个元祖
    29. flag, msg = user_interface.register_interface(username, password)
    30. # 3)根据flag判断用户注册是否成功,用于控制break
    31. if flag:
    32. print(msg)
    33. break
    34. else:
    35. print(msg)
    36. # 2.登录功能
    37. #成功登录了之后,一定会修改全局变量:login_user
    38. def login():
    39. #登录视图
    40. while True:
    41. #1)让用户输入用户名和密码
    42. username = input('请输入用户名:').strip()
    43. password = input('请输入密码:').strip()
    44. #2)调用接口层,将数据传给登录接口
    45. flag, msg = user_interface.login_interface(username, password)
    46. if flag:
    47. print(msg)
    48. global login_user
    49. login_user = username
    50. break
    51. else:
    52. print(msg) #有一个小bug,输入错误后,我想返回主页 #d #成功登录了#
    53. # 3.查看余额
    54. @common.login_auth
    55. def check_balance():
    56. #1.直接调用查看余额接口,获取用户余额
    57. #装饰器本身是有login_user
    58. balance = user_interface.check_bal_interface(login_user)
    59. print(f'用户{login_user} 账户余额为:{balance}')
    60. # 4.提现功能
    61. @common.login_auth
    62. def withdraw():
    63. while True:
    64. #1)让用户输入提现金额
    65. input_money = input('请输入提现金额:').strip()
    66. #2)判断用户输入的金额是否是数字
    67. if not input_money.isdigit(): #isdigit()-可以判断字符串
    68. print('请输入')
    69. continue
    70. #3)用户提现金额,将数据提现的金额交给接口层处理
    71. flag, msg = bank_interface.withdraw_interface(login_user, input_money)
    72. if flag:
    73. print(msg)
    74. break
    75. # 5.还款功能
    76. @common.login_auth
    77. def repay():
    78. '''
    79. 银行卡还款,无论是信用卡或储蓄卡,是否能任意大小的金额
    80. :return:
    81. '''
    82. while True:
    83. #1) 让用户输入还款金额
    84. input_money = input('请输入需要还款的金额:').strip()
    85. #2)判断用户输入的是否是数字
    86. if not input_money.isdigit():
    87. print('请输入正确的金额')
    88. continue
    89. input_money = int(input_money)
    90. #3)判断用户输入的金额大于0
    91. if input_money > 0:
    92. #4)调用还款接口
    93. flag, msg = bank_interface.repay_interface(login_user, input_money)
    94. if flag:
    95. print(msg)
    96. break
    97. else:
    98. print('输入的金额不能小于0')
    99. # 6.转账功能
    100. @common.login_auth
    101. def transfer():
    102. '''
    103. 1.接收 用户输入的 转账金额
    104. 2.接收用户输入的 转账目标用户
    105. :return:
    106. '''
    107. while True:
    108. #1) 让用户输入转账用户与金额
    109. to_user = input('请输入转账目标用户').strip()
    110. money = input('请输入转账金额').strip()
    111. #2)数据判断
    112. if not money.isdigit():
    113. print('请输入数字')
    114. continue
    115. money = int(money)
    116. if money > 0:
    117. #调用转账接口
    118. flag, msg = bank_interface.transfer_interface(
    119. login_user,to_user,money
    120. )
    121. if flag:
    122. print(msg)
    123. break
    124. else:
    125. print(msg)
    126. else:
    127. print('请输入正确的金额')
    128. # 7.查看流水
    129. @common.login_auth
    130. def check_flow():
    131. #直接调用查看流水接口
    132. flow_list = bank_interface.check_flow_interface(login_user)
    133. if flow_list:
    134. for flow in flow_list:
    135. print(flow)
    136. else:
    137. print('当前用户没有流水!')
    138. # 8.购物功能
    139. @common.login_auth
    140. def shop():
    141. #不从文件中读取商品数据,直接写
    142. #创建商品列表
    143. # shop_list = {
    144. # '0': {'name': '包子', 'price': 30}
    145. # }
    146. shop_list = [
    147. ['包子', 3], #0
    148. ['可乐', 5], #1
    149. ['book', 200],
    150. ['pc', 9999],
    151. ]
    152. #初始化当前购物车
    153. shopping_car = {} #{'商品名称':['单价','数量']]}
    154. while True:
    155. #枚举:enumerate(可迭代对象)--->元祖(可迭代对象的索引,索引对应的值)
    156. for index, shop in enumerate(shop_list):
    157. shop_name, shop_price = shop
    158. print(f'商品编号为{index}, 商品名称{shop_name}, 商品单价:{shop_price}')
    159. print(shop)
    160. choice = input('请输入商品编号:(是否结账输入y or n)').strip()
    161. #让用户根据商品编号进行选择
    162. #输入的是y进行支付结算功能
    163. if choice == 'y':
    164. if not shopping_car:
    165. print('购物车是空的,不能支付,请重新输入')
    166. continue
    167. #调用支付接口进行支付
    168. flag, msg = shop_interface.shopping_interface(login_user,shopping_car)
    169. if flag:
    170. print(msg)
    171. break
    172. else:
    173. print(msg)
    174. #输入的是n添加购物车(把shopping_car添加到json中)
    175. elif choice == 'n':
    176. #调用添加购物车接口
    177. if not shopping_car:
    178. print('购物车是空的,不能添加,请重新输入')
    179. continue
    180. flag, msg = shop_interface.add_shop_car_interface(login_user, shopping_car)
    181. if flag:
    182. print(msg)
    183. break
    184. else:
    185. print(msg)
    186. if not choice.isdigit():
    187. print('请输入正确的编号!')
    188. continue
    189. if not choice.isdigit():
    190. print('请输入正确的编号!')
    191. continue
    192. choice = int(choice)
    193. if choice not in range(len(shop_list)):
    194. print('请输入正确的编号!')
    195. continue
    196. shop_name, shop_price = shop_list[choice]
    197. #加入购物车
    198. #判断用户选择的商品是否重复,重复加1
    199. if shop_name in shopping_car:
    200. #添加商品数量
    201. shopping_car[shop_name][1] += 1
    202. else:
    203. #否则数量默认为1
    204. shopping_car[shop_name] = [shop_price, 1]
    205. # 9.查看购物车
    206. @common.login_auth
    207. def check_shop_car():
    208. shop_car = shop_interface.check_shop_car_interface(login_user)
    209. print(shop_car)
    210. # 10.管理员功能
    211. @common.login_auth
    212. def admin():
    213. '''
    214. 管理员功能:课后作业
    215. :return:
    216. '''
    217. from core import admin
    218. admin.admin_run()
    219. # 创建函数功能字典
    220. func_dic = {
    221. '1': register,
    222. '2': login,
    223. '3': check_balance,
    224. '4': withdraw,
    225. '5': repay,
    226. '6': transfer,
    227. '7': check_flow,
    228. '8': shop,
    229. '9': check_shop_car,
    230. '10': admin
    231. }
    232. # 视图层主程序
    233. def run():
    234. while True:
    235. print('''
    236. ======= ATM + 购物车 =======
    237. 1.注册功能
    238. 2.登录功能
    239. 3.查看余额
    240. 4.提现功能
    241. 5.还款功能
    242. 6.转账功能
    243. 7.查看流水
    244. 8.购物功能
    245. 9.查看购物车
    246. 10.管理员功能
    247. ========== end ============
    248. ''')
    249. choice = input('请输入功能编号:').strip()
    250. if choice not in func_dic:
    251. print('请输入正确的功能编号!')
    252. continue
    253. func_dic.get(choice)()

    -admin.py

    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2022/09/04 11:50
    4. @Author : Rice
    5. @CSDN : C_小米同学
    6. @FileName: admin.py
    7. '''
    8. from core import src
    9. from interface import admin_interface
    10. # 添加用户
    11. def add_user():
    12. src.register()
    13. # 修改用户额度
    14. def change_balance():
    15. while True:
    16. change_user = input('请输入需要修改额度的用户').strip()
    17. money = input('请输入需要修改的用户额度:').strip()
    18. if not money.isdigit():
    19. print('请输入数字')
    20. continue
    21. flag, msg = admin_interface.change_balance_interface(change_user, money)
    22. if flag:
    23. print(msg)
    24. break
    25. else:
    26. print(msg)
    27. break
    28. # 输入修改额度
    29. # 输入修改用户
    30. # 调用修改额度接口
    31. # 冻结账户
    32. def lock_user():
    33. while True:
    34. change_user = input('请输入需要修改额度的用户:').strip()
    35. flag, msg = admin_interface.lock_user_interface(change_user)
    36. if flag:
    37. print(msg)
    38. break
    39. else:
    40. print(msg)
    41. break
    42. # 管理员功能字典
    43. admin_dic = {
    44. '1': add_user,
    45. '2': change_balance,
    46. '3': lock_user
    47. }
    48. def admin_run():
    49. while True:
    50. print('''
    51. 1、添加用户
    52. 2、修改额度
    53. 3、冻结账户
    54. ''')
    55. choice = input('请输入管理员功能编号:').strip()
    56. # 判断功能编号是否存在
    57. if choice not in admin_dic:
    58. print('请输入正确的功能编号!')
    59. continue
    60. # 调用用于选择的功能函数
    61. admin_dic.get(choice)()

    4.interface

     -user_interface.py

    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2022/09/02 14:52
    4. @Author : Rice
    5. @CSDN : C_小米同学
    6. @FileName: user_interface.py
    7. '''
    8. '''
    9. 逻辑接口层
    10. 用户接口
    11. '''
    12. import json
    13. import os
    14. from conf import settings
    15. from db import db_handler
    16. from lib import common
    17. user_logger = common.get_logger('user')
    18. #user_logger.setLevel(10)
    19. #注册接口
    20. def register_interface(username, password, balance=5000):
    21. # 2)查看用户是否存在
    22. #2.1)调用 数据处理层中的select函数,会返回用户字典或None
    23. user_dic = db_handler.select(username)
    24. #若用户存在,则return,告诉用户重新输入(是通过用户名来判断是否存在的,跟密码没关系)
    25. if user_dic:
    26. return False, '用户名已存在!'
    27. #3)用户不存在,则保存用户数据
    28. #做密码加密
    29. password = common.get_pwd_md5(password)
    30. user_dic = {
    31. 'username': username,
    32. 'password': password,
    33. 'balance': balance,
    34. # 用于记录用户流水的列表
    35. 'flow': [],
    36. # 用于记录用户购物车
    37. 'shop_car': {},
    38. # locked: 用于记录用户是否被冻结
    39. # False:未冻结 True:已冻结
    40. 'locked': False
    41. }
    42. #3.2)保存数据
    43. db_handler.save(user_dic)
    44. msg = f'{username} 用户注册成功'
    45. #记录日志
    46. user_logger.info(msg)
    47. return True, msg
    48. #登录接口
    49. def login_interface(username, password):
    50. #1)先查看当前用户数据是否存在
    51. user_dic = db_handler.select(username)
    52. #2)判断用户是否存在
    53. #若有冻结用户,则需要判断是否被锁定
    54. if user_dic:
    55. if user_dic.get('locked'):
    56. return False, '当前用户已被锁定'
    57. #给用户输入的密码做一次加密
    58. password = common.get_pwd_md5(password)
    59. #3)校验密码是否一致
    60. if password == user_dic.get('password'):
    61. msg = f'用户{username}登录成功!'
    62. user_logger.info(msg)
    63. return True, msg
    64. else:
    65. msg = f'用户{username}密码错误!'
    66. user_logger.warn(msg)
    67. return False, msg
    68. msg = f'用户{username}不存在!'
    69. user_logger.warn(msg)
    70. return False, msg
    71. #查看余额接口
    72. def check_bal_interface(username):
    73. user_dic = db_handler.select(username)
    74. return user_dic['balance']

    -shop_interface.py

    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2022/09/02 14:53
    4. @Author : Rice
    5. @CSDN : C_小米同学
    6. @FileName: shop_interface.py
    7. '''
    8. '''
    9. 商城购物接口层
    10. '''
    11. from db import db_handler
    12. #商品准备结算接口
    13. def shopping_interface(login_user, shopping_car):
    14. #计算消费金额
    15. cost = 0
    16. for price_number in shopping_car.values():
    17. price, number = price_number
    18. cost += (price*number)
    19. #导入银行接口
    20. from interface import bank_interface
    21. #逻辑校验成功后,在调用银行支付接口
    22. flag = bank_interface.pay_interface(login_user,cost)
    23. if flag:
    24. return True, '支付成功,准备发货'
    25. return False, '支付失败,金额不足'
    26. #购物车添加接口
    27. def add_shop_car_interface(login_user, shopping_car):
    28. #获取当前用户的购物车
    29. user_dic = db_handler.select(login_user)
    30. shop_car = user_dic.get('shop_car')
    31. #添加购物车
    32. for shop_name, price_number in shopping_car.items():
    33. #每个商品的数量
    34. number = price_number[1]
    35. if shop_name in shop_car:
    36. user_dic['shop_car'][shop_name] += number
    37. db_handler.save(user_dic)
    38. print('添加到json成功')
    39. else:
    40. user_dic['shop_car'].update({shop_name: price_number})
    41. db_handler.save(user_dic)
    42. print('添加到json成功')
    43. return True, '添加购物车成功'
    44. #查看购物车接口
    45. def check_shop_car_interface(username):
    46. user_dic = db_handler.select(username)
    47. return user_dic.get('shop_car')

    -bank_interface.py

    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2022/09/02 14:53
    4. @Author : Rice
    5. @CSDN : C_小米同学
    6. @FileName: bank_interface.py
    7. '''
    8. '''
    9. 银行先关业务的接口
    10. '''
    11. from db import db_handler
    12. #提现接口(手续费5%)
    13. def withdraw_interface(username, money):
    14. #1)先获取用户字典
    15. user_dic = db_handler.select(username)
    16. #校验用户的钱是否足够
    17. balance = int(user_dic.get('balance'))
    18. #本金+手续费
    19. momey2 = int(money) * 1.05 #money是str,用int类型转换
    20. #判断用户金额是否足够
    21. if balance >= momey2:
    22. #2)修改用户字典中的金额
    23. balance -= momey2
    24. user_dic['balance'] = balance
    25. #记录流水
    26. flow = f'用户{username} 提现金额{money}成功,手续费是:{momey2 - float(money)}$ 剩余{balance}'
    27. user_dic['flow'].append(flow)
    28. #3)再保存数据,或更新数据
    29. db_handler.save(user_dic)
    30. # money是str,用int类型转换
    31. return True, flow
    32. def repay_interface(username, money):
    33. '''
    34. 1.获取用户的金额
    35. 2.给用户加钱操作
    36. :param username:
    37. :param money:
    38. :return:
    39. '''
    40. #1.获取用户字典
    41. user_dic = db_handler.select(username)
    42. #2.直接做加钱的操作
    43. user_dic['balance'] += money
    44. #记录流水
    45. flow = f'用户{username} 还款{money}成功! 当前额度为{user_dic["balance"]}'
    46. user_dic['flow'].append(flow)
    47. #3.调用数据处理层,将修改后的数据进行更新
    48. db_handler.save(user_dic)
    49. return True, flow
    50. def transfer_interface(login_user, to_user, money):
    51. '''
    52. 1.获取'当前用户' 数据
    53. 2.获取'目标用户' 数据
    54. 3.获取转账金额
    55. :return:
    56. '''
    57. login_user_dic = db_handler.select(login_user)
    58. to_user_dic = db_handler.select(to_user)
    59. if not to_user_dic:
    60. return False, '目标用户不存在'
    61. #4)若用户存在,则判断'当前用户的转账金额' 是足够的
    62. if login_user_dic['balance'] >= money:
    63. login_user_dic['balance'] -= money
    64. to_user_dic['balance'] += money
    65. #当前用户流水
    66. login_user_flow = f'用户{login_user} 给用户 {to_user} 转账 {money}$ 成功'
    67. login_user_dic['balance'].append(login_user_flow)
    68. #目标用户流水
    69. to_user_flow = f'用户{to_user} 给用户 {login_user} 转账 {money}$ 成功'
    70. to_user_dic['flow'].append(to_user_flow)
    71. #调用数据处理层,保存数据
    72. db_handler.save(login_user_dic)
    73. db_handler.save(to_user_dic)
    74. return True, login_user_flow
    75. return False, '当前用户转账金额不足'
    76. def check_flow_interface(login_user):
    77. user_dic = db_handler.select(login_user)
    78. return user_dic.get('flow')
    79. #支付接口
    80. def pay_interface(login_user, cost):
    81. user_dic = db_handler.select(login_user)
    82. #判断用户金额
    83. if user_dic.get('balance') >= cost:
    84. user_dic['balance'] -= cost
    85. flow = f'用户消费金额:{cost}$'
    86. user_dic['flow'].append(flow)
    87. #保存数据
    88. db_handler.save(user_dic)
    89. return True
    90. return False

    -admin_interface.py

    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2022/09/04 12:39
    4. @Author : Rice
    5. @CSDN : C_小米同学
    6. @FileName: admin_interface.py
    7. '''
    8. from db import db_handler
    9. from lib import common
    10. admin_logger = common.get_logger('admin')
    11. #修改额度接口
    12. def change_balance_interface(username, money):
    13. user_dic = db_handler.select(username)
    14. if user_dic:
    15. #修改额度
    16. user_dic['balance'] = int(money)
    17. db_handler.save(user_dic)
    18. msg = f'管理员修改用户:{username}额度修改成功'
    19. admin_logger.info(msg)
    20. return True, '额度修改成功!'
    21. return False, '修改额度用户不存在'
    22. #冻结账户接口
    23. def lock_user_interface(username):
    24. user_dic = db_handler.select(username)
    25. if user_dic:
    26. user_dic['locked'] = True
    27. db_handler.save(user_dic)
    28. return True, f'用户{username}冻结成功'
    29. return False, '冻结用户不存在'

    5.db

    -db_handler.py

    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2022/09/02 14:57
    4. @Author : Rice
    5. @CSDN : C_小米同学
    6. @FileName: db_handler.py
    7. '''
    8. '''
    9. 数据处理层
    10. -专门用户处理数据
    11. '''
    12. import json
    13. import os
    14. from conf import settings
    15. #查看数据
    16. def select(username):
    17. #1)接收接口层传过来的username用户名,拼接用户json文件路劲
    18. user_path = os.path.abspath(os.path.join(settings.USER_DATA_PATH, f'{username}.json')).replace('\\', '/')
    19. #2)校验用户json文件是否存在
    20. if os.path.exists(user_path):
    21. #3)打开数据,并返回给接口层
    22. with open(user_path, 'r', encoding='utf-8') as f:
    23. user_dic = json.load(f) # 导出数据
    24. return user_dic
    25. #3)不return,默认返回return None
    26. #保存数据
    27. def save(user_dic):
    28. #1)拼接用户的数据字典
    29. username = user_dic.get('username')
    30. user_path = os.path.abspath(os.path.join(settings.USER_DATA_PATH, f'{username}.json')).replace('\\', '/')
    31. #2)保存用户数据
    32. with open(user_path, 'w', encoding='utf-8') as f:
    33. # 导入数据(ensure_ascii=False,让文件中的中文数据显示更美观)
    34. json.dump(user_dic, f, ensure_ascii=False)

    6.lib

    -common.py

    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2022/09/02 14:50
    4. @Author : Rice
    5. @CSDN : C_小米同学
    6. @FileName: common.py
    7. '''
    8. '''
    9. 存放公共方法
    10. '''
    11. import hashlib
    12. import logging.config
    13. from conf import settings
    14. def get_pwd_md5(password):
    15. md5_obj = hashlib.md5()
    16. md5_obj.update(password.encode('utf-8')) #传入的数据需要时"字节串"
    17. salt = 'rice这是一个ATM'
    18. md5_obj.update(salt.encode('utf-8'))
    19. return md5_obj.hexdigest()
    20. #登录认证装饰器
    21. def login_auth(func):
    22. from core import src
    23. def inner(*args, **kwargs):
    24. if src.login_user:
    25. res = func(* args, ** kwargs)
    26. return res
    27. else:
    28. print('使用功能前,请先登录')
    29. src.login()
    30. return inner
    31. #添加日子功能:(日志功能在接口层使用)
    32. #获取日志功能
    33. #获取日志对象
    34. def get_logger(log_type):
    35. '''
    36. :param log_type: 比如是user日子,bank日子,购物商城日志
    37. :return:
    38. '''
    39. #1、加载日志配置信息
    40. logging.config.dictConfig(settings.LOGGING_DIC)
    41. #2、获取日志对象
    42. logger = logging.getLogger(log_type)
    43. return logger

    7.log

    8.readme

    # 项目说明书
    ## 项目:ATM + 购物车
    
    # 项目需求
        模拟实现一个ATM + 购物商城程序
    
            1.额度 15000或自定义 ->注册功能
            2.实现购物商城,买东西加入 购物车,调用信用卡接口结账-》购物、支付
            3.可以提现,手续费5%-》提现功能
            4.支持多账户登录-》登录功能
            5.支持账户间转账  -》转账功能
            6.记录日常消费流水-》记录流水功能
            7.提供还款接口  -》还款功能
            8.ATM记录操作日志 —》记录日志功能
            9.提供管理接口,包括添加账户、用户额度,冻结账户等。。。-》管理员功能
            10.用户认证用装饰器-》登录认证装饰器
    
    ## "用户视图层"展示给用户选择的功能
        1.注册功能
        2.登录功能
        3.查看余额
        4.提现功能
        5.还款功能
        6.转账功能
        7.查看流水
        8.购物功能
        9.查看购物车
        10.管理员功能
       
    
    # 一个项目如何从无到有
    ## 一 需求分析
        1.拿到项目,想在客户那里讨论需求
        商量项目的功能能否实现,周期,价格,得到需求文档
        2.最后在公司内部需要开一次会议,得到最终的开发文档,
        交给不同的岗位的程序员进行开发
            -Python:后端,爬虫
            -不同的岗位:
                -UI界面设计:
                    -设计软件的布局,会根据软件的外观切成一张张图片
                -前端:
                    -拿到UI交给他的图片,去搭建网页页面
                    -设计一些页面中,哪些位置需要接收数据,需要进行数据交互
                -后端:
                    -直接核心的业务逻辑,调度数据库进行数据的增删
                -测试:
                    -会给代码进行全面测试,比如压力测试,界面测试
                -运维
                    -部署项目
    ## 二 程序的架构设计
    ### 1、程序设计的好处
        1)思路不清晰
        2)不会出现写一半推翻重写
        3)方便自己或以后的同时更好维护
    ### 2、 三层架构设计的好处
        1)每个功能都分成三部分
        2)如果用户更换不同的用户界面或不同的数据储存机制,这样
        都不会影响接口层的核心逻辑代码。拓展性强
        3)可以在接口层,准确的记录接口和流水
    ### 3、三层架构
    #### 一 用户视图层
        用于与用户交互的,可以接受用户输入,打印接口返回的数据
    #### 二 逻辑接口层
        接受 用户视图层 传递过来的参数,根据逻辑判断调用数据层加以处理,
        并返回一个结果给用户视图层
    #### 三 数据处理层
        接受接口层传递过来的参数,做数据的
            - 保存 save()
            - 查看数据 select()
            - 更新数据
            - 删除数据
    ## 三 分任务开发
    ## 四 测试
    ## 五 上线
    
    # 统计代码
    

  • 相关阅读:
    iText7画发票PDF——小tips
    一幅长文细学华为MRS大数据开发(五)——MapReduce和Yarn
    Linux使用正则匹配配置文件有效内容
    linux驱动开发.之spi测试工具spidev_test源码(一)
    中国石油大学(北京)-《 油气藏经营管理》第一阶段在线作业
    R语言和医学统计学(6):重复测量方差分析
    k8s的ClusterIP和NodePort类型有何不同
    springboot常用注解
    Spring学习笔记(四)--spring配置文件schema约束
    Xlua在unity中使用luaide打断点
  • 原文地址:https://blog.csdn.net/weixin_43507744/article/details/126692924