每日一题.PYTHON编写信用卡程序(支持购物,取款,查询,还款,转账) ?

具体需求:


文件结构:

|-- bankcarddatabase.db       信用卡账户相关数据库

|-- bankcardlockbase.db        信用卡账户锁定数据库

|-- CommonPyutils.py            通用公用方法

|-- CreditCardManager.py      信用卡管理(取现, 查询, 还款, 转账)

|-- main.py                              主文件

|-- productsdatabase.db         商品列表数据库


代码实现:

/xm-workspace/xm-pyss/auto_python/xmdevops_limanman/CommonPyutils.py :

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# OsChina: http://my.oschina.net/pydevops/
# Purpose:
#
"""
import cPickle


def pkl_loadordump(pkl_file, pkl_type, pkl_data=None):
    """Pickle file with load or dump.

    Args:
        pkl_file: pickle source file
        pkl_type: pickle type, default in (load, dump)
        pkl_data: pickle data, default None
    Returns:
        load -> dict
        dump -> None
    """
    if pkl_type == 'load':
        with open(pkl_file, 'r+b') as rhandler:
            try:
                return cPickle.load(rhandler)
            except EOFError as cPickle_err:
                # 文件为空,load时出错
                pass
            return {}

    if pkl_type == 'dump':
        with open(pkl_file, 'w+b') as whandler:
            cPickle.dump(pkl_data, whandler)

/xm-workspace/xm-pyss/auto_python/xmdevops_limanman/CreditCardManager.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# OsChina: http://my.oschina.net/pydevops/
# Purpose:
#
"""
import datetime


# 信用卡记录
def card_event_record(bank_database, credit_card,
                      action_strs, cash_take, cash_surplus):
    """Card event record.

    Args:
        bank_database: bank database
        credit_card  : credit card for event record
        action_strs  : action(
                       存款   deposit
                       取款   withdrawl
                       转账   transfer)
        cash_take    : cash you take
        cash_surplus : cash surplus
    Returns:
        None
    """
    cur_date = datetime.datetime.today().__str__()
    bank_database[credit_card]['all_event'].append([
       # 当前日期  目标卡号       操作类型
        cur_date, credit_card, action_strs, cash_take, cash_surplus
    ])

# 注册信用卡
def register_bankcard(bank_database, credit_card, credit_pass):
    """Register bankcard.

    Args:
        bank_database: bank database
        credit_card  : bank card number for register
        credit_pass  : bank card password for register
    Returns:
        None
    """
    if bank_database.has_key(credit_card):
        print 'notice: bank card %d has been registed.' % (credit_card)
        return False
    bank_database.update({
        credit_card: {
            'user_pass': credit_pass,
            'all_meony': 0,
            # 默认最大额度
            'cashquota': 1500,
            # 交易明细列表
            'all_event': []
        }
    })
    return True

# 登陆信用卡(账户/密码规范验证略)
def credit_card_login(bank_database, credit_card, credit_pass):
    """Credit card login.
    Args:
        bank_database: bank database
        credit_card  : bank card number for login
        credit_pass  : back card password for login
    Returns:
        None
    """
    if not bank_database.has_key(credit_card):
        print 'notice: bank card %s has not been exists.' % (credit_card)
        return False
    if credit_pass == bank_database[credit_card]['user_pass']:
        return True
    print 'notice: back card password with wrong.'
    return False

# 信用卡取现(登陆已验证,此处无需验证)
def take_card_cash(bank_database, credit_card, cash_take):
    """Take card cash.

    Args:
        bank_database: bank database
        credit_card  : bank card for take cache
        cash_take    : how money cash you want to take.
    Returns:
        bool
    """
    # 扣款
    cur_money = bank_database[credit_card]['all_meony']
    kou_money = cash_take*(1+0.01)

    surplus_money = cur_money - kou_money
    if surplus_money > 0:
        bank_database[credit_card]['all_meony'] -= kou_money
        card_event_record(bank_database, credit_card, 'withdrawl',
                          cash_take, cur_money)
        return True
    else:
        cur_quota = bank_database[credit_card]['cashquota']
        if cur_quota + surplus_money > 0:
            bank_database[credit_card]['cashquota'] += surplus_money
            card_event_record(bank_database, credit_card, 'withdrawl',
                              cash_take, cur_money)
            return True
        else:
            print 'notice: cash you take overtop limit quota.'
            return False

