# 二 一个项目开发前,有一份开发文档
#
# 项目: 编写小说阅读程序实现下属功能
#
# # 一:程序运行开始时显示
# 0 账号注册
# 1 账号登录
# 2 充值功能
# 3 阅读小说
import os,sys ATM_PATH = os.path.dirname(__file__)
DB_PATH = os.path.join(ATM_PATH,'db.txt')
LOG_PATH = os.path.join(ATM_PATH,'log.txt')
DIR_PATH = os.path.join(ATM_PATH,'story_class.txt') def check(user):
with open(DB_PATH,'r',encoding='utf-8') as f:
for line in f:
users = line.strip().split(':')
if user == users[0]:
return True
else:
return False def log_in():
global user_in
global login
while True:
user = input('请输入账号:').strip()
with open(DB_PATH,'r',encoding='utf-8') as f:
pwd = input('请输入密码:').strip()
for line in f:
users = line.strip().split(':')
if user == users[0] and pwd == users[1]:
print('登录成功')
user_in = user
login = True
return True
else:
print('登录失败,请重新登录') def register():
while True:
user = input('请输入账号:').strip()
if user:
if not check(user):
pwd = input('请输入密码:').strip()
if pwd:
pwd2 = input('请确认密码:').strip()
if pwd == pwd2:
with open(DB_PATH,'a',encoding='utf-8') as f:
f.write('{}:{}:{}\n'.format(user,pwd,0))
print('注册成功')
else:
print('密码不一致')
else:
print('密码不能为空哦')
else:
print('账号已存在')
else:
print('账号不能为空哦') def log_money(func):
def wrapper(*args,**kwargs):
func(*args,**kwargs)
with open(LOG_PATH,'a',encoding='utf-8') as f:
import time
time1 = time.strftime('%Y-%m-%d %X')
if func.__name__ == 'money_in':
f.write('{} {} 充值 {}元\n'.format(time1,user_in,money))
if func.__name__ == 'money_out':
f.write('{} {} 消费 {}元\n'.format(time1,user_in,money))
return wrapper def log_in_check(func):
def wrapper(*args,**kwargs):
if login:
func(*args,**kwargs)
return True
else:
print('请登录后再操作')
return False
return wrapper @log_money
@log_in_check
def money_in():
while True:
money = input('充值多少:').strip()
if money.isdigit():
money = int(money)
NEW_PATH = os.path.join(ATM_PATH,'.db.txt.swap')
with open(DB_PATH,'r',encoding='utf-8') as f,\
open(NEW_PATH,'w',encoding='utf-8') as f1:
for line in f:
users = line.strip().split(':')
if user_in == users[0]:
users[2] = int(users[2]) + money
f1.write('{}:{}:{}\n'.format(users[0],users[1],users[2]))
print('充值成功,金额为:{}'.format(money))
os.remove(DB_PATH)
os.rename(NEW_PATH,DB_PATH)
break
else:
print('请输入整数数字') @log_money
def money_out(money):
while True:
money = int(money)
NEW_PATH = os.path.join(ATM_PATH, '.db.txt.swap')
with open(DB_PATH, 'r', encoding='utf-8') as f, \
open(NEW_PATH, 'w', encoding='utf-8') as f1:
for line in f:
users = line.strip().split(':')
if user_in == users[0]:
users[2] = int(users[2]) - money
f1.write('{}:{}:{}\n'.format(users[0], users[1], users[2]))
print('购买成功,金额为:{}'.format(money))
os.remove(DB_PATH)
os.rename(NEW_PATH, DB_PATH)
break @log_in_check
def read_book():
with open(DIR_PATH,'r',encoding='utf-8') as f1:
dir = eval(f1.read())
while True:
print("""==========================
0 玄幻武侠
1 都市爱情
2 高效养猪36技
10 上传的小说
==========================""")
choice = input('请输入编号:').strip()
if choice.isdigit():
if choice in dir:
dir1 =dir[choice]
for i in dir1:
print('{} {} 价格:{}'.format(i,dir1[i][0],dir1[i][1]))
choice2 = input('请输入编号:').strip()
if choice2.isdigit():
if choice2 in dir[choice]:
dir2 = dir1[choice2]
shop = input('是否购买 {} ,价格: {},y确认:'.format(dir2[0],dir2[1]))
if shop.lower() == 'y':
global money
money = dir2[1]
money_out(money)
book = dir2[0]
RD_PATH = os.path.join(ATM_PATH, 'fictions', book)
with open(RD_PATH,'r',encoding='utf-8') as f:
book_data = f.read()
print('''* * * * * * * * * * * * * * * * * * *
{0}
* * * * * * * * * * * * * * * * * * *'''.format(book_data))
input()
break
else:
break
else:
print('没有这个书哦')
else:
print('请输入整数数字')
else:
print('还没有这个书哦')
else:
print('请输入整数数字') @log_in_check
def book_up():
while True:
path_book = input('请输入所要上传的书籍路径:').strip()
if os.path.exists(path_book):
name = os.path.basename(r'{}'.format(path_book))
print(name)
UP_PATH = os.path.join(ATM_PATH, 'fictions', name)
print(UP_PATH)
if os.path.exists(UP_PATH):
up_choice = input('文件已存在,是否覆盖:y/n:::').strip()
if up_choice.lower() != 'y':
continue
with open(path_book,'rb') as f,\
open(r'{}'.format(UP_PATH),'wb') as f1:
print('正在上传 ...')
f1.write(f.read())
print('上传完成')
with open(DIR_PATH,'r',encoding='utf-8') as f,\
open('book_up.txt','w',encoding='utf-8') as f1:
d = eval(f.read().strip())
d['10'][str(len(d['10']))] = [name,0]
print(d['10'])
f1.write(str(d))
os.remove(DIR_PATH)
os.rename('book_up.txt',DIR_PATH)
break
else:
print('路径不存在,请重新输入') if __name__ == '__main__':
func_dic = {'0':['账号注册',register],
'1':['账号登录',log_in],
'2':['充值功能',money_in],
'3':['阅读小说',read_book],
'4':['上传小说',book_up],
'5':['退出',exit],
} user_in = None
login =False
while True:
print('===========================')
for i in range(len(func_dic)):
print('{} {}'.format(i,func_dic[str(i)][0]))
print('---------------------------')
choice = input('请输入命令编号:').strip()
if choice == 'q':
break
if choice in func_dic:
func_dic[choice][1]()
else:
print('没有这个编号')
continue # # 三:文件story_class.txt存放类别与小说文件路径,如下,读出来后可用eval反解出字典
{
"0":{
"0":["倚天屠狗记.txt",3],
"1":["沙雕英雄转.txt",10]
},
"1":{
"0":["令人羞耻的爱.txt",6],
"1":["二狗的妻子与大草原的故事.txt",5]
}, }
#
# 3.1、用户登录成功后显示如下内容,根据用户选择,显示对应品类的小说编号、小说名字、以及小说的价格
# """
# 0 玄幻武侠
# 1 都市爱情
# 2 高效养猪36技
# """
#
# 3.2、用户输入具体的小说编号,提示是否付费,用户输入y确定后,扣费并显示小说内容,如果余额不足则提示余额不足
#
# # 四:为功能2.2、3.1、3.2编写认证功能装饰器,要求必须登录后才能执行操作
#
# # 五:为功能2.2、3.2编写记录日志的装饰器,日志格式为:"时间 用户名 操作(充值or消费) 金额"
#
#
# # 附加:
# # 可以拓展作者模块,作者可以上传自己的作品

