需求背景:
為了更好的解放雙手,提高記賬效率,本人想要制作一個基於python的自動化記賬程序,用於統計本人每星期、每月、每年,甚至是每日的盈虧記錄,目前該程序是處於半自動化狀態,后期會逐漸更新,爭取全套流程純自動化,不需要過多的人工參與,擺脫苦哈哈記賬統計的耗時任務。
需求總目標:
日賬目:連接常用的支付通信軟件,將自己每花費一筆,就自動歸類在一個臨時存儲位置,然后這個臨時存儲位置可以用excel格式記錄存儲,並將其下載到指定的電腦桌面位置。
星期賬目:對一星期的花銷和盈收做出統計,並用圖的方式展示各種類花銷情況和收入情況。
月賬目:對一個月(即四個星期)的花銷和盈收做出統計,並用圖的方式展示各種類花銷情況和收入情況。
年賬目:對一年(即12個月)的花銷和盈收做出統計,並用圖的方式展示各種類花銷情況和收入情況
本次記賬程序1.0的目標:
對一星期(即2021年5月23日 至 2021年5月29日)的盈收情況統計,可以得出其一星期的總收入、總支出、剩余額【注:本次編寫不會介紹太多理論性的東西,純小白實操教程】
具體內容:
前期准備工作
本次基於python記賬程序的實現,前提要部署好python的編譯環境,這里本人使用anaconda里的jupyter notebook作為編譯器,如若不會安裝,這里有傳送門:
Anaconda的下載【清華鏡像的】:
https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/
Anaconda的安裝教程:
https://www.cnblogs.com/sui776265233/p/11453004.html
若第一次安裝anaconda,在搭建好編譯環境后,需要打開cmd窗口,開始下載第三方庫【如何打開cmd窗口,使用快捷鍵win+r,輸入cmd即可】,以下展示cmd窗口效果。
因為本次需要使用的庫有xlrd庫、xlwt庫、pyinstaller庫和calendar庫,所以在彈窗的黑色窗口中分別輸入命令,下載xlrd庫:
pip install xlrd
效果圖如下:
同理:下載完成后,繼續下載xlwt庫,命令為:
pip install xlwt
下載pyinstaller庫,命令為:
pip install pyinstaller
下載calendar庫,命令為:
pip install calendar
下載完成后,可以繼續在cmd窗口輸入命令:pip list,用於檢查自己是否下載成功
編碼思路
到這里,基本的准備工作是完成了,現在就開始到編碼環節了。
首先要有思路:
- 對於日記賬的數據,先要獲取單張表的支出和收入
- 進入到每個記錄日記賬的表格去獲取其中的收支情況
- 將匯總好的內容寫入到新的excel表格中
- 將.ipynb的程序轉成.py程序,並將其打包,實現python程序轉化為.exe的腳本程序(即不打開python編譯環境就可以自動運行寫好的python程序內容)
開始編碼
思路想好后,就正式編碼了:
導入第三方庫
在寫python程序前,可以將需要使用到的第三方庫先進行導入,導入的語法格式是:import 第三方庫名,這個第三方庫名就是我們剛才下載的那些庫【注:pyinstaller庫可以不用,因為這個是將寫好的python程序打包成.exe,不用導入進來】
導入庫的源碼如下【含注釋,最好手動敲寫】:
import xlrd# 從Excel文件讀取數據和格式化信息的庫,支持.xls以及.xlsx文件
import xlwt# 用於將數據和格式化信息寫入舊Excel文件的庫
import calendar# 導入日歷庫
獲取表格里的收支數據
接下來是開始獲取單張表的收支數據,這里我展示一下我的記賬excel模板是:
可以從上圖看到,我的黃底紅字那里,是對當天記賬情況的總結,只要直接獲取收支數據對應的表格內容即可。
故這里的思路是:
獲取單張表支出的源碼如下【含注釋,最好手動敲寫】:
# 獲取單張表的支出
def get_single_pay(pay_url):# pay_url為支出表的路徑
# 確定文件路徑
excel_url = str(pay_url)
# 打開xlsx的文件
data = xlrd.open_workbook(excel_url)
#打開第一張表
table = data.sheets()[0]
# 獲取總支出的單元格內容【索引從0開始】,即第一行的第三列
pay = table.cell(0,2).value
return pay
獲取單張表收入的源碼如下【含注釋,最好手動敲寫】:
# 獲取單張表的收入
def get_single_income(income_url):# income_url為收入表的路徑
# 確定文件路徑
excel_url = str(income_url)
# 打開xlsx的文件
data = xlrd.open_workbook(excel_url)
#打開第一張表
table = data.sheets()[0]
# 獲取總收入的單元格內容【索引從0開始】,即第一行的第九列
income = table.cell(0,8).value
return income
統計一星期的收支情況
在獲取單個表格里的收支數據,就要把思路拓展了,如何才能獲取多個表格里的收支數據,其實思路還是和獲取單個表格數據的思路是一致的,只是不同的是,如何才能進入表格里,而且還是不重樣呢?
這里我使用的是用記賬的時間來作為每個excel表格的命名,效果圖如下:
那這樣子就有順序了,而且每個表格都是唯一標識的,然而,我轉念一想,如果我記賬的時間是跨月的,但是又是在一星期的范圍內,我該如何統計呢?比如說記賬時間是2021-5-30到2021-6-5,可以看到雖然是在一星期的范圍內,可是他們的月份卻是不一致的,該如何解決呢?又或者是2020-12-31到2021-1-6,不單單是月份不一樣,連年份也不以言,又該如何解決呢?
其實,無論是同年不同月,還是不同年也不同月,關鍵要抓住月份是否一致就夠了,因此我在寫程序時,做了一個分流,即判斷月份是否一致,如果月份一致,就按照正常程序獲取對應的表格數據即可;可是如果月份不一致,就需要分成兩部步,先獲取開始的日期到該月結束的日期,在獲取新月的1號到結束的日期,不就能完美的解決剛才提出的問題的嗎?
解決日期的問題,就開始統計一星期的收支情況了,思路是:
【注:
1、分流判斷:如果開始的月份和結束的月份一致,則調用之前寫好的獲取收支數據的函數,並添加到對應的總列表中;否則分成兩部分獲取表格數據,一個是獲取開始的日期到該月結束的日期的收支數據,另一個是獲取新月的1號到結束的日期的收支數據;
2、空列表存儲的順序是先支出后收入】
獲取一星期表收支數據的源碼如下【含注釋,最好手動敲寫】:
# 獲取一星期的表的收入和支出
# start取記賬的開始日期,如2021-5-23
# end取記賬的結束日期,如2021-5-29
def get_pay_and_income(start,end):
# 存儲一星期總支出的數據
pays_list = []
# 存儲一星期總收入的數據
incomes_list = []
# 分隔開始時間,分成年月日
start_split = str(start).split("-")
# 分隔結束時間,分成年月日
end_split = str(end).split("-")
if int(start_split[1]) == int(end_split[1]):
# 獲取指定這個月的開始 到 結束的賬單名
for this_day in range(int(start_split[2]),int(end_split[2])+1):#【this_day指的是月的天數】
# 確定文件路徑
this_excel_url = "./賬單/{}-{}-{}.xlsx".format(start_split[0],start_split[1],this_day)
# 獲取單表中支出的單元格內容【索引從0開始】
pay = get_single_pay(this_excel_url)
# 將獲取的數字加入到總支出列表中
pays_list.append(pay)
# 獲取單表中收入的單元格內容【索引從0開始】
income = get_single_income(this_excel_url)
# 將獲取的數字加入到總收入列表中
incomes_list.append(income)
else:
# 獲取這月的總天數
this_month_day = calendar.monthlen(int(start_split[0]),int(start_split[1]))
# 前部分:獲取指定月的開始 到 這月結束的賬單名
for pre_day in range(int(start_split[2]),this_month_day+1):#【pre_day指的是這個月/年的天數】
# 確定文件路徑
pre_excel_url = "./賬單/{}-{}-{}.xlsx".format(start_split[0],start_split[1],pre_day)
# 獲取單表中支出的單元格內容【索引從0開始】
pay = get_single_pay(pre_excel_url)
# 將獲取的數字加入到總支出列表中
pays_list.append(pay)
# 獲取單表中收入的單元格內容【索引從0開始】
income = get_single_income(pre_excel_url)
# 將獲取的數字加入到總收入列表中
incomes_list.append(income)
# 后部分:獲取新月的開始 到 指定月結束的賬單名
for after_day in range(1,int(end_split[2])+1):#【after_day指的是新月/新年的天數】
# 確定文件路徑
after_excel_url = "./賬單/{}-{}-{}.xlsx".format(end_split[0],end_split[1],after_day)
# 獲取單表中支出的單元格內容【索引從0開始】
pay = get_single_pay(after_excel_url)
# 將獲取的數字加入到總支出列表中
pays_list.append(pay)
# 獲取單表中收入的單元格內容【索引從0開始】
income = get_single_income(after_excel_url)
# 將獲取的數字加入到總收入列表中
incomes_list.append(income)
# 將一星期的收入和支出,用列表格式呈現
pays_incomes_list = []# 創建一個空列表存儲
pays_incomes_list.append(sum(pays_list))# 將統計好的支出列表,裝進空列表中
pays_incomes_list.append(sum(incomes_list))# 將統計好的收入列表,裝進空列表中
return pays_incomes_list# 返回的內容為支出-收入字典內容
將統計的新數據寫入表格
恭喜你,到這里你已經獲取了想要的一星期收支數據的匯總情況,現在將其添加到新的表格中。
思路是:
一星期賬目數據匯總寫入的源碼如下【含注釋,最好手動敲寫】:
# 一星期內容匯總
# start取記賬的開始日期,如2021-5-23
# end取記賬的結束日期,如2021-5-29
def write_pay_and_income(start,end):
# 創建workbook
workbook = xlwt.Workbook()# 注意Workbook的開頭要大寫
# 創建sheet對象,並設置sheet的名稱
sheet = workbook.add_sheet("七天匯總",cell_overwrite_ok=True)
# 向sheet頁的(0,0)位置寫入標題
sheet.write(0,0,"一星期的收支情況分析")
# 向sheet頁的(2,0)位置寫入“總支出”
sheet.write(2,0,"總支出")
# 向sheet頁的(2,1)位置寫入“總收入”
sheet.write(2,1,"總收入")
# 向sheet頁的(2,2)位置寫入“剩余利潤”
sheet.write(2,2,"剩余利潤")
# 獲取一星期表的收入和支出的數據
accounts_value = get_pay_and_income(start,end)
# 向sheet頁的(3,0)位置寫入支出數據
sheet.write(3,0,accounts_value[0])
# 向sheet頁的(3,1)位置寫入收入數據
sheet.write(3,1,accounts_value[1])
# 計算出一星期表的剩余利潤
profit = accounts_value[1] - accounts_value[0]
# 向sheet頁的(3,2)位置寫入剩余利潤數據
sheet.write(3,2,profit)
# 確定保存文件的路徑
save_url = "./賬單/{}到{}的匯總表.xls".format(start,end)# 【只能是xls,而不能是xlsx】
# 保存該excel文件,有同名文件直接覆蓋
workbook.save(save_url)
print("寫入完成")
自定義交互
不知道你有沒有發現,我寫的python程序都是使用函數進行封裝的,每個函數實現某個特定的功能,所以要使用需要將其調用出來,並且,為了能使這個自動化記賬程序能夠持續使用,其記賬的開始和結束日期一定不能寫固定的,因此我使用了input函數,它可以實現將用戶輸入的開始和結束日期,實時放進函數中進行匯總統計,這就是我為什么定義函數時,要把開始記賬日期和結束記賬日期作為函數的形參。
交互的源碼如下【含注釋,最好手動敲寫】:
start_time = input("開始時間:") # 輸入2021-5-23
end_time = input("結束時間:")# 輸入2021-5-29
write_pay_and_income(start_time,end_time)
生成統計的excel效果圖如下:
生成.exe程序
到這里,你已經完成了核心的編碼過程,現在正是將你寫好的程序做成.exe程序吧。
思路是:
此處是將.ipynb轉成.py文件
此處是將.py程序生成.exe文件
打開cmd窗口,然后輸入如下命令:pyinstaller -F (腳本路徑+腳本名),這個腳本路徑就是你當前存放.py程序的位置,這個腳本名就是你當前.py程序的名字,效果圖如下
生成.exe程序的截圖,如下:
根據exe保存路徑,找到后可以放置在指定運行環境的文件夾下,雙擊就可運行【注:使用input就可以實現與用戶交互;相同的文件重新打包,會將原本打包的內容覆蓋】
效果圖如下:
【注意:這個gif有些投影不足,是我在自定義日期時,格式是年-月-日,這個“-”切記不要丟失了】
結語
當然,此處程序還是有挺多的不足和需要改進的地方的,比如沒有對種類進行划分,沒有用圖形化的界面展示等,這些不足將會持續的更新…