具体需求:
文件结构:
|-- 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()
有图有像: