码迷,mamicode.com
首页 > 编程语言 > 详细

python实例_模拟ATM取款机+购物商城

时间:2018-03-21 14:00:00      阅读:410      评论:0      收藏:0      [点我收藏+]

标签:end   ber   主程序   count   style   form   图片   enumerate   logging   

一,作者介绍

吴海东:My Blog:http://www.cnblogs.com/whd-67270

 

二,程序说明

1.ATM取款机提现、还款、转账功能

2.冻结账户、创建新账户功能

3.商品购物功能

4.退出

 

三,程序前准备

● account.txt:创建该文件用于存放信用卡账户信息

技术分享图片

● savings.txt:创建该文件用于存放储蓄卡信息

技术分享图片

 

● frozen.txt:创建该文件存放冻结账户信息,此文件初始化可为空

● goods:创建该文件存放购物的商品

技术分享图片

 

● shopping_cart:创建该文件存放已购买的商品,此文件初始化可为空

● trade_log:创建该文件用于存放日志信息,此文件初始化可为空

 

四,程序脚本

main.py:脚本主程序入口

#-*-UTF-8-*-
import os
from core import bank
from core import login
from shopping_mail import shopping
import logging
from logging.handlers import RotatingFileHandler
# 获取日志文件的绝对路径
BASE_DIR = (os.path.dirname(os.path.abspath(__file__)))

# 设置日志格式


def log_format():
    """
    设置日志格式
    :return:
    """
    file_name = (BASE_DIR + "\\trade_log")
    login.file_exist_check(file_name)
    logging.basicConfig(
        filename=file_name,
        level=logging.INFO,
        format=[%(asctime)s] [%(filename)s:%(lineno)d] %(levelname)s %(message)s,
        datefmt=%Y-%m-%d %H:%M:%S %p)


def main():
    log_format()  # 调用日志
    # 显示登录首页服务平台选项
    while True:
        print(1.信用卡\n2.商城\n3.退出)
        fm_server = input("请选择你的服务编号:")
        if fm_server.isdigit():
            fm_server = int(fm_server)
            # 判断选项编号是否符合条件
            if fm_server <= 3 and fm_server >= 0:
                if fm_server == 1:
                    bank.credit_platform()   # 进入信用卡服务平台
                elif fm_server == 2:
                    username = bank.verify_password()   # 用户登录账户密码验证
                    username = username[0]
                    shopping.shopping_service(username)   # 进入购物商城
            else:
                print("\033[1;31m请输入规范的服务编号!\033[0m")
                continue
        else:
            print("\033[1;31m错误的服务编号!\033[0m")
            continue


if __name__ == __main__:
    main()

 

login.py:用户登录账户密码验证

#-*-UTF-8-*-
import os
import sys
import logging
# 获取账户文件绝对路径
BASE_DIR = (os.path.dirname(os.path.abspath(__file__)))


def configure_file(file_name, action):
    """
    定义一个方法读取文件
    :param file_name: 账户文件
    :param action: 读操作
    :return:返回读取账户文件结果
    """
    with open(file_name, action, encoding=utf-8)as f:
        file_line = f.readlines()
        return file_line


def file_exist_check(file_name):
    """
    检查文件是否存在
    :param file_name:账户文件
    """
    if not os.path.exists(file_name):
        print("Error: file %s is not exist!!!" % file_name)
        exit(2)

# 创建新用户


def create_account():
    """
    创建一个新的账户
    :return: 返回创建账户的结果
    """
    file_name = (BASE_DIR + "\\account.txt")   # 获取账户文件
    file_exist_check(file_name)   # 调用文件检查是否存在
    while True:
        loginSucces = False   # 定义loginSucces为False
        # 调用读取文件方法
        file_line = configure_file(file_name, r)
        new_user = input("请创建账户名:")   # 获取用户输入的账户名
        if new_user.isalpha():
            for line in file_line:
                line = eval(line)
                user = line["account"][0]
                # 判断输入的账户名是否在账户文件中
                if new_user in user:
                    print("此用户名已存在!")
                    break
                # 如果不存在就跳过
                elif new_user not in user:
                    pass
            else:
                new_passwd = input("请创建账户密码:")   # 获取用户输入的账户密码
                # 把新创建的账户写入账户文件,并指定信用卡金额数
                with open(file_name, a+, encoding="utf-8")as f:
                    f.write(
                        "{‘account‘:[\‘%s\‘,\‘%s\‘],‘credit_money‘:\‘%s\‘}\n" %
                        (str(new_user), str(new_passwd), 500000))
                    loginSucces = True   # 把loginSucces改为True
                    if loginSucces:
                        print("\033[1;32m账户创建成功\n请重新登录账号\033[0m")
                    return loginSucces
                    break
