一、项目开发流程

1.项目需求分析:

(1)明确项目的体功能(要明确到底要写什么东西,实现什么功能)

这个阶段的话具体要询问产品经理以及客户(客户对产品的具体需求)

(2)参与人员:

产品经理;开发经理;架构师

1.架构师 开发经理提前构思大致方案

2.引导客户提出合理要求(避免不合理的请求)

3.记录会议内容

(3)技术人员主要职责:

引导客户提出一些比较合理,比较容易实现的需求。

2.项目架构设计:

(1)明确项目的核心技术点

项目使用的编程语言;

项目使用的框架;

项目所使用的数据库;

项目报价

(2)参与人员:

架构师

3.项目分组开发:

(1)明确每个组每个人具体到写该项目的哪些功能

(2)参与人员:

架构师;开发经理;普通程序员

4.项目提交测试:

(1)程序员自己本身写完自测以及交付测试小组测试(错的太多可能会扣绩效)

(2)参与人员:

普通的程序员;测试小组

5.项目交付上线:

(1)参与人员:

运维工程师

(2)可以直接把项目交给客户帮客户定期维护

"""

小公司:成长速度特别快 但是压力非常大

大公司:履历好看 福利待遇好 较为安逸

"""

二、项目需求分析

1.主题

主题是带大家快速如门python直至开发一个ATM+购物车系统,ATM的实现类似于银行自助提款机核心业务,购物车的实现类似于淘宝商城购物系统。

2.项目核心

项目的核心不仅在于引领初学者快速入门python项目开发,更是站在项目架构的角度教你如何在程序开发之初合理且优雅地设计程序的架构,从而极大地提升程序的开发效率与可扩展性。

3.项目需求:

额度15000或自定义

支持多账户登录

可以查看账户余额

可以提现(可自定义手续费比例)

提供还款接口

支持账户间转账

记录每月日常消费流水

实现购物商城,买东西加入购物车,调用信用卡接口结账

提供管理接口,包括添加账户、用户额度,冻结账户等

ATM记录操作日志

用户认证功能

4.从需求中提炼出项目的核心功能

用户注册

用户登录

查看余额

账户提现

充值功能

转账功能

查看账单

购物车功能

管理员功能

5.从功能中在提炼出核心技术点

python核心语法

python诸多模块

装饰器知识

三、项目架构设计(重点)

1.架构前拓展

编写代码的改进历程:

(1)代码直接写在一个文件里面,采用面条版堆积;

(2)将有些具体的功能采用函数封装;

上述两个阶段类似于小公司,一个员工身兼数职

(3)讲不同的功能拆分到不同的文件

上述阶段类似于大公司 工具职责划分部门 每个员工只干该岗位的具体事宜

敲重点:拆分的目的是为了更好的管理资源和代码,提升程序的扩展性。

2.项目架构(重要)

(1)百度

以用户登录为例:

浏览器页面获取用户名和密码;

基于网络将用户名和密码发送给百度服务器;

服务端去数据库中校验用户数据。

三层架构:

浏览器;服务端;数据库

(2)淘宝

以购买商品为例:

浏览器页面展示商品总价;

基于网络将购买商品的操作发送给服务端做核心校验;

之后操作相应数据库完成数据修改。

三层架构:

浏览器;服务端;数据库

3.三层架构

(1)用户层

只做数据展示,数据获取功能

cmd窗口可以充当用户层

将来可以替换成浏览器或者app

(2)核心逻辑层

业务逻辑(真正的核心业务逻辑处理(代码))

某个py文件充当逻辑层

将来可以替换成软件开发目录规范或者现成的框架

(3)数据层

数据的增删改查

json文件充当数据库

可以替换成数据库程序

ATM架构设计
三层架构
core目录下的src.py(浏览器)
interface目录下的多个py文件(框架)
db目录下db_handler.py(数据库服务)

四、项目目录搭建

1.第一层

core文件夹

src.py文件充当第一层

2.第二层

iinterface文件 充当第二层

根据业务逻辑的不同再次拆分便于后期维护管理

user_interface.py

bank_interface.py

shop_interface.py

admin_interface.py

3.第三层

后续通过代码动态创建,或者直接创建db文件夹

五、项目功能搭建

1.注册

2.登陆

3.查看余额

4.提现

5.还款

6.转账

7.查看流水

8.添加购物车功能

