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

python项目练习之ATM

时间:2018-08-18 11:32:30      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:time   图片   evel   connect   setting   dump   account   current   spl   

程序框图 (消费模块暂未写入)

技术分享图片

 

 bin:程序执行


技术分享图片
 1 import os
 2 import sys
 3 base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 4 print(base_dir)
 5 sys.path.append(base_dir)
 6 
 7 from core import main
 8 
 9 
10 if __name__ == __main__:   #当作为脚本直接运行的时候,此时__name__等于__main__,当作为模块导入的时候,__name__为文件名但不带.py,故不运行if后语句。
11     main.run()
atm.py

 

config:配置文件


技术分享图片
 1 import os
 2 import sys
 3 import logging
 4 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 5 
 6 
 7 DATABASE = {
 8     engine: file_storage, #support mysql,postgresql in the future
 9     name:accounts,
10     path: "%s/db" % BASE_DIR
11 }
12 
13 
14 LOG_LEVEL = logging.INFO
15 LOG_TYPES = {
16     transaction: transactions.log,
17     access: access.log,
18     11111:11111.log
19 }
20 
21 TRANSACTION_TYPE = {
22     repay:{action:plus, interest:0},
23     withdraw:{action:minus, interest:0.05},
24     transfer:{action:minus, interest:0.05},
25     consume:{action:minus, interest:0},
26 }
settings

 

core:程序主要代码


技术分享图片
 1 import json
 2 import time
 3 from core import db_handler
 4 from conf import settings
 5 
 6 
 7 def load_current_balance(account_id):
 8     ‘‘‘
 9     return account balance and other basic info
10     :param account_id:
11     :return:
12     ‘‘‘
13     db_path = db_handler.db_handler(settings.DATABASE)
14     account_file = "%s/%s.json" %(db_path,account_id)
15     with open(account_file) as f:
16         acc_data = json.load(f)
17         return  acc_data
18 def dump_account(account_data):
19     ‘‘‘
20     after updated transaction or account data , dump it back to file db
21     :param account_data:
22     :return:
23     ‘‘‘
24     db_path = db_handler.db_handler(settings.DATABASE)
25     account_file = "%s/%s.json" %(db_path,account_data[id])
26     with open(account_file, w) as f:
27         acc_data = json.dump(account_data,f)
28 
29     return True
accounts
技术分享图片
 1 import os
 2 from core import db_handler
 3 from conf import settings
 4 from core import logger
 5 import json
 6 import time
 7 
 8 def acc_auth(account,password):
 9     ‘‘‘
10     account auth func
11     :param account: credit account number
12     :param password: credit card password
13     :return: if passed the authentication , retun the account object, otherwise ,return None
14     ‘‘‘
15     db_path = db_handler.db_handler(settings.DATABASE)
16     account_file = "%s/%s.json" %(db_path,account)
17     print(account_file)  #base_dir + accounts + account.json
18     if os.path.isfile(account_file):   #判断文件名是否存在,存在执行下面语句
19         with open(account_file,r) as f:
20             account_data = json.load(f)
21             if account_data[password] == password:
22                 exp_time_stamp = time.mktime(time.strptime(account_data[expire_date], "%Y-%m-%d"))
23                 if time.time() >exp_time_stamp:
24                     print("\033[31;1mAccount [%s] has expired,please contact the back to get a new card!\033[0m" % account)
25                 else: #passed the authentication
26                     return  account_data
27             else:
28                 print("\033[31;1mAccount ID or password is incorrect!\033[0m")
29     else:
30         print("\033[31;1mAccount [%s] does not exist!\033[0m" % account)
31 
32 def acc_login(user_data,log_obj):
33     ‘‘‘
34     account login func
35     :user_data: user info data , only saves in memory
36     :return:
37     ‘‘‘
38     retry_count = 0
39     while user_data[is_authenticated] is not True and retry_count < 3 :
40         account = input("\033[32;1maccount:\033[0m").strip()
41         password = input("\033[32;1mpassword:\033[0m").strip()
42         auth = acc_auth(account, password)
43         if auth: #not None means passed the authentication
44             user_data[is_authenticated] = True
45             user_data[account_id] = account
46             #print("welcome")
47             return auth
48         retry_count +=1
49     else:
50         log_obj.error("account [%s] too many login attempts" % account)
51         exit()
登陆认证
技术分享图片
 1 def file_db_handle(conn_params):
 2     ‘‘‘
 3     parse the db file path
 4     :param conn_params: the db connection params set in settings
 5     :return:
 6     ‘‘‘
 7     print(file db:,conn_params)
 8     db_path =%s/%s %(conn_params[path],conn_params[name])
 9     return db_path
