码迷,mamicode.com
首页 > 其他好文 > 详细

ATM程序项目规范

时间:2018-08-12 01:31:13      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:sage   ===   .sh   配置   日志格式   append   控制   out   保存   

 

ATM购物车程序(练习)

------------README

作者:飞乐
版本:示例版本 v0.1
程序介绍:
    实现ATM常用功能
    功能全部用python的基础知识实现,用到了time\os\sys\open\函数\模块知识, 主要帮给大家一个简单的模块化编程的示例

    注意:只实现了"认证""注册""购物""支付"功能

程序结构:
ATM--/
├——─ README
├── atm #ATM主程目录
│   ├── __init__.py
│   ├── bin #ATM 执行文件 目录
│   │   ├── __init__.py
│   │   ├── start.py  #ATM 执行程序
│   │   └── manage.py #ATM 管理端,未实现
│   ├── conf #配置文件
│   │   ├── __init__.py
│   │   └── settings.py #文本配置
│   ├── core #主要程序逻辑都 在这个目录 里
│   │   ├── __init__.py
│   │   ├── auth.py      #用户认证模块
│   │   ├── shop.py  #购物商城
│   │   ├── register.py       #用户注册模块
│   │   ├── src.py         #主逻辑交互程序
│   ├── db  #用户数据存储的地方
│   │   ├── __init__.py
│   │   ├── db.py #生成一个临时的账户数据 
│   │   └── error_db.py #账户锁定文本 
│   ├── lib  #公共程序
│   │   ├── __init__.py 
│   │   ├── common.py     #临时获取的用户信息
│   └── log #日志目录
│        ├── __init__.py
└── ── ├── access.log #用户访问和操作的相关日志

ATM

-------bin目录

start.py

技术分享图片
1 import sys,os
2 BASE_DIR=os.path.dirname(os.path.dirname(__file__))
3 sys.path.append(BASE_DIR)
4 
5 from core import src
6 src.run()
View Code

 

-------conf目录

settings.py

import os


BASE_DIR=os.path.dirname(os.path.dirname(__file__))
DB_PATH=r%s\db\db.txt%BASE_DIR#用户注册信息路径
ER_PATH=r%s\db\error_db.txt%BASE_DIR#锁定账户的信息路径

#以下内容是增加的功能
LOG_PATH=r%s\log\access.log%BASE_DIR#定义日志文件路径 BOSS_LOG_PATH=r%s\log\boss.log%BASE_DIR#定义日志文件路径 """ logging配置 """ # 定义三种日志输出格式 开始 standard_format = [%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d] [%(levelname)s][%(message)s] #其中name为getlogger指定的名字 simple_format = ‘[task_id:%(name)s][%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s id_simple_format = [task_id:%(name)s][%(levelname)s][%(asctime)s] %(message)s # log配置字典(字典的key不能改) LOGGING_DIC = { version: 1, #定义的版本 disable_existing_loggers: False,#无用 #1、定义日志的格式 formatters: {#字典的key可以随便取 standard: {#key是固定格式 format: standard_format#定义的日志格式 }, simple: { format: simple_format }, id_simple:{ format:id_simple_format }, }, filters: {}, #过滤,不用 #2、定义日志输入的目标:文件或者终端,发送给boss handlers: {#控制文件写入 #打印到终端的日志 stream: { level: DEBUG, class: logging.StreamHandler, # 打印到屏幕 formatter: simple#绑定格式 }, #打印到文件的日志,收集info及以上的日志 access: { level: DEBUG, class: logging.handlers.RotatingFileHandler, # 保存到文件(日志轮转) formatter: standard,#绑定日志格式 filename: LOG_PATH, # 日志文件 maxBytes: 1024*1024*5, # 日志大小 5M#一份日志文件的大小 backupCount: 5,#最多保存五份日志,写完五份时轮转 encoding: utf-8, # 日志文件的编码,再也不用担心中文log乱码了 }, #打印到文件的日志,收集error及以上的日志 boss: { level: ERROR, class: logging.handlers.RotatingFileHandler, # 保存到文件(日志轮转) formatter: id_simple,#绑定日志格式 filename: BOSS_LOG_PATH, # 日志文件 maxBytes: 1024*1024*5, # 日志大小 5M#一份日志文件的大小 backupCount: 5,#最多保存五份日志,写完五份时轮转 encoding: utf-8, # 日志文件的编码,再也不用担心中文log乱码了 }, }, loggers: { #logging.getLogger(__name__)拿到的logger配置 : {#定义日志的名字 handlers: [access, stream,boss], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 level: DEBUG, propagate: False, # 向上(更高level的logger)传递 }, }, } #因为这是单独的功能,下面代码不能在这里写,要把它写在lib文件common内 # import logging.config # import logging # logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置 # # l1=logging.getLogger(‘egon‘) # l1.debug(‘测试‘)

 

-------core目录

auth.py

