zoukankan      html  css  js  c++  java
  • 自动化记账程序1.0

    需求背景:

    为了更好的解放双手,提高记账效率,本人想要制作一个基于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窗口效果。
    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有些投影不足,是我在自定义日期时,格式是年-月-日,这个“-”切记不要丢失了】

    结语

    当然,此处程序还是有挺多的不足和需要改进的地方的,比如没有对种类进行划分,没有用图形化的界面展示等,这些不足将会持续的更新…

  • 相关阅读:
    struts2中<s:select>标签的使用
    正则表达式(括号)、[中括号]、{大括号}的区别小结
    解读邮箱正则表达式:^w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$
    Struts2国际化-getText()方法
    Eclipse的Tomcat热部署,免重启的方法
    hdu 5056Boring count
    纸板上的虚拟现实和代码中的Cardboard
    OC-Protocol实现业务代理
    UVA 11237
    mysql相关日志汇总
  • 原文地址:https://www.cnblogs.com/dyxi/p/14856570.html
Copyright © 2011-2022 走看看