python3 实现简单的信用卡还款,取款转账功能V2
仅实现还款,取款,转账,信息查询功能
程序结构:
atm(函数主执行程序):
1 2 3 4 5 6 7 8 9 | #Author by Andy #_*_ coding:utf-8 _*_ import os,sys Father_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(Father_path) from core import main if __name__ = = '__main__' : main.run() |
main(程序主逻辑模块):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | #Author by Andy #_*_ coding:utf-8 _*_ import os,sys,time,json Father_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert( 0 ,Father_path) from core import auth from core import db_handle from conf import settings from conf import Color_set from core import transaction color = Color_set.Colorset() user_data = { 'account_id' : None , 'is_authentic' : False , 'account_data' : None } def auth_transfer_id(): trans_id = input ( "输入转账ID:" ).strip() trans_file = Father_path + "/db/accounts/%s.json" % trans_id if os.path.isfile(trans_file): return trans_id def action_type(acc_data,action): Exit_flag = True while Exit_flag: values = input ( "请输入%s金额:" % action.strip()) if values.isdigit(): if action = = "还款" : action_result = transaction.make_transaction(acc_data, "repayment" ,values) if action_result: print (color.red( "您的最新余额为%s" % action_result[ 'balance' ])) break elif action = = "取款" : action_result = transaction.make_transaction(acc_data, "enchashment" , values) if action_result: print (color.red( "您的最新余额为%s" % action_result[ 'balance' ])) break elif action = = "转账" : while True : trans_id = auth_transfer_id() if trans_id = = acc_data[ 'id' ]: print (color.red( "账户无效,请重新输入!" )) elif not trans_id: Exit_flag = False print (color.red( "账户无效,请重新输入!" )) elif trans_id: f = Father_path + "/db/accounts/%s.json" % trans_id trans_file = open (f) trans_dict = json.load(trans_file) action_result = transaction.make_transaction(acc_data, "transfer" , values) if action_result: print (color.red( "您的最新余额为%s" % action_result[ 'balance' ])) # logger.logger(acc_data["id"], action_result['balance'], "transfer") break else : print ( "\033[31;1m 账户无效,请重新输入!!\033[;0m" ) break elif values = = "b" : Exit_flag = False else : print (color.red( "[%s]不是有效的金额,必需输入数字!" % values)) def account_info(acc_data): print ( "以下为您的个人账户基本信息:\n" ) print (color.red( "卡号:%s\n信用额度:%s\n可用余度:%s\n还款日:%s\n出账日:%s\n账户状态:%s\n" % (acc_data[ 'id' ],acc_data[ 'credit' ],acc_data[ 'balance' ],acc_data[ 'pay_day' ],acc_data[ 'account_day' ],acc_data[ 'status' ])) ) def repayment(acc_data): action_type(acc_data, "还款" ) def enchashment(acc_data): action_type(acc_data, "取款" ) def transfer(acc_data): action_type(acc_data, "转账" ) def billing(acc_data): print ( "账单查询功能正在建设中,给您造成不便,敬请谅解!" ) def logout(acc_data): print ( "欢迎再次使用,祝生活愉快,再见!" ) exit() def interactive(acc_data): menu = color.red( ''' 1. 账户信息\n 2. 还款\n 3. 取款\n 4. 转账\n 5. 账单\n 6. 退出\n ''' ) menu_dic = { '1' : account_info, '2' : repayment, '3' : enchashment, '4' : transfer, '5' : billing, '6' : logout } str = "欢迎使用银行信用卡自助服务系统!\n" for i in str : sys.stdout.write(i) sys.stdout.flush() time.sleep( 0.3 ) Exit_flag = True while Exit_flag: print (menu) user_option = input ( "请选择服务项目:" ).strip() if user_option in menu_dic: menu_dic[user_option](acc_data) else : print (color.red( "输入错误,请重新输入!" )) def run(): acc_data = auth.acc_login(user_data) if user_data[ 'is_authentic' ]: user_data[ 'account_data' ] = acc_data interactive(acc_data) |
db_handle(用于判断数据类型以及数据文件位置模块):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #Author by Andy #_*_ coding:utf-8 _*_ ''' conn_params must be a dict 以下定义了两个函数: file_db_handle 来确定数据文件的路径 db_handle_type 来确定数据文件的类型 ''' def file_db_handle(conn_params): db_path = '%s/%s' % (conn_params[ 'path' ],conn_params[ 'name' ]) return db_path def db_handle_type(conn_params): if conn_params[ 'engine' ] = = 'file_storage' : return file_db_handle(conn_params) |
auth(用户认证模块):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #Author by Andy #_*_ coding:utf-8 _*_ import os,sys,json Father_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert( 0 ,Father_path) from core import db_handle from conf import settings from conf import Color_set color = Color_set.Colorset() def acc_auth(account,passwd): db_path = db_handle.db_handle_type(settings.DATABASE) data_file = '%s/%s.json' % (db_path,account) if os.path.isfile(data_file): with open (data_file,encoding = 'utf-8' ) as f: account_data = json.load(f) if account_data[ 'password' ] = = passwd: return account_data else : print (color.red( "用户名或密码错误!" )) else : print (color.red( "账户不存在!" )) def acc_login(user_data): retry_times = 0 while user_data[ "is_authentic" ] is not True and retry_times < 3 : account = input ( "请输入账号:" ) passwd = input ( "请输入密码:" ) auth = acc_auth(account,passwd) if auth: user_data[ "is_authentic" ] = True user_data [ "account_id" ] = account return auth retry_times + = 1 else : print (color.red( "账户 [%s] 错误登录次数已达上限,已被锁定,解锁请联系客服10086!" % account)) exit() |
accounts (读取和保存用户数据模块):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #Author by Andy #_*_ coding:utf-8 _*_ import json,os,sys Father_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert( 0 ,Father_path) from core import db_handle from conf import settings def load_current_balance(account_id): db_path = db_handle.db_handle_type(settings.DATABASE) account_file = "%s/%s.json" % (db_path, account_id) with open (account_file,encoding = 'utf-8' ) as f: acc_data = json.load(f) return acc_data def dump_account(account_data): db_path = db_handle.db_handle_type(settings.DATABASE) account_file = "%s/%s.json" % (db_path, account_data[ "id" ]) with open (account_file, "w" ,encoding = 'utf-8' ) as f: json.dump(account_data, f) return True |
settings(程序配置模块):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #Author by Andy #_*_ coding:utf-8 _*_ import os,sys Father_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) DATABASE = { 'engine' : 'file_storage' , 'name' : 'accounts' , 'path' : '%s/db' % Father_path } TRANSACTIONE_TYPE = { 'repayment' : { 'action' : 'plus' , 'interest' : 0 }, 'enchashment' : { 'action' : 'minus' , 'interest' : 0.005 }, 'transfer' : { 'action' : 'minus' , 'interest' : 0.005 } } |
Color_set(字体输出颜色设置模块):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #coding:gbk # ------------------------------------------------ # python终端显示彩色字符类,可以调用不同的方法 # 选择不同的颜色.使用方法看示例代码就很容易明白. # ------------------------------------------------ # # 显示格式: \033[显示方式;前景色;背景色m # ------------------------------------------------ # 显示方式 说明 # 0 终端默认设置 # 1 高亮显示 # 4 使用下划线 # 5 闪烁 # 7 反白显示 # 8 不可见 # 22 非粗体 # 24 非下划线 # 25 非闪烁 # # 前景色 背景色 颜色 # 30 40 黑色 # 31 41 红色 # 32 42 绿色 # 33 43 黃色 # 34 44 蓝色 # 35 45 紫红色 # 36 46 青蓝色 # 37 47 白色 # ------------------------------------------------ class Colorset( object ): # 显示格式: \033[显示方式;前景色;背景色m # 只写一个字段表示前景色,背景色默认 RED = '\033[31m' # 红色 GREEN = '\033[32m' # 绿色 YELLOW = '\033[33m' # 黄色 BLUE = '\033[34m' # 蓝色 FUCHSIA = '\033[35m' # 紫红色 CYAN = '\033[36m' # 青蓝色 WHITE = '\033[37m' # 白色 #: no color RESET = '\033[0m' # 终端默认颜色 def color_str( self , color, s): return '{}{}{}' . format ( getattr ( self , color), s, self .RESET ) def red( self , s): return self .color_str( 'RED' , s) def green( self , s): return self .color_str( 'GREEN' , s) def yellow( self , s): return self .color_str( 'YELLOW' , s) def blue( self , s): return self .color_str( 'BLUE' , s) def fuchsia( self , s): return self .color_str( 'FUCHSIA' , s) def cyan( self , s): return self .color_str( 'CYAN' , s) def white( self , s): return self .color_str( 'WHITE' , s) # ----------使用示例如下:------------- # color = Colorset() # print(color.red('I am red!')) # print(color.green('I am gree!')) # print(color.yellow('I am yellow!')) # print(color.blue('I am blue!')) # print(color.fuchsia('I am fuchsia!')) # print(color.cyan('I am cyan!')) # print(color.white('I am white')) |
transaction(转账、取款、还款实际执行模块):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #Author by Andy #_*_ coding:utf-8 _*_ import os,sys,json Father_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert( 0 ,Father_path) from conf import settings from conf import Color_set from core import accounts color = Color_set.Colorset() def make_transaction(acc_data, action_type, values, * * others): values = float (values) if action_type in settings.TRANSACTIONE_TYPE: interest = values * settings.TRANSACTIONE_TYPE[action_type][ 'interest' ] old_balance = acc_data[ 'balance' ] if settings.TRANSACTIONE_TYPE[action_type][ 'action' ] = = "plus" : new_balance = old_balance + values + interest print ( "此次操作的手续费为:%s" % interest) elif settings.TRANSACTIONE_TYPE[action_type][ 'action' ] = = "minus" : new_balance = old_balance - values - interest print ( "此次操作的手续费为:%s" % interest) if new_balance < 0 : print (color.red( "当前信用值%s不允许进行此交易[-%s],当前余额%s" % \ (acc_data[ "cridit" ], (values + interest), old_balance))) return acc_data[ "balance" ] = new_balance accounts.dump_account(acc_data) return acc_data else : print (color.red( "交易类型 [%s] 不存在!" % action_type)) |
用户数据文件:
10086.jason:
1 | { "id" : 10010 , "pay_day" : "每月9日" , "balance" : 15000 , "status" : "nomal" , "credit" : 15000 , "password" : "abcd" , "account_day" : "每月21日" } |
10010.jason:
1 | { "balance" : 801645.0 , "id" : 10086 , "pay_day" : "\u6bcf\u670822\u65e5" , "credit" : 15000 , "password" : "abcd" , "status" : "nomal" , "account_day" : "\u6bcf\u67085\u65e5" } |
转载请注明出处!
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
· AI Agent爆火后,MCP协议为什么如此重要!
· dotnet 源代码生成器分析器入门
· Draw.io:你可能不知道的「白嫖级」图表绘制神器
· ASP.NET Core 模型验证消息的本地化新姿势
· Java使用多线程处理未知任务数方案