ATM+

ATM:模拟实现一个ATM + 购物商城程序

 

额度 15000或自定义

实现购物商城,买东西加入 购物车,调用信用卡接口结账

可以提现,手续费5%

支持多账户登录

支持账户间转账

记录每月日常消费流水

提供还款接口

ATM记录操作日志

提供管理接口,包括添加账户、用户额度,冻结账户等。。。

用户认证用装饰器

文件结构:

Atm

--bin   ---logon.py     ...登录入口

--conf---initialize.py     ...初始化商店商品
         ---goods.conf     ...存储商品信息

--core---admin.py        ...管理员接口
    ---idcard.py      ...ATM接口
         ---main.py .      ...登录门户
         ---shopping.py              ...购物商店

--db ---dbinfo.py           ...读写用户信息接口
  ---username.dir     ...存储用户信息
  ---username.bak
  ---username.dat

--log ---record.py       ...读写ATM操作日志
  ---username.log         ...ATM操作日志

readme:

已存在用户:zhuhuan,密码123
管理员登录:admin/admin
使用注册注册账号,直接登录使用已存在用户,管理员账号密码只能在管理员的功能中使用

 

调用关系:
logon.py中的logo()调用main.py中的face()
  face()调用admin.py中的admin();
       idcard.py中的atm;
       shopping中的shop()

      admin()调用本文件内的build(新建账号),write_off(注销账号),freeze(冻结账号),unfreeze(解冻账号),chance(修改额度)
      atm() 调用本文件内的repay(还款),withdrawals(提现),transfer(转账),调用log中的record.py中的logs记录操作日志
      shop() 调用idcard.py中的pay_bill()结账
      log中记录ATM操作日志
      conf中记录商店商品
      db中记录用户信息
      atm()中有装饰器deco,用于判断在调用atm时是否使用登录接口登录过.

 

流程图:

bin 下的logon.py:

#!/usr/bin/env python
# -*-coding:utf-8-*-
# Author:zh
import sys,os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import core

we=core.main.Welcome()

#入口方法
def logo():
    info = '''\033[36;1m--------Welcome--------
    \t1.注册
    \t2.登陆\033[0m
    '''
    print(info)
    recv = input("请输入需要进行的操作序号-->").strip()

    if recv == "1":
        we.regis()
        we.login()
    if recv == "2":
        we.login()
    else:
        print("输入错误")
logo()
logon.py

conf:初始化商城信息

#!/usr/bin/env python
# -*-coding:utf-8-*-
# _author_=zh
import os
path=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))+os.sep+"conf"

def initialize():
    #初始化商店货物
    GOODS='''[["clothes",80],["pants",40],["Shoes",50],["watch",300],["bicycle",500]]'''
    if not os.path.exists("goods.conf"):
        with open(r"%s%s%s" % (path, os.sep,"goods.conf"),"w",encoding="utf-8") as files:
            files.write(GOODS)
initialize.py

core:主要内容:包含ATM接口,购物商城接口,管理员接口,主程序

  主程序:

#!/usr/bin/env python
# -*-coding:utf-8-*-
# Author:zh
import sys,os
sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import log
import db
from core import idcard
from core import shopping
from core import admin

class Welcome(object):
    name,pwd='',''
    def enter(self):
        name = input("请输入用户名:").strip().lower()
        pwd = input("请输入密码:").strip().lower()
        self.name=name
        self.pwd=pwd

    #登录
    def login(self):
        count=0
        sign=True
        while sign:
            self.enter()
            if self.name=="q" or self.pwd=="q":
                exit()
            dict_l=db.dbinfo.file_r(self.name)
            if not dict_l:
                exit()
            count += 1
            if count>3:
                print("错误次数过多,账户被冻结,请联系管理员")
                dict_l["user_sign"]=1
                db.dbinfo.file_w(self.name, dict_l)
                sign = False
            if dict_l["name"]==self.name and dict_l["pwd"]==self.pwd:
                if dict_l["user_sign"]==0:
                    print("Welcome,%s"%self.name)
                    dict_l["logon_sign"]=1
                    db.dbinfo.file_w(self.name,dict_l)
                    while True:
                        face(dict_l)
                    sign=False
                else:
                    print("账户已被冻结")
            else:
                print("输入错误,请重新输入")
    #注册
    def regis(self):
        self.enter()
        dict_r={}
        dict_r["name"]=self.name
        dict_r["pwd"] = self.pwd
        dict_r["money"]=15000
        #用户状态(1表示冻结,0正常)
        dict_r["user_sign"]=0
        #用户登录状态(1表示已登录,0表示未登录
        dict_r["logon_sign"]=0
        db.dbinfo.file_w(self.name,dict_r)
        print("\033[32;1m注册成功!请登录\033[0m")