9.查看购物车功能

10.结算购物车功能

11.管理员功能

六、作业

start.py

import weekends_work.core.src
# 完善购物车程序 尝试拆分成软件开发目录规范并添加日志功能
import os # 获取文件目前所在位置
out_path = os.path.dirname(os.path.dirname(__file__))
db_path = os.path.join(out_path, 'db') if __name__ == '__main__':
weekends_work.core.src.choice_user()

settings.py

import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DB_DIR = os.path.join(BASE_DIR, 'db')
if not os.path.exists(DB_DIR):
os.mkdir(DB_DIR) # 定义日志输出格式 开始
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]' # 其中name为getlogger指定的名字
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
# 自定义文件路径
OUT_PATH = os.path.dirname(os.path.dirname(__file__))
LOG_PATH = os.path.join(OUT_PATH, 'log')
if not os.path.exists(LOG_PATH):
os.mkdir(LOG_PATH)
logfile_path = os.path.join(LOG_PATH, 'z1.log') LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {}, # 过滤日志
'handlers': {
# 打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
# 打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024 * 1024 * 5, # 日志大小 5M
'backupCount': 5,
# 这里两个参数的意思是一个日志文件最多写5M,最多可以存在五个不同的日志文件,但是当数量达到五个之后就会出现最早的那个会被删除,
# 然后再产生一个新的文件(类似于覆盖了最早的那个文件)
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
# logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
}, # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
# '购物车记录': {
# 'handlers': ['default','console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
# 'level': 'WARNING',
# 'propagate': True, # 向上(更高level的logger)传递
# }, # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
},
}

src.py