技术分享图片
 1 import sys,os
 2 BASE_DIR=os.path.dirname(os.path.dirname(__file__))
 3 sys.path.append(BASE_DIR)
 4 from lib import common  #导入读取到的用户信息
 5 from conf import settings #导入配置模块获取文本路径,用于锁定账户写入文本
 6 
 7 
 8 def outter(func):
 9     def inner(*args,**kwargs):
10         user_info_dic = common.user_info()
11         while True:
12             if len(user_info_dic) == 0:
13                 print(请先注册)
14                 break
15             if common.current_user[username]:
16                 print(用户已登录)
17                 res = func(*args,**kwargs)
18                 return res
19 
20             uname=input(用户名>>:).strip()
21             if uname==q:break
22             if uname not in user_info_dic:
23                 print(用户不存在。。。)
24                 continue
25 
26             if uname in common.user_error_info():
27                 print(此账户已被锁定)
28                 continue
29 
30             if user_info_dic[uname][status]>2:
31                 with open(settings.ER_PATH,a,encoding=utf-8)as f:
32                     f.write(%s|%uname)
33                     user_info_dic[uname][status]=0
34                     print(尝试次数过多,账户已被锁定)
35                     continue
36 
37             pwd=input(密码>>:).strip()
38             if pwd==q:break
39             if pwd==user_info_dic[uname][password]:
40                 print(欢迎 %s 登录成功%uname)
41                 common.current_user[username]=uname#将用户名存入临时字典内
42                 common.current_user[balance]=int(user_info_dic[uname][balance])#将价格信息转成int存入字典内,用于购物运算
43                 res=func(*args,**kwargs)
44                 return res
45             else:
46                 print(密码错误)
47                 user_info_dic[uname][status] +=1
48     return inner
49 
50 
51 @outter
52 def auth1():
53     pass
View Code

 

register.py

技术分享图片
 1 import sys,os
 2 BASE_DIR=os.path.dirname(os.path.dirname(__file__))
 3 sys.path.append(BASE_DIR)
 4 from conf import settings
 5 
 6 def get_uname():
 7     while True:
 8         uname=input(请输入用户名>>:).strip()
 9         if not uname.isalpha():
