# 二 一个项目开发前,有一份开发文档
#
# 项目: 编写小说阅读程序实现下属功能
#
# # 一:程序运行开始时显示
# 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. DroidVim:在安卓手机上使用vim

    背景 有时候在邮件,钉钉,微信上收到一份文件,急需打开看一下,但有些文件用普通编辑器打开体验实在不佳,例如 patch,log 甚至 bin 文件.由于日常在电脑上使用的是 vim ,一个朴素的想法就 ...

  2. 初学qt——提示窗体

    带选择的窗体 QMessageBox::StandardButton rb = QMessageBox::critical(NULL, QString::fromLocal8Bit("提示& ...

  3. symfony 5.05 dev安装为了更好的迭代更新

    我的项目目录 安装命令  composer create-project symfony/website-skeleton:^5.0.x-dev manage 数据查询测试输出

  4. python库常用函数学习

    os.path #返回标准化的绝对路径,基本等同于normpath() os.path.abspath(path) #返回文件名 os.path.basename(path) #返回目录名 os.pa ...

  5. Docker实战之Zookeeper集群

    1. 概述 这里是 Docker 实战系列第四篇.主要介绍分布式系统中的元老级组件 Zookeeper. ZooKeeper 是一个开源的分布式协调服务,是 Hadoop,HBase 和其他分布式框架 ...

  6. AI:拿来主义——预训练网络(二)

    上一篇文章我们聊的是使用预训练网络中的一种方法,特征提取,今天我们讨论另外一种方法,微调模型,这也是迁移学习的一种方法. 微调模型 为什么需要微调模型?我们猜测和之前的实验,我们有这样的共识,数据量越 ...

  7. web前端 关于浏览器兼容的一些知识和问题解决

    浏览器兼容 为什么产生浏览器兼容,浏览器兼容问题什么是浏览器兼容: 所谓的浏览器兼容性问题,是指因为不同的浏览器对同一段代码有不同的解析,造成页面显示效果不统一的情况. 浏览器兼容产生的原因: 因为不 ...

  8. 在Shadow DOM使用原生模板

    原生模板的优势 延迟了资源加载 延迟了加载和处理模板所引用的资源的时机,这样,用户就能够在模板中使用任意多的资源,却不阻碍页面的渲染. 延迟了渲染内容 无论模板在什么位置,浏览器不会把模板中的内容直接 ...

  9. 前端面试题(HTML、CSS部分)

    HTML.CSS部分: 一.html5有哪些新特性.移除了那些元素?如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和 HTML5?   新特性: HTML5 现在已经不是 SGML 的 ...

  10. 关于Spring注解@Component、@Repository、@Service、@Controller @Resource、@Autowired、@Qualifier 解析

    1.Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository.@Service和 @Controller 其实这三个跟@Com ...