# 判断账户密码


def auth_name(func):
    """
    定义一个装饰器
    :param func: 装饰verify_password函数
    :return: 返回账户密码验证的结果
    """
    def wrapper_name():
        """
        验证登录的账户密码
        :return:
        """
        while True:
            loginSucces = False  # 定义loginSucces为False
            file_name = (BASE_DIR + "\\account.txt")  # 获取账户文件
            file_exist_check(file_name)   # 检查账户文件
            file_line = configure_file(file_name, r)  # 读取账户文件
            username = input(请输入账户名:).strip()   # 获取输入的账户名
            if username.isalpha():   # 判断输入的账户名是否是字符串
                for line_username in file_line:
                    line_username = eval(line_username)  # 转换成字典
                    # 判断输入的账户名是否在字典里
                    if username in line_username[account][0]:
                        file_name = (BASE_DIR + "\\frozen.txt")   # 获取冻结账户文件
                        file_exist_check(file_name)  # 检查文件是否存在
                        file_line = configure_file(file_name, r)  # 读取文件
                        if len(file_line) != 0:   # 判断文件是否为空
                            # 如果不为空,检查输入的文件名是否在冻结文件里
                            for line_locking in file_line:
                                line_locking = eval(line_locking)
                                if username in line_locking[frozen_username]:
                                    print("\033[1;31m该用户已被冻结!\033[0m")
                                    logging.info(
                                        "username:%s Frozen account" % username)
                                    # 如果不在冻结文件里就提示输入密码
                                elif username not in line_locking[frozen_username]:
                                    password = input(请输入账户密码:).strip()
                                    # 如果密码跟账户文件里的不一致,提示密码错误信息,并要求重新输入账户密码
                                    if password != line_username[account][1]:
                                        print(
                                            "\033[1;31mPassword error!\033[0m")
                                        logging.info(
                                            username:%s Password error! % username)
                                        continue
                                    # 如果密码一致,输出欢迎信息
                                    elif password == line_username[account][1]:
                                        print(
                                            "\033[1;32mhonorific:%s Welcome to use credit card service\033[0m" %
                                            username)
                                        logging.info(
                                            username:%s login Success! % username)
                                        loginSucces = True
                                        if loginSucces:
                                            return username, loginSucces
                        # 如果文件是空的,提示输入密码
                        elif len(file_line) == 0:
                            password = input(请输入账户密码:).strip()
                            # 如果密码跟账户文件里的不一致,提示密码错误信息,并要求重新输入账户密码
                            if password != line_username[account][1]:
                                print("\033[1;31mPassword error!\033[0m")
                                logging.info(
                                    username:%s Password error! % username)
                                continue
                            # 如果密码一致,输出欢迎信息
                            elif password == line_username[account][1]:
                                print(
                                    "\033[1;32mhonorific:%s Welcome to use credit card service\033[0m" %
                                    username)
                                logging.info(
                                    username:%s login Success! % username)
                                loginSucces = True
                                if loginSucces:
                                    return username, loginSucces
                    else:
                        continue   # 递归检查
                else:
                    print("\033[1;31m请输入正确的用户名和密码!\033[0m")
                    continue
            else:
                print("\033[1;31m请输入规范的用户名和密码!\033[0m")
                continue
    return wrapper_name

 

bank.py:信用卡服务主入口

#-*-UTF-8-*-
import os
import sys
import re
import logging
BASE_DIR = (os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)   # 添加core目录的绝对路径
# 获取ATM目录的绝对路径
BASE_DIRR_REMOTE = (
    os.path.dirname(
        os.path.dirname(
            os.path.abspath(__file__))))

from login import auth_name
from core import login


@auth_name
def verify_password():   # 定义装饰账户密码验证的函数
    return ok


def credit_platform():
    """
    信用卡登录界面选项
    """
    while True:
        print(1.登录\n2.注册\n3.退出)
        bk_server = input("请选择你的服务编号:")
        if bk_server.isdigit():
            bk_server = int(bk_server)
            if bk_server <= 3 and bk_server >= 0:
                if bk_server == 1:
                    # 调用装饰账户密码验证的函数
                    username, loginSucces = verify_password()
                    # 判断如果loginSucces的返回结果为Ture,进入信用卡服务平台
                    if str(loginSucces) == True:
                        user_menu(username)
                elif bk_server == 2:
                    # 调用创建新账户功能,并判断是否创建成功
                    loginSucces = login.create_account()
                    # 判断如果loginSucces的返回结果为Ture,返回信用卡登录界面
                    if str(loginSucces) == True:
                        continue
                # 退出信用卡登录界面
                elif bk_server == 3:
                    break
            else:
                print("请输入规范的服务编号!")
                continue
        else:
            print("错误的服务编号!")
            continue