#登陆后的首界面
def face(dict_l):
    dict_info = {"1": shopping.shop, "2": idcard.atm,
                 "3": admin.admin, "4": log.record.notes}
    info = '''\033[34;1m
1.购物商城
2.ATM
3.管理员
4.操作记录
5.退出
\033[0m
'''
    print(info)
    num=input("请输入需要进行的操作序号-->").strip()
    if num=="5":
        exit()
    try:
        dict_info[num](dict_l)
    except FileNotFoundError as e:
        print("\33[31;1m还未存在信用卡操作,没有记录\33[0m")
main.py

  ATM接口:

#!/usr/bin/env python
# -*-coding:utf-8-*-
# Author:zh
import db
import log
import core

def deco(func):
    # 装饰器:判断用户登录是否使用的登录接口登录
    def account(*args, **kwargs):
        user = args
        if user[0]["logon_sign"] == 1:
            func(*args, **kwargs)
        else:
            print("请重新登录")
            we = core.main.Welcome()
            we.login()
    return account
@deco
def atm(dict_l):
    money = Money(dict_l)
    dict_info = {"1": money.repay, "2": money.withdrawals,
                 "3": money.transfer}
    while True:
        info='''\033[32;1m
    1.还款
    2.提现
    3.转账
    4.查看信息
    5.退出
    6.返回上一层
\033[0m
'''
        print(info)
        num = input("请输入需要进行的操作序号-->").strip()
        if num=="5":
            exit()
        elif num=="6":
            break
        elif num=="4":
            log.record.notes(dict_l)
        elif num in dict_info.keys():
            dict_info[num]()
        else:
            print("输入错误")
class Money(object):
    # dict_l:传入的登录人信息
    def __init__(self,dict_l):
        self.dict_l=dict_l
        self.info = db.dbinfo.file_r(self.dict_l["name"])
    # 还款
    def repay(self):
        arrears=15000-self.info["money"]
        print("name:%s,欠费:%s"%(self.info["name"],arrears))
        num=input("请输入还款金额:")
        if num.isdigit():
            num=int(num)
            self.info["money"]=self.info["money"]+num
            db.dbinfo.file_w(self.info["name"],self.info)
            print("还款成功")
            infomation="还款,还款金额:%s,可用额度%s"%(num,self.info["money"])
            log.record.logs(infomation,self.dict_l["name"])
        else:
            print("输入错误")

    # 提现
    def withdrawals(self):
        print("可提现金额:%s"%self.info["money"])
        num = input("请输入提现金额:")
        if num.isdigit():
            num=int(num)
            self.info["money"]=self.info["money"]-num-0.05*num
            db.dbinfo.file_w(self.info["name"],self.info)
            print("提现成功")
            infomation="提现,提现金额:%s,可用额度%s"%(num,self.info["money"])
            log.record.logs(infomation,self.dict_l["name"])
        else:
            print("输入错误")

    # 转账
    def transfer(self):
        print("可转账金额:%s"%self.info["money"])
        name = input("请输入转账用户名称:")
        num = input("请输入转账金额:")
        info_other = db.dbinfo.file_r(name)
        if info_other:
            if num.isdigit():
                num = int(num)
                self.info["money"]-=num
                info_other["money"]+=num
                db.dbinfo.file_w(self.info["name"], self.info)
                db.dbinfo.file_w(info_other["name"], info_other)
                print("转账成功")
                infomation = "转账,转账账户:%s,转账金额:%s,此卡可用额度%s" % (num,info_other["name"],info["money"])
                log.record.logs(infomation, self.dict_l["name"])
            else:
                print("输入错误")

    # 支付,bill:传入需要结账的金额
    def pay_bill(self,bill):
        if bill>self.dict_l["money"]:
            print("信用卡钱不够")
        else:
            self.dict_l["money"]-=bill
            db.dbinfo.file_w(self.dict_l["name"],self.dict_l)
            infomation = "结账,结账金额:%s,可用额度%s" % (bill, self.dict_l["money"])
            log.record.logs(infomation, self.dict_l["name"])
idcard.py

  购物商城接口:

#!/usr/bin/env python
# -*-coding:utf-8-*-
# Author:zh
import sys,os
sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import conf
from core import idcard
path=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))+os.sep+"conf"
def show():
    # 格式化输出商品
    conf.initialize.initialize()
    with open(r"%s%s%s" % (path, os.sep,"goods.conf"),"r",encoding="utf-8") as files:
        goods=files.read()
    goods=eval(goods)
    for i in goods:
        print("\033[32;1m%s.%s......%s\033[0m"%(goods.index(i)+1,i[0],i[1]))
    return goods

#购物商城
def shop(dict_l):
    having=[]
    money = idcard.Money(dict_l)
    while True:
        snap=show()
        num=input("请输入需要加入购物车的商品编号(s结账):").strip()
        #传给结账接口的费用参数
        bill=0
        if num.isdigit():
            num=int(num)
        if num in range(1,len(snap)+1):
            having.append(snap[num-1])
        elif num=="s":
            for i in having:
                bill=bill+i[1]
            money.pay_bill(dict_l,bill)
            break
        elif num=="b":
            break
        elif num=="q":
            exit()
        else:
            print("输入错误")
