# 二 一个项目开发前,有一份开发文档
#
# 项目: 编写小说阅读程序实现下属功能
#
# # 一:程序运行开始时显示
# 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. jQuery样式及html属性操作

    样式及html属性操作1,行内样式 css(); a:获取样式 元素.css(样式名称); b:设置单个样式 元素.css("样式名称":"样式值"); c:设 ...

  2. [ASP.NET Core 3框架揭秘] 服务承载系统[1]: 承载长时间运行的服务[上篇]

    借助.NET Core提供的承载(Hosting)系统,我们可以将任意一个或者多个长时间运行(Long-Running)的服务寄宿或者承载于托管进程中.ASP.NET Core应用仅仅是该承载系统的一 ...

  3. 【Java】Map总结和源码注释

    前言 Map为一个Java中一个重要的数据结构,主要表示<key, value>的映射关系对.本文包括了相关Map数据结构的总结和源码的阅读注释. HashMap 初始化,可以选择第二个初 ...

  4. 超全!python的文件和目录操作总结

    文件的基本读写 path = r'C:\Users\Brady\Documents\tmp' with open(path + r'\demo.txt', 'r', encoding='utf-8') ...

  5. 如何理解js中的this和实际应用中需要避开哪些坑

    this是什么 this就是函数内部的关键字 看下面例子理解js中的this // 例子1 function fnOne () { console.log(this) } 'use strict' f ...

  6. 微信小程序学习简介

    如何向微信小程序导入DEMO源码: 参考方法 参考学习小程序官方文档 小程序官方文档 小程序目录简介 app.json :设置一些工程全局的量.js : 写一些函数逻辑.wxml: 调用.js中写的函 ...

  7. 停下来,回头看 ——记2020BUAA软工第一次作业-热身!

    description: 'Mar 1st, 2020 - Mar 3rd, 2020' 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任建) 这个作业的要求在哪里 第一次作 ...

  8. .NET Core 3.x之下的配置框架

    一.配置框架的核心类库 首先我们使用.NET Core的配置框架需要安装额外的NuGet扩展包,下面是列举最常用的几个扩展包以及所对应的配置功能 NuGet Package Description M ...

  9. VMWare12pro安装Centos 6.9教程

    VMWare下Centos 6.9安装教程,记录如下 1.新建虚拟机 (1)点击文件-->新建虚拟机 (2)选择 自定义(高级)-->下一步 (3)选择Workstation 12.0-- ...

  10. HTML5 基础知识(1)——基本标签

    ## HTML**概念**:是最基础的网页开发语言(Hyper Text Markup Langage 超文本标记语言) > 1.超文本:超文本是用超链接的方式i,将各种不同空间的文字组织在一起 ...