# 信用卡查询(登陆已验证,此处无需验证)
def query_transdetails(bank_database, credit_card):
    """Query transaction details.

    Args:
        bank_database: bank database
        credit_card  : credit card for query
    Returns:
        list
    """
    return bank_database[credit_card]['all_event']

# 信用卡还款(假设20号为还款日, 无利息)
def card_repayment(bank_database, credit_card, cash_repay):
    """Card repayment.

    Args:
        bank_database: bank database
        credit_card  : credit card for cash repayment
        cash_repay   : cash repayment
    Returns:
        bool
    """
    # 还款
    cur_money = bank_database[credit_card]['all_meony']
    cashquota = bank_database[credit_card]['cashquota']
    cur_money = cur_money + cash_repay - (1500 - cashquota)
    if cur_money >=0:
        bank_database[credit_card]['cashquota'] = 1500
        bank_database[credit_card]['all_meony'] += (cash_repay+cashquota-1500)
        card_event_record(bank_database, credit_card, 'deposit',
                          cash_repay, cur_money)
        return True
    else:
        print 'notice: less than the amount of repayment.'
        return False

# 信用卡转账(假设免手续费)
def transfer_account(bank_database, credit_card, transfer_cash):
    """Transfer money to other account.

    Args:
        bank_database: bank database
        credit_card  : credit card for transfer money
        transfer_cash: money you transfer
    Returns:
        bool
    """
    if transfer_cash % 100 != 0:
        print 'notice: transfer cash must be multiple of 100.'
        return False
    bank_database[credit_card]['all_meony'] += transfer_cash
    return True

if __name__ == '__main__':
    pass

