函数模块-ATM 自动取款机

#作业要求

ATM自动取款机

  1. 指定最大透支额度
  2. 可取款
  3. 定期还款(每月指定日期还款,如15号)
  4. 可存款
  5. 定期出账单
  6. 支持多用户登陆,用户间转帐
  7. 支持多用户
  8. 管理员可添加账户、指定用户额度、冻结用户等
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = "Elijah"
__date__ = "2017/7/5 14:01"

# 导入
import datetime
import re

# 全局变量
GLOBAL_VAR = {'user_info': {},
              'user_name': '',
              'user_locked': [],
              'user_bill': [],
              'opera_num': '', }


# 函数定义
def login():
    '''
    功能选择界面
    :return:
    '''
    welcome_str = '''
                                      欢迎来到ATM自动取款机
------------------------------------------------------------------------------------------------------
请选择您的操作:
1、用户登陆
2、管理员登陆
3、退出
    '''
    while True:
        print(welcome_str)
        opera_num = input('请输入操作编号1-3:\n>>>').strip()
        if opera_num.isdigit() and 0 < int(opera_num) < 4:
            return opera_num
        else:
            print('你输入的操作编号有误!请重新输入!')
            continue


def read_info(user_info):
    '''
    将用户信息读至内存
    :return:info_dict
    '''
    info_list = []
    info_dict = {}
    with open(user_info, mode='r', encoding='utf-8') as f:
        for line in f:
            info_list.clear()
            info_list.append(line.split(',')[1])
            info_list.append(line.split(',')[2])
            info_list.append(line.split(',')[3])
            info_list.append(line.split(',')[4])
            info_dict[line.split(',')[0]] = info_list.copy()
        return info_dict


def write_info(info_dict, user_info):
    '''
    将内存写至用户文件
    :param info_dict:
    :param user_info:
    :return:
    '''
    with open(user_info, mode='w', encoding='utf-8') as f:
        for k, v in info_dict.items():
            f.write(k + ',' + v[0] + ',' + v[1] + ',' + v[2] + ',' + v[3] + ',\n')


def read_ubill(username):
    '''
    将用户账单读取到内存
    :param username:
    :return:
    '''
    bill_name = username + '_bill.txt'
    bill_list = []
    with open(bill_name, mode='r', encoding='utf-8') as f:
        bill_list.clear()
        for line in f:
            bill_list.append(line.split(',')[0])
            bill_list.append(line.split(',')[1])
            bill_list.append(line.split(',')[2])
            bill_list.append(line.split(',')[3])
        return bill_list


def write_ubill(bill_list, username):
    '''
    将用户账单写回文件
    :param bill_list:
    :param username:
    :return:
    '''
    str = ''
    bill_name = username + '_bill.txt'
    with open(bill_name, mode='w', encoding='utf-8') as f:
        for index, i in enumerate(bill_list):
            if (index + 1) % 4 == 0:
                str = str + i + ',\n'
            else:
                str = str + i + ','
        f.write(str)


def read_locked(user_locked):
    '''
    将锁定用户读至内存
    :param user_locked:
    :return:
    '''
    with open(user_locked, mode='r', encoding='utf-8') as f:
        locked = f.read()
        locked_list = locked.split(',')
        return locked_list


def write_locked(locked_list):
    '''
    将内存写至锁定用户文件
    :return:
    '''
    str = ''
    with open('user_locked.txt', mode='w', encoding='utf-8') as f_lock:
        for i in locked_list:
            str = str + i + ','
        f_lock.write(str)


def user_login(info_dict, locked_list):
    '''
    用户操作
    :param info_dict:
    :param locked_list:
    :return: username
    '''
    count = 0
    while True:
        username = input('请输入用户名(或者输入q退出):\n>>>').strip()
        if username.lower() == 'q':
            return ('6 , ')
        password = input('请输入密码:\n>>>').strip()
        if username in locked_list:
            print('对不起,您输入的用户名已经被冻结,请联系管理员!')
            continue
        for k, v in info_dict.items():
            if k == username and v[0] == password:
                welcome_str = '''
            欢迎来到ATM自动取款机
-----------------------------------------------
1、存款
2、取款
3、转账
4、显示账单
5、修改密码
6、退出
                '''
                print(welcome_str)
                return username
            else:
                continue
        count += 1
        if count > 3:
            if username in info_dict.keys():
                locked_list.append(username)
                print('对不起,您登陆失败的次数过多,该用户已经被冻结!')
                continue
        else:
            print('对不起,您输入的用户名或密码有误,请重新输入!')
            continue