def user_menu(username):
    """
    信用卡用户服务选项
    :param username:登录的信用卡账户名
    """
    while True:
        print(1.提现\n2.还款\n3.转账\n4.查看额度\n5.冻结账户\n6.退出账户)
        bk_server = input("请选择你的服务编号:")
        if bk_server.isdigit():
            bk_server = int(bk_server)
            if bk_server <= 6 and bk_server >= 0:
                if bk_server == 1:
                    creditcard(username)  # 调用提取现金
                elif bk_server == 2:
                    repayment_Savingsdeposit(username)  # 调用信用卡还款
                elif bk_server == 3:
                    # 调用信用卡转账
                    account_name_a, transfer_money = judge_account(username)
                    transfer_accounts(account_name_a, transfer_money)
                elif bk_server == 4:
                    query_money(username)   # 调用查询金额
                elif bk_server == 5:
                    loginSucces = Frozen_account(username)  # 调用冻结账户
                    if str(loginSucces) == True:
                        credit_platform()
                    elif loginSucces == False:
                        pass
                elif bk_server == 6:
                    break  # 退出信用卡服务平台


def credit_card_field(username, file_name, money_key, line):
    """
    定义一个方法处理信用卡的金额变动
    :param username: 信用卡账户名
    :param file_name: 账户文件
    :param money_key: 金额字段
    :param line: 读取账户文件
    :return: 返回两个金额数
    """
    total_old = line[money_key]
    total_new = line[money_key]
    total_new = re.match("^\d\d*", total_new)
    total_new = total_new.group()
    total_new = int(total_new)
    return total_old, total_new, line


def creditcard(username):
    """
    服务类型:提取现金
    扣取信用卡金额
    :param username: 信用卡账户名
    """
    # 获取账户文件
    file_name = (BASE_DIRR_REMOTE + r"\core\account.txt")
    # 检查账户文件是否存在
    login.file_exist_check(file_name)
    # 调用读取账户文件
    file_line = login.configure_file(file_name, r)
    while True:
        with open(file_name, w, encoding="utf-8")as f:
            for line in file_line:
                line = eval(line)  # 将每条账户信息转成字典
                user = line["account"][0]  # 获取账户名
                # 如果账户名在这条字典里,就提示输入金额数
                if username in user:
                    # 调用信用卡字段处理方法获取两个金额数
                    total_old, total_new, line = credit_card_field(
                        username, file_name, "credit_money", line)
                    draw_money = input("请输入提取的金额数:").strip()
                    if draw_money.isdigit():
                        draw_money = int(draw_money)
                        # 如果输入的金额数小于等于总金额数,就扣取金额
                        if draw_money <= total_new:
                            total_new -= draw_money  # 减去金额
                            total_new *= 0.5   # 减去%5手续费金额
                            # 把新的金额数跟之前的金额数做替换并写入账户文件
                            line_update = str(line).replace(
                                str(total_old), str(total_new))
                            f.write("%s\n" % line_update)
                            # 调用日志文件记录扣取的金额数
                            logging.info(
                                "username:%s,business:Withdrawals,credit card---Amount of deducted amount:%s" %
                                (str(username), str(draw_money)))
                            # 调用现金储蓄文件,把扣取的金额数加入到文件中
                            savingsdeposit_card(username, draw_money)
                            continue   # 递归查询账户文件
                    else:
                        print("取款数额超出信用卡金额范围!")
                        break
                # 如果这个账户名不在这条字典里,直接写入原文件
                else:
                    line = str(line)
                    f.write("%s\n" % line)
            else:
                break


def savingsdeposit_card(username, draw_money):
    """
    服务类型:提取现金
    存入金额到现金储蓄文件
    :param username: 账户名
    :param draw_money: 信用卡扣取的金额数
    """
    # 获取储蓄文件
    file_name = (BASE_DIRR_REMOTE + r"\core\savings.txt")
    # 检查文件是否存在
    login.file_exist_check(file_name)
    # 读取储蓄文件
    file_line = login.configure_file(file_name, r)
    with open(file_name, w, encoding=utf-8)as f:
        for line in file_line:
            line = eval(line)   # 将每条账户信息转成字典
            user = line["cash_money"][0]  # 获取账户名
            # 如果账户名在这条字典里,就加上金额数并替换之前的金额数写入储蓄文件
            if username in user:
                line_old = line["cash_money"][1]
                line_new = line["cash_money"][1]
                line_new = int(line_new)
                line_new += draw_money
                line_update = str(line).replace(str(line_old), str(line_new))
                f.write("%s\n" % line_update)
                print("\033[1;32m----提现成功----\033[0m")
                # 调用日志文件记录存入的金额数
                logging.info(
                    "username:%s,business:Withdrawals,Memory card---Amount of deposit:%s" %
                    (str(username), str(draw_money)))
            # 如果账户名不在这条字典里,直接写入原文件
            else:
                line = str(line)
                f.write("%s\n" % line)


