自動化記賬程序1.0

需求背景:

為了更好的解放雙手,提高記賬效率,本人想要製作一個基於python的自動化記賬程序,用於統計本人每星期、每月、每年,甚至是每日的盈虧記錄,目前該程序是處於半自動化狀態,後期會逐漸更新,爭取全套流程純自動化,不需要過多的人工參與,擺脫苦哈哈記賬統計的耗時任務。

需求總目標:

日賬目:連接常用的支付通信軟件,將自己每花費一筆,就自動歸類在一個臨時存儲位置,然後這個臨時存儲位置可以用excel格式記錄存儲,並將其下載到指定的電腦桌面位置。
星期賬目:對一星期的花銷和盈收做出統計,並用圖的方式展示各種類花銷情況和收入情況。
月賬目:對一個月(即四個星期)的花銷和盈收做出統計,並用圖的方式展示各種類花銷情況和收入情況。
年賬目:對一年(即12個月)的花銷和盈收做出統計,並用圖的方式展示各種類花銷情況和收入情況

本次記賬程序1.0的目標:

對一星期(即2021年5月23日 至 2021年5月29日)的盈收情況統計,可以得出其一星期的總收入、總支出、剩餘額【註:本次編寫不會介紹太多理論性的東西,純小白實操教程】

具體內容:

前期準備工作

本次基於python記賬程序的實現,前提要部署好python的編譯環境,這裡本人使用anaconda里的jupyter notebook作為編譯器,如若不會安裝,這裡有傳送門:

Anaconda的下載【清華鏡像的】:
//mirrors.tuna.tsinghua.edu.cn/anaconda/archive/

Anaconda的安裝教程:
//www.cnblogs.com/sui776265233/p/11453004.html

若第一次安裝anaconda,在搭建好編譯環境後,需要打開cmd窗口,開始下載第三方庫【如何打開cmd窗口,使用快捷鍵win+r,輸入cmd即可】,以下展示cmd窗口效果。
1.png

因為本次需要使用的庫有xlrd庫、xlwt庫、pyinstaller庫和calendar庫,所以在彈窗的黑色窗口中分別輸入命令,下載xlrd庫:

pip install xlrd

效果圖如下:

2.png

同理:下載完成後,繼續下載xlwt庫,命令為:

pip install xlwt

下載pyinstaller庫,命令為:

pip install pyinstaller

下載calendar庫,命令為:

pip install calendar

下載完成後,可以繼續在cmd窗口輸入命令:pip list,用於檢查自己是否下載成功
3.png
4.png

編碼思路

到這裡,基本的準備工作是完成了,現在就開始到編碼環節了。
首先要有思路:

  1. 對於日記賬的數據,先要獲取單張表的支出和收入
  2. 進入到每個記錄日記賬的表格去獲取其中的收支情況
  3. 將匯總好的內容寫入到新的excel表格中
  4. 將.ipynb的程序轉成.py程序,並將其打包,實現python程序轉化為.exe的腳本程序(即不打開python編譯環境就可以自動運行寫好的python程序內容)

開始編碼

思路想好後,就正式編碼了:

導入第三方庫

在寫python程序前,可以將需要使用到的第三方庫先進行導入,導入的語法格式是:import 第三方庫名,這個第三方庫名就是我們剛才下載的那些庫【註:pyinstaller庫可以不用,因為這個是將寫好的python程序打包成.exe,不用導入進來】

導入庫的源碼如下【含注釋,最好手動敲寫】:

import xlrd# 從Excel文件讀取數據和格式化信息的庫,支持.xls以及.xlsx文件
import xlwt# 用於將數據和格式化信息寫入舊Excel文件的庫
import calendar# 導入日曆庫

獲取表格里的收支數據

接下來是開始獲取單張表的收支數據,這裡我展示一下我的記賬excel模板是:

5.png
可以從上圖看到,我的黃底紅字那裡,是對當天記賬情況的總結,只要直接獲取收支數據對應的表格內容即可。
故這裡的思路是:

graph TD
先定義一個函數,形參是參數是文件的路徑名 –> 打開文件 –> 獲取目標單元格數據

獲取單張表支出的源碼如下【含注釋,最好手動敲寫】:

# 獲取單張表的支出
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表格的命名,效果圖如下:

6.png

那這樣子就有順序了,而且每個表格都是唯一標識的,然而,我轉念一想,如果我記賬的時間是跨月的,但是又是在一星期的範圍內,我該如何統計呢?比如說記賬時間是2021-5-30到2021-6-5,可以看到雖然是在一星期的範圍內,可是他們的月份卻是不一致的,該如何解決呢?又或者是2020-12-31到2021-1-6,不單單是月份不一樣,連年份也不以言,又該如何解決呢?

其實,無論是同年不同月,還是不同年也不同月,關鍵要抓住月份是否一致就夠了,因此我在寫程序時,做了一個分流,即判斷月份是否一致,如果月份一致,就按照正常程序獲取對應的表格數據即可;可是如果月份不一致,就需要分成兩部步,先獲取開始的日期到該月結束的日期,在獲取新月的1號到結束的日期,不就能完美的解決剛才提出的問題的嗎?

解決日期的問題,就開始統計一星期的收支情況了,思路是:

graph TD
先定義一個函數,形參分別是開始賬目的日期和結束賬目的日期
–>
定義兩個列表,用於存儲總支出和總收入的數據
–>
將獲取的開始和結束日期進行字符串分割,獨立出其年月日
–>
分流判斷
–>
將總收入和總支出的表格數據分別累加
–>
分別添加到一個新的空列表中存儲

【註:
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# 返回的內容為支出-收入字典內容

將統計的新數據寫入表格

恭喜你,到這裡你已經獲取了想要的一星期收支數據的匯總情況,現在將其添加到新的表格中。
思路是:

graph TD

定義一個函數,參數為開始記賬和結束記賬日期
–>
創建表格和表單
–>
將匯總好的數據,向對應的目標單元格寫入
–>
確定保存地址
–>
完成保存

一星期賬目數據匯總寫入的源碼如下【含注釋,最好手動敲寫】:

# 一星期內容匯總

# 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效果圖如下:

7.png

生成.exe程序

到這裡,你已經完成了核心的編碼過程,現在正是將你寫好的程序做成.exe程序吧。
思路是:

graph TD
將.ipynb轉換成.py文件 –> 將.py程序生成.exe文件

此處是將.ipynb轉成.py文件

8.png

9.png

此處是將.py程序生成.exe文件
打開cmd窗口,然後輸入如下命令:pyinstaller -F (腳本路徑+腳本名),這個腳本路徑就是你當前存放.py程序的位置,這個腳本名就是你當前.py程序的名字,效果圖如下

10.png

生成.exe程序的截圖,如下:
11.png

根據exe保存路徑,找到後可以放置在指定運行環境的文件夾下,雙擊就可運行【註:使用input就可以實現與用戶交互;相同的文件重新打包,會將原本打包的內容覆蓋】

效果圖如下:
exe程序執行效果.gif
【注意:這個gif有些投影不足,是我在自定義日期時,格式是年-月-日,這個「-」切記不要丟失了】

結語

當然,此處程序還是有挺多的不足和需要改進的地方的,比如沒有對種類進行劃分,沒有用圖形化的界面展示等,這些不足將會持續的更新…