def user_operation(username):
    '''
    用户选择操作
    :param username:
    :return:(choice_num + ',' + username)
    '''
    while True:
        welcome_str = '''
            欢迎来到ATM自动取款机
-----------------------------------------------
1、存款
2、取款
3、转账
4、显示账单
5、修改密码
6、退出
                '''
        print(welcome_str)
        choice_num = input('\n请输入操作编号1-6:\n>>>').strip()
        if choice_num.isdigit() and 0 < int(choice_num) < 7:
            return (choice_num + ',' + username)
        else:
            print('对不起,您输入的操作编号有误,请重新输入!')
            continue


def is_debt(info_dict, bill_list, username):
    '''
    检查用户是否有欠款
    :param info_dict:
    :param bill_list:
    :param username:
    :return:
    '''
    if (int(str(datetime.date.today()).split('-')[2]) == 1) and (int(info_dict[username][3]) > 0):
        if (int(info_dict[username][1]) - int(info_dict[username][3])) >= 0:
            debt_num = info_dict[username][3]
            info_dict[username][1] = str(int(info_dict[username][1]) - int(info_dict[username][3]))
            info_dict[username][3] = '0'
            bill_list.append(str(datetime.date.today()))
            bill_list.append('0')
            bill_list.append(debt_num)
            bill_list.append(info_dict[username][1])
            print('您好,今天的日期是' + str(datetime.date.today()) + ',今日为还款日,系统已经自动为您还款!' +
                  '目前您的余额为:' + info_dict[username][1])
        else:
            print('您好,今天的日期是' + str(datetime.date.today()) +
                  ',今日为还款日,您的余额不足以还清欠款!请及时存款还款!\n目前您的余额为:' + info_dict[username][1])
    elif (int(str(datetime.date.today()).split('-')[2]) < 15) and (int(info_dict[username][3]) > 0):
        print('您好,今天的日期是' + str(datetime.date.today()) + '\n您目前欠款金额为:' + info_dict[username][3] +
              ',\n请在本月15日前还清欠款,否则系统将自动还款!')


def admin_login():
    '''
    管理员操作:默认管理员用户名:admin,密码:admin123
    :return:
    '''
    while True:
        username = input('请输入管理员用户名,默认admin,(或者输入q退出):\n>>>').strip()
        if username.lower() == 'q':
            break
        password = input('请输入管理员密码,默认admin123:\n>>>').strip()
        if username == 'admin' and password == 'admin123':
            break
            # while True:
            #     choice_num = input('\n请输入操作编号1-4:\n>>>').strip()
            #     if choice_num.isdigit() and 0 < int(choice_num) < 5:
            #         return choice_num
            #     else:
            #         print('对不起,您输入的操作编号有误,请重新输入!')
            #         continue
        else:
            continue


def admin_operation():
    '''
    管理员操作
    :return:
    '''
    while True:
        welcome_str = '''
    欢迎来到ATM自动取款机-管理员功能区
-----------------------------------------------
1、添加用户
2、冻结用户
3、设定用户额度
4、退出
            '''
        print(welcome_str)
        choice_num = input('\n请输入操作编号1-4:\n>>>').strip()
        if choice_num.isdigit() and 0 < int(choice_num) < 5:
            return choice_num
        else:
            print('对不起,您输入的操作编号有误,请重新输入!')
            continue


def deposit_money(info_dict, bill_list, username):
    '''
    存款
    :param info_dict:
    :return:
    '''
    while True:
        deposit_num = input('请输入存款金额(或者输入q退出):\n>>>').strip()
        if deposit_num.isdigit():
            print('当前余额为:' + info_dict[username][1] + '\n存入后余额为:' + str(int(info_dict[username][1]) + int(deposit_num)))
            is_sure = input('是否确认存款(y/n)?\n>>>').strip()
            if is_sure.lower() == 'y':
                info_dict[username][1] = str(int(info_dict[username][1]) + int(deposit_num))
                bill_list.append(str(datetime.date.today()))
                bill_list.append(deposit_num)
                bill_list.append('0')
                bill_list.append(info_dict[username][1])
            elif is_sure.lower() == 'n':
                break
            else:
                print('输入有误,请重新确认!')
                continue
        elif deposit_num.lower() == 'q':
            break
        else:
            print('存款金额输入有误,请重新输入!')
            continue


def draw_money(info_dict, bill_list, username):
    '''
    取款
    :return:
    '''
    while True:
        draw_num = input('请输入取款金额(或者输入q退出):\n>>>').strip()
        if draw_num.isdigit() and ((int(info_dict[username][1]) + int(info_dict[username][2]) - int(draw_num)) >= 0):
            print('当前余额为:' + info_dict[username][1] + '\n取款后后余额为:' + str(int(info_dict[username][1]) - int(draw_num)))
            is_sure = input('是否确认取款(y/n)?\n>>>').strip()
            if is_sure.lower() == 'y':
                if (int(info_dict[username][1]) < int(draw_num) < (
                            int(info_dict[username][1]) + int(info_dict[username][3]))):
                    info_dict[username][1] = '0'
                    info_dict[username][3] = str(int(draw_num) - int(info_dict[username][1]))
                    bill_list.append(str(datetime.date.today()))
                    bill_list.append('0')
                    bill_list.append(draw_num)
                    bill_list.append('0')
                elif (int(info_dict[username][1]) >= int(draw_num)):
                    info_dict[username][1] = str(int(info_dict[username][1]) - int(draw_num))
                    bill_list.append(str(datetime.date.today()))
                    bill_list.append('0')
                    bill_list.append(draw_num)
                    bill_list.append(str(int(info_dict[username][1])))
            elif is_sure.lower() == 'n':
                break
            else:
                print('输入有误,请重新确认!\n')
                continue
        elif draw_num.lower() == 'q':
            break
        elif draw_num.isdigit() and ((int(info_dict[username][1]) + int(int(info_dict[username][2]) - int(draw_num))) < 0):
            print('对不起,取款金额大于当前余额与最大额度之和,请重新输入!\n用户:' + username +
                  ' 当前余额为:' + info_dict[username][1] + '\n')
            continue
        else:
            print('取款金额输入有误,请重新输入!\n')
            continue


def trans_money(info_dict, bill_list, username):
    '''
    转账
    :param info_dict:
    :param bill_list:
    :param username:
    :return:
    '''
    while True:
        for index, i in enumerate(info_dict.keys()):
            if not i == username:
                if (index + 1) % 5 == 0:
                    print(str(i) + '\n', end='')
                else:
                    print(str(i) + '、', end='')
        trans_choice = input('\n请输入向哪位用户转账(或者输入q退出):\n>>>').strip()
        if trans_choice in info_dict.keys():
            trans_num = input('请输入转账金额:\n>>>').strip()
            if (trans_num.isdigit()) and (int(trans_num) <= int(info_dict[username][2])):
                is_sure = input('是否确定向用户 ' + trans_choice + ' 转账:' + trans_num + ' ? (y/n)\n>>>')
                if is_sure.lower() == 'y':
                    info_dict[trans_choice][1] = str(int(info_dict[trans_choice][1]) + int(trans_num))
                    info_dict[username][1] = str(int(info_dict[username][1]) - int(trans_num))
                    bill_list.append(str(datetime.date.today()))
                    bill_list.append('0')
                    bill_list.append(trans_num)
                    bill_list.append(str(int(info_dict[username][1])))
                    trans_name = trans_choice + '_bill.txt'
                    with open(trans_name, mode='w', encoding='utf-8') as f:
                        f.write(str(datetime.date.today()) + ',' + trans_num + ',' + '0' + ',' + str(
                            info_dict[trans_choice][1]) + ',')
                    print('转账成功!')
                elif is_sure.lower() == 'n':
                    continue
                else:
                    print('输入有误,请重新输入!\n')
                    continue
            else:
                print('对不起,您输入的金额有误或超出现有余额,请重新输入!\n')
                continue
        elif trans_choice.lower() == 'q':
            break
        else:
            print('对不起,你输入的用户名有误,请重新输入!\n')
            continue