import os
from weekends_work.lib import common
from weekends_work.db import db_hanlder
from weekends_work.interface import user_interface
from weekends_work.interface import shop_interface
from weekends_work.interface import bank_interface
from weekends_work.interface import admin_interface good_list = [['挂壁面', 3],
['印度飞饼', 22],
['极品木瓜', 666],
['土耳其土豆', 999],
['伊拉克拌面', 1000],
['董卓戏张飞公仔', 2000],
['仿真玩偶', 10000]] out_path = os.path.dirname(os.path.dirname(__file__))
db_path = os.path.join(out_path, 'db') log_user = {'name': ''} def choice_user():
while True: choice_user = input(
'''请选择需要执行的功能:\n1、用户登陆\n2、用户注册\n3、添加购物车\n4、结算购物车\n5、充值\n6、查看购物车中当前内容\n7、清空购物车中内容\n8、修改购物车中内容\n9、转账\n10、查看消费记录\n11、执行管理员功能\n请输入需要执行的指令(q退出):''')
if choice_user == 'q':
print('退出成功')
break
if choice_user not in user_choice:
print('功能编号不存在 请重新输入')
continue
func_name = user_choice.get(choice_user) # 获取函数名
res = func_name() # 调用函数
if res:
print(res) # 登陆功能
def log_in():
is_log_bool = True
while is_log_bool:
log_name = input('请输入登陆的用户名(q退出):')
# 获取用户名
if log_name == 'q':
break
# 输q退出 log_pwd = input('请输入密码:')
# 获取密码
answer = user_interface.login_interface(log_name, log_pwd)
print(answer)
if answer == '登陆成功':
break # 注册功能
def sign_in():
while True:
# 获取注册的用户名
sign_name = input('请输入注册的用户名(q退出):').strip()
if sign_name == 'q':
break
# 如果前面的操作都没出错,就获取密码,需要输入两次进行确定
sign_pwd = input('请输入密码:').strip()
check_sign_pwd = input('请确认密码:').strip()
answer = user_interface.signin_interface(sign_name, sign_pwd, check_sign_pwd)
print(answer)
if answer == '注册成功':
break # 添加购物车功能
@common.is_log_z
def shop_add():
count = 1
while True: print('-----------------商品目录如下:----------------')
for i, j in enumerate(good_list, start=1):
lis_shop = f'''
商品编号:{i}
商品名:{j[0]}
商品价格:{j[1]}元
'''
print(lis_shop)
choice_shop = input('请输入需要添加到购物车的物品(输入编号):').strip()
if choice_shop == 'q':
print('成功退出')
break
# 获取用户需要购买商品的编号
shop_name = good_list[int(choice_shop) - 1][0]
shop_price = good_list[int(choice_shop) - 1][1]
choice_number = input(f'请输入需要购买{shop_name}数量:')
# 编号在范围内就获取需要购买的数量
answer = shop_interface.shop_add_interface(choice_shop, choice_number, count)
print(answer)
count += 1
if answer == '退出成功':
break # 结算购物车功能
@common.is_log_z
def settle_account():
answer = shop_interface.settle_account_interface()
print(answer) # 充值功能
@common.is_log_z
def balance_add():
res = db_hanlder.infor_read(log_user['name'])
if res['is_lock'] == True:
return '你在黑名单中,没这个权限了'
else:
balance_add_number = input('请输入充值金额:').strip()
answer = bank_interface.balance_add_interface(balance_add_number)
print(answer) # 查看购物车功能
@common.is_log_z
def shop_car_print():
res_befor = db_hanlder.infor_read(log_user['name'])
print(f'-------------用户:{log_user["name"]}当前购物车中物品如下:------------')
if res_befor['shop_car'] == {}:
print('空')
lg = common.get_logger('查看购物车记录')
lg.debug(f'用户{log_user["name"]}购物车为空')
else:
for i in res_befor['shop_car']:
number_i = res_befor['shop_car'][i][0]
price_i = res_befor['shop_car'][i][1] infor_p = f'''
--------------------------------------------------
商品名:{i}
单价:{price_i}
已添加数量:{number_i}
--------------------------------------------------
'''
print(infor_p)
lg = common.get_logger('查看购物车记录')
lg.debug(f'用户{log_user["name"]}购物车内容已查看') # 清空购物车功能
@common.is_log_z
def shop_car_clear():
answer = shop_interface.shop_car_clear_interface()
print(answer) # 修改购物车功能
@common.is_log_z
def change_shop_car():
while True: print(f'-------------用户:{log_user["name"]}当前购物车中物品如下:------------')
answer = shop_interface.change_shop_car_interface()
print(answer)
if answer == '成功退出':
break # 查看流水
@common.is_log_z
def log_shopping():
res_befor = db_hanlder.infor_read(log_user['name'])
print(f'---------------用户{log_user}流水:----------------')
lg = common.get_logger('查看流水记录')
lg.debug(f'用户{log_user["name"]}查看流水')
for i in res_befor['record']:
print(f'''
{i}元
''') # 转账功能
@common.is_log_z
def send_money():
res = db_hanlder.infor_read(log_user['name'])
if res['is_lock'] == True:
return '你在黑名单中,没这个权限了'
else:
while True: # 获取转账对象并判断是否存在
send_user = input('请输入转账对象:')
if send_user == 'q':
print('成功退出')
lg = common.get_logger('转账记录')
lg.debug(f'用户{log_user["name"]}直接退出')
break
send_number = input('请输入转账金额:')
answer = bank_interface.send_money_interface(send_user, send_number)
print(answer)
if answer == '转账成功':
break @common.is_log_z
def administrator_function():
if log_user['name'] == 'zzh':
while True:
is_continue = input('管理员功能如下:设置黑名单用户\n请按1执行功能(q退出):').strip() answer = admin_interface.administrator_function_interface(is_continue)
print(answer)
if answer == '成功退出' or answer == '修改成功':
break else:
lg = common.get_logger('管理员操作记录')
lg.debug(f'用户{log_user["name"]}退出')
print('不是管理员用户!') user_choice = {'1': log_in,
'2': sign_in,
'3': shop_add,
'4': settle_account,
'5': balance_add,
'6': shop_car_print,
'7': shop_car_clear,
'8': change_shop_car,
'9': send_money,
'10': log_shopping,
'11': administrator_function
}

common.py

import logging
import logging.config
import os
import hashlib
from weekends_work.conf import settings
from weekends_work.core import src out_path = os.path.dirname(os.path.dirname(__file__))
db_path = os.path.join(out_path, 'db') # 记录日志
def get_logger(name):
logging.config.dictConfig(settings.LOGGING_DIC) # 自动加载字典中的配置
logger1 = logging.getLogger(name)
return logger1 # 判断有没有这个文件
def is_there(log_name):
file_name = f'{log_name}.json'
file_path = os.path.join(db_path, file_name)
# 拼接路径,查找这个文件是不是存在
is_file = os.path.exists(file_path)
return is_file # 对密码使用hash加密
def use_hash(pwd):
pwd_md5 = hashlib.md5()
pwd_md5.update(pwd.encode('utf8'))
pwd_md5_get = pwd_md5.hexdigest()
return pwd_md5_get # 整个装饰器判断是否登陆了
def is_log_z(func):
def intter(*args, **kwargs):
if src.log_user.get('name'):
res = func(*args, **kwargs)
return res
else: print('请先进行登陆')
src.log_in() return intter

