在上一篇《Python之區塊鏈入門》中講述了區塊鏈的基礎知識,並用Python實現了區塊和區塊鏈的結構。在本篇中,將基於上面的內容實現一個簡單的記賬本功能。
記賬本的功能如下: 實現基本的收支記錄; 計算當前餘額; 對收支情況做簡單統計分析。
賬單記錄的格式如下:
日期|描述|金額
下面開始一步步實現上述功能。 一、定義收支記錄
在上一篇中區塊的內容是簡單的文本,這裡實現將基於Block實現一個支援收支記錄格式的類,代碼如下:
In [36]:
from datetime import datetimeclass AccountBill(Block): def __init__(self, content, amount): t = datetime.now().strftime('%Y-%m-%d %H:%M:%S') data = "{}|{}|{}".format(t, content, amount) return super(AccountBill, self).__init__(data) ''' 擷取金額數量 ''' def get_amount(self): amount = 0 if self.data: amount = int(self.data.split('|')[2]) return amount def get_content(self): content = '' if self.data: content = self.data.split('|')[1] return content def __repr__(self): return 'Bill: {}>'.format( self.data )
In [37]:
# 建立記錄AccountBill('測試', 100)
Out[37]:
Bill: 2017-07-30 10:46:23|測試|100>
二、計算當前餘額
上面已經定義了收支記錄,接下來在BlockChain基礎上定義一個方法用來計算當前餘額。代碼如下:
In [91]:
from collections import OrderedDictclass AccountBook(BlockChain): def __init__(self): self.head = None # 指向最新的一個區塊 self.blocks = OrderedDict() # 包含所有區塊的一個字典 ''' 添加記錄 ''' def add_block(self, new_bill): new_bill.mine() super(AccountBook, self).add_block(new_bill) ''' 計算當前餘額 ''' def balance(self): balance = 0 if self.blocks: for k, v in self.blocks.items(): balance += v['block'].get_amount() return balance def __repr__(self): num_existing_blocks = len(self.blocks) return 'AccountBook<{} Bills, Head: {}>'.format( num_existing_blocks, self.head.identifier if self.head else None )
In [92]:
# 建立幾筆記錄book = AccountBook()b1 = AccountBill('工資', 10000)book.add_block(b1)b2 = AccountBill('房租', -2500)book.add_block(b2)b3 = AccountBill('衣服', -1500)book.add_block(b3)b4 = AccountBill('吃飯', -1000)book.add_block(b4)b5 = AccountBill('股票收入', 200)book.add_block(b5)b6 = AccountBill('看電影', -200)book.add_block(b6)b7 = AccountBill('購物', -1000)book.add_block(b7)b8 = AccountBill('水電費等', -100)book.add_block(b8)
In [93]:
# 計算當前餘額book.balance()
Out[93]:
3900
三、簡單分析收支記錄
In [76]:
# 列印收支記錄for k,v in book.blocks.items(): print(v['block'].data)2017-07-30 19:57:57|工資|100002017-07-30 19:57:57|房租|-25002017-07-30 19:57:57|衣服|-15002017-07-30 19:57:58|吃飯|-10002017-07-30 19:57:58|股票收入|2002017-07-30 19:57:58|看電影|-2002017-07-30 19:57:59|購物|-10002017-07-30 19:57:59|水電費等|-100
In [50]:
# 使用柱狀圖展示收支記錄%matplotlib inlineimport matplotlibimport numpy as npimport matplotlib.pyplot as pltplt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標籤# 初始化資料x_data = [] # 金額y_data = [] # 描述colors = [] # 顏色for k,v in book.blocks.items(): bill = v['block'] y_data.append(bill.get_content()) amount = bill.get_amount() if amount > 0: x_data.append(amount) colors.append('blue') else: x_data.append(-amount) colors.append('red') y_pos = np.arange(len(y_data)) plt.bar(y_pos, x_data, align='center', alpha=0.5, color=colors)plt.xticks(y_pos, y_data)plt.ylabel('金額')plt.title('收支記錄') plt.show()
In [55]:
# 簡單分析支出組成labels = []amounts = []colors = ['gold', 'yellowgreen', 'lightcoral', 'lightskyblue'] # 用不同顏色顯示 for k,v in book.blocks.items(): bill = v['block'] amount = bill.get_amount() # 只展示支出 if amount < 0: labels.append(bill.get_content()) amounts.append(-amount) plt.pie(amounts, labels=labels, colors=colors, shadow=True, autopct='%1.1f%%')plt.axis('equal')plt.show()
作者:Walker Python愛好者社區專欄作者 授權原創發布,請勿轉載,謝謝。
出處:Python之區塊鏈簡單記賬本實現