def show_bill(username):
    '''
    显示账单
    :return:
    '''
    while True:
        choice_bill = input('\n请输入查询的账单年月,如2017-05(或者输入q退出):\n>>>').strip()
        if re.match(r"^[0-9]{6}", choice_bill.replace('-', '')):
            print(choice_bill.rjust(15, '-') + ' ' + '用户:' + username + ' 账单明细'.ljust(15, '-'))
            print('交易日期 | 存款金额 | 取款金额 | 余额')
            bill_name = username + '_bill.txt'
            with open(bill_name, mode='r', encoding='utf-8') as f:
                for line in f:
                    if line.startswith(choice_bill):
                        print(line.replace(',', '     '), end="")
        elif choice_bill.lower() == 'q':
            break
        else:
            print('对不起,您输入的查询账单年月有误,请重新输入!')
            continue


def change_pwd(info_dict, username):
    '''
    修改用户密码
    :return:
    '''
    flag = False
    while True:
        for k, v in info_dict.items():
            if k == username:
                old_pwd = input('请输入用户 ' + username + '原密码:\n>>>').strip()
                if old_pwd == v[0]:
                    new_pwd = input('请输入新密码:\n>>>').strip()
                    v[0] = new_pwd
                    print('密码修改成功!')
                    flag = True
                    break
                else:
                    print('对不起,您输入的原密码不正确,请重新输入!')
                    break
            else:
                continue
        if flag:
            break


def add_user(info_dict):
    '''
    添加用户
    :return:
    '''
    new_list = []
    while True:
        new_user = input('请输入想要添加的用户名(或者输入q退出):\n>>>').strip()
        if new_user.lower() == 'q':
            break
        if new_user in info_dict.keys():
            print('对不起,此用户名已经存在!请重新输入!')
            continue
        else:
            new_pwd = input('请设置用户 ' + new_user + '密码:\n>>>').strip()
            new_list.append(new_pwd)
            new_list.append('0')
            new_list.append('10000')
            new_list.append('0')
            info_dict[new_user] = new_list.copy()
            print('用户 ' + new_user + '添加成功!默认用户额度为10000!')


def freeze_user(info_dict, locked_list):
    '''
    冻结用户
    :param info_dict:
    :param locked_list:
    :return:
    '''
    while True:
        print('当前存在的用户如下:')
        for index, i in enumerate(info_dict.keys()):
            if (index + 1) % 5 == 0:
                print(str(i) + '\n', end='')
            else:
                print(str(i) + '、', end='')
        user_lock = input('\n请输入要冻结的用户名(或者输入q退出):\n>>>').strip()
        if user_lock in info_dict.keys():
            is_sure = input('确认要冻结用户 ' + user_lock + ' ? (y/n)').strip()
            if is_sure.lower() == 'y':
                locked_list.append(user_lock)
                print('冻结用户 ' + user_lock + ' 成功!\n')
            elif is_sure.lower() == 'n':
                break
            else:
                print('您的输入有误,请重新输入!')
                continue
        elif user_lock.lower() == 'q':
            break
        else:
            print('对不起,您输入的用户名不存在,请重新输入!')
            continue


def set_limit(info_dict):
    '''
    指定用户额度
    :return:
    '''
    flag = False
    while True:
        print('当前存在的用户如下:')
        for index, i in enumerate(info_dict.keys()):
            if (index + 1) % 5 == 0:
                print(str(i) + '\n', end='')
            else:
                print(str(i) + '、', end='')
        choice_user = input('\n请输入想要修改密码的用户名(或者输入q退出):\n>>>').strip()
        if choice_user.lower() == 'q':
            break
        for k, v in info_dict.items():
            if k == choice_user:
                old_pwd = input('请输入用户 ' + choice_user + '密码:\n>>>').strip()
                if old_pwd == v[0]:
                    new_limit = input('请输入用户新额度:\n>>>').strip()
                    v[2] = new_limit
                    print('用户额度修改成功!')
                    flag = True
                    break
                else:
                    print('对不起,您输入的原密码不正确,请重新输入!')
                    break
            else:
                continue
        if flag:
            break