user_interface.py

from weekends_work.lib import common
from weekends_work.db import db_hanlder
from weekends_work.core import src def signin_interface(sign_name, sign_pwd, check_sign_pwd):
if sign_name == '':
# 如果用户名为空就重新注册 lg = common.get_logger('注册记录')
lg.debug('用户名为空')
return '用户名不能为空!'
is_file = common.is_there(sign_name)
# 拼接路径,查找这个文件是不是存在(判断这个用户名是否已经存在) if is_file:
# 当这个文件存在了(用户名重复了),重新注册
lg = common.get_logger('注册记录')
lg.debug(f'用户{sign_name}重复')
return '用户名重复请重新输入!' if sign_pwd != check_sign_pwd:
# 如果两次密码不一致,重新注册
lg = common.get_logger('注册记录')
lg.debug(f'用户{sign_name}两次密码不一致')
return '两次密码不一致,请重新输入!'
sign_pwd_md5_get = common.use_hash(sign_pwd) user_infor = {'name': sign_name, 'password': sign_pwd_md5_get, 'balance': 15000, 'shop_car': {},
'record': [], 'is_lock': False}
db_hanlder.infor_save(sign_name, user_infor)
lg = common.get_logger('注册记录')
lg.debug(f'用户{sign_name}注册成功')
return '注册成功' def login_interface(log_name, log_pwd):
if log_name == '':
# 如果用户名为空就重新注册
return '用户名不能为空!'
# 拼接路径,查找这个文件是不是存在(判断这个用户名是否已经存在)
is_file = common.is_there(log_name)
if not is_file:
lg = common.get_logger('登录记录')
lg.debug('用户名错误')
return '用户名错误'
# 如果有这个文件(有这个用户)
print('用户名正确')
res = db_hanlder.infor_read(log_name)
log_pwd_md5_get = common.use_hash(log_pwd)
if res['password'] != log_pwd_md5_get:
lg = common.get_logger('登录记录')
lg.debug(f'用户{log_name}密码错误')
return '密码错误'
src.log_user['name'] = log_name
lg = common.get_logger('登录记录')
lg.debug(f'用户{log_name}登陆成功')
return '登陆成功'

shop_interface.py

