python完成ATM(分目录)

模块跳转:

常用模块

项目需求:

   用**规范化项目目录**的格式模拟一个ATM系统。
项目功能:

1. 登录(可支持多个账户(非同时)登录)。
2. 注册。
3. 查看余额。
4. 存钱。
5. 转账(给其他用户转钱)。
6. 查看账户流水。
7. 退出
提供的思路:ATM直译就是取款机,但是咱们是模拟一个取款机,此取款机可以完成实现存钱,转账,查看余额,以及查看账户流水等功能。
要求以及分值分配:
1. 利用装饰器完成登录验证功能(3,4,5,6功能需要验证)(5分)。
2. 登录功能要求:用户名、密码(密码需要md5加密)从文件中读取,进行三次验证,验证不成功则退出整个程序。(5分)
3. 注册功能要求:(5分)
+ 用户名要求:只能含有字母数字不能含有特殊字符并且要确保唯一性。
+ 密码的要求:长度在6与14个字符之间,密文存储。
+ 初始钱数:money: 0.
+ **注意**:每个用户的以上信息通过字典以及json模块,以 用户名.json的形式存储,用户的json文件存储在db文件夹中。
4. 查看余额功能要求:(5分)
用户登录成功之后,选择此功能即可显示账户余额,并且将每次查看记录通过日志的方式记录到用户日志中(用户日志文件建议为:用户名.log)。

5. 存钱功能要求:(5分)

用户通过输入存储的钱数,然后将存储的钱累加到用户名.json那个json文件的字典中,并且将每次存钱记录通过日志的方式记录到用户日志中(用户日志文件建议为:用户名.log)。

6. 转账功能要求:(5分)

用户通过输入对方用户名以及转账钱数完成给对方转账功能。

+ 要检测输入的对方用户账户是否存在。
+ 要检测你账户余额是否够用。
+ 将每次转账记录通过日志的方式记录到用户日志中(用户日志文件建议为:用户名.log)。

7. 查看流水要求:(5分)

用户通过选择此功能将用户专属的log打印出来。 8. 整个项目完成流畅,逻辑清楚,极少bug。(5分)

目录结构:

具体代码:

start.py

import sys
import os
BASE_PATH = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_PATH)
from core import src

if __name__ == '__main__':
    src.run()
View Code

settings.py

import os
import logging.config
BASE_PATH = os.path.dirname(os.path.dirname(__file__))
user_path = os.path.join(BASE_PATH, 'db')
LOGGING_PATH = os.path.join(BASE_PATH, 'log', 'admin.log')
SIMPLE_FORMAT = '[%(asctime)s] %(message)s'

LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,

    'formatters': {

        'simple': {
            'format': SIMPLE_FORMAT,
        },
    },
    'filters': {},
    'handlers': {
        # 打印到终端的日志
        'stream': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        # 打印到文件的日志,收集info及以上的日志
        'file': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
            'formatter': 'simple',
            'filename': LOGGING_PATH,  # 日志文件
            'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        },
    },
    'loggers': {
        # logging.getLogger(__name__)拿到的logger配置
        '': {
            'handlers': ['stream', 'file'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}
View Code

src.py

import os
import hashlib
import json
from conf import settings
from lib import common


# 登录状态
status_dic = {
    'username': None,
    'status': False
}
flag = True

li = os.listdir(settings.user_path)


# 登录函数
def login():
    count = 0
    while count < 3:
        username = input("请输入姓名: ").strip()
        password = input("请输入密码: ").strip()
        ret = hashlib.md5()
        ret.update(password.encode("utf-8"))
        pwd = ret.hexdigest()
        with open(settings.user_path+'\\'+username +".json",encoding="utf-8") as f:
            s = json.loads(f.readline())
            if username+'.json' in li and s[username] == pwd:
                status_dic["username"] = username
                status_dic['status'] = True         # 状态改为True
                print("登陆成功")
                return True
            else:
                print("账号或密码错误,请重新登录")
            count += 1

# 注册函数
def register():
    count = 0
    while count < 3:
        username = input("请输入新账号: ").strip()
        password = input("请输新入密码: ").strip()
        if username in li:                # 判断用户是否在文件中存在
            print("用户名已存在,请重新输入")
            continue
        elif not username.isalnum():        # 判断用户是否是字母或数字组成
            print("账号含有非法字符,请重新输入")
            continue
        elif 5 < len(password) < 15:         # 限制密码在6-14位之间
            dic = {}
            md5 = hashlib.md5()
            md5.update(password.encode("utf-8"))
            pwd = md5.hexdigest()
            with open(settings.user_path+'\\'+username +".json", encoding="utf-8", mode="w") as f1:
                dic[username] = pwd
                dic.setdefault("money",0)
                s = json.dumps(dic)
                f1.write(s+"\n")
                print("恭喜!注册成功")
                return True
        else:
            print("密码不合规范,请重新输入")
        count += 1

@common.auth
def look_money():
    print("您已进入查看余额功能")
    with open(settings.user_path + '\\' + status_dic["username"] + '.json', encoding="utf-8", mode="r") as f:
        ret = json.loads(f.read())
        print(f'余额为:{ret["money"]}')

@common.auth
def money():
    print("您已进入存钱功能")
    c_money = input("请输入要存储的金额:").strip()
    cq_money = int(c_money)
    with open(settings.user_path+'\\'+status_dic["username"] +'.json',encoding="utf-8",mode="r") as f3,\
        open(settings.user_path+'\\'+status_dic["username"] +'.bak',encoding="utf-8",mode="w") as f4:
        ret = json.loads(f3.readline())
        ret["money"] += cq_money
        s = json.dumps(ret)
        f4.write(s)
    os.remove(settings.user_path+'\\'+status_dic["username"] +'.json')
    os.rename(settings.user_path+'\\'+status_dic["username"] +'.bak',settings.user_path+'\\'+status_dic["username"] +'.json')
    print(f"恭喜存钱成功")

@common.auth
def zq_money():
    print("您已进入转账功能")
    zz_user = input("请输入对方账户: ").strip()
    zz_money = int(input("请输入要转的金额: ").strip())
    zz_user1 = zz_user + ".json"
    if zz_user1 not in li:  # 判断用户是否在文件中存在
        print("用户名不存在")
    else:
        with open(settings.user_path + '\\' + status_dic["username"] + '.json', encoding="utf-8", mode="r") as f1, \
                open(settings.user_path + '\\' + status_dic["username"] + '.bak', encoding="utf-8", mode="w") as f2:
            ret = json.loads(f1.readline())
            ret["money"] -= zz_money
            s = json.dumps(ret)
            f2.write(s)
        os.remove(settings.user_path + '\\' + status_dic["username"] + '.json')
        os.rename(settings.user_path + '\\' + status_dic["username"] + '.bak',
                  settings.user_path + '\\' + status_dic["username"] + '.json')
        with open(settings.user_path + '\\' + zz_user1, encoding="utf-8", mode="r") as f2, \
                open(settings.user_path + '\\' + zz_user1+".bak", encoding="utf-8", mode="w") as f3:
            ret = json.loads(f2.readline())
            ret["money"] += zz_money
            s = json.dumps(ret)
            f3.write(s)
        os.remove(settings.user_path + '\\' + zz_user1)
        os.rename(settings.user_path + '\\' + zz_user1+".bak",
                  settings.user_path + '\\' + zz_user1)
        print("转账交易成功")
@common.auth
def ch_user():
    print("您已进入查看账户流水功能")
    logger = common.record_logger()
    logger.info(f'status_dic["username"]进行了流水操作')


# 退出程序
def exit_program():
    global flag
    flag = False
    return flag

def run():
    choice_dict = {
        1: login,
        2: register,
        3: look_money,
        4: money,
        5: zq_money,
        6: ch_user,
        7: exit_program,
    }

    while flag:
        print('''
        欢迎来到ATM系统
        1:请登录
        2:请注册
        3:查看余额
        4:存钱
        5:转账
        6:查看账户流水
        7:退出程序''')
        choice = input('请输入您选择的序号:').strip()
        if choice.isdigit():
            choice = int(choice)
            if 0 < choice <= len(choice_dict):
                choice_dict[choice]()
            else:
                print("您输入的超出范围")
        else:
            print("输入不合规范,重新输入")
View Code

ddu.json

{"ddu": "e10adc3949ba59abbe56e057f20f883e", "money": 500}

common.py

from core import src
from conf.settings import LOGGING_DIC
import logging.config
def auth(f):
    def inner(*args, **kwargs):
        if src.status_dic["status"]:
            ret = f(*args, **kwargs)
            return ret
        else:
            print("-------登录页面-------")
            src.login()
            ret = f(*args, **kwargs)
            return ret
    return inner


def record_logger():
    """记录日志"""
    logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
    logger = logging.getLogger()  # 生成一个log实例
    return logger
View Code


猜你喜欢

转载自www.cnblogs.com/duyu123/p/11317775.html
atm