if __name__ == '__main__':
    while True:
        GLOBAL_VAR['user_info'] = read_info('user_info.txt')
        GLOBAL_VAR['user_locked'] = read_locked('user_locked.txt')
        login_choice = login()
        if login_choice.strip() == '1':
            login_user = user_login(GLOBAL_VAR['user_info'], GLOBAL_VAR['user_locked'])
            while True:
                opera_return = user_operation(login_user)
                write_locked(GLOBAL_VAR['user_locked'])
                write_info(GLOBAL_VAR['user_info'], 'user_info.txt')
                GLOBAL_VAR['opera_num'] = opera_return.split(',')[0]
                GLOBAL_VAR['user_name'] = opera_return.split(',')[1]
                try:
                    GLOBAL_VAR['user_bill'] = read_ubill(GLOBAL_VAR['user_name'])
                except:
                    with open((GLOBAL_VAR['user_name'] + '_bill.txt'), mode='w', encoding='utf-8') as f:
                        f.write('')
                if GLOBAL_VAR['opera_num'].strip() == '1':
                    deposit_money(GLOBAL_VAR['user_info'], GLOBAL_VAR['user_bill'], GLOBAL_VAR['user_name'])
                    write_info(GLOBAL_VAR['user_info'], 'user_info.txt')
                    write_ubill(GLOBAL_VAR['user_bill'], GLOBAL_VAR['user_name'])
                    write_locked(GLOBAL_VAR['user_locked'])
                elif GLOBAL_VAR['opera_num'].strip() == '2':
                    is_debt(GLOBAL_VAR['user_info'], GLOBAL_VAR['user_bill'], GLOBAL_VAR['user_name'])
                    draw_money(GLOBAL_VAR['user_info'], GLOBAL_VAR['user_bill'], GLOBAL_VAR['user_name'])
                    write_info(GLOBAL_VAR['user_info'], 'user_info.txt')
                    write_ubill(GLOBAL_VAR['user_bill'], GLOBAL_VAR['user_name'])
                elif GLOBAL_VAR['opera_num'].strip() == '3':
                    trans_money(GLOBAL_VAR['user_info'], GLOBAL_VAR['user_bill'], GLOBAL_VAR['user_name'])
                    write_info(GLOBAL_VAR['user_info'], 'user_info.txt')
                    write_ubill(GLOBAL_VAR['user_bill'], GLOBAL_VAR['user_name'])
                    write_locked(GLOBAL_VAR['user_locked'])
                elif GLOBAL_VAR['opera_num'].strip() == '4':
                    show_bill(GLOBAL_VAR['user_name'])
                elif GLOBAL_VAR['opera_num'].strip() == '5':
                    change_pwd(GLOBAL_VAR['user_info'], GLOBAL_VAR['user_name'])
                    write_info(GLOBAL_VAR['user_info'], 'user_info.txt')
                elif GLOBAL_VAR['opera_num'].strip() == '6':
                    print('欢迎您下次光临ATM自动取款机!再见!')
                    break
        elif login_choice.strip() == '2':
            admin_login()
            while True:
                admin_choice = admin_operation()
                if admin_choice.strip() == '1':
                    add_user(GLOBAL_VAR['user_info'])
                    write_info(GLOBAL_VAR['user_info'], 'user_info.txt')
                elif admin_choice.strip() == '2':
                    freeze_user(GLOBAL_VAR['user_info'], GLOBAL_VAR['user_locked'])
                    write_locked(GLOBAL_VAR['user_locked'])
                elif admin_choice.strip() == '3':
                    set_limit(GLOBAL_VAR['user_info'])
                    write_info(GLOBAL_VAR['user_info'], 'user_info.txt')
                elif admin_choice.strip() == '4':
                    print('管理程序退出!谢谢光临!')
                    break
        elif login_choice.strip() == '3':
            print('欢迎您下次光临ATM自动取款机!再见!')
            exit()
        else:
            print('您的输入有误,请重新输入!')
            continue
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值