from weekends_work.core import src
from weekends_work.lib import common
from weekends_work.db import db_hanlder good_list = [['挂壁面', 3],
['印度飞饼', 22],
['极品木瓜', 666],
['土耳其土豆', 999],
['伊拉克拌面', 1000],
['董卓戏张飞公仔', 2000],
['仿真玩偶', 10000]] def shop_add_interface(choice_shop, choice_number, count):
little_shop_car = {} if not choice_shop.isdigit():
# 判断是否是纯数字编号,不是就重新来过
lg = common.get_logger('添加购物车记录')
lg.debug(f'用户{src.log_user["name"]}商品编号错误')
return '请输入正确的数字编号!' if int(choice_shop) not in range(1, 8):
lg = common.get_logger('添加购物车记录')
lg.debug(f'用户{src.log_user["name"]}商品编号错误')
return '你他奶奶的商品编号超出范围了!'
# 判断编号范围是否在范围内
shop_name = good_list[int(choice_shop) - 1][0]
shop_price = good_list[int(choice_shop) - 1][1] if not choice_number.isdigit():
# 如果购买数量不是纯数字也重新来过
lg = common.get_logger('添加购物车记录')
lg.debug(f'用户{src.log_user["name"]}商品编号错误')
return '数量需要是纯数字!'
if little_shop_car.get(shop_name) == None:
# 临时购物车中如果没有这个商品的信息就直接加入
little_shop_car[shop_name] = [int(choice_number), shop_price]
else:
# 如果有信息就相加
little_shop_car[shop_name][0] += int(choice_number)
res_befor = db_hanlder.infor_read(src.log_user['name'])
old_car = res_befor.get('shop_car')
if old_car and count == 1:
# 如果数据库中不为空,把里面的数据值加进来
for i in old_car: if little_shop_car.get(i) == None:
little_shop_car[i] = old_car[i]
else:
little_shop_car[i][0] += old_car[i][0]
print('商品添加成功')
lg = common.get_logger('添加购物车记录')
lg.debug(f'用户{src.log_user["name"]}商品成功加入临时购物车')
if_continue = input('输入q退出,其他字符继续购物')
if if_continue == 'q':
if little_shop_car:
res_befor['shop_car'] = little_shop_car
db_hanlder.infor_save(src.log_user['name'], res_befor)
lg = common.get_logger('添加购物车记录')
lg.debug(f'用户{src.log_user["name"]}购物结束')
return '退出成功'
else:
lg = common.get_logger('添加购物车记录')
lg.debug(f'用户{src.log_user["name"]}未购物直接退出')
return '退出成功' def settle_account_interface():
res_befor = db_hanlder.infor_read(src.log_user['name'])
count_money_all = 0
for i in res_befor['shop_car']:
list_i = res_befor['shop_car'][i]
count_money = list_i[1] * list_i[0]
count_money_all += count_money
balance_u = res_befor['balance'] - count_money_all
res_befor['record'].append(f'-{count_money_all}')
if balance_u <= 0:
lg = common.get_logger('结算记录')
lg.debug(f'用户{src.log_user["name"]}余额不支持结算')
return '余额不足'
res_befor['balance'] = balance_u
res_befor['shop_car'] = {}
db_hanlder.infor_save(src.log_user["name"], res_befor)
lg = common.get_logger('结算记录')
lg.debug(f'用户{src.log_user["name"]}结算成功')
return f'尊敬的{src.log_user["name"]} 您本次消费{count_money} 卡上余额剩余{balance_u} 欢迎下次再来挥霍!!!' def shop_car_clear_interface():
res_befor = db_hanlder.infor_read(src.log_user['name'])
res_befor['shop_car'] = {}
db_hanlder.infor_save(src.log_user['name'], res_befor)
lg = common.get_logger('清空购物车记录')
lg.debug(f'用户{src.log_user["name"]}购物车已清空')
return f'用户{src.log_user["name"]}购物车已清空' def change_shop_car_interface():
res_befor = db_hanlder.infor_read(src.log_user['name'])
if res_befor['shop_car'] == {}:
lg = common.get_logger('修改购物车记录')
lg.debug(f'用户{src.log_user["name"]}购物车为空')
return '购物车为空' else:
for i in res_befor['shop_car']:
number_i = res_befor['shop_car'][i][0]
price_i = res_befor['shop_car'][i][1] infor_p = f'''
--------------------------------------------------
商品名:{i}
单价:{price_i}
已添加数量:{number_i}
--------------------------------------------------
'''
print(infor_p)
change_name = input('请输入需要更改的商品名称(要中文输完整,输入q退出):').strip()
if change_name == 'q':
lg = common.get_logger('修改购物车记录')
lg.debug(f'用户{src.log_user["name"]}直接退出')
return '成功退出'
if change_name in res_befor['shop_car']:
change_number = int(input('需要更改的数量:').strip())
if change_number == 0:
res_befor['shop_car'][change_name].pop
print(res_befor)
lg = common.get_logger('修改购物车记录')
lg.debug(f'用户{src.log_user["name"]}购物车内容已修改')
else:
res_befor['shop_car'][change_name][0] = change_number
print(res_befor)
lg = common.get_logger('修改购物车记录')
lg.debug(f'用户{src.log_user["name"]}购物车内容已修改')
db_hanlder.infor_save(src.log_user['name'], res_befor)

admin_interface.py