10             print(输入不合法)
11             continue
12         with open(settings.DB_PATH,r,encoding=utf-8)as f:
13             for line in f:#如果break没有运行,则运行else
14                 line=line.strip(\n).split(,)
15                 if uname==line[0]:
16                     print(用户已存在)
17                     break
18             else:
19                 return uname
20 def get_pwd():
21     while True:
22         pwd1=input(请输入密码>>:).strip()
23         if not len(pwd1) > 0:
24             print(输入不能为空)
25             continue
26         pwd2=input(请再次输入密码>>:).strip()
27         if pwd1==pwd2:
28             return pwd1
29         else:
30             print(两次输入密码不一致,请重新输入)
31 def get_bal():
32     while True:
33         bal=input(请输入金额>>:).strip()
34         if bal.isdigit():
35             return bal
36         else:
37             print(输入非法)
38 def uinfo_write(uname,pwd,bal):
39     with open(settings.DB_PATH,a,encoding=utf-8)as f:
40         f.write(%s,%s,%s\n%(uname,pwd,bal))
41         print(注册成功)
42 
43 #用户注册执行入口
44 def registe():
45     print(\033[34;1m========注册=========\033[0m)
46     uname=get_uname()
47     pwd=get_pwd()
48     bal=get_bal()
49     uinfo_write(uname,pwd,bal)
View Code

 

shop.py

技术分享图片
 1 import sys,os
 2 BASE_DIR=os.path.dirname(os.path.dirname(__file__))
 3 sys.path.append(BASE_DIR)
 4 from lib import common
 5 from core import auth
 6 
 7 @auth.outter
 8 def shopping():
 9     #登录成功,开始购物
10     uname_of_db=common.current_user[username]#获取用户名
11     balance_of_db=common.current_user[balance]#获取余额
12     print(\033[32;1m欢迎进入购物商城\n尊敬的用户 [%s] 您的余额为 [%s],祝您购物愉快\033[0m%(
13         uname_of_db,balance_of_db))
14     while True:
15         goods = [
16             {"name":"电脑","price":2000},
17             {"name":"鼠标","price":10},
18             {"name":"游艇","price":20},
19             {"name":"美女","price":100},
20         ]
21         print(------商品编号-------商品名称-----商品价格------)
22         for index,item in enumerate(goods):
23             print(         %s            %s            %s%(
24                 index,goods[index][name],goods[index][price]))
25         print(--------------------end------------------------)
26         choice=input(请输入想购买的商品编号,输入"q"退出>>:).strip()
27         if choice.isdigit():
28             choice=int(choice)
29             if choice < 0 or choice >= len(goods):continue#判断购买的商品是否超过可选范围
30 
31             gname=goods[choice][name]#商品名
32             gprice=goods[choice][price]#商品价格
33 
34             if balance_of_db >= gprice:
35                 if gname in common.shopping_cart:#原来已经买过了
36                     common.shopping_cart[gname][count] +=1
37                 else:
38                     common.shopping_cart[gname]={gprice:gprice,count:1}
39 
40                 balance_of_db -=gprice #扣钱
41                 common.current_user[balance]=balance_of_db#更新账户余额
42                 print(成功购买 %s 添加到购物车,价格是 %s%(gname,gprice))
43             else:
44                 print(你个穷逼买不起,产品价格是 {price} ,你还差 {lack_price}.format(
45                     price=gprice,
46                     lack_price=(gprice-balance_of_db)
47                 ))
48             print(common.shopping_cart)
49             print(退出并支付购买的商品请输入:"b")
50         elif choice==b:
51             break
52         elif choice==q:
53             common.shopping_cart={}
54             break
55         else:
56             print(输入非法)
View Code

 

src.py

from core import register#用户注册模块
from core import auth #导入用户注册模块
from core import shop #导入购物模块
from lib import common#导入公共模块
from conf import settings #导入配置模块
import os

#支付,注册,认证等日志功能我都没有添加,想看效果的自己尝试。
logger1=common.get_logger(‘atm‘)#必须传入一个值,在lib/common中函数get_logger中有参数。

@auth.outter
def pay():
    print(------------支付---------\n)
    print("""
    ---------------------------------已购买商品列表---------------------------------
    id          商品                   数量             单价               总价
    """)
    total_cost=0
    for i,key in enumerate(common.shopping_cart):
        print(%22s%18s%18s%18s%18s%(
            i,
            key,
            common.shopping_cart[key][count],
            common.shopping_cart[key][gprice],
            common.shopping_cart[key][count]*common.shopping_cart[key][gprice]
        ))
        total_cost +=common.shopping_cart[key][count]*common.shopping_cart[key][gprice]
    print(‘‘‘
    您的总花费为:%s
    您的余额为:%s
    ---------------------------------end---------------------------------
    ‘‘‘%(total_cost,common.current_user[balance]))
    while True:
        if len(common.shopping_cart) == 0:
            print(购物车为空,无需支付)
            break

        inp=input(确认购买(yes/no?)>>:).strip()
        if inp not in [Y,N,y,n,yes,no]:continue
        if inp in [Y,y,yes]:
            #将余额写入文件

            src_file=settings.DB_PATH
            dst_file=r%s.swp%settings.DB_PATH
            with open(src_file,r,encoding=utf-8)as read_f,                open(dst_file,w,encoding=utf-8)as write_f:
                for line in read_f:
                    if line.startswith(common.current_user[username]):
                        l=line.strip(\n).split(,)
                        l[-1]=str(common.current_user[balance])
                        line=,.join(l)+\n
                        #在内存中修改的数据,写入到硬盘中
                    write_f.write(line)
            os.remove(src_file)
            os.rename(dst_file,src_file)
            print(购买成功,请耐心等待发货)
            common.shopping_cart={}
            common.current_user[username]=None
            common.current_user[balance]=None
            break
        if inp in [N,n,no]:
            print(正在退出支付平台。。。。。)
            break

@auth.outter
def transter():
    print(------------转账---------)

    logger1.error(‘小明给小红转账100000,转账转错了‘)


dic={
    1:auth.auth1,
    2:register.registe,
    3:shop.shopping,
    4:pay,
    5:transter,
}

def run():
    while True:
        print(‘‘‘
        1 认证
        2 注册
        3 购物
        4 支付
        5 转账
        ‘‘‘)
        choice = input(>>: ).strip()
        if choice in dic:
            dic[choice]()
        elif choice==q:break
        else:
            print(输入非法)

 

 

-------db目录

db.txt

1 alex,abc,2400

error_db.txt

alex|egon|jack|

 

-------lib目录

common.py

from conf import settings #引入配置模块获取文本信息路径,用于读取用户信息
import logging.config
import logging

#在这里要写成单独的功能
def get_logger(name):
    logging.config.dictConfig(settings.LOGGING_DIC)  # 导入上面定义的logging配置
    l1=logging.getLogger(name)
    return l1


#获取用户列表信息
def user_info():
    user_info_dic={}
    with  open(settings.DB_PATH,r,encoding=utf-8)as f:
        for line in f:
            line=line.strip(\n).split(,)
            user_info_dic[line[0]]={
                password:line[1],
                balance:line[2],
                status:0,
            }
    return user_info_dic


#获取被锁定的用户信息
def user_error_info():
    with open(settings.ER_PATH,r,encoding=utf-8)as f:
        line=f.read()
        line=line.strip().split(|)
        return line

#将登成功的信息保存到字典中
current_user={
    username:None,
    balance:None,
}

shopping_cart={}

 

 

-------log目录

access.log(已实现)

记录日志功能

此功能已经实现,上面展开中标记颜色的代码。

后续还有其它功能,持续更新中..........

ATM程序项目规范

标签:sage   ===   .sh   配置   日志格式   append   控制   out   保存   

原文地址:https://www.cnblogs.com/happyfei/p/9454668.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!