Day5作业,商城+ATM机+后台管理
晚来了....东西太多,需要写的blog内容太多,re讲的渣渣,不明白为什么oldboy经常换老师,吐槽下吧,真心不爱了....
github地址在这:https://github.com/ccorzorz/ATM-shoppmall
商城用原来的,先上图吧:
商城图:
ATM后台管理:
ATM终端:
README:
1.测试帐号:
商城测试帐号:cc/123 或者自己注册
ATM 终端测试帐号:cc/123 alex/123 或者自己注册
ATM 管理员测试帐号:admin/admin 2.需安装的第三方模块:prettytable 3.文件目录以及说明请看file_struct_info 文件 4.数据库主要文件说明:
ATM 用户信息数据库:
atm_admin_db.json:
{用户名:'[用户状态,密码,信用额度,可用额度,[消费记录]'}
账单数据库:
{用户名:[本月还款金额,账单日期内的消费记录]} 5.账单生成说明:
每月账单生成可在linux 系统中的 crontab 里写入,或者登录管理员后台手动生成账单,账单日为每月22日
还款日为每月10日,生成账单时需要22日后才可生成账单,否则会提示日期未到 6.商城代码的说明:
时间原因,使用了第二天的商城作业修改的,但没有大幅对商城做模块拆分,只在 ATM 系统做了模块拆分 7.代码运行说明:
bin目录中的文件为入口:
ATM 终端:python3 atm.py start
ATM管理后台:python3 credit_manage.py start
购物商城:python3 shop.py 8.ATM 程序功能说明:
1.商城支付,充值功能接入 ATM 的支付接口
2.ATM 管理员可建卡,为方便测试,登录直接为用户名密码模式,并非6222...的卡号类型
3.支付时需要随机验证码
4.用户名的密码处理使用了MD5加密
5.账单使用了时间判断,并单独生成了每个月的账单,管理员可23日0点以后生成账单
6.逾期利息用户登录后可查询,但利息计算由于时间问题,并未对逾期分期还款等功能做处理
7.取现,支付等有5%的手续费,并会一并扣除
8.用户转账只能给此模拟银行的账户转账
9.后台管理可建卡,冻结,解冻账户,但不能删除用户
10.用户还款时,如超过需还款金额,会有提示,而且只能超额还款一次
11.提现,转账可用额度,为信用额度的一半
目录介绍:
.
|______init__.py
|____bin #执行文件目录
| |____atm.py #atm 终端开始程序,python3 atm.py start
| |____credit_manage.py #atm 后台开始程序,python3 atm.py start
| |____shop.py #
|____conf #配置文件信息
| |____setting.py #通用设置模块
|____core
| |____atm_admin_op.py #ATM 管理操作模块
| |____atm_run.py #ATM 终端运行主程序
| |____bills_rate.py #ATM用户查询账单模块
| |____data_op.py #数据操作类模块
| |____format_num.py #价格处理模块,处理为人民币标准显示
| |____generate_bills.py #账单生成模块
| |____logger.py #日志处理模块
| |____manager_main.py #ATM 管理员操作主程序
| |____pass_handler.py #密码 MD5加密处理模块
| |____shop_mall.py #商城主程序模块
| |____terminal_discover_bills.py #ATM 查看账单模块
| |____terminal_op.py #ATM 用户常规操作模块
| |____terminal_pay.py #ATM 支付接口
| |____terminal_repay.py #ATM 还款模块
| |____terminal_show_record.py #ATM 查看消费记录模块
| |____terminal_transfers.py #ATM 转账模块
| |____terminal_view_credit.py #ATM 查看用户额度信息模块
| |____terminal_withdraw.py #ATM 终端取现模块
| |____time_cal.py #时间处理模块
| |____veri_code.py #随机验证码模块,用来支付时验证
|____db #数据库目录
| |____201605_bills.json #atm 每月账单
| |____201609_bills.json #atm 每月账单
| |____atm_admin_db.json #atm 管理员数据库
| |____atm_cart_db.json #atm 系统用户信息,包括消费记录数据等信息
| |____goods.json #商城商品信息,包括价格,分类以及库存等
| |____mall_cart.json #商城用户购物车信息,保存用户未结账退出时的购物车信息
| |____mall_user.json #商城用户文件数据库,包括购买记录
| |____mall_user_lock #商城用户锁定用户文件
|____log
| |____access.log #atm 用户访问日志
| |____admin.log #atm 管理员操作日志
| |____trans.log #atm 用户终端操作日志
bin目录下:
atm.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
ATM 终端入口
""" import sys
sys.path.append('..')
from core import atm_run if len(sys.argv)==2 and sys.argv[1]=='start':
atm_run.main()
else:
print('\"python atm.py start\" to starup programe!!')
credit_manage.py:
#!/usr/bin/env python3
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
ATM管理后台入口
""" import sys
sys.path.append('..')
from core import manager_main
if len(sys.argv)==2 and sys.argv[1]=='start':
manager_main.main()
else:
print('\"python3 credit_manage.py start\" to starup programe')
# manager_main.main()
shop.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
购物商城入口
""" import sys
sys.path.append('..')
from core import shop_mall shop_mall.main()
conf目录:
setting.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
配置文件,配置交易费率字典,消费记录函数,以及日志的文件和等级等信息
"""
import sys,time,logging,datetime
sys.path.append('..')
from core import data_op,logger dt=time.strftime('%Y-%m-%d %H:%M:%S') trans_rate={'提现':0.05,'转账':0.05,'还款':0,'支付':0,'收款':0} def record(user_name,TransType,business,amounts):
user_data=data_op.l_d()
rates=trans_rate[TransType]*amounts
user_data[user_name][4].append({dt:[TransType,business,amounts,rates]})
data_op.flush_d(user_data)
return True LOG_LEVEL=logging.DEBUG
LOG_TYPE={'access':'access.log','trans':'trans.log','admin':'admin.log'}
core目录:
atm_admin_op.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
管理员操作模块,
show_all 查看所有账户信息
c_u 新建用户
freeze_u 冻结账户
un_freeze 解冻账户
enhance_credit 提升额度
logout 退出登录
"""
import sys
sys.path.append('..')
from core import data_op,format_num,pass_handler
from core.logger import * def show_all():
"""
显示所有用户信息
:return: None
"""
user_data=data_op.l_d()
print('现有账户额度以及状态'.center(30,'*'))
for item in user_data:
if user_data[item][0]==0:
user_data[item][0]='冻结'
else:
user_data[item][0]='正常'
print('{:10s}{:15s}{:10s}'.format(item,
format_num.fn(user_data[item][2]),
user_data[item][0])) def c_u():
"""
创建用户,额度,以及密码,密码使用 md5处理,并记录 log 日志,修改相关数据库
:return: None
"""
user_data=data_op.l_d()
while True:
inp=input('请输入用户帐号,输入 b 返回主菜单:')
if inp=='b':
break
elif user_data.get(inp)==None:
while True:
balance=input('请输入初始额度,必须为整数的数字:')
if balance.isdigit():
balance=int(balance)
break
else:
print('输入有误,重新输入...')
pwd_inp=input('请输入用户的密码:')
pwd=pass_handler.md5_pwd(pwd_inp)
user_data[inp]=[1,pwd,balance,balance,[]]
data_op.flush_d(user_data)
print('帐号{}信息添加成功,额度为{}'.format(inp,format_num.fn(balance)))
log_admin.info('添加{}帐号信息,额度:{}'.format(inp,balance))
break
else: #如果用户存在,提示用户
print('帐号{}已存在,请重新输入.'.format(inp)) def freeze_u():
"""
冻结用户,修改相关数据库
:return: None
"""
user_data=data_op.l_d()
while True:
show_all()
inp=input('请输入要冻结的账户,输入 b 返回主菜单:')
if inp=='b':
break
elif user_data.get(inp)==None: #如无账户,提示管理员
print('无{}账户信息'.format(inp))
else:
if user_data[inp][0]==0:
print('账户{}已被冻结,无需重复操作'.format(inp))
break
else:
user_data[inp][0]=0
data_op.flush_d(user_data)
print('账户{}冻结成功!'.format(inp))
log_admin.info('冻结账户{}'.format(inp))
break def un_freeze_u():
"""
解冻账户,与冻结账户操作相反,并修改数据库
:return:
"""
user_data=data_op.l_d()
freeze_user_list=[]
for item in user_data:
if user_data[item][0]==0:
freeze_user_list.append(item)
if len(freeze_user_list)==0:
print('无被冻结账户,无需继续操作.')
return False
else:
print('已被冻结用户如下'.center(20,'*'))
for item in freeze_user_list:
print(item)
while True:
inp=input('请输入要解除冻结状态的账户,输入 b 返回主菜单:')
if inp=='b':
break
elif inp not in freeze_user_list:
print('冻结状态账户中无{}账户信息'.format(inp))
else:
if user_data[inp][0]==1:
print('账户{}未冻结,无需重复操作'.format(inp))
break
else:
user_data[inp][0]=1
data_op.flush_d(user_data)
print('账户{}解冻成功!'.format(inp))
# loggerin
log_admin.info('解冻账户{}'.format(inp))
break def enhance_credit():
"""
提升用户额度,并修改用户信用额度以及可用额度信息
:return: None
"""
user_data=data_op.l_d()
ex_flag=1
while ex_flag:
show_all()
inp=input('请输入用户名,输入 b 返回主菜单:')
if inp=='b':
break
if user_data.get(inp) == None: #判断用户是否存在
print('无{}账户信息,请重新输入.'.format(inp))
else:
# print(user_data[inp])
amount=user_data[inp][2]
f_amount=format_num.fn(amount)
print('账户{}目前最高额度为{}'.format(inp,f_amount))
while ex_flag:
want_amount=input('请输入要提升的额度,需要数字并且是整数:')
if want_amount.isdigit():
want_amount=int(want_amount)
if want_amount<=amount:
print('提升目标额度小于或等于目前额度,无需提升')
else:
dif_amount=want_amount-user_data[inp][2]
user_data[inp][2]=want_amount
user_data[inp][3]+=dif_amount
data_op.flush_d(user_data)
print('额度提升成功,目前{}额度为{}'.format(inp,format_num.fn(want_amount)))
log_admin.info('账户{}提升额度为{}'.format(inp,want_amount))
ex_flag=0
else:
print('输入有误,请重新输入.') def logout_manage():
"""
退出信息,并记录日志
:return:
"""
log_admin.info('admin退出登录')
exit('程序退出!') def login():
"""
登录信息
:return:
"""
admin_data=data_op.l_a_d()
inp=input('请输入管理员帐号:')
if admin_data.get(inp)==None:
print('管理员角色中无用户{}'.format(inp))
else:
i=0
while i<4:
if i ==3:
print('输入超过三次,关闭登录.')
return False
pwd=input('请输入{}的密码:'.format(inp))
if pwd==admin_data[inp]:
return True
else:
i+=1
atm_run.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
ATM 终端操作
"""
import sys,prettytable,time
sys.path.append('..')
from core.terminal_op import *
from core import terminal_op,terminal_repay,terminal_show_record,\
terminal_transfers,terminal_view_credit,terminal_withdraw,\
terminal_discover_bills,bills_rate def logout():
exit('系统退出') #将函数名称对应写入列表方便用户选择
menu=[terminal_view_credit.view_credit,
terminal_show_record.show_record,
terminal_repay.repay,
terminal_withdraw.withdraw,
terminal_transfers.transfers,
terminal_discover_bills.inquire_bills,
bills_rate.inquire_rates,
logout] def main():
"""
先执行登录函数,返回1时进入主菜单
:return:
"""
res=terminal_op.login()
if res:
row=prettytable.PrettyTable()
row.field_names=['查看可用额度','查看消费记录','还款','提现','转账',
'查询本月账单','还款逾期情况查询','退出']
row.add_row([0,1,2,3,4,5,6,'q&quit'])
while True:
print('\033[31;1m欢迎来到宇宙最屌老男孩支行\033[0m'.center(93,'*'))
print(row)
inp=input('请输入对应的操作序列号:')
if inp.isdigit():
inp=int(inp)
if inp>7:
print('输入有误,请重新输入!!')
else:
#如果用户选择正确,执行对应的函数
menu[inp](tip['user_name'])
time.sleep(1)
elif inp.lower()=='q' or inp.lower()=='quit':
logout()
else:
print('输入有误,请重新输入!!')
else:
pass if __name__ == '__main__':
main()
bills_rate.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
账单查询模块
""" import sys,json,time
sys.path.append('..')
from core import terminal_op,data_op,format_num,veri_code,time_cal,\
generate_bills,terminal_discover_bills
from conf.setting import * def current_10th():
"""
取当月10号的时间,并返回结构时间的数据
:return: 结构时间的数据
"""
current_10th_time=time_cal.get_10th_of_current_month()
current_10th_time_stamp=time_cal.time_s_to_stamp(current_10th_time)
return current_10th_time_stamp def last_22nd():
"""
取上个月22号的时间,并返回结构时间的数据
:return: 结构时间的数据
"""
last_22nd_time=time_cal.get_22nd_of_last_month()
last_22nd_time_stamp=time_cal.time_s_to_stamp(last_22nd_time)
return last_22nd_time_stamp def inquire_rates(args):
"""
查询账单利息函数
:param args: 用户名
:return: None
"""
user_data=data_op.l_d()
user_record=user_data[args][4]
last_22nd_stamp=last_22nd()
current_10th_stamp=current_10th()
today=datetime.datetime.today()
today_stamp=time_cal.time_s_to_stamp(today)
if today_stamp <= current_10th_stamp:
# 如未到10日,提醒用户利息为0
print('未到本月10号,目前利率为0,如果已还款请飘过,如未还款,请速还款')
time.sleep(1)
else:
#计算入账的总和
income_list=[]
for item in user_record:
for key in item: #判断目前时间是否在上月22日到本月10日之间
if last_22nd_stamp<time_cal.str_to_stamp(key)<=current_10th_stamp:
income_list.append(item.get(key))
income=[]
for item in income_list:
if '收款' in item or '还款' in item:
income.append(item[2])
income_amount=sum(income)
current_file_month=generate_bills.check_file_month()
bills_db_list=terminal_discover_bills.check_exist_bills()
if len(bills_db_list)==0: #判断是否存在账单文件
print('暂无账单生成,请联系客服或者银行行长,每月22日生成账单')
time.sleep(1)
else:
dates=[]
for item in bills_db_list:
dates.append(item.split('_')[0])
if current_file_month in dates:
bills_data=json.load(open('../db/{}_bil'
'ls.json'.format(current_file_month),'r'))
should_amount=bills_data[args][0]
if income_amount>=should_amount:
# 判断入账的费用是否大于消费的费用总和
print('已全部还清,无逾期!')
time.sleep(1)
else:#否则进行逾期天数和利息计算
out_rate=0.0005
print('有逾期还款,逾期利率为每日万分之五')
td=int(time.strftime('%Y%m%d'))
current_10th_time=time_cal.get_10th_of_current_month()
dead_line=[]
dead_line.extend(str(current_10th_time).split(' ')[0].split('-'))
dead_line=int(''.join(dead_line))
days=td-dead_line
interest=days*out_rate*bills_data.get(args)[0]
interest=format_num.fn(interest)
print('您有逾期费用产生,'
'逾期天数\033[31;1m{}\033[0m,逾期利率为万分之五,'
'截止到今天的逾期利息'
'为\033[31;1m{}\033[0m'.format(days,interest))
time.sleep(1)
else:
print('暂无账单生成')
data_op.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
数据库操作函数配置
"""
import json
def l_d():
"""
读 atm 用户数据库
:return:
"""
user_data=json.load(open('../db/atm_cart_db.json','r'))
return user_data def flush_d(args):
"""
写入 ATM用户数据
:param args: 新的用户数据
:return: True
"""
json.dump(args,open('../db/atm_cart_db.json','w'),ensure_ascii=False,indent=1)
return True def l_a_d():
"""
加载管理员数据库
:return:
"""
admin_data=json.load(open('../db/atm_admin_db.json','r'))
return admin_data
format_num.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz def fn(args):
"""
将金额转化为人民币模式,带逗号分隔,保留小数点两位,四舍五入
:param args:
:return:
"""
num='{:,.2f}'.format(args)
return num
generate_bills.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
账单生成模块
"""
import sys,json,time
sys.path.append('..')
from core import terminal_op,data_op,format_num,veri_code,time_cal
from conf.setting import *
from core.logger import * def generate_bills(args):
"""
用户账单内容生成函数
:param args: 用户名
:return: 指定用户的欠款和消费记录内容
"""
user_data=data_op.l_d()
records=user_data.get(args)[4]
#上月22日,本月22日的时间戳生成
last_22=time_cal.get_22nd_of_last_month()
last_22_stamp=time_cal.time_s_to_stamp(last_22)
current_22=time_cal.get_22nd_of_current_month()
current_22_stamp=time_cal.time_s_to_stamp(current_22)
time_range_records=[]
for item in records:
for key in item:
key_stamp=time_cal.str_to_stamp(key)
if last_22_stamp < key_stamp < current_22_stamp:
time_range_records.append({key:item[key]})
# print(time_range_records)
if len(time_range_records)==0:
bills=0
else:
income_records=[] #入账记录
expend_records=[] #消费记录
for item in time_range_records:
for ite in item:
if '还款' in item[ite] or '收款' in item[ite]:
income_records.append(item[ite][2])
else:
expend_records.append(item[ite][3])
expend_records.append(item[ite][2])
if len(income_records)==0:income=0
else:income=sum(income_records)
if len(expend_records)==0:
expend=0
else:
expend=sum(expend_records)
if income>=expend:
bills=0
else:
bills=expend-income
bills_contect=[bills,time_range_records] #相关信息生成列表
return bills_contect def check_file_month():
"""
判断并生成本月账单文件的日期字符串
:return:
"""
mon=time_cal.get_22nd_of_last_month()
file_month=str(mon).strip().split(' ')[0].strip().split('-')
file_month.pop(2)
res=''.join(file_month) #字符串萍姐
return res def main():
"""
主函数
:return:
"""
dtd=time.strftime('%d')
dtd=int(dtd)
if dtd<=22: #判断时间是否过22日,如果未到22日,提醒用户
print('本月生成账单日期未到,操作退出!')
time.sleep(1)
else:
user_data=data_op.l_d()
bill={}
for item in user_data:
bills_contect=generate_bills(item)
bill[item]=bills_contect
# print(bill)
file_month=check_file_month()
#如果过22日,遍历相关日期内的数据,并将数据写入文件,生产新的文件
json.dump(bill,open('../db/{}_bills.json'.format(file_month),'w'),
ensure_ascii=False,indent=1)
print('账单已生成,目录为:\033[31;1m../db/\033[0m,'
'文件名称为:\033[31;1m{}_bills.json\033[0m'.format(file_month))
log_admin.info('生成账单文件{}_bills.json'.format(file_month))
time.sleep(1)
logger.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
日志模块
"""
import sys,logging
sys.path.append('..')
from conf.setting import * def logger(log_type):
"""
定义日志模块
:param log_type: 日志的用户
:return:
"""
logger=logging.getLogger(log_type)
logger.setLevel(LOG_LEVEL) ch=logging.StreamHandler()
ch.setLevel(LOG_LEVEL) fh=logging.FileHandler('../log/{}'.format(LOG_TYPE[log_type]))
fh.setLevel(LOG_LEVEL) formatter=logging.Formatter('%(asctime)s - %(name)s -'
' %(levelname)s - %(message)s') ch.setFormatter(formatter)
fh.setFormatter(formatter) logger.addHandler(ch)
logger.addHandler(fh) return logger #将日志实例化,防止进入循环后多次刷新日志
log_trans=logger('trans')
log_access=logger('access')
log_admin=logger('admin')
manager_main.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
管理员操作主函数
"""
import sys,prettytable
sys.path.append('..')
from core import atm_admin_op,generate_bills def show_menu():
"""
定义显示菜单函数
:return:
"""
row=prettytable.PrettyTable()
row.field_names=['新增账号','冻结用户','解冻用户','提升用户额度',
'查看所有用户','生成上月账单','退出程序']
row.add_row([0,1,2,3,4,5,'q&quit'])
print(row) #函数名列表化
menu_list=[atm_admin_op.c_u,
atm_admin_op.freeze_u,
atm_admin_op.un_freeze_u,
atm_admin_op.enhance_credit,
atm_admin_op.show_all,
generate_bills.main,
atm_admin_op.logout_manage] def main():
"""
执行函数,登录成功后显示主菜单,用户选择对应的函数名后,执行对应的函数
:return:
"""
login_res=atm_admin_op.login()
if login_res:
while True:
show_menu()
inp=input('请选择操作对应的序列号:')
if inp=='q' or inp=='quit':
menu_list[6]()
elif inp.isdigit():
inp=int(inp)
if inp<6:
menu_list[inp]()
else:
print('选择有误,请重新输入.')
else:
print('选择有误,请重新输入.') else:
print('登录失败!') if __name__ == '__main__':
main()
pass_handler.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz import hashlib def md5_pwd(pwd):
"""
为了防止解密,hashlib.md5时加入自己的字段
将密码转化为 md5形式
:param pwd: 密码明文
:return: 加密后的密码
"""
hash=hashlib.md5(bytes('odlboy',encoding='utf8'))
hash.update(bytes(pwd,encoding='utf8'))
res=hash.hexdigest()
return res
shop_mall.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz #加载模块
import sys
sys.path.append('..')
import json,prettytable,time,collections
from core import terminal_pay
#将json中的数据赋值为变量
user_info=json.load(open('../db/mall_user.json','r'))
goods=json.load(open('../db/goods.json','r'))
save_cart=json.load(open('../db/mall_cart.json','r'))
#设置时间戳的变量
time_now=time.strftime('%Y-%m-%d %H:%M:%S')
cart=None
user_name=None
balance=None #打开用户锁定文件,并将其转化为列表
user_lock=open('../db/mall_user_lock','r+')
locker=user_lock.readlines() #定义刷新商品信息的函数
def refresh_goods():
json.dump(goods,open('../db/goods.json','w'),ensure_ascii=False,indent=1) def refresh_user():
json.dump(user_info,open('../db/mall_user.json','w'),ensure_ascii=False,indent=1) #定义如果未结算退出时记录购物车信息的函数
def cache_cart(user_name):
save_cart[user_name]=cart #将购物车列表赋值于要保存的数据变量
# json文件写入
json.dump(save_cart,open('../db/mall_cart.json','w'),ensure_ascii=False,indent=1)
#定义用户注册函数
def regis():
#设置退出标识符
exit_flag=0
while exit_flag==0:
user_name=input('请输入您的用户名:')
if user_name in user_info.keys():
print('此用户已被注册,请重新输入.')
else:
user_pwd=input('请输入您的密码:')
for i in range(3):
user_pwd_again=input('请再次确认您的密码:')
if user_pwd_again==user_pwd:
#赋值密码变量
user_info[user_name]=[user_pwd_again,0,[]]
#将变量写入user_info文件
refresh_user()
print('用户名%s已注册成功,请登录购买商品...'%user_name)
exit_flag=1
break
elif i==2:
print('您输入的密码次数超过三次,注册关闭!')
exit_flag=1
else:
print('您输入的密码和上次输入的密码不匹配,请重新输入,还有%s次机会.'%(2-i))
#定义用户充值函数
def refill(user_name):
for i in range(3):
amount=input('请输入您要充值的金额,请输入数字:')
if amount.isdigit():
result=terminal_pay.pay_api(int(amount),'大牛逼商城',)
if result:
user_info[user_name][1]+=int(amount)
#写入用户的json文件中
refresh_user()
print('\033[32;1m土豪,请保养程序员!!!\033[0m充值成功,您的余'
'额为\033[31;1m%s\033[0m'%user_info[user_name][1])
#打印余额
balance=user_info[user_name][1]
print(balance)
break
else:
print('充值失败,请联系最屌银行行长')
break
elif i==2:
exit('你在坑我么?告诉你要输入数字的,程序关闭...')
else:
print('您输入的不是数字,请重新输入..')
#定义显示购物车函数
def show_vcart(cart):
# print(cart)
if len(cart)>0:
#将内存中的购物车列表计算重复数量
v_cart = collections.Counter(cart)
#转化为字典,方便取值
dv_cart=dict(v_cart)
#使用prettytable 显示购物车信息
row=prettytable.PrettyTable()
row.field_names=['序列号','商品名称','商品数量','商品总价']
for i in enumerate(dv_cart):
index=i[0]
item=i[1][0]
totle_price = i[1][1] * dv_cart[i[1]]
item_amount = dv_cart[i[1]]
row.add_row([index,item,item_amount,totle_price])
print(row)
else:
print('\033[31;1m购物车为空\033[0m'.center(50,'*'))
time.sleep(1)
#定义付款结算函数
def check_cart():
while True:
inp = input('''1.余额支付
2.信用卡支付
选择支付类型:''')
if inp == '1':
if len(cart)>0:
v_cart=collections.Counter(cart)
dv_cart=dict(v_cart)
#定义空列表
ddv_cart=[]
#遍历字典,将字典中的元素添加入空列表
for i in enumerate(dv_cart):
index=i[0]
item=i[1][0]
totle_price = i[1][1] * dv_cart[i[1]]
item_amount = dv_cart[i[1]]
ddv_cart.append([item,item_amount,totle_price])
#改变json数据中的变量值,记录购物历史
user_info[user_name][2].append([time_now,ddv_cart])
#更改余额
user_info[user_name][1]=balance
#更爱用户余额,写入购物历史数据,更改商品库存
refresh_user()
refresh_goods()
#清空购物车中的商品
cart.clear()
#将清空的购物车信息写入二次登陆的用户信息
cache_cart(user_name)
print('\033[31;1m结账成功,波多野结衣即将为您送货,请准备收货...\033[0m')
time.sleep(1)
break
else:
print('\033[31;1m购物车是空的...\033[0m')
#如果为空,重置二次登陆用户的购物车信息
cache_cart(user_name)
time.sleep(1)
break
# break
# return True
elif inp == '2':
if len(cart)>0:
# print(cart)
pri_list=[]
for item in cart:
pri_list.append(item[1])
sum_amount=sum(pri_list)
result=terminal_pay.pay_api(sum_amount,'大牛逼商城',)
if result:
v_cart=collections.Counter(cart)
dv_cart=dict(v_cart)
#定义空列表
ddv_cart=[]
#遍历字典,将字典中的元素添加入空列表
for i in enumerate(dv_cart):
index=i[0]
item=i[1][0]
totle_price = i[1][1] * dv_cart[i[1]]
item_amount = dv_cart[i[1]]
ddv_cart.append([item,item_amount,totle_price])
#改变json数据中的变量值,记录购物历史
user_info[user_name][2].append([time_now,ddv_cart])
#更爱用户余额,写入购物历史数据,更改商品库存
refresh_user()
refresh_goods()
#清空购物车中的商品
cart.clear()
#将清空的购物车信息写入二次登陆的用户信息
cache_cart(user_name)
print('\033[31;1m结账成功,波多野结衣即将为您送货,请准备收货...\033[0m')
time.sleep(1)
break else:
print('信用卡支付失败!!!')
time.sleep(1)
break
else:
print('\033[31;1m购物车是空的...\033[0m')
time.sleep(1)
break #定义查看购物历史函数
def show_his(user_name):
user_info=json.load(open('../db/mall_user.json','r'))
#购物历史数据变量赋值
his_list=user_info[user_name][2]
#入购物历史为空的处理
if len(his_list)==0:
print('无购物历史...')
else:
for his in his_list:
#取值时间戳
dt=his[0]
print('\033[31;1m购物时间:%s\033[0m'.center(50,'*')%dt)
#打印购买详情
row=prettytable.PrettyTable()
row.field_names=['商品名称','数量','总额']
for item in his[1]:
#变量取值
p_name=item[0]
p_amount=item[1]
p_totle=item[2]
row.add_row([p_name,p_amount,p_totle])
print(row)
#定义编辑购物车函数,后期追加的功能,所以代码比较多,跟之前写的耦合性较弱
def edit_cart(user_name):
#定义变量,用set的方式去重,并转化为列表,作为商品信息
e_cart=list(set(cart))
e_vcart=collections.Counter(cart)
e_vcart=dict(e_vcart)
#将列表排序,方便取值
e_cart.sort()
#打印购物车信息
row=prettytable.PrettyTable()
row.field_names=['商品序列号','商品名称','商品数量','总价']
for i in enumerate(e_cart):
index=i[0]
p_name=i[1][0]
p_price=i[1][1]
p_amount=e_vcart[i[1]]
p_totle=i[1][1]*e_vcart[i[1]]
p_belong=i[1][2]
row.add_row([index,p_name,p_amount,p_totle])
print(row)
while True:
#用户选择商品序列
choice_num=input('请输入要编辑的商品序列号,输入\033[31;1mq或quit\033[0m为退出编辑购物车:')
#设置条件,输入为数字,并且小于商品列表的数量
if choice_num.isdigit() and int(choice_num)<len(e_cart):
#变量赋值
choice_num=int(choice_num)
goods_stock=goods[e_cart[choice_num][2]][e_cart[choice_num][0]]['stock']
p_amount=e_vcart[e_cart[choice_num]]
balance=user_info[user_name][1]
print('目前商品库存量为\033[32;1m%s\033[0m'%goods_stock)
while True:
choice_num_d=input('输入要购买的商品数量:')
if choice_num_d.isdigit():
choice_num_d=int(choice_num_d)
if choice_num_d<=goods_stock:
if choice_num_d==p_amount:
print('修改商品数量成功')
break
elif choice_num_d>p_amount:
#计算差价
d_price=int(choice_num_d-p_amount)*int(e_vcart[e_cart[choice_num]])
if balance>=d_price:
for i in range(choice_num_d-p_amount):
cart.append(e_cart[choice_num])
#使用差价计算余额
balance-=d_price
#修改库存信息
goods_stock+=p_amount
goods_stock-=choice_num_d
else:
print('余额不足,修改失败,请充值!')
break
else:
d_price=int(abs(choice_num_d-p_amount))*(e_vcart[e_cart[choice_num]])
for i in range(abs(choice_num_d-p_amount)):
cart.remove(e_cart[choice_num])
#计算差价,修改库存,余额
balance+=d_price
goods_stock+=p_amount
goods_stock-=choice_num_d
print('修改成功.')
break
else:
print('输入数量有误,请合适商品的库存...')
break
else:
print('输入类型有误请重新输入...')
break
elif choice_num == 'q' or choice_num == 'quit':
print('退出编辑购物车...')
break
else:
print('输入有误,请重新输入...') def main():
#设置退出循环标识符初始值
break_flag=0
#程序开始,输入用户名
name=input('请输入\033[31;1m壕\033[0m的用户名:')
global user_name
user_name=name
if user_name in locker:
#退出并回显
exit('用户已被锁定')
#判断是否在为已注册用户并且未被锁定
elif user_name in user_info.keys() and user_info not in locker:
for i in range(3):
#退出标识符是否被改变
if break_flag==1:
#如改为1退出循环
break
else:
#确认密码
pwd=input('请输入%s的密码:'%user_name)
if pwd==user_info[user_name][0]:
#判断是否有未结算退出的购物清单
global cart
if save_cart.get(user_name)==None:
#如果空,将购物车设置为空
cart=[]
else:
#反之,将读取未结算商品列表
cart=save_cart[user_name]
for i in range(len(cart)):
cart[i]=tuple(cart[i])
print('登陆成功...')
print('欢迎来到大牛逼商城,走过路过,不要错过...'.center(50,'*'))
while break_flag==0:
#判断购物车是否为空,设置余额初始值
global balance
if save_cart.get(user_name)==None or len(save_cart[user_name])<=0:
balance = user_info[user_name][1]
print('壕,您的账户余额为:\033[31;1m%s\033[0m,\033[32;1m(钱不够?账户'
'充值请输入r,回车继续购物)\033[0m:'%balance)
else:
#如果购物车不为空,计算扣除商品总价后的余额初始
cart_price_list=[]
for i in cart:
cart_price_list.append(i[1])
# balance=user_info[user_name][1]-sum(cart_price_list)
print('\033[31;1m您的购物车中还有未结算的商品,如减去购物车'
'中的商品总价,您的余额为\033[0m\033[31;1m%s\033[0m'%balance)
time.sleep(1)
#显示购物主菜单
mrow=prettytable.PrettyTable()
mrow.field_names=['功能','购物','查看购物车','查看购物历史',
'余额充值','退出购物商城','确认购买','编辑购物车']
mrow.add_row(['快捷键','回车','S或showcart','H或history',
'R或refill','Q或quit','C或check','E或者edit'])
print(mrow)
menu=input('''\033[32;1m选择菜单:\033[0m''')
#判断用户选择
if menu.lower()=='r':
refill(user_name) #执行充值函数
elif menu.lower()=='h' or menu.lower()=='history':
time.sleep(1)
show_his(user_name) #执行查看购物历史记录函数
time.sleep(1)
elif menu.lower()=='s' or menu.lower()=='showcart' :
time.sleep(1)
show_vcart(cart) #执行查看购物车函数
elif menu.lower()=='c' or menu.lower()=='check':
check_cart()
elif menu.lower()=='q' or menu.lower()=='quit':
cache_cart(user_name) #执行未结算退出保存购物清单函数
exit('已退出商城')
elif menu.lower()=='e' or menu.lower()=='edit':
edit_cart(user_name) #执行编辑购物车函数
elif len(menu)==0: #判断输入为回车
while break_flag==0:
print('壕,您的扣除购物车中的钱款预计账户余额为:\033[31;1m%s\033[0m:'%balance)
print('请选择商品的类型编号'.center(50,'='))
cla_list=list(goods.keys()) #将分类转化为列表
#打印商品分类
for i in cla_list:
print(cla_list.index(i),i)
#让用户选择分类序列号
choice_cla_num=input('\033[32;1m请选择您要购买物品类型所对'
'应的序列号(返回主菜单输入b或back,查看购物车输入s,确认付款输入c,退出输入q或quit):\033[0m')
#判断用户输入的类型,如果为数字并且数字小于列表元素数量
if choice_cla_num.isdigit() and int(choice_cla_num)<len(cla_list):
#设置变量
choice_cla_num=int(choice_cla_num)
cla=cla_list[choice_cla_num]
goods_list=list(goods[cla]) #取出对应的商品列表
while break_flag==0:
print('壕,您的预计账户余额为:\033[31;1m%s\033[0m'%balance)
row=prettytable.PrettyTable()
row.field_names=['序列号','商品名称','商品价格','商品库存']
for p in goods_list:
p_num=goods_list.index(p)
p_name=p
p_price=goods[cla][p]['price']
p_stock=goods[cla][p]['stock']
row.add_row([p_num,p_name,p_price,p_stock])
print(row)
#用户选择物品编号
choice_p_num=input('\033[32;1m输入您要购买的商品序列号,返回商品分类请输入'
'b或back,查看购物车输入s,确认付款输入c,退出系统输入q或quit:\033[0m')
if choice_p_num.isdigit() and int(choice_p_num)<len(goods_list):
#定义变量
p_name=goods_list[int(choice_p_num)]
p_price=goods[cla][p_name]['price']
p_stock=goods[cla][p_name]['stock']
p_belong=goods[cla][p_name]['belong']
while break_flag==0:
p_count=input('\033[32;1m输入您要购买的商品数量,直接回车系统默认数量默1:\033[0m')
#判断库存
if len(p_count)==0:
p_count=1
elif p_count.isdigit():
if int(p_count) <= p_stock:
p_count = int(p_count)
else:
print('库存数量有限,最大购买数量为%s' % p_stock)
break
#余额大于商品总价
# if balance >= p_count*p_price:
p_stock-=p_count
goods[cla][p_name]['stock']=p_stock
#加入购物车
for i in range(p_count):
cart.append((p_name,p_price,p_belong))
print('商品\033[32;1m%s\033[0m已加入购物车'%p_name)
v_cart=collections.Counter(cart)
print('\033[31;1m未付款商品\033[0m'.center(50,'*'))
#显示购物车
show_vcart(v_cart)
#余额减去商品总价
balance-=p_count*p_price
break
elif choice_p_num.lower()=='b' or choice_p_num.lower=='back':
break
elif choice_p_num.lower()=='s':
show_vcart(cart) #查看购物车
elif choice_p_num.lower()=='c' or choice_p_num.lower()=='check':
check_cart() #确认支付
elif choice_p_num.lower()=='q' or choice_p_num.lower()=='quit':
cache_cart(user_name)
exit('已退出商城')
else:
print('输入类型错误,请重新输入')
time.sleep(1)
elif choice_cla_num.lower()=='s'or choice_cla_num.lower()=='showcart':
show_vcart(cart) #查看购物车
elif choice_cla_num.lower()=='c' or choice_cla_num.lower()=='check':
check_cart()
elif choice_cla_num.lower()=='b'or choice_cla_num.lower()=='back':
break
elif choice_cla_num.lower()=='q' or choice_cla_num.lower()=='quit':
break_flag=1
cache_cart(user_name)
elif choice_cla_num.lower()=='e' or choice_cla_num.lower()=='edit':
edit_cart(user_name) #编辑购物车
else:
print('输入有误,请重新输入')
#输入密码超过三次,用户锁定,并写入被锁用户名单文件
elif i==2:
user_lock.write('\n%s'%user_name)
user_lock.close()
exit('三次密码错误,账户已被锁定')
else:
print('密码错误,请重新输入...')
else:
#用户注册选项
y_or_n=input('没有此用户名,需要注册才能进入商城!!!'
'是否要注册?\033[31;1m输入y或者回车为注册,n或者q退出\033[0m:')
if len(y_or_n)==0 or y_or_n=='y':
regis() #执行用户注册函数
elif y_or_n=='n' or y_or_n=='q':
exit('程序退出...')
else:
exit('输入错误,程序退出...') if __name__ == '__main__':
main()
terminal_discover_bills.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
账单查询模块
"""
import sys,json,time,os,prettytable
sys.path.append('..')
from core import terminal_op,data_op,format_num,veri_code,time_cal,generate_bills
from conf.setting import * def check_exist_bills():
"""
判断账单文件是否存在
:return: 账单文件列表
"""
file_dir=os.listdir('../db') #将../db 目录下的内容生成列表形式
bills_db_list=[]
for item in file_dir: #将以 bills.json 结尾的字符串添加进列表
if item.endswith('bills.json'):
bills_db_list.append(item)
return bills_db_list def inquire_bills(args):
"""
账单查询函数
:param args: 用户名
:return: None
"""
#确认本月的账单文件名的日期字符串
current_file_month=generate_bills.check_file_month()
bills_db_list=check_exist_bills()
if len(bills_db_list)==0: #如果为空,提示用户无账单
print('未到账单日,账单未生成!')
else:
dates=[]
for item in bills_db_list:
dates.append(item.split('_')[0])
# print(dates)
if current_file_month in dates:
print('本月账单已生成:{}'.format(current_file_month))
time.sleep(1)
#加载账单数据,并显示用户欠款额度和消费记录
bills_data=json.load(open('../db/{}_bil'
'ls.json'.format(current_file_month),'r'))
print('{}于{}月的账单'.center(52,'*').format(args,current_file_month))
print('需还款金额:\033[31;1m{}(人民'
'币)\033[0m'.format(format_num.fn(bills_data[args][0])))
print('消费记录'.center(52,'-'))
row=prettytable.PrettyTable()
row.field_names=['时间','交易方式','商家','金额','利息']
record=bills_data.get(args)[1]
# print(record)
for item in record:
for key in item:
row.add_row([key,item[key][0],item[key][1],
item[key][2],item[key][3],])
print(row)
print('\033[31;1m请务必在下月10日(包括10日)之'
'前还款,否则会有每日0.05%利息产生!\033[0m') else:
print('未到账单日,账单未生成!')
terminal_op.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
ATM 终端操作模块
"""
import sys
sys.path.append('..')
from core import data_op,format_num,pass_handler
from core.logger import * #定义全局变量
tip={'user_name':None,'login_state':False} def check_login(func):
"""
定义一个装饰器,但后来发现逻辑中没什么乱用...搁置了,判断用户是否登录
:param func:
:return:
"""
def inner(*args,**kwargs):
if tip['login_state']:
res=func(*args,**kwargs)
return res
else:
print('\033[31;1m此操作需要登录!!!\033[0m')
return inner def freeze_count(args):
"""
修改用户帐号状态的标志符函数
:param args: 用户名
:return: None
"""
user_data=data_op.l_d()
user_data[args][0]=0
data_op.flush_d(user_data) def login():
user_data=data_op.l_d()
inp=input('请输入账户名:')
if user_data.get(inp)==None:
print('{}账户错误,请重新输入..'.format(inp))
else:
if user_data[inp][0]==0: #判断用户状态
print('您的账户{}已被冻结,请联系管理员'.format(inp))
log_access.warning('冻结用户{}尝试登录'.format(inp))
return False
else:
i=0
while i<4:
if i==3:
freeze_count(inp) #输入超过三次,冻结用户,修改状态标志符
print('您的账户{}已被冻结,请联系管理员'.format(inp))
log_access.warning('用户{}被冻结'.format(inp))
return False
pwd_inp=input('请输入{}的密码:'.format(inp))
pwd=pass_handler.md5_pwd(pwd_inp) #密码加密匹配
if pwd==user_data[inp][1]:
tip['user_name']=inp
tip['login_state']=True #修改全局变量字典
# print(tip)
print('登录成功!')
log_access.info('用户{}登录成功'.format(inp))
return True
else:
print('密码输入有误,请重新输入.')
i+=1 if __name__ == '__main__':
login()
terminal_pay.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
支付接口
"""
import sys,time
sys.path.append('..')
from core import terminal_op,data_op,format_num,veri_code
from conf.setting import *
from core.logger import * def pay_api(args,business):
"""
支付接口主函数
:param args: 支付金额
:param business: 支付商家
:return: True:支付成功 False:支付失败
"""
print('\033[31;1m欢迎使用宇宙最屌银行支付接口,支付需要登录\033[0m')
res=terminal_op.login() #支付前先登录
if res:
user_data=data_op.l_d()
tip=terminal_op.tip
user_name=tip['user_name']
balance=user_data[tip['user_name']][3]
#提示用户可用额度
print('您的可用额度为{}'.format(format_num.fn(balance)))
if balance < args: #额度不足,提醒
print('\033[31;1m可用额度不足,请使用其他方式支付\033[0m')
log_trans.info('{}调用支付接口,额度不足,支付失败'.format(user_name))
time.sleep(1)
return False
else:
#如果额度够,验证码验证,并修改相关用户数据信息
user_data[tip['user_name']][3]-=args
res=veri_code.check_veri()
if res:
data_op.flush_d(user_data)
record(user_name,'支付',business,args)
print('支付完成')
log_trans.info('{}支付调用,用'
'户{}支付{}'.format(business,user_name,args))
return True
else:
print('验证码失败,支付失败,loser!!')
time.sleep(1)
return False
else:
#登录失败
print('支付失败,请用其他方式支付,或者联系银行行长!')
log_trans.info('支付接口支付失败,登录验证不通过')
time.sleep(1)
return False if __name__ == '__main__':
pay_api(100,'test')
terminal_repay.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
还款模块
"""
import sys
sys.path.append('..')
from core import data_op,format_num
from conf.setting import *
from core.logger import * def repay(args):
"""
还款函数
:param args:
:return:
"""
user_data=data_op.l_d()
#如果可用额度大于等于信用额度,提示用户无需还款
if user_data[args][3] >= user_data[args][2]:
print('无欠款,无需还款!!!')
else:
#计算需还款额度
need_repay=user_data[args][2]-user_data[args][3]
print('您所需还款金额为:\033[31;1m{}\033[0m'.format(format_num.fn(need_repay)))
while True:
amount=input('请输入还款金额:')
if amount.isdigit():
amount=int(amount)
if amount>need_repay: #判断如果大于需还款金额,用户选择
inp=input('还款金额多余所需还款金额,是否继续?'
'\033[32;1m回车或y 继续,back 或者 b 为返回\033[0m:')
if len(inp)==0 or inp.lower() == 'y':
#修改用户账户信息
user_data[args][3]+=amount
data_op.flush_d(user_data)
print('还多了...还款完成!,目前可用信用金额'
'为\033[31;1m{}\033[0m'.format
(format_num.fn(user_data[args][3])))
record(args,'还款','终端机',amount)
log_trans.info('{}成功还款{}'.format(args,amount))
break
elif inp.lower() == 'b' or inp.lower()=='back':
break
else:
#修改用户账户信息
user_data[args][3]+=amount
data_op.flush_d(user_data)
print('还款完成!目前可用信用金额'
'为\033[31;1m{}\033[0m'.format
(format_num.fn(user_data[args][3])))
record(args,'还款','终端机',amount)
log_trans.info('{}成功还款{}'.format(args,amount))
break
else:
print('输入有误,请重新输入.')
terminal_show_record.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
消费记录模块
"""
import sys,prettytable
sys.path.append('..')
from core import data_op,format_num def show_record(args):
"""
查看交易记录函数
:param args: 用户名
:return: None
"""
user_data=data_op.l_d()
records=user_data.get(args)[4]
if len(records)==0:
print('无消费记录!')
else:
row=prettytable.PrettyTable()
row.field_names=['时间','交易','商家','交易金额','利息']
for item in records:
for record in item:
row.add_row([record,item[record][0],item[record][1],
item[record][2],item[record][3]])
print(row)
terminal_transfers.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
转账模块
"""
import sys
sys.path.append('..')
from core import data_op,format_num,veri_code
from conf.setting import *
from core.logger import * def transfers(args):
#载入用户数据
user_data=data_op.l_d()
able_amount=user_data[args][3]
max_amount_2=user_data[args][2]/2
#可用额度如果大于信用额度的二分之一,则可转账额度为可用额度
if able_amount>=max_amount_2:
able_wd_amount=max_amount_2
else:#否则,可转账额度为可用额度
able_wd_amount=able_amount
print('您的可用转账额度为:{}'.format(format_num.fn(able_wd_amount)))
t_user_name=input('请输入您要转入的账户名称:')
#判断用户转账目标是否存在于本系统数据库中
if user_data.get(t_user_name)==None:
print('本银行无此账户信息,请核实信息后再进行转账...')
else:
#转账操作
for i in range(4):
if i ==3:
print('输入格式错误超过3次,退出提现操作.')
break
amount=input('请输入转账金额:')
if amount.isdigit():
amount=int(amount)
#判断金额是否超支
if amount>able_wd_amount:
print('最高转账额度为{},已超支,'
'退出操作!'.format(format_num.fn(able_wd_amount)))
break
else:
#如不超支,转账,先验证码验证
res=veri_code.check_veri()
if res:
#修改数据库信息
user_data[args][3]-=amount+amount*trans_rate['转账']
user_data[t_user_name][3]+=amount
data_op.flush_d(user_data)
print('转账成功,现可消费额度为:'
'{}'.format(format_num.fn(user_data[args][3])))
record(args,'转账','终端机',amount)
record(t_user_name,'收款',args,amount)
log_trans.info('{}向{}成功转账{}'.format(args,t_user_name,amount))
break
else:
print('验证失败!转账操作失败!!')
log_trans.info('{}向{}转账失败'.format(args,t_user_name))
break
else:
i+=1
print('输入格式错误,还有{}次机会'.format(3-i))
terminal_view_credit.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
查看用户信息模块
"""
import sys
sys.path.append('..')
from core import data_op,format_num def view_credit(args):
"""
查看用户信息,加载数据,并将相关数据显示至屏幕
:param args:用户名
:return:
"""
user_data=data_op.l_d()
if user_data.get(args)==None:
print('无此用户.')
else:
balance=user_data[args][3]
balance=format_num.fn(balance)
credit=format_num.fn(user_data[args][2])
print('您的信用额度:\033[31;1m{}\033[0m,目前可用信用额'
'度为\033[31;1m{}\033[0m'.format(credit,balance))
terminal_withdraw.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
提现模块
"""
import sys
sys.path.append('..')
from core import data_op,format_num
from conf.setting import *
from core.logger import * def withdraw(args):
"""
提现函数,与转账模块基本一样,但无需验证目标用户
:param args: 用户名
:return:
"""
user_data=data_op.l_d()
able_amount=user_data[args][3]
max_amount_2=user_data[args][2]/2
if able_amount>=max_amount_2:
able_wd_amount=max_amount_2
else:
able_wd_amount=able_amount
print('您的可用提现额度为:{}'.format(format_num.fn(able_wd_amount)))
for i in range(4):
if i ==3:
print('输入格式错误超过3次,退出提现操作.')
break
amount=input('请输入提现金额:')
if amount.isdigit():
amount=int(amount)
if amount>able_wd_amount:
print('最高取现额度为{},已超支,'
'退出操作!'.format(format_num.fn(able_wd_amount)))
log_trans.info('{}提现操作失败'.format(args))
break
else:
user_data[args][3]-=amount+amount*trans_rate['提现']
data_op.flush_d(user_data)
print('现可消费额度为:'
'{}'.format(format_num.fn(user_data[args][3])))
record(args,'提现','终端机',amount)
log_trans.info('{}成功提现{}'.format(args,amount))
break
else:
i+=1
print('输入格式错误,还有{}次机会'.format(3-i))
time_op.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
"""
时间处理模块
"""
import datetime,time
def get_22nd_of_last_month():
"""
获取上个月第一天的日期,然后加21天就是22号的日期
:return: 返回日期
"""
today=datetime.datetime.today()
year=today.year
month=today.month
if month==1:
month=12
year-=1
else:
month-=1
res=datetime.datetime(year,month,1)+datetime.timedelta(days=21)
return res def get_22nd_of_next_month():
"""
获取下个月的22号的日期
:return: 返回日期
"""
today=datetime.datetime.today()
year=today.year
month=today.month
if month==12:
month=1
year+=1
else:
month+=1
res=datetime.datetime(year,month,1)+datetime.timedelta(days=21)
return res def get_10th_of_current_month():
"""
获取本月的10号的日期
:return: 返回日期
"""
today=datetime.datetime.today()
year=today.year
month=today.month
res=datetime.datetime(year,month,11)
return res def get_22nd_of_current_month():
"""
获取本月22号的日期
:return: 返回日期
"""
today=datetime.datetime.today()
year=today.year
month=today.month
res=datetime.datetime(year,month,22)
return res def time_s_to_stamp(args):
"""
将datetime日期格式,先timetuple()转化为struct_time格式
然后time.mktime转化为时间戳
:param args: datetime时间格式数据
:return: 时间戳格式数据
"""
res=time.mktime(args.timetuple())
return res def str_to_stamp(args):
"""
将时间字符串格式转化为时间戳格式
:param args: 时间字符串格式
:return: 时间戳数据
"""
r=time.strptime(args,'%Y-%m-%d %H:%M:%S')
res=time.mktime(r)
return res
veri_code.py:
#!/usr/bin/env python
# -*-coding=utf-8-*-
# Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
# GitHub:https://github.com/ccorzorz
import random def veri_code():
"""
#定义随机验证码函数
:return: 返回生成的随机码
"""
li = []
for i in range(6): #循环6次,生成6个字符
r = random.randrange(0, 5) #随机生成0-4之间的数字
if r == 1 or r == 4: #如果随机数字是1或者4时,生成0-9的数字
num = random.randrange(0, 9)
li.append(str(num))
else: #如果不是1或者4时,生成65-90之间的数字
temp = random.randrange(65, 91)
char = chr(temp) #将数字转化为ascii列表中对应的字母
li.append(char)
r_code = ''.join(li) #6个字符拼接为字符串
print('\033[31;1m%s\033[0m' % r_code)
return r_code #返回字符串 def check_veri():
res=veri_code()
for i in range(3):
code=input('请输入验证码:')
if code.lower() == res.lower():
return True
else:
print('验证码错误,剩余尝试次数:{}'.format(2-i))
db目录:
201605_bills.json:
{
"ccc": [
0,
[]
],
"alex2": [
0,
[]
],
"alex1": [
0,
[]
],
"chengc": [
0,
[]
],
"cc": [
11694.949999999997,
[
{
"2016-06-09 18:02:26": [
"提现",
"终端机",
8000,
400.0
]
},
{
"2016-06-09 18:10:34": [
"支付",
"大牛逼商城",
300,
0
]
},
{
"2016-06-09 18:20:56": [
"支付",
"大牛逼商城",
1800,
0
]
},
{
"2016-06-09 18:26:33": [
"还款",
"终端机",
1,
0
]
},
{
"2016-06-09 19:26:48": [
"提现",
"终端机",
1000,
50.0
]
},
{
"2016-06-09 19:27:37": [
"提现",
"终端机",
2,
0.1
]
},
{
"2016-06-09 21:35:38": [
"转账",
"终端机",
1,
0.05
]
},
{
"2016-06-09 21:36:45": [
"转账",
"终端机",
1,
0.05
]
},
{
"2016-06-09 23:00:46": [
"还款",
"终端机",
20,
0
]
},
{
"2016-06-09 23:02:20": [
"提现",
"终端机",
1,
0.05
]
},
{
"2016-06-09 23:02:20": [
"提现",
"终端机",
3,
0.15000000000000002
]
},
{
"2016-06-09 23:03:47": [
"转账",
"终端机",
50,
2.5
]
},
{
"2016-06-09 23:34:05": [
"转账",
"终端机",
1,
0.05
]
},
{
"2016-06-09 23:34:05": [
"收款",
"cc",
1,
0
]
},
{
"2016-06-10 00:28:04": [
"转账",
"终端机",
100,
5.0
]
}
]
],
"alex": [
0,
[
{
"2016-06-09 21:36:45": [
"收款",
"cc",
1,
0
]
},
{
"2016-06-09 23:03:47": [
"收款",
"cc",
50,
0
]
},
{
"2016-06-10 00:28:04": [
"收款",
"cc",
100,
0
]
}
]
],
"cccc": [
0,
[]
]
}
atm_admin_db.json:
{"admin":"admin"}
atm_cart_db.json:
{
"cccc": [
1,
"b864ac015392b00d908bb7f760036248",
13000,
3000,
[]
],
"ccc": [
1,
"3580a3546bd6afa4a37d0a02c46a4b5a",
10000,
5000,
[]
],
"alex2": [
1,
"b864ac015392b00d908bb7f760036248",
15000,
15000,
[]
],
"wyw": [
1,
"b864ac015392b00d908bb7f760036248",
100000,
105201,
[
{
"2016-06-12 10:41:11": [
"收款",
"cc",
1,
0
]
},
{
"2016-06-12 16:30:15": [
"收款",
"cc",
5200,
0
]
}
]
],
"ab": [
1,
"b864ac015392b00d908bb7f760036248",
1223,
1223,
[]
],
"alex1": [
1,
"b864ac015392b00d908bb7f760036248",
5100,
5000,
[]
],
"chengc": [
1,
"b864ac015392b00d908bb7f760036248",
150000,
150000,
[]
],
"alex": [
1,
"b864ac015392b00d908bb7f760036248",
16000,
15152,
[
{
"2016-06-09 21:36:45": [
"收款",
"cc",
1,
0
]
},
{
"2016-06-09 23:03:47": [
"收款",
"cc",
50,
0
]
},
{
"2016-06-10 00:28:04": [
"收款",
"cc",
100,
0
]
}
]
],
"yangk": [
1,
"b864ac015392b00d908bb7f760036248",
19999,
19999,
[]
],
"cc": [
1,
"b864ac015392b00d908bb7f760036248",
51004,
50755.999999999985,
[
{
"2016-06-09 18:02:26": [
"提现",
"终端机",
8000,
400.0
]
},
{
"2016-06-09 18:10:34": [
"支付",
"大牛逼商城",
300,
0
]
},
{
"2016-06-09 18:20:56": [
"支付",
"大牛逼商城",
1800,
0
]
},
{
"2016-06-09 18:26:33": [
"还款",
"终端机",
1,
0
]
},
{
"2016-06-09 19:26:48": [
"提现",
"终端机",
1000,
50.0
]
},
{
"2016-06-09 19:27:37": [
"提现",
"终端机",
2,
0.1
]
},
{
"2016-06-09 21:35:38": [
"转账",
"终端机",
1,
0.05
]
},
{
"2016-06-09 21:36:45": [
"转账",
"终端机",
1,
0.05
]
},
{
"2016-06-09 23:00:46": [
"还款",
"终端机",
20,
0
]
},
{
"2016-06-09 23:02:20": [
"提现",
"终端机",
1,
0.05
]
},
{
"2016-06-09 23:02:20": [
"提现",
"终端机",
3,
0.15000000000000002
]
},
{
"2016-06-09 23:03:47": [
"转账",
"终端机",
50,
2.5
]
},
{
"2016-06-09 23:34:05": [
"转账",
"终端机",
1,
0.05
]
},
{
"2016-06-09 23:34:05": [
"收款",
"cc",
1,
0
]
},
{
"2016-06-10 00:28:04": [
"转账",
"终端机",
100,
5.0
]
},
{
"2016-06-15 20:51:11": [
"还款",
"终端机",
1,
0
]
},
{
"2016-06-15 20:51:11": [
"还款",
"终端机",
1,
0
]
},
{
"2016-06-12 10:15:59": [
"支付",
"test",
100,
0
]
},
{
"2016-06-12 10:41:11": [
"转账",
"终端机",
1,
0.05
]
},
{
"2016-06-12 10:41:11": [
"提现",
"终端机",
200,
10.0
]
},
{
"2016-06-12 10:41:11": [
"还款",
"终端机",
2000,
0
]
},
{
"2016-06-12 13:03:54": [
"支付",
"大牛逼商城",
100,
0
]
},
{
"2016-06-12 16:28:03": [
"支付",
"大牛逼商城",
900,
0
]
},
{
"2016-06-12 16:30:15": [
"还款",
"终端机",
22,
0
]
},
{
"2016-06-12 16:30:15": [
"提现",
"终端机",
300,
15.0
]
},
{
"2016-06-12 16:30:15": [
"转账",
"终端机",
5200,
260.0
]
},
{
"2016-06-15 13:07:51": [
"支付",
"大牛逼商城",
5888,
0
]
},
{
"2016-06-15 13:09:16": [
"还款",
"终端机",
12000,
0
]
}
]
],
"1234": [
1,
"15da27ca7d6c671cbdf85396b9096d80",
10000,
1220,
[]
]
}
goods.json:
{
"服装": {
"T恤": {
"stock": 887,
"belong": "服装",
"price": 300
},
"小白鞋": {
"stock": 5954,
"belong": "服装",
"price": 900
},
"Nudie牛仔裤": {
"stock": 3973,
"belong": "服装",
"price": 699
},
"驴牌腰带": {
"stock": 2999,
"belong": "服装",
"price": 9999
}
},
"手机": {
"华为Mate": {
"stock": 5995,
"belong": "手机",
"price": 2999
},
"Iphone": {
"stock": 2996,
"belong": "手机",
"price": 5888
},
"锤子2(这特么真是手机)": {
"stock": 2994,
"belong": "手机",
"price": 998
},
"XiaoMi 4": {
"stock": 5395,
"belong": "手机",
"price": 1999
}
},
"电脑": {
"Mac pro": {
"stock": 3994,
"belong": "电脑",
"price": 9999
},
"Mac Air": {
"stock": 6001,
"belong": "电脑",
"price": 6999
},
"IBM X240": {
"stock": 3003,
"belong": "电脑",
"price": 6999
},
"Surface Book": {
"stock": 3020,
"belong": "电脑",
"price": 8999
}
},
"汽车": {
"Porsche 911": {
"stock": 594,
"belong": "汽车",
"price": 2999999
},
"Tesla Model S": {
"stock": 3000,
"belong": "汽车",
"price": 799999
},
"BMW X3": {
"stock": 399,
"belong": "汽车",
"price": 499999
},
"PASST": {
"stock": 297,
"belong": "汽车",
"price": 299999
}
},
"家电": {
"微波炉": {
"stock": 2994,
"belong": "家电",
"price": 800
},
"彩电": {
"stock": 397,
"belong": "家电",
"price": 5000
},
"洗衣机": {
"stock": 597,
"belong": "家电",
"price": 999
},
"冰箱": {
"stock": 300,
"belong": "家电",
"price": 3000
},
"热水器": {
"stock": 900,
"belong": "家电",
"price": 600
}
}
}
mall_cart.json:
{
"cc": [],
"shane": []
}
mall_user.json:
{
"zc": [
"123",
0,
[]
],
"shane": [
"123",
96105,
[
[
"2016-06-06 13:54:13",
[
[
"微波炉",
2,
1600
],
[
"洗衣机",
1,
999
]
]
],
[
"2016-06-06 13:54:13",
[
[
"T恤",
2,
600
],
[
"Nudie牛仔裤",
1,
699
]
]
]
]
],
"zhangxiaodong": [
"zhangxiaodong",
0,
[]
],
"123": [
"123",
0,
[]
],
"cc": [
"123",
73045,
[
[
"2016-05-19 14:23:37",
[
[
"小白鞋",
1,
900
],
[
"T恤",
1,
300
]
]
],
[
"2016-05-19 17:07:06",
[
[
"微波炉",
1,
800
]
]
],
[
"2016-05-19 17:56:19",
[
[
"Nudie牛仔裤",
1,
699
],
[
"洗衣机",
1,
999
]
]
],
[
"2016-05-20 10:07:34",
[
[
"IBM X240",
1,
6999
]
]
],
[
"2016-05-20 13:34:32",
[
[
"锤子2(这特么真是手机)",
1,
998
]
]
],
[
"2016-05-20 15:59:02",
[
[
"洗衣机",
1,
999
]
]
],
[
"2016-06-06 13:51:04",
[
[
"小白鞋",
2,
1800
]
]
],
[
"2016-06-06 15:25:05",
[
[
"T恤",
1,
300
]
]
],
[
"2016-06-06 15:25:05",
[
[
"Mac Air",
1,
6999
]
]
],
[
"2016-06-06 17:29:16",
[
[
"微波炉",
1,
800
]
]
],
[
"2016-06-07 11:37:57",
[
[
"Nudie牛仔裤",
1,
699
]
]
],
[
"2016-06-07 14:12:59",
[
[
"彩电",
1,
5000
]
]
],
[
"2016-06-08 09:26:10",
[
[
"微波炉",
2,
1600
]
]
],
[
"2016-06-08 17:19:09",
[
[
"彩电",
1,
5000
],
[
"T恤",
3,
900
]
]
],
[
"2016-06-08 17:20:05",
[
[
"小白鞋",
1,
900
]
]
],
[
"2016-06-08 17:20:05",
[
[
"Iphone",
1,
5888
]
]
],
[
"2016-06-08 17:20:05",
[
[
"XiaoMi 4",
1,
1999
]
]
],
[
"2016-06-08 17:29:18",
[
[
"小白鞋",
2,
1800
]
]
],
[
"2016-06-08 17:29:18",
[
[
"小白鞋",
1,
900
]
]
],
[
"2016-06-08 17:31:51",
[
[
"Nudie牛仔裤",
2,
1398
]
]
],
[
"2016-06-08 17:35:40",
[
[
"T恤",
1,
300
]
]
],
[
"2016-06-08 17:36:25",
[
[
"Mac pro",
1,
9999
]
]
],
[
"2016-06-08 17:50:44",
[
[
"T恤",
1,
300
]
]
],
[
"2016-06-08 17:54:24",
[
[
"华为Mate",
1,
2999
]
]
],
[
"2016-06-09 18:10:34",
[
[
"T恤",
1,
300
]
]
],
[
"2016-06-09 18:20:56",
[
[
"小白鞋",
2,
1800
]
]
],
[
"2016-06-12 16:28:03",
[
[
"小白鞋",
1,
900
]
]
],
[
"2016-06-15 13:07:51",
[
[
"Iphone",
1,
5888
]
]
]
]
],
"chengc": [
"123456",
999999999,
[]
]
}
mall_user_lock:
shane
log日志会自动创建..
trans.log:
2016-06-15 20:51:21,143 - trans - INFO - cc成功还款1
2016-06-15 20:51:27,495 - trans - INFO - cc成功还款1
2016-06-15 20:51:27,495 - trans - INFO - cc成功还款1
2016-06-12 10:16:09,824 - trans - INFO - test支付调用,用户cc支付100
2016-06-12 10:43:13,253 - trans - INFO - cc向wyw成功转账1
2016-06-12 10:43:24,376 - trans - INFO - cc成功提现200
2016-06-12 10:43:48,317 - trans - INFO - cc成功还款2000
2016-06-12 13:04:25,868 - trans - INFO - 大牛逼商城支付调用,用户cc支付100
2016-06-12 13:04:47,828 - trans - INFO - cc调用支付接口,额度不足,支付失败
2016-06-12 13:05:33,324 - trans - INFO - cc调用支付接口,额度不足,支付失败
2016-06-12 16:28:34,212 - trans - INFO - 大牛逼商城支付调用,用户cc支付900
2016-06-12 16:30:37,353 - trans - INFO - cc成功还款22
2016-06-12 16:30:52,169 - trans - INFO - cc成功提现300
2016-06-12 16:31:19,328 - trans - INFO - cc向wyw成功转账5200
2016-06-15 13:08:31,554 - trans - INFO - 大牛逼商城支付调用,用户cc支付5888
2016-06-15 13:09:36,623 - trans - INFO - cc成功还款12000
Day5作业,商城+ATM机+后台管理的更多相关文章
- 老男孩Day16作业:登录、注册、后台管理页面(动态)
一.作业需求: 1.后台管理主界面(左边菜单框.(全选.反选)框.返回顶部按钮) 2.老男孩登录.注册页面 二.博客地址:https://www.cnblogs.com/catepython/p/93 ...
- 老男孩Day17作业:后台管理平台编辑表格
一.作业需求: 后台管理平台 ,编辑表格: 1. 非编辑模式: 可对每行进行选择: 反选: 取消选择 2. 编辑模式: 进入编辑模式时如果行被选中,则被选中的行万变为可编辑状态,未选中的不改变 退出编 ...
- 模块购物商城和ATM机代码:
http://outofmemory.cn/python/video/let-us-python/ python为程序员服务 快来加入群[python爬虫交流群](群号570070796),发现精彩 ...
- 微擎 人人商城 对接京东vop 对接京东商品,同步商品 地址,库存,价格,上下架等。(二) 设置后台管理界面
昨天提到了,由于vop商品池未开通,故对接工作只能暂缓,现在要做一个专门针对vop商品的后台管理, 老规矩,先上设计链路图 因为后台本来就是有比较完善的商品管理系统, 所以我们只是针对vop 进行简单 ...
- Python学习day5作业
目录 Python学习day5作业 ATM和购物商城 1. 程序说明 2. 基本流程图 3. 程序测试帐号 4. 程序结构: 5. 程序测试 title: Python学习day5作业 tags: p ...
- Python-S13作业-day5-之 ATM
Python-S13作业-day5-之 ATM 需求: 模拟实现一个ATM + 购物商城程序 额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 其实是两 ...
- Django-Admin后台管理
Rhel6.5 Django1.10 Python3.5 应用环境:Python+Virtualenv(Python Virtualenv运行Django环境配置) Django-Admin后台管理 ...
- 集成一体化的移动POS开单扫描解决方案--"移动开单掌上POS"。它集后台管理软件
针对商贸企业的批发.零售管理设计的软硬件集成一体化的移动POS开单扫描解决方案--"移动开单掌上POS".它集后台管理软件.商品价格.库存等信息查询,店铺.展销会开单,移动捡货配送 ...
- 【tornado】系列项目(二)基于领域驱动模型的区域后台管理+前端easyui实现
本项目是一个系列项目,最终的目的是开发出一个类似京东商城的网站.本文主要介绍后台管理中的区域管理,以及前端基于easyui插件的使用.本次增删改查因数据量少,因此采用模态对话框方式进行,关于数据量大采 ...
随机推荐
- 实践论:github搜索源码内容
github搜索源码内容 github搜索源码内容 github搜索源码内容
- 2019-2020-1 20199301《Linux内核原理与分析》第二周作业
第二周Linux学习笔记 文件打包与解压缩 tar工具打包 tar的解压和压缩都是同一个命令,只需参数不同,使用较方便. 创建一个包时文件名必须紧跟在 -f 之后,解包一个文件(-x参数)到指定路径的 ...
- 如何在C中传递二维数组作为参数?
回答: 在C语言中,有很多方法可以将2d数组作为参数传递.在下面的部分中,我描述了将2d数组作为参数传递给函数的几种方法. 使用指针传递2d数组以在c中运行 多维数组的第一个元素是另一个数组,所以在这 ...
- x006-函数和模块的使用
来源:百度SEO公司 函数和模块的使用 在Python中可以使用def关键字来定义函数,和变量一样每个函数也有一个响亮的名字,而且命名规则跟变量的命名规则是一致的.在函数名后面的圆括号中可以放置传递给 ...
- 006——转载-MATLAB数字与字符之间的转换
(一)参考文献:https://jingyan.baidu.com/article/5bbb5a1bd8dcb113eba1799d.html (二)数字转换成字符串 第一步在我们的电脑上打开matl ...
- sql server set赋值和select 赋值的区别以及使用方法
sqlserver存储过程中SELECT 与 SET 对变量赋值的区别 (备注:虽然变量赋值使用方法已经不是问题,但是,了解一下select和set赋值的区别,还是提高了不少认识.应该有很多人并不 ...
- learning scala How To Create Implicit Function
println("Step 1: How to create a wrapper String class which will extend the String type") ...
- bzoj 5206
$n$ 点 $m$ 边图的有限制三元环个数 首先将所有左右端点并且属性相同的边的权值相加,合并为一条边 在这只之前得先排序排序之前得先判断是否需要交换左右端点的位置 T_T 然后统计三元环 补充说明按 ...
- 【算法】变邻域搜索算法(Variable Neighborhood Search,VNS)超详细一看就懂的解析
更多精彩尽在微信公众号[程序猿声] 变邻域搜索算法(Variable Neighborhood Search,VNS)一看就懂的解析 00 目录 局部搜索再次科普 变邻域搜索 造轮子写代码 01 局部 ...
- 【概率论】5-6:正态分布(The Normal Distributions Part II)
title: [概率论]5-6:正态分布(The Normal Distributions Part II) categories: - Mathematic - Probability keywor ...