import os
from weekends_work.db import db_hanlder
from weekends_work.core import src
from weekends_work.lib import common out_path = os.path.dirname(os.path.dirname(__file__))
db_path = os.path.join(out_path, 'db') def administrator_function_interface(is_continue):
if is_continue == 'q':
lg = common.get_logger('管理员操作记录')
lg.debug(f'管理员{src.log_user["name"]}退出')
return '成功退出'
if is_continue == '1':
check_all_user = os.listdir(db_path) print('----------当前用户信息如下:------------')
for i in check_all_user: filename = os.path.splitext(i)[1]
if filename != '.json':
continue
username, outher_infor = i.split('.') res_infor = db_hanlder.infor_read(username) print(f'''
用户名称:{username}
是否在黑名单中:{res_infor.get('is_lock')}
''') change_user = input('输入需要修改黑白名单权限的用户名称(全称):').strip()
if f'{change_user}.json' not in check_all_user:
lg = common.get_logger('管理员操作记录')
lg.debug(f'管理员{src.log_user["name"]}输入用户名错误')
return '用户不存在'
change_infor = input('请输入想要给予的权限(True或False):')
print(type(change_infor))
if change_infor == 'True' or change_infor == 'False':
res_infor_change = db_hanlder.infor_read(change_user)
res_infor_change['is_lock'] = bool(change_infor)
db_hanlder.infor_save(change_user, res_infor_change)
lg = common.get_logger('管理员操作记录')
lg.debug(f'管理员{src.log_user["name"]}修改权限成功')
return '修改成功'
else: lg = common.get_logger('管理员操作记录')
lg.debug(f'管理员{src.log_user["name"]}权限信息输入错误')
return '权限信息错误' else:
lg = common.get_logger('管理员操作记录')
lg.debug(f'管理员{src.log_user["name"]}输入错误指令') return '请输入正确的指令'

db_hanlder.py

import json
import os out_path = os.path.dirname(os.path.dirname(__file__))
db_path = os.path.join(out_path, 'db') # 数据保存
def infor_save(log_name, user_infor):
file_name = f'{log_name}.json'
file_path = os.path.join(db_path, file_name)
with open(file_path, 'w', encoding='utf8') as f1:
json.dump(user_infor, f1, ensure_ascii=False) # 数据读取
def infor_read(log_name):
file_name = f'{log_name}.json'
file_path = os.path.join(db_path, file_name)
with open(file_path, 'r', encoding='utf8') as f1:
res = json.load(f1)
return res

bank_interface.py

import os
from weekends_work.core import src
from weekends_work.lib import common
from weekends_work.db import db_hanlder out_path = os.path.dirname(os.path.dirname(__file__))
db_path = os.path.join(out_path, 'db') def balance_add_interface(balance_add_number):
if balance_add_number == '':
lg = common.get_logger('充值记录')
lg.debug('金额为空')
return '金额不能为空'
if not balance_add_number.isdigit():
lg = common.get_logger('充值记录')
lg.debug('金额输入不是纯数字')
return '金额不是纯数字' res_befor = db_hanlder.infor_read(src.log_user["name"]) res_befor['balance'] += int(balance_add_number)
res_befor['record'].append(f'+{balance_add_number}')
db_hanlder.infor_save(src.log_user["name"], res_befor)
lg = common.get_logger('充值记录')
lg.debug(f'用户{src.log_user["name"]}充值成功')
return f'用户{src.log_user["name"]}充值成功' def send_money_interface(send_user, send_number):
res_befor = db_hanlder.infor_read(src.log_user["name"])
money_now = res_befor['balance']
# 获取用户当前余额
ans = common.is_there(send_user)
# 判断转账对象是否存在
if not ans:
lg = common.get_logger('转账记录')
lg.debug(f'用户{src.log_user["name"]}转账用户不存在')
return '用户不存在'
# 如果用户存在就转账 if int(send_number) >= money_now:
lg = common.get_logger('转账记录')
lg.debug(f'用户{src.log_user["name"]}余额不足')
return '余额不足'
# 如果转账金额足够就转账 res_befor_s1 = db_hanlder.infor_read(send_user)
res_befor_s1['balance'] += int(send_number) db_hanlder.infor_save(send_user, res_befor_s1)
# 转账之后把转账用户中的金额扣除
res_befor['balance'] -= int(send_number)
res_befor['record'].append(f'-{send_number}')
db_hanlder.infor_save(src.log_user['name'], res_befor)
lg = common.get_logger('转账记录')
lg.debug(f'用户{src.log_user["name"]}转账成功')
return '转账成功'