shopping.py

  管理员接口:

#!/usr/bin/env python
# -*-coding:utf-8-*-
# _author_=zh
import os
import db
from core import main

#管理员接口
def admin(dict_l):
    account = Account()
    dict_info = {"1": account.build, "2": account.write_off, "3": account.freeze,
                 "4": account.unfreeze, "5": account.chance}
    name = input("请输入管理员账号和密码(name/pwd):")
    if name == "admin/admin":
        print("Welcome")
        while True:
            info = '''\033[32;1m
    1.新建账户
    2.注销账户
    3.冻结账户
    4.解冻账户
    5.修改额度
    6.退出
    7.返回上一层
            \033[0m
            '''
            print(info)
            num = input("请输入需要进行的操作序号-->").strip()
            if num == "6":
                exit()
            elif num == "7":
                break
            elif num in dict_info.keys():
                dict_info[num]()
            else:
                print("输入错误")
    else:
        print("输入错误")


class Account(object):
    #新建账户
    def build(self):
        name = input("请输入用户名:").strip().lower()
        pwd = input("请输入密码:").strip().lower()
        dict_r = {}
        dict_r["name"] =name
        dict_r["pwd"] =pwd
        dict_r["money"] = 15000
        dict_r["user_sign"] = 0
        db.dbinfo.file_w(name, dict_r)
        print("新建成功")
    #注销账户
    def write_off(self):
        name=input("请输入需要注销的账号:")
        self.path_data=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))+os.sep+"db"+os.sep+name
        self.path_log=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))+os.sep+"log"+os.sep+name
        try:
            os.remove(self.path_data+".txt.dir")
            os.remove(self.path_data + ".txt.dat")
            os.remove(self.path_data + ".txt.bak")
            os.remove(self.path_log+".log")
            print("删除成功")
        except FileNotFoundError as e:
            print(e)
    #冻结账户
    def freeze(self):
        name=input("请输入需要冻结的账号:")
        info=db.dbinfo.file_r(name)
        info["user_sign"]=1
        db.dbinfo.file_w(name,info)
        info = db.dbinfo.file_r(name)
        print("冻结成功!")
    #解冻账户
    def unfreeze(self):
        name = input("请输入需要解冻的账号:")
        info=db.dbinfo.file_r(name)
        info["user_sign"]=0
        db.dbinfo.file_w(name,info)
        print("解冻成功!")
    #修改额度
    def chance(self):
        name = input("请输入需要修改的账号:")
        info = db.dbinfo.file_r(name)
        print("现有额度:%s"%info["money"])
        num=input("请输入需要修改的额度:")
        if num.isdigit():
            num=int(num)
            info["money"]=num
            db.dbinfo.file_w(name, info)
            print("修改成功!")
        else:
            print("输入错误")
admin

 

db:数据库目录,存储用户基本信息

  dbinfo.py:写入用户信息,读取用户信息

#!/usr/bin/env python
# -*-coding:utf-8-*-
# Author:zh

import shelve
import os
import bin
path=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))+os.sep+"db"
#写入文件,按用户名称存入
def file_w(name,dict):
    db=shelve.open(r"%s%s%s.txt"%(path,os.sep,name))
    db[name]=dict
#读取文件内容
def file_r(name):
    if  os.path.exists(r"%s%s%s.txt.dir" % (path, os.sep, name)):
        db = shelve.open(r"%s%s%s.txt" % (path, os.sep, name))
        return db[name]
    else:
        print("\033[31;1m用户名不存在!\033[0m")
        return None
dbinfo.py

log:记录日志信息

  record.py:日志记录,读取

#!/usr/bin/env python
# -*-coding:utf-8-*-
# _author_=zh
import os
import logging
from logging import handlers

path=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))+os.sep+"log"
#读取日志
def notes(dict_l):
    with open(r"%s%s%s.log"%(path,os.sep,dict_l["name"]),encoding="utf-8") as files:
        info=files.read()
        print(info)
#记录并在屏幕输出日志,infomation:日志内容
def logs(infomation,name):
    logger=logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)
    #格式
    f_formatter = logging.Formatter("%(asctime)s %(levelname)s:%(message)s")
    #h为屏幕输出的Handler fh为日志输出的Handler
    ch=logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    ch.setFormatter(f_formatter)
    fh=handlers.TimedRotatingFileHandler(r"%s%s%s.log"%(path,os.sep,name),when="D",interval=1,backupCount=3,encoding="utf-8")
    fh.setLevel(logging.INFO)
    fh.setFormatter(f_formatter)
    logger.addHandler(ch)
    logger.addHandler(fh)

    logger.info(infomation)
record.py

 

posted @ 2017-10-12 21:21  zhuh  阅读(183)  评论(0编辑  收藏  举报