ATM 最初版的更多相关文章

  1. 设计模式(十二):通过ATM取款机来认识“状态模式”(State Pattern)

    说到状态模式,如果你看过之前发布的重构系列的文章中的<代码重构(六):代码重构完整案例>这篇博客的话,那么你应该对“状态模式”并不陌生,因为我们之前使用到了状态模式进行重构.上一篇博客我们 ...

  2. ATM

    package duzhaonan;import java.util.Scanner;import javax.swing.JOptionPane;class Account{//创建的账户类 Str ...

  3. ATM+购物车

    本次代码的实现用到了模块间的互相调用,这对于初学者而言有些难度,不过这也是我们必须要掌握的,在以后的大程序中,多个模块会让我们的代码看起来简洁明了,易排错 (本次代码只是简单的实现的基本的功能,其代码 ...

  4. 简单的ATM取款过程

    一个简单的ATM的取款过程是这样的:首先提示用户输入密码(pwd),最多只能输3次,超过三次则提示用户“密码已输入三次错误,请取卡.“结束交易.如果用户密码正确,在提示用户输入金额(money),AT ...

  5. 大话JS面向对象之开篇万物皆对象------(ATM取款机引发的深思)

    一,总体概要 OO(面向对象)概念的提出是软件开发工程发展的一次革命,多年来我们借助它使得很多大型应用程序得以顺利实现.如果您还没有掌握并使用OO进行程序设计和开发,那么您无疑还停留在软件开发的石器时 ...

  6. ATM模拟器(附代码及运行结果)

    源代码: import java.util.Scanner; class Account{ String identify; String name; String date; String key; ...

  7. bzoj 1179[Apio2009]Atm (tarjan+spfa)

    题目 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一 ...

  8. ATM跨行取款的清算方式

    ATM跨行取款和POS机是类似的,因为没有商户参与,所以不需要收单清算,过程更为简单. 回到文章最开头的例子:你拿着一张工行卡去建行的ATM取了100元,这个跨行业务在CNAPS体系中的过程如下: 你 ...

  9. 工行ATM转账——事务操作

    今儿去工行ATM给已朋友转账,遇到这么个情况: 选择对外转账后输入转入账号(输入两次),接着提示输入转入金额(输入一次金额),按确定,系统提示交易中,3秒左右,提示“输入账号无效”,系统自动中断了操作 ...

随机推荐

  1. 微信小程序支付到第三方商户账号

    使用场景:合作商家使用本公司小程序开店,要求支付金额直接到合作商家的公司微信账户; 使用要求:合作商家需提供微信支付关联,商户号,商户API密钥,API证书(该证书只用作退款功能,不开发退款可以不用) ...

  2. 【技巧】歪脑筋优化flexbox瀑布流布局方案

    效果先行 需求 在大量"不定宽"元素并排的布局模式下,上图是我们想要的最佳布局但是FlexBox布局虽然枪弹但并不能完全呈现以上布局,于是我们需要结合FlexBox作下小的改动即可 ...

  3. 关于IT培训机构的个人看法

    1.前言 缘分与巧合,最近接触比较多的培训机构出来的人,以及看过关于培训机构的文章和问答.虽然没在培训机构上过课,但是接触过很多培训机构出来的人,也看过一些培训机构的课程.关于培训机构,我也有自己的看 ...

  4. 适配iphoneX

    tips iphone6设备宽高为375×667,屏幕分辨率为750×1334,故其设备像素比(dpr)为2.iphoneX的设备宽高375*812,屏幕分辨率为1125x2436,故dpr=3 适配 ...

  5. SpringBoot入门系列(四)整合模板引擎Thymeleaf

    前面介绍了Spring Boot的优点,然后介绍了如何快速创建Spring Boot 项目.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/ ...

  6. Asp.Net Core 中IdentityServer4 授权中心之应用实战

    一.前言 查阅了大多数相关资料,查阅到的IdentityServer4 的相关文章大多是比较简单并且多是翻译官网的文档编写的,我这里在 Asp.Net Core 中IdentityServer4 的应 ...

  7. 机器学习实战:意大利Covid-19病毒感染数学模型及预测

    作者:Gianluca Malato deephub翻译组:刘欣然 当今世界正在与一个新的敌人作斗争,那就是Covid-19病毒. 该病毒自首次在中国出现以来,在世界范围内迅速传播.不幸的是,意大利的 ...

  8. WEB渗透之扫描 - Nikto

    2020.0202 好事成双 Nikto 纯主动 识别软件版本 存在安全隐患的文件 配置漏洞 web应用安全隐患 避免404误判 使用 插件:nikto -list-plugins 避免404误判功能 ...

  9. jQuery插件select2跨域设置xhrFields参数

    ajax跨越时默认不带cookie,如果需要带cookie调用,需要设置参数 xhrFields: { withCredentials: true },如: $.ajax({url : "h ...

  10. ggplot2(3) 语法突破

    3.1 简介 图形图层语法基于Wilkinson的图形语法,并在其基础上添加了许多新功能,使得图形更有表现力,并能完美地嵌入到R的环境中. 图形图层语法使得图形的重复更新变得简单——每次只更新一个特征 ...