/xm-workspace/xm-pyss/auto_python/xmdevops_limanman/main.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# OsChina: http://my.oschina.net/pydevops/
# Purpose:
#
"""
import os
import sys
import pprint
import random
import atexit
import calendar
import datetime
import linecache
import blessings
from CommonPyutils import pkl_loadordump
from CreditCardManager import (card_event_record, register_bankcard,
                               credit_card_login, take_card_cash,
                               query_transdetails, card_repayment,
                               transfer_account, )

def list_product(product_database):
    """"List shopping products.

    Args:
        product_database: product linecache.
    Returns:
        str - formated lines.
    """
    screen_width = int(TERMINAL.width) - 2
    p_index_width = p_price_width = 15
    p_name_width = screen_width - p_index_width - p_price_width
    common_format = '%-*s%-*s%*s'
    print '=' * screen_width
    print common_format % (p_index_width, 'Index', p_name_width, 'Product',
                           p_price_width, 'Price')
    print '=' * screen_width
    for cur_index, cur_item in enumerate(product_database):
        p_name = cur_item.split()[0].strip()
        p_price = cur_item.split()[-1].strip()
        print common_format % (p_index_width, cur_index,
                               p_name_width, p_name,
                               p_price_width, p_price)
    print '-' * screen_width

def calculate_summary_money(shopping_dict):
    """Calculate summary money.

    Args:
        shopping_dict: shopping list and money
    Returns:
        int
    """
    sum_money = 0
    for cur_item in shopping_dict:
        sum_money += sum(shopping_dict[cur_item])
    return sum_money

# 开始购物
def start_shopping(product_datafile, product_database, shopping_dict):
    """Start shopping.

    Args:
        product_database: product database
    Returns:
        None
    """
    while True:
        choice_error = False
        list_product(product_database)
        cur_choice = raw_input('choice number(q for settlement): ').strip()
        if cur_choice in ('q', 'quit', 'exit'):
            break
        if not cur_choice.isdigit():
            choice_error = True
        if int(cur_choice) >= len(product_database):
            choice_error = True
        if choice_error:
            print 'notice: choice number with error. input again.'
            continue
        cur_choice = int(cur_choice)
        if not shopping_dict.has_key(cur_choice):
            shopping_dict.update({
                cur_choice: []
            })
        p_price = product_database[cur_choice].split()[-1].strip()
        shopping_dict[cur_choice].append(int(p_price))
        # 更新缓冲区内容
        linecache.updatecache(product_datafile)
    # 打印购买商品列表
    pprint.pprint(shopping_dict)

# 登陆验证
def start_login(bank_database, lock_database):
    """Start login verification.

    Args:
        bank_database: bank database
        lock_database: lock database
    Returns:
        None
    """
    account_set = set()
    retry_count = 3
    while retry_count > 0:
        bank_card = raw_input('please input bank card: ')
        card_pass = raw_input('please input card pass: ')
        if lock_database.has_key(bank_card):
            sys.exit('notice: account %s has been locked.' % (bank_card))
        if credit_card_login(bank_database, bank_card, card_pass):
            print 'notice: welcome %s to login.' % (bank_card)
            break
        else:
            retry_count -= 1
            account_set.add(bank_card)
            continue
    else:
        # 同一个账户三次密码输入错误才会被锁定
        if len(account_set) == 1:
            lock_account = account_set.pop()
            if not lock_database.has_key(lock_account):
                lock_database.update({
                    lock_account: []
                })
            lock_event = '%s %s %s.' % (datetime.datetime.now(),
                                        lock_account, 'locked')
            lock_database[lock_account].append(lock_event)
            pkl_loadordump(lock_datafile, 'dump', lock_database)
            pprint.pprint(lock_database)
            sys.exit(': '.join(['notice', lock_event]))

    return bank_card, card_pass

# 购物结算
def start_settlement(shopping_dict, bank_card, card_pass):
    """Start settlement.

    Args:
        shopping_dict: shopping dict.
    Returns:
        None
    """
    settlement_ok = False
    spend_money = calculate_summary_money(shopping_dict)
    while not take_card_cash(bank_database, bank_card, spend_money):
        # 网页验证(略)
        pay_money = raw_input('input cash number: ')
        if transfer_account(bank_database, bank_card, int(pay_money)):
            settlement_ok = True

    if settlement_ok:
        shopping_dict.clear()
    print 'notice: %s cost %s money.' % (bank_card, spend_money)
    return settlement_ok

def main():
    """Main function."""
    shopping_dict = {}
    product_datafile = os.path.join(os.getcwd(), 'productsdatabase.db')
    product_database = linecache.getlines(product_datafile)

    while True:
        # 20日还款日
        cur_year = datetime.datetime.now().year
        cur_month = datetime.datetime.now().month
        lst_date = calendar.monthrange(cur_year, cur_month)

        if cur_month == '20':
            print 'notice: today is repayment. must be repay.'
            # 网页验证(略)
            repay_cash = raw_input('input repay cash num: ')
            card_repayment(bank_database, bank_card, int(repay_cash))

        # 最后打账单日
        if cur_month == lst_date:
            for cur_item in bank_database:
                print '==> %s' % (cur_item)
                if cur_item['all_event']:
                    pprint.pprint(cur_item['all_event'])

        user_choice = raw_input('''
        0. 继续购物
        1. 开始结算
        2. 打印清单

        please input choice num: ''')

        if user_choice in ('q', 'quit', 'exit'):
            break
        if user_choice not in ('0', '1', '2'):
            print 'notice: invalid choice number. input again.'
            continue
        if user_choice == '0':
            # 开始购物
            start_shopping(product_datafile, product_database, shopping_dict)
        elif user_choice == '1':
            # 登陆验证
            bank_card, card_pass = start_login(bank_database, lock_database)

            # 购物结算
            start_settlement(shopping_dict, bank_card, card_pass)
        else:
            # 打印清单
            pprint.pprint(bank_database)

    # 回调写入
    atexit.register(pkl_loadordump, bank_datafile, 'dump', bank_database)
    atexit.register(pkl_loadordump, lock_datafile, 'dump', lock_database)


if __name__ == '__main__':
    # 终端相关
    TERMINAL = blessings.Terminal()
    # 可变结构
    bank_datafile = os.path.join(os.getcwd(), 'bankcarddatabase.db')
    lock_datafile = os.path.join(os.getcwd(), 'bankcardlockbase.db')
    bank_database = pkl_loadordump(bank_datafile, 'load')
    lock_database = pkl_loadordump(lock_datafile, 'load')
    # 零时数据
    for _ in xrange(3):
        cur_card = random.randint(1111111111111111111,
                                  9999999999999999999)
        cur_card = str(cur_card)
        register_bankcard(bank_database, cur_card, cur_card)

    pprint.pprint(bank_database)
    main()


有图有像:

每日一题.PYTHON编写信用卡程序(支持购物,取款,查询,还款,转账) ?_第1张图片

你可能感兴趣的:(每日一题.PYTHON编写信用卡程序(支持购物,取款,查询,还款,转账) ?)