def repayment_Savingsdeposit(username):
    """
    服务类型:信用卡还款
    扣取储蓄文件金额
    :param username: 账户名
    """
    # 获取储蓄文件
    file_name = (BASE_DIRR_REMOTE + r"\core\savings.txt")
    # 检查文件是否存在
    login.file_exist_check(file_name)
    # 读取储蓄文件
    file_line = login.configure_file(file_name, r)
    while True:
        with open(file_name, w, encoding=utf-8)as f:
            for line in file_line:
                line = eval(line)  # 将每条账户信息转成字典
                user = line["cash_money"][0]  # 获取账户名
                # 如果账户名在这条字典里,提示输入金额数
                if username in user:
                    line_old = line["cash_money"][1]
                    line_new = line["cash_money"][1]
                    repay_money = input("请输入还款的金额数:").strip()
                    if repay_money.isdigit():
                        repay_money = int(repay_money)
                        line_new = int(line_new)
                        # 如果输入的金额数小于等于总金额数,就扣取金额并替换原来的金额数并写入储蓄文件
                        if repay_money <= line_new:
                            line_new -= repay_money
                            line_update = str(line).replace(
                                str(line_old), str(line_new))
                            f.write("%s\n" % line_update)
                            # 调用日志文件记录扣取的金额数
                            logging.info(
                                "username:%s,business:repayment,Memory card---Amount of deducted amount:%s" %
                                (str(username), str(repay_money)))
                            # 调用信用卡账户文件,把扣取的金额数加入到文件中
                            repayment_creditcard(username, repay_money)
                        else:
                            print("取款数额超出信用卡金额范围!")
                            break
                    else:
                        print("请输入规范的金额数!")
                        break
                # 如果账户名不在这条字典里,直接写入原文件
                else:
                    line = str(line)
                    f.write("%s\n" % line)
                    continue  # 递归查询储蓄文件
            else:
                break


def repayment_creditcard(username, repay_money):
    """
    服务类型:信用卡还款
    存入金额到信用卡账户文件
    :param username: 账户名
    :param repay_money: 储蓄文件扣取的金额数
    """
    # 获取账户文件
    file_name = (BASE_DIRR_REMOTE + r"\core\account.txt")
    # 检查文件是否存在
    login.file_exist_check(file_name)
    # 读取账户文件
    file_line = login.configure_file(file_name, r)
    with open(file_name, w, encoding=utf-8)as f:
        for line in file_line:
            line = eval(line)  # 将每条账户信息转成字典
            user = line["account"][0]  # 获取账户名
            # 如果账户名在这条字典里,就调用信用卡字段处理方法获取两个金额数
            if username in user:
                total_old, total_new, line = credit_card_field(
                    username, file_name, "credit_money", line)
                total_new += repay_money  # 加上金额数到信用卡账户文件
                # 把新的金额数跟之前的金额数做替换,并写入信用卡账户文件
                line_update = str(line).replace(str(total_old), str(total_new))
                f.write("%s\n" % line_update)
                print("\033[1;32m----还款成功----\033[0m")
                # 调用日志文件记录存入的金额数
                logging.info(
                    "username:%s,business:repayment,credit card---Amount of deposit:%s" %
                    (str(username), str(repay_money)))
            else:
                # 如果账户名不在这条字典里,直接写入原文件
                line = str(line)
                f.write("%s\n" % line)