10月28日内容总结——ATM项目开发流程的更多相关文章

  1. 2016年10月28日 星期五 --出埃及记 Exodus 19:13

    2016年10月28日 星期五 --出埃及记 Exodus 19:13 He shall surely be stoned or shot with arrows; not a hand is to ...

  2. [2018-11-03]2018年10月28日宁波dotnet社区活动回顾及下次活动预告

    离上次活动,有半年了,汗.之后尽量保证每月一次,以组织为主,多邀请嘉宾来分享. 本次活动不足之处 人手不足:由于活动组织事项受限于人手(目前就我一个,这次活动前后我又应邀给大红鹰学院应届生介绍dotn ...

  3. 10月28日下午MySQL数据库的增加、删除、查询(匹配数据库登录和可以增、删、查的显示数据库内容的页面))

    一.匹配数据库登录 步骤: 1.做一个普通的登录界面,注意提交方式为post. <!--登录界面--> <form action="chuli.php" meth ...

  4. 10月28日PHP基础知识测试题

    本试题共40道选择题,10道判断题,考试时间1个半小时 一:选择题(单项选择,每题2分): 1. LAMP具体结构不包含下面哪种(A) A:Windows系统 B:Apache服务器 C:MySQL数 ...

  5. 【第400篇题解纪念2016年10月28日】【28.10%】【codeforces 617E】XOR and Favorite Number

    time limit per test4 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  6. [2020年10月28日普级组]1406.SMRTFUN

    S M R T F U N SMRTFUN SMRTFUN 题目描述 "又肥又温顺,又大又笨,他们看起来那么傻,而且也不有趣--" 这些牛想要证明,他们是既有趣,又聪明的.为了这样 ...

  7. [2020年10月28日普级组]1408.MSWORLD

    1408. M S W O R L D 1408.MSWORLD 1408.MSWORLD 题目描述 Bessie , Farmer John 的优选牛,刚刚获得了一个牛科动物选美比赛的冠军!并得到了 ...

  8. 10月28日上午 PHP数据访问

    1.建一个连接(连接PHP和MYSQL) $db = new MySQLi("localhost","root","666","t ...

  9. Week8(10月28日)

    Part I:提问  =========================== 1. Lazy.Eager.Explicit Loading的关键字是什么? 2. 请比较三种加载方式的性能. Part ...

  10. EditPlus 4.3.2475 中文版已经发布(10月28日更新)

    新的修订版修复了上移多个插入点时会造成程序崩溃的问题.

随机推荐

  1. java-代码编写规范

    命名 变量/方法:小驼峰. mBtnHelloWorld 控件 mBtnTest: 按键 mTvTest:文本

  2. fastposter v2.10.0 简单易用的海报生成器

    fastposter海报生成器是一款快速开发海报的工具.只需上传一张背景图,在对应的位置放上组件(文字.图片.二维.头像)即可生成海报. 点击代码直接生成各种语言的调用代码,方便快速开发. 现已服务众 ...

  3. day17-Servlet06

    Servlet06 15.HttpServletResponse 15.1HttpServletResponse介绍 每次HTTP请求,Tomcat都会创建一个HttpServletResponse对 ...

  4. 2022-11-14 Acwing每日一题

    本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的.同时也希望 ...

  5. Kubernetes IPVS和IPTABLES

    个人名片: 对人间的热爱与歌颂,可抵岁月冗长 Github‍:念舒_C.ying CSDN主页️:念舒_C.ying 个人博客 :念舒_C.ying Kubernetes IPVS和IPTABLES ...

  6. Selenium4+Python3系列(九) - 上传文件及滚动条操作

    一.上传文件操作 上传文件是每个做自动化测试同学都会遇到,而且可以说是面试必考的问题,标准控件我们一般用send_keys()就能完成上传, 但是我们的测试网站的上传控件一般为自己封装的,用传统的上传 ...

  7. JS逆向实战9——cookies DES加密混淆

    cookie加密 DES 混淆 目标网站:aHR0cHM6Ly90bGNoZW1zaG9wLnlvdXpoaWNhaS5jb20vbWFpbi90ZW5kP05vdGljZUNhdGVJZD0xJk5 ...

  8. redis集群之主从复制集群的原理和部署

    最近在复盘redis的知识,所以本文开始希望介绍下redis的集群架构.原理以及部署:本文主要介绍redis的主从复制集群,包括其架构模型,原理,高可用等: 一.主从集群的介绍   redis的主从复 ...

  9. Day27:异常详解

    异常 1.1 异常概述 异常(Exception)指程序运行中出现的不正常情况:文件找不到.网络异常.非法参数等等. 我们通过代码来了解一下: public class Demo{ public st ...

  10. 第二章:seaborn调色板

    1.系统默认调色板 1 import seaborn as sns 2 import matplotlib.pyplot as plt 3 4 # 设置画布的大小 5 sns.set(context= ...