7.1 問題
創建account.py腳本,要求如下:
假設在記賬時,有一萬元錢
無論是開銷還是收入都要進行記賬
記賬內容包括時間、金額和說明等
記賬數據要求永久存儲
7.2 方案
創建4個函數,分別實現記錄開銷、記錄收入、查詢收支、判斷函數調用的四個方法,導入時間模塊獲取時間,導入os模塊判斷文件是否存在,導入pickle模塊用來python特有類型與數據類型轉換:
1.調用show_menu()函數後,先判斷記錄餘額文件是否存在,如果不存在創建文件並寫入餘額,如果存在,利用while循環在交互端輸出提示,請用戶input0/1/2/3任意數值,如果輸入的值不是0/1/2/3,打印輸入值無效請重新輸入並重新開始循環,如果輸入的值是3,停止整個循環,如果輸入的值是0/1/2通過字典鍵值對關聯關係,調用相對應函數
2.如果輸入的值是0,字典cmds中0鍵對應的值是spend_money,調用spend_money ()記錄開銷函數,讓此函數實現獲取當前系統日期、輸入開銷金額、輸入開銷備註信息、以二進制讀方式打開記錄餘額文件計算本次開銷後餘額,以寫方式打開記錄餘額文件將計算後開銷餘額寫入文件,以追加方式打開記賬文件,將日期、開銷、備註、餘額寫入追加入記賬文件最後
3.如果輸入的值是1,字典cmds中0鍵對應的值是save_money,調用save_money ()記錄收入函數,讓此函數實現獲取當前系統日期、輸入收入金額、輸入收入備註信息、以二進制讀方式打開記錄餘額文件計算本次收入後餘額,以寫方式打開記錄餘額文件將計算後收入餘額寫入文件,以追加方式打開記賬文件,將日期、開銷、備註、餘額寫入追加入記賬文件最後
4.如果輸入的值是2,調用查詢收支函數query (),以二進制讀方式打開記賬文件,利用for循環遍歷文件中數據,打印出來,打開記錄餘額文件讀取餘額並打印。
需要注意的是:爲確保代碼可以正常執行,while循環利用try except語句處理異常,優先匹配特殊異常,讓用戶按下Ctrl+C或Ctrl+D可以退出程序,遇到索引錯誤可以結束當次循環,重新開始選擇選項。
將記錄餘額文件以及記賬文件作爲參數傳入函數中
7.3 步驟
實現此案例需要按照如下步驟進行。
步驟一:編寫腳本
[root@localhost day05]# vim account.py
#!/usr/bin/env python3
#日期 開銷 收入 餘額 備註
import time
import os
import pickle as p
def spend_money(record, wallet):
date = time.strftime('%Y-%m-%d')
amount = int(input('金額: '))
comment = input('備註: ')
with open(wallet, 'rb') as fobj:
#load從數據文件中讀取數據,並轉換爲Python的數據結構
balance = p.load(fobj) – amount
with open(wallet, 'wb') as fobj:
#dump將數據通過特殊形式轉換爲只有python語言認識的字符串,並寫入文件
p.dump(balance, fobj)
with open(record, 'a') as fobj:
fobj.write(
"%-15s%-8s%-8s%-10s%-20s\n" %
(date, amount, 'n/a', balance, comment)
)
def save_money(record, wallet):
date = time.strftime('%Y-%m-%d')
amount = int(input('金額: '))
comment = input('備註: ')
with open(wallet, 'rb') as fobj:
balance = p.load(fobj) + amount
with open(wallet, 'wb') as fobj:
p.dump(balance, fobj)
with open(record, 'a') as fobj:
fobj.write(
"%-15s%-8s%-8s%-10s%-20s\n" %
(date, 'n/a', amount, balance, comment)
)
def query(record, wallet):
with open(record) as fobj:
for line in fobj:
print(line, end='')
with open(wallet, 'rb') as fobj:
#load從數據文件中讀取數據,並轉換爲Python的數據結構
balance = p.load(fobj)
print('當前餘額: %s' % balance)
def show_menu():
prompt = """(0) 記錄開銷
(1) 記錄收入
(2) 查詢收支記錄
(3) 退出
請選擇(0/1/2/3): """
cmds = {'0': spend_money, '1': save_money, '2': query}
record = 'record.txt' # 記帳
wallet = 'wallet.data' # 記錄餘額
if not os.path.exists(wallet): #判斷文件是否存在
with open(wallet, 'wb') as fobj:
p.dump(10000, fobj)
while True:
try:
choice = input(prompt).strip()[0]
except IndexError:
continue
except (KeyboardInterrupt, EOFError):
print('\nBye-bye')
choice = '3'
if choice not in '0123':
print('無效輸入,請重試')
continue
if choice == '3':
break
cmds[choice](record, wallet)
if __name__ == '__main__':
show_menu()
步驟二:測試腳本執行
[root@localhost day05]# python3 account.py
(0) 記錄開銷
(1) 記錄收入
(2) 查詢收支記錄
(3) 退出
請選擇(0/1/2/3): 0
金額: 2000
備註: huafei
(0) 記錄開銷
(1) 記錄收入
(2) 查詢收支記錄
(3) 退出
請選擇(0/1/2/3): 1
金額: 1000
備註: shouru
(0) 記錄開銷
(1) 記錄收入
(2) 查詢收支記錄
(3) 退出
請選擇(0/1/2/3): 2
2018-04-25 2000 n/a 28890 huafei
2018-04-25 n/a 1000 29890 shouru
當前餘額: 29890
(0) 記錄開銷
(1) 記錄收入
(2) 查詢收支記錄
(3) 退出
請選擇(0/1/2/3): 3
[root@localhost day05]# python3 account.py
(0) 記錄開銷
(1) 記錄收入
(2) 查詢收支記錄
(3) 退出
請選擇(0/1/2/3): ^C
Bye-bye
[root@localhost day05]# python3 account.py
(0) 記錄開銷
(1) 記錄收入
(2) 查詢收支記錄
(3) 退出
請選擇(0/1/2/3):
Bye-bye