def judge_account(username):
    """
    服务类型:信用卡转账
    信用卡账户转账服务
    :param username: 账户名
    :return 返回输入的账户名和扣取的金额数
    """
    # 获取信用卡账户文件
    file_name = (BASE_DIRR_REMOTE + r"\core\account.txt")
    # 检查文件是否存在
    login.file_exist_check(file_name)
    # 读取信用卡账户文件
    file_line = login.configure_file(file_name, r)
    while True:
        # 获取输入的两次账户名
        account_name_a = input("请输入转账的用户名:").strip()
        account_name_b = input("请再次输入转账的用户名:").strip()
        # 判断账户名是否是字符串类型
        if account_name_a.isalpha() and account_name_b.isalpha():
            # 如果两次输入的账户名不一致打印错误信息,并要求重新输入
            if account_name_a != account_name_b:
                print("两次用户名不一致!")
                continue
            # 如果两次输入的账户名都等于当前登录的账户名,就提示错误信息,并要求重新输入
            elif account_name_a == username and account_name_b == username:
                print("不可以给自己转账!")
                continue
            else:
                with open(file_name, r+, encoding=utf-8)as f:
                    # 将每条账户信息转成字典
                    for line_transfer_money in file_line:
                        line_transfer_money = eval(line_transfer_money)
                        # 获取每条字典的账户名
                        user = line_transfer_money["account"][0]
                        # 如果账户名在这条字典里就截取这条账户信息的金额数
                        if username in user:
                            total_old = line_transfer_money["credit_money"]
                            total_new = line_transfer_money["credit_money"]
                            # 获取输入的转账金额数
                            transfer_money = input("请输入转账的金额:").strip()
                            # 判断是否是整数类型
                            if transfer_money.isdigit():
                                transfer_money = int(transfer_money)
                                total_new = int(total_new)
                                # 如果输入的金额数小于等于总金额数,就扣取金额并替换原来的金额数并写入账户文件
                                if transfer_money <= total_new:
                                    total_new -= transfer_money
                                    line_update = str(line_transfer_money).replace(
                                        str(total_old), str(total_new))
                                    f.write("%s\n" % line_update)
                                    # 调用日志文件记录扣取的金额数
                                    logging.info(
                                        "username:%s,business:Transfer accounts,credit card---Number of transfers:%s" %
                                        (str(username), str(transfer_money)))
                                    # 调用转账功能需要被转账的账户
                                    # transfer_accounts(account_name_a,transfer_money)
                                else:
                                    print("取款数额超出信用卡金额范围!")
                                    break
                            else:
                                print("请输入规范的金额数!")
                                break
                        else:
                            # 如果账户名不在这条字典里,直接写入原文件
                            line_transfer_money = str(line_transfer_money)
                            f.write("%s\n" % line_transfer_money)
                            # transfer_accounts(account_name_a, transfer_money)
                            continue
                    else:
                        return account_name_a, transfer_money


def transfer_accounts(account_name_a, transfer_money):
    """
    服务类型:信用卡转账
    :param account_name_a: 被转账的账户名
    :param transfer_money:信用卡账户扣取的金额数
    """
    # 获取账户文件
    file_name = (BASE_DIRR_REMOTE + r"\core\account.txt")
    # 检查文件是否存在
    login.file_exist_check(file_name)
    # 读取账户文件
    file_line = login.configure_file(file_name, r)
    while True:
        with open(file_name, r+, encoding=utf-8)as f:
            for line_transfer_money in file_line:
                line_transfer_money = eval(line_transfer_money)  # 将每条账户信息转成字典
                user = line_transfer_money["account"][0]  # 获取每条字典的账户名
                # 如果账户名在这条字典里就将金额数加到总金额数,并替换字典原来的金额数后写入账户文件
                if account_name_a in user:
                    line_old = line_transfer_money["credit_money"]
                    line_new = line_transfer_money["credit_money"]
                    line_new = int(line_new)
                    line_new += transfer_money
                    line_update = str(line_transfer_money).replace(
                        str(line_old), str(line_new))
                    f.write("%s\n" % line_update)
                    print("\033[1;32m----转账成功----\033[0m")
                    # 调用日志文件记录存入的金额数
                    logging.info(
                        "username:%s,business:Transfer accounts,Memory card---Amount of deposit:%s" %
                        (str(account_name_a), str(transfer_money)))
                else:
                    # 如果账户名不在这条字典里,直接写入原文件
                    line_transfer_money = str(line_transfer_money)
                    f.write("%s\n" % line_transfer_money)
            else:
                break


def query_money(username):
    """
    查询信用卡账户余额
    :param username: 账户名
    """
    # 获取账户文件
    file_name = (BASE_DIRR_REMOTE + r"\core\account.txt")
    # 检查文件是否存在
    login.file_exist_check(file_name)
    # 读取账户文件
    file_line = login.configure_file(file_name, r)
    for line in file_line:
        line = eval(line)   # # 将每条账户信息转成字典
        user = line["account"][0]  # 获取每条字典的账户名
        # 如果账户名在这条字典里,就打印这个账户的余额信息
        if username in user:
            print(%s\n用户名:%s 信用卡剩余余额:%s\n%s\n %
                  (= * 50, username, line[credit_money], = * 50))