10 
11 def mysql_db_handle(conn_parms):
12     pass
13 def db_handler(conn_parms):
14     ‘‘‘
15     connect to db
16     :param conn_parms: the db connection params set in settings
17     :return:a
18     ‘‘‘
19 
20     if conn_parms[engine] == file_storage:
21         return file_db_handle(conn_parms)
22 
23     if conn_parms[engine] == mysql:
24         return mysql_db_handle(conn_parms)
数据存储路径
技术分享图片
 1 import logging
 2 from conf import settings
 3 
 4 def logger(log_type):
 5 
 6     #create logger
 7     logger = logging.getLogger(log_type)
 8     logger.setLevel(settings.LOG_LEVEL)
 9 
10 
11     # create console handler and set level to debug
12     ch = logging.StreamHandler()
13     ch.setLevel(settings.LOG_LEVEL)
14 
15     # create file handler and set level to warning
16     log_file = "%s/log/%s" %(settings.BASE_DIR, settings.LOG_TYPES[log_type])
17     fh = logging.FileHandler(log_file)
18     fh.setLevel(settings.LOG_LEVEL)
19     # create formatter
20     formatter = logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s)
21 
22     # add formatter to ch and fh
23     ch.setFormatter(formatter)
24     fh.setFormatter(formatter)
25 
26     # add ch and fh to logger
27     logger.addHandler(ch)
28     logger.addHandler(fh)
29 
30     return logger
日志
技术分享图片
  1 from core import auth
  2 from core import accounts
  3 from core import logger
  4 from core import accounts
  5 from core import transaction
  6 import time
  7 
  8 #transaction logger
  9 trans_logger = logger.logger(transaction)
 10 #access logger
 11 access_logger = logger.logger(access)
 12 
 13 
 14 #temp account data ,only saves the data in memory
 15 user_data = {
 16     account_id:None,
 17     is_authenticated:False,
 18     account_data:None
 19 
 20 }
 21 
 22 def account_info(acc_data):
 23     print(user_data)
 24 def repay(acc_data):
 25     ‘‘‘
 26     print current balance and let user repay the bill
 27     :return:
 28     ‘‘‘
 29     account_data = accounts.load_current_balance(acc_data[account_id])  #获取用户id,就是要用实时的最新数据,为了安全
 30     #for k,v in account_data.items():
 31     #    print(k,v )
 32     current_balance= ‘‘‘ --------- BALANCE INFO --------
 33         Credit :    %s
 34         Balance:    %s‘‘‘ %(account_data[credit],account_data[balance])
 35     print(current_balance)
 36     back_flag = False
 37     while not back_flag:
 38         repay_amount = input("\033[33;1mInput repay amount:\033[0m").strip()
 39         if len(repay_amount) >0 and repay_amount.isdigit():
 40             #print(‘ddd 00‘)
 41             new_balance = transaction.make_transaction(trans_logger,account_data,repay, repay_amount)
 42             if new_balance:
 43                 print(‘‘‘\033[42;1mNew Balance:%s\033[0m‘‘‘ %(new_balance[balance]))
 44 
 45         else:
 46             print(\033[31;1m[%s] is not a valid amount, only accept integer!\033[0m % repay_amount)
 47 
 48         if repay_amount == b:
 49             back_flag = True
 50 def withdraw(acc_data):
 51     ‘‘‘
 52     print current balance and let user do the withdraw action
 53     :param acc_data:
 54     :return:
 55     ‘‘‘
 56     account_data = accounts.load_current_balance(acc_data[account_id])
 57     current_balance= ‘‘‘ --------- BALANCE INFO --------
 58         Credit :    %s
 59         Balance:    %s‘‘‘ %(account_data[credit],account_data[balance])
 60     print(current_balance)
 61     back_flag = False
 62     while not back_flag:
 63         withdraw_amount = input("\033[33;1mInput withdraw amount:\033[0m").strip()
 64         if len(withdraw_amount) >0 and withdraw_amount.isdigit():
 65             new_balance = transaction.make_transaction(trans_logger,account_data,withdraw, withdraw_amount)  # new_balance就是 函数返回值 acount_data
 66             if new_balance:
 67                 print(‘‘‘\033[42;1mNew Balance:%s\033[0m‘‘‘ %(new_balance[balance]))
 68 
 69         else:
 70             print(\033[31;1m[%s] is not a valid amount, only accept integer!\033[0m % withdraw_amount)
 71 
 72         if withdraw_amount == b:
 73             back_flag = True
 74 
 75 def transfer(acc_data):
 76     pass
 77 def pay_check(acc_data):
 78     pass
 79 def logout(acc_data):
 80     pass
 81 def interactive(acc_data):
 82     ‘‘‘
 83     interact with user
 84     :return:
 85     ‘‘‘
 86     menu = u‘‘‘
 87     ------- Oldboy Bank ---------
 88     \033[32;1m1.  账户信息
 89     2.  还款(功能已实现)
 90     3.  取款(功能已实现)
 91     4.  转账
 92     5.  账单
 93     6.  退出
 94     \033[0m‘‘‘
 95     menu_dic = {
 96         1: account_info,
 97         2: repay,
 98         3: withdraw,
 99         4: transfer,
100         5: pay_check,
101         6: logout,
102     }
103     exit_flag = False
104     while not exit_flag:
105         print(menu)
106         user_option = input(">>:").strip()
107         if user_option in menu_dic:
108             menu_dic[user_option](acc_data)  #比如选择了2 ,则运行 repay(acc_data),调用repay函数
109 
110         else:
111             print("\033[31;1mOption does not exist!\033[0m")
112 def run():
113     ‘‘‘
114     this function will be called right a way when the program started, here handles the user interaction stuff
115     :return:
116     ‘‘‘
117     acc_data = auth.acc_login(user_data,access_logger)   #userdata作为条件,access_logger作为日志信息传入
118     if user_data[is_authenticated]:
119         user_data[account_data] = acc_data  #acc_data 即是用户信息 1234.json
120         interactive(user_data) #交互
主程序
技术分享图片
 1 from conf import settings
 2 from core import accounts
 3 from core import logger
 4 #transaction logger
 5 
 6 
 7 def make_transaction(log_obj,account_data,tran_type,amount,**others):
 8     ‘‘‘
 9     deal all the user transactions
10     :param account_data: user account data
11     :param tran_type: transaction type
12     :param amount: transaction amount
13     :param others: mainly for logging usage
14     :return:
15     ‘‘‘
16     amount = float(amount)
17     if tran_type in  settings.TRANSACTION_TYPE:
18 
19         interest =  amount * settings.TRANSACTION_TYPE[tran_type][interest]
20         old_balance = account_data[balance]
21         if settings.TRANSACTION_TYPE[tran_type][action] == plus:
22             new_balance = old_balance + amount + interest
23         elif settings.TRANSACTION_TYPE[tran_type][action] == minus:
24             new_balance = old_balance - amount - interest
25             #check credit
26             if  new_balance <0:
27                 print(‘‘‘\033[31;1mYour credit [%s] is not enough for this transaction [-%s], your current balance is
28                 [%s]‘‘‘ %(account_data[credit],(amount + interest), old_balance ))
29                 return
30         account_data[balance] = new_balance
31         accounts.dump_account(account_data) #save the new balance back to file
32         log_obj.info("account:%s   action:%s    amount:%s   interest:%s" %
33                           (account_data[id], tran_type, amount,interest) )
34         return account_data
35     else:
36         print("\033[31;1mTransaction type [%s] is not exist!\033[0m" % tran_type)
交易种类

 

db:用户信息存储


技术分享图片
1 {"id": "gkx", "password": "123", "credit": 15000, "balance": 15000, "enroll_date": "2016-01-02", "expire_date": "2021-01-01", "pay_day": 22, "status": 0}
View Code

 

python项目练习之ATM

标签:time   图片   evel   connect   setting   dump   account   current   spl   

原文地址:https://www.cnblogs.com/gkx0731/p/9496301.html

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