ATM 最初版
# 二 一个项目开发前,有一份开发文档
#
# 项目: 编写小说阅读程序实现下属功能
#
# # 一:程序运行开始时显示
# 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 最初版的更多相关文章
- 设计模式(十二):通过ATM取款机来认识“状态模式”(State Pattern)
说到状态模式,如果你看过之前发布的重构系列的文章中的<代码重构(六):代码重构完整案例>这篇博客的话,那么你应该对“状态模式”并不陌生,因为我们之前使用到了状态模式进行重构.上一篇博客我们 ...
- ATM
package duzhaonan;import java.util.Scanner;import javax.swing.JOptionPane;class Account{//创建的账户类 Str ...
- ATM+购物车
本次代码的实现用到了模块间的互相调用,这对于初学者而言有些难度,不过这也是我们必须要掌握的,在以后的大程序中,多个模块会让我们的代码看起来简洁明了,易排错 (本次代码只是简单的实现的基本的功能,其代码 ...
- 简单的ATM取款过程
一个简单的ATM的取款过程是这样的:首先提示用户输入密码(pwd),最多只能输3次,超过三次则提示用户“密码已输入三次错误,请取卡.“结束交易.如果用户密码正确,在提示用户输入金额(money),AT ...
- 大话JS面向对象之开篇万物皆对象------(ATM取款机引发的深思)
一,总体概要 OO(面向对象)概念的提出是软件开发工程发展的一次革命,多年来我们借助它使得很多大型应用程序得以顺利实现.如果您还没有掌握并使用OO进行程序设计和开发,那么您无疑还停留在软件开发的石器时 ...
- ATM模拟器(附代码及运行结果)
源代码: import java.util.Scanner; class Account{ String identify; String name; String date; String key; ...
- bzoj 1179[Apio2009]Atm (tarjan+spfa)
题目 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一 ...
- ATM跨行取款的清算方式
ATM跨行取款和POS机是类似的,因为没有商户参与,所以不需要收单清算,过程更为简单. 回到文章最开头的例子:你拿着一张工行卡去建行的ATM取了100元,这个跨行业务在CNAPS体系中的过程如下: 你 ...
- 工行ATM转账——事务操作
今儿去工行ATM给已朋友转账,遇到这么个情况: 选择对外转账后输入转入账号(输入两次),接着提示输入转入金额(输入一次金额),按确定,系统提示交易中,3秒左右,提示“输入账号无效”,系统自动中断了操作 ...
随机推荐
- ueditor富文本编辑器——上传图片按钮卡顿,响应慢
最近负责将公司官网从静态网站改版成动态网站,方便公司推广营销人员修改增加文案,避免官网文案维护过于依赖技术人员.在做后台管理系统时用到了富文本编辑器Ueditor,因为公司有一个阿里云文件资源服务器, ...
- iOS 开发富文本之TTTAttributedLabel 在某个特定位置的文字添加跳转,下划线,修改字体大小,颜色
@property(nonatomic , strong) TTTAttributedLabel * ttLabel; @property(nonatomic , strong) NSRange li ...
- 全网最详细的一篇Flutter 尺寸限制类容器总结
Flutter中尺寸限制类容器组件包括ConstrainedBox.UnconstrainedBox.SizedBox.AspectRatio.FractionallySizedBox.Limited ...
- 前端每日实战:111# 视频演示如何用纯 CSS 创作一只艺术的鸭子
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/aaoveW 可交互视频 此视频是可 ...
- 数据结构-ST表
数据结构-ST表 不可修改,在线查询的 RMQ 问题. 其中 \(f[i][j]\) 表示 \(i\sim i+(1<<j)-1\) 这段的 RMQ 值. 时间复杂度 \(O(n\log ...
- 基于 Redis 实现 CAS 操作
基于 Redis 实现 CAS 操作 Intro 在 .NET 里并发情况下我们可以使用 Interlocked.CompareExchange 来实现 CAS (Compare And Swap) ...
- 【05】openlayers 网格图层
效果: 创建地图: //创建地图 var map = new ol.Map({ //设置显示地图的视图 view: new ol.View({ projection: 'EPSG:4326', //投 ...
- 我的学习笔记之node----node.js+socket.io实时聊天(1)
本想着从hello word开篇,也确实写了相关学习笔记.各种原因吧,现在又着急写出作品,便作罢. 这里将记录一个node.js+socket.io的实时聊天程序.(当然我也是跟着网上各种教程资料学习 ...
- DataFrame简介(一)
1. DataFrame 本片将介绍Spark RDD的限制以及DataFrame(DF)如何克服这些限制,从如何创建DataFrame,到DF的各种特性,以及如何优化执行计划.最后还会介绍DF有哪些 ...
- C语言程序设计(五) 选择控制结构
第五章 选择控制结构 分治策略:任务分解细化 程序设计语言:为了让计算机执行由高级语言编写的程序指令,必须把这些指令从高级语言形式转换成计算机能理解的机器语言形式,这种转换是由编译器来完成的 算法:为 ...