def Frozen_account(username):
    """
    冻结账户
    :param username: 账户名
    :return 返回冻结账户是否成功状态
    """
    # 获取冻结文件
    file_name = (BASE_DIRR_REMOTE + r"\core\frozen.txt")
    # 检查文件是否存在
    login.file_exist_check(file_name)
    # 读取冻结文件
    file_line = login.configure_file(file_name, r)
    while True:
        loginSucces = False
        # 如果文件的行数不等于0,就把每条信息转成字典
        if len(file_line) != 0:
            for line_locking in file_line:
                line_locking = eval(line_locking)
                # 如果账户名在冻结文件里就输出打印信息
                if username in line_locking[frozen_username]:
                    print("该账户已处于冻结状态!")
                # 如果账户名不在冻结文件里,就输出是否冻结该用户提示
                elif username not in line_locking[frozen_username]:
                    locking = input("是否确定冻结该账户?y/n:")
                    if locking.isalpha():
                        # 如果等于y,就把该账户名追加写入冻结文件,并返回loginSucces状态
                        if locking == "y":
                            with open(file_name, a+, encoding=utf-8)as f:
                                f.write(
                                    "\n{‘frozen_username‘:‘%s‘}" %
                                    username)
                                print("\033[1;32m该账户冻结成功!\033[0m")
                                loginSucces = True
                                return loginSucces
                        # 如果等于n,直接返回loginSucces状态
                        elif locking == "n":
                            return loginSucces
                        else:
                            print("错误的选项请重新输入!")
                            continue
                    else:
                        print("输入的数据类型不符合规范,请重新输入!")
                        continue
        # 如果行数等于0,就输出是否冻结该账户提示
        if len(file_line) == 0:
            locking = input("是否确定冻结该账户?y/n:")
            if locking.isalpha():
                # 如果等于y,就把该账户名追加写入冻结文件,并返回loginSucces状态
                if locking == "y":
                    with open(file_name, w, encoding=utf-8)as f:
                        f.write("{‘frozen_username‘:‘%s‘}\n" % username)
                        print("\033[1;32m该账户冻结成功!\033[0m")
                        loginSucces = True
                        return loginSucces
                # 如果等于n,直接返回loginSucces状态
                elif locking == "n":
                    return loginSucces
                else:
                    print("\033[1;31m错误的选项请重新输入!\033[0m")
                    continue
            else:
                print("\033[1;31m输入的数据类型不符合规范,请重新输入!\033[0m")
                continue

 

 shopping.py:购物商城主入口

#-*-UTF-8-*-
import os
import sys
import time
import re
import logging

# 获取shopping_mail目录的绝对路径
BASE_DIR_LOCAL = (os.path.dirname(os.path.abspath(__file__)))
# 获取ATM目录的绝对路径
BASE_DIR = (os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from core import login
from core import bank

# 定义一个空列表
#shopping_list = []


def shopping_bar_view(username):
    """
    查看购物栏内已购买的物品信息
    :param username: 用户名
    """
    # 获取购物栏文件
    file_name = (BASE_DIR_LOCAL + r"\shopping_cart")
    # 检查文件是否存在
    login.file_exist_check(file_name)
    # 读取购物栏文件
    file_line = login.configure_file(file_name, r)
    if len(file_line) != 0:
        for line in file_line:
            line = eval(line)
            # 如果查到用户名就打印此用户的所有已购物品信息
            if username in line.keys():
                print(
                    "已购买的物品:\n%s\n%s\n" %
                    (line[username]["goods"], = * 50))


def configure_file(username, file_name, shopping_list):
    """
    新用户已购物品写入购物栏文件
    :param username: 用户名
    :param file_name: 购物栏文件名
    :param shopping_list: 购物列表
    """
    with open(file_name, w, encoding=utf-8)as f:
        f.write("{\"%s\":{\"goods\":%s}}\n" % (username, shopping_list))
    logging.info("username:%s,Already purchased:%s" %
                 (str(username), str(shopping_list)))


def already_exists_configure_file(username, file_name, shopping_list):
    """
    已存在购物栏的用户再次写入已购物品到购物栏文件
    :param username: 用户名
    :param file_name: 购物栏文件名
    :param shopping_list: 购物列表
    """
    with open(file_name, r+, encoding=utf-8)as f:
        login.file_exist_check(file_name)
        file_line = login.configure_file(file_name, r)
        for line in file_line:
            line = eval(line)
            # 如果查到用户名在这条字典里,就获取这个用户的购物列表项
            if username in line.keys():
                line_user = line[username]["goods"]
                line_old = line_user
                line_new = line_user
                # 将购物列表添加到购物栏的购物列表里
                line_new.extend(shopping_list)
                # 替换旧的购物栏购物列表并写入购物栏文件里
                line_updat = str(line).replace(str(line_old), str(line_new))
                f.write("%s\n" % line_updat)
                # 调用日志文件记录新的购物列表信息
                logging.info(
                    "username:%s,Buy again:%s" %
                    (str(username), str(shopping_list)))
            else:
                # 如果查不到用户名在这条字典里,就直接写入原文件
                line = str(line)
                f.write("%s\n" % line)


def shopping_bag(file_line):
    """
    打印出购物商品列表
    :param file_line: 购物商品文件名
    :return: 返回用户输入的商品编号跟商品名
    """
    line = [line.strip() for line in file_line]
    for index, line in enumerate(line):
        print(index, line)
    purchase = input("请选择你要的商品:")
    return purchase, file_line


def commodity_payment(username, sum, BASE_DIR):
    """
    商品结账付款
    :param username: 用户名
    :param sum: 付款金额
    :param BASE_DIR: 账户文件名
    """
    # 获取账户文件
    file_name = (BASE_DIR + r"\core\account.txt")
    # 检查文件是否存在
    login.file_exist_check(file_name)
    # 读取账户文件
    file_line = login.configure_file(file_name, r)
    with open(file_name, r+, encoding="utf-8")as f:
        for line_creditcard in file_line:
            line_creditcard = eval(line_creditcard)
            user = line_creditcard["account"][0]  # 获取账户名
            # 如果账户名在这条字典里,就获取这个用户的信用卡金额
            if username in user:
                total_old = line_creditcard["credit_money"]
                total_new = line_creditcard["credit_money"]
                total_new = re.match("^\d\d*", total_new)
                total_new = total_new.group()
                total_new = int(total_new)
                sum = int(sum)
                # 如果付款金额数小于等于信用卡金额数,就扣取付款金额并替换旧的信用卡金额数写入原文件
                if sum <= total_new:
                    total_new -= sum
                    line = str(line_creditcard).replace(
                        str(total_old), str(total_new))
                    f.write("%s\n" % line)
                    # 调用日志文件记录扣取的金额数并打印输出信息
                    logging.info(
                        "username:%s,Total deductions:%s" %
                        (str(username), str(sum)))
                    print("\033[1;32m付款成功!\033[0m")
            # 如果账户名不在这条字典里,就直接写入原文件,继续循环下一条字典
            else:
                line = str(line_creditcard)
                f.write("%s\n" % line)


def shopping_once(username):
    """
    用户第一次购买商品入口
    :param username: 用户名
    """
    shopping_list = []  # 定义一个空的购物列表
    while True:
        # 获取商品文件
        file_name = (BASE_DIR_LOCAL + r"\goods")
        # 检查文件是否存在
        login.file_exist_check(file_name)
        # 读取商品文件
        file_line = login.configure_file(file_name, r)
        # 调用打印购物商品列表函数
        purchase, goods_file = shopping_bag(file_line)
        if purchase.isdigit():
            purchase = int(purchase)
            # 如果返回的商品编号小于商品文件的总行数并且大于0
            if purchase < len(goods_file) and purchase >= 0:
                # 获取这个编号的商品并以逗号分割成列表
                commodity = goods_file[purchase]
                commodity = commodity.strip().split(,)
                # 把商品添加到空的购物列表里,并输出打印shopping_list
                shopping_list.append(commodity)
                print("Have buy goods:%s" % shopping_list)
                # 获取用户输入的选项
                Whether_payment = input("是否确定付款y或n:")
                if Whether_payment.isalpha():
                    Whether_payment = str(Whether_payment)
                    if Whether_payment == y:
                        print("正在付款中。。。。")
                        sum = 0  # 定义一个初始值便于累加金额数
                        # 循环获取购物列表的每个商品的金额数
                        for total_line in shopping_list:
                            goods_money = total_line[1]
                            goods_money = int(goods_money)
                            sum += goods_money  # 把所有商品的金额数进行累加
                        # 调用商品结账付款入口
                        commodity_payment(username, sum, BASE_DIR)
                        # 获取购物栏文件
                        file_name = (BASE_DIR_LOCAL + "\\shopping_cart")
                        # 检查文件是否存在
                        login.file_exist_check(file_name)
                        # 调用把物品写入购物栏入口
                        configure_file(username, file_name, shopping_list)
                        print("商品交易完成")
                        while True:
                            # 交易完成后,打印输出信息
                            print("继续购买:y\n查看已购买的物品:l\n退出商城:q\n")
                            # 获取用户输入的选项
                            user_option = input("请选择服务选项:")
                            if user_option.isalpha():
                                if str(user_option) == y:
                                    # 调用再次购物商品入口
                                    shopping_secondary(username)
                                elif str(user_option) == l:
                                    # 调用打印购物栏列表
                                    shopping_bar_view(username)
                                    continue
                                elif str(user_option) == q:
                                    exit("\033[1;32m欢迎下次光临!\033[0m")  # 退出购物商城
                            else:
                                print("\033[1;31m请输入规范的选项!\033[0m")
                                continue
                    # 如果是n,回到购物商品选项列表
                    elif Whether_payment == n:
                        continue
                else:
                    print("\033[1;31m请输入规范的选项!\033[0m")
                    continue


def shopping_secondary(username):
    """
    用户再次商品购物入口
    :param username:用户名
    """
    shopping_list = []  # 定义一个空的购物列表
    while True:
        # 获取商品文件
        file_name = (BASE_DIR_LOCAL + r"\goods")
        # 检查文件是否存在
        login.file_exist_check(file_name)
        # 读取商品文件
        file_line = login.configure_file(file_name, r)
        # 调用打印购物商品列表函数
        purchase, goods_file = shopping_bag(file_line)
        if purchase.isdigit():
            purchase = int(purchase)
            # 如果返回的商品编号小于商品文件的总行数并且大于0
            if purchase < len(goods_file) and purchase >= 0:
                # 获取这个编号的商品并以逗号分割成列表
                commodity = goods_file[purchase]
                commodity = commodity.strip().split(,)
                # 把商品添加到空的购物列表里,并输出打印shopping_list
                shopping_list.append(commodity)
                print("Have buy goods:%s" % shopping_list)
                # 获取用户输入的选项
                Whether_payment = input("是否确定付款y或n:")
                if Whether_payment.isalpha():
                    Whether_payment = str(Whether_payment)
                    if Whether_payment == y:
                        print("正在付款中。。。。")
                        sum = 0  # 定义一个初始值便于累加金额数
                        # 循环获取购物列表的每个商品的金额数
                        for total_line in shopping_list:
                            goods_name = total_line[0]
                            goods_money = total_line[1]
                            goods_money = int(goods_money)
                            sum += goods_money  # 把所有商品的金额数进行累加
                        # 调用商品结账付款入口
                        commodity_payment(username, sum, BASE_DIR)
                        # 获取购物栏文件
                        file_name = (BASE_DIR_LOCAL + "\\shopping_cart")
                        # 检查文件是否存在
                        login.file_exist_check(file_name)
                        # 调用把物品写入购物栏入口
                        already_exists_configure_file(
                            username, file_name, shopping_list)
                        print("商品交易完成")
                        while True:
                            # 交易完成后,打印输出信息
                            print("继续购买:y\n查看已购买的物品:l\n退出商城:q\n")
                            user_option = input("请选择服务选项:")
                            if user_option.isalpha():
                                if str(user_option) == y:
                                    continue  # 返回继续购物
                                elif str(user_option) == l:
                                    # 调用打印购物栏列表
                                    shopping_bar_view(username)
                                    continue
                                elif str(user_option) == q:
                                    exit("\033[1;32m欢迎下次光临!\033[0m")  # 退出购物商城
                            else:
                                print("\033[1;32m请输入规范的选项!\033[0m")
                                continue
                    # 如果是n,回到购物商品选项列表
                    elif Whether_payment == n:
                        continue
                else:
                    print("\033[1;31m请输入规范的选项!\033[0m")
                    continue


def shopping_service(username):
    """
    用户进入商品购物系统平台主入口
    :param username: 用户名
    """
    # 获取购物栏文件
    file_name = (BASE_DIR_LOCAL + r"\shopping_cart")
    # 检查文件是否存在
    login.file_exist_check(file_name)
    # 读取购物栏文件
    file_line = login.configure_file(file_name, r)
    # 如果文件的总行数不等于0,就把每行都转成字典
    if len(file_line) != 0:
        for line in file_line:
            line = eval(line)
            # 如果用户名在其中一条字典里,就打印输出该用户的购物历史
            if username in line.keys():
                print("购物历史:\n%s\n%s\n" % (line[username]["goods"], = * 50))
                # 调用用户再次商品购物入口进行购物
                shopping_secondary(username)
            # 如果用户名不在这条字典里,就继续检查下一条字典
            elif username not in line.keys():
                continue
            # 如果用户名都不在字典里,就调用用户第一次商品购物入口
            else:
                shopping_once(username)
    # 如果文件的总行数不等于0,就调用用户第一次商品购物入口
    else:
        shopping_once(username)

 

python实例_模拟ATM取款机+购物商城

标签:end   ber   主程序   count   style   form   图片   enumerate   logging   

原文地址:https://www.cnblogs.com/whd-672701/p/8616155.html

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