hello,大家好,我是虞元坚律师。好久不写文章,今天给大家介绍Python法律实务的一个基础应用——司法计算器的制作。

司法计算是一门律师基本功,尤其对诉讼律师来说,更是经常遇到,例如诉讼费、律师费、利息、违约金的计算等等。网络上,有各种各样的司法计算器工具可以供大家直接使用,比如针对2020年利息计算的新规定,律师云助理小程序就给大家提供了非常详细的LPR计算器功能。可是呢,第三方的计算器有好有坏,有时候我们还有自己的个性化需求,比如,市场上习惯将利息计算的天数,计头不计尾,但是可能我们有的律师或者法务根据客户的需要,需要又算头又算尾,又或者有自己个性化的违约金公式。如果每次都靠自己手算或者摁计算机,未免耗时又枯燥。既然学习了Python,我们不如利用Python来制作自己的计算器。接下来,我就以LPR计算器为例子,给大家介绍通过Python来编写LPR计算器小软件。重要的不是学习LPR计算器的开发,重要的是希望大家通过这篇文章,举一反三,能够自己编写各式各样的个性计算工具。话不多说,我们进入正题。

知识点归纳:

第一步:整理业务逻辑

其实编程只是一种将想法程序化的过程,最重要的是业务逻辑的设计,如果这个业务逻辑没有理顺的话,可能后面就走不通了,考虑的时候要将可能的情形尽量考虑全面。其实也不难,这里直接把方案告诉大家,如果有错误,欢迎大家指正:

第二步:建立自己的LPR数据库或存储文件

LPR跟之前的同期同档利息有一个不同点,就是LPR的利息央行每个月20号左右会更新,因此,需要在每月的20号留意央行的信息,并将数值保存下来。保存的方案有很多种,笔者是通过爬虫技术采集后放在数据库中,在需要的时候调用。对初学者来说,还构建数据库难度相对较高,可以直接保存在py文件中保存,在需要的时候以文本方式打开调用,或者直接放在Python文件的变量中。以下我就直接将2019-08-20起到2020-02-20止的所有的lpr利息放在lpr_lib这个变量中使用。可以看出,这是一个列表嵌套字典的数据类型。

lpr_lib=[
{'lpr1': 4.25, 'lpr5':4.85 ,'uploadDate': '2019-08-20' ,'timeStamp':1566259200 },
{'lpr1': 4.20, 'lpr5':4.85 ,'uploadDate': '2019-09-20' ,'timeStamp':1568937600},
{'lpr1': 4.20, 'lpr5': 4.85 ,'uploadDate': '2019-10-21','timeStamp':1571616000},
{'lpr1': 4.15, 'lpr5': 4.80 ,'uploadDate': '2019-11-20','timeStamp':1574208000},
{'lpr1': 4.15, 'lpr5': 4.80 ,'uploadDate': '2019-12-20','timeStamp':1576800000},
{'lpr1': 4.15, 'lpr5': 4.80 ,'uploadDate': '2020-01-20','timeStamp':1579478400},
{'lpr1': 4.05, 'lpr5': 4.75, 'uploadDate': '2020-02-20','timeStamp':1582156800},
]

上面的“timeStamp”就是日期的时间戳,所谓时间戳,就是从1970年01月01日00时00分00秒计算到现在的秒数或者毫秒数。这里有个知识点,就是日期与时间戳的转换,你可以选择百度时间戳转换工具直接转换,也可以直接使用python将格式化的日期转换成时间戳,函数略微麻烦,没必要硬记,知道怎么调用就行了:

import time   #不要忘了导入时间模块
startDate='2019-10-10' #开始日期
startDate_timeStamp = int(time.mktime(time.strptime(startDate, "%Y-%m-%d"))) #"%Y-%m-%d"表示年月日,与你startDate的格式对应
print(startDate_timeStamp )
#结果:1570636800

日期转换成时间戳的目的,主要是为了比较日期大小或计算日期间隔,数值越大,日期越后。

第三步:给需要使用的变量赋值,变量的命名尽量与实际的含义有关。

capital=10000   #本金
startDate='2019-10-10' #开始日期
endDate='2020-02-02' #截至日期
startDate_timeStamp = int(time.mktime(time.strptime(startDate, "%Y-%m-%d"))) #开始日期的时间戳
endDate_timeStamp = int(time.mktime( time.strptime(endDate, "%Y-%m-%d"))) #结束日期的时间戳
mylpr=[] #新的列表,用来存放筛选出来的LPR档期

为了表述方便,下面开始日期、截至日期等术语,我就直接以变量名如startDate、endDate来代替。

第四步:获取相关日期内相关的lpr利息档次

为了找到我们需要的LPR档期,我们需要考虑出现的可能情况,有时候我们在编程中可以画一些简单的逻辑图来做辅助,有助于我们考虑尽可能多的情况:

进制计算器_进制计算器在线计算_进制计数器

LPR_Update表示LPR档期的更新日期

从上图中,我们可以看出,LPR_Update1是一定需要且存在的,LPR_Update2有可能存在,也可能不存在。比如现在是2020年03月02日, StartDate我也取该日,那么一直到当月20日左右新发布LPR之前,我们都是沿用的2月份的LPR利息。

上图中第一个LPR_Update1如何获取呢,如何保证在startDate之前的lpr档期正好是前一个而不是前前个,甚至更遥远的呢,其实只要计算两者时间戳之差,如果在一个月以内的,就是最近的一期:

#逻辑表述,非使用的代码
startDate_timestamp>=lpr_timestamp and startDate_timestamp-lpr_timestamp<2678400 #2678400是31天的秒数
#2678400=60*60*24*31
#startDate_timestamp 开始日期的时间戳 lpr_timestamp: Lpr更新日期的时间戳

第二个LPR_Update2 就更容易了:

#逻辑表述,非使用的代码
lpr_timestamp>=startDate_timestamp and lpr_timestamp<=endDate_timestamp
#startDate_timestamp 开始日期的时间戳 endDate_timestamp:结束日期的时间戳 lpr_timestamp: Lpr更新日期的时间戳

上述两个逻辑合并在一起,本例中具体用python语言怎么表达呢:

mylpr=[]
for i in lpr_lib:
if (startDate_timeStamp>i['timeStamp'] and startDate_timeStamp-i['timeStamp']<2678400 ) or (i['timeStamp']>=startDate_timeStamp and i['timeStamp']<=endDate_timeStamp):
mylpr.append(i)
print('mylpr:',mylpr)
# 结果显示 mylpr: [{'lpr1': 4.2, 'lpr5': 4.85, 'uploadDate': '2019-09-20', 'timeStamp': 1568937600}, {'lpr1': 4.2, 'lpr5': 4.85, 'uploadDate': '2019-10-21', 'timeStamp': 1571616000}, {'lpr1': 4.15, 'lpr5': 4.8, 'uploadDate': '2019-11-20', 'timeStamp': 1574208000}, {'lpr1': 4.15, 'lpr5': 4.8, 'uploadDate': '2019-12-20', 'timeStamp': 1576800000}, {'lpr1': 4.15, 'lpr5': 4.8, 'uploadDate': '2020-01-20', 'timeStamp': 1579478400}]

这里用到了列表循环,将存储在lpr_lib这个列表变量中符合我们要求的LPR档期全都保存到了一个新的列表变量mylpr当中。以上就完成了,LPR计算器工作的一半了,接下来,就要进入到具体的计算场景当中了,实务当中,各地的法院计算标准不一,有些地方以平均LPR值计算,有些地方以最后有效的LPR值作为计算,也有些地方可能以各个LPR来分段计算(笔者尚未遇到过),笔者在微信小程序”律师云助理”和网站中都已做成现成的计算器工具,欢迎体验。

律师云助理

律师云助理小程序

以上完整的代码,整理起来就是:

import time

if __name__=='__main__':
lpr_lib=[
{'lpr1': 4.25, 'lpr5':4.85 ,'uploadDate': '2019-08-20' ,'timeStamp':1566259200 },
{'lpr1': 4.20, 'lpr5':4.85 ,'uploadDate': '2019-09-20' ,'timeStamp':1568937600},
{'lpr1': 4.20, 'lpr5': 4.85 ,'uploadDate': '2019-10-21','timeStamp':1571616000},
{'lpr1': 4.15, 'lpr5': 4.80 ,'uploadDate': '2019-11-20','timeStamp':1574208000},
{'lpr1': 4.15, 'lpr5': 4.80 ,'uploadDate': '2019-12-20','timeStamp':1576800000},
{'lpr1': 4.15, 'lpr5': 4.80 ,'uploadDate': '2020-01-20','timeStamp':1579478400},
{'lpr1': 4.05, 'lpr5': 4.75, 'uploadDate': '2020-02-20','timeStamp':1582156800},
]

capital=10000 #本金
startDate='2019-10-10' #开始日期
endDate='2020-02-02' #截至日期
startDate_timeStamp = int(time.mktime(time.strptime(startDate, "%Y-%m-%d")))
endDate_timeStamp = int(time.mktime( time.strptime(endDate, "%Y-%m-%d")))
mylpr=[]
for i in lpr_lib:
# print('i:',i)
if (startDate_timeStamp>i['timeStamp'] and startDate_timeStamp-i['timeStamp']<2678400 ) or (i['timeStamp']>=startDate_timeStamp and i['timeStamp']<=endDate_timeStamp):
mylpr.append(i)

#以上,我们就将所有需要用到LPR利息档次都放到了mylpr变量当中,以供我们下一步使用。

以上,我们已经将我们需要的LPR档期从我们自己LPR仓库或者存储变量中拆分了出来,接下来,我们要根据实务中不同的LPR场景,来进行设计。实务当中,我们可能会遇到按照LPR平均值求利息的,或者按照截至月份的LPR来求利息的,或者最严谨也最麻烦的,按照每个分段来计算LPR利息的。前面两种都非常简单,重点是第三种方式,接下来,我们以LPR一年期利息为例子,依次设计这三种方案:

在计算这三种情形之前,有一个计算是三者通用的,那就是计算startDate和endDate的天数,这个其实非常简单,利用时间戳做减法运算就可以了:

    days= int((endDate_timeStamp-startDate_timeStamp)/(60*60*24))
print('days:',days)
---------------------------------------------------------------------------------------------------
#结果:days: 115

1、 以LPR平均值求利息

    avgTotal_1=0
for m in mylpr:
avgTotal_1=avgTotal_1+m['lpr1']
avgLPR_1= avgTotal_1/len(mylpr)
print('avgTotal_1:',avgTotal_1,'avgLPR_1:',avgLPR_1)
---------------------------------------------------------------------------------------------------
#结果:avgTotal_1: 20.85 avgLPR_1: 4.17

获得了平均LPR值,接下来就只需要利息天数套入传统的利息计算公式中就行了:

interest= days*capital*avgLPR_1*(1/360)*(1/100) #注意前面的lpr_lib存储的利息是省略掉了%的年息

2、以截至月LPR求利息

由于本例当中,笔者将所有LPR利息,都按照日期从前到后的顺序存储在了lpr_lib这个列表变量当中,由于my_lpr的求得也是根据遍历lpr_lib得出的,因此也很容易推出,截至月即最后一个lpr档期即my_lpr列表中的最后一个位置的值,即:

lastLPR=mylpr[-1]
interest= days*capital*lastLPR*(1/360)*(1/100)

3、分段结算LPR利息

分段计算要复杂一点,我们需要单独筛选出startDate到endDate之间每个lpr档次中涉及的天数,并且将每个档期中的开始日期和截至日期和天数差计算出来,这里需要考虑的情况要多一点,思考的时候要逻辑严密些:

进制计算器在线计算_进制计算器_进制计数器

简单逻辑图

从我上图简单画的逻辑图可以看出,只有一个lpr档期,即my_lpr长度为1的时候,计算最简单。但是当不止1个LPR档期的时候,就需要我们分别考虑可能的情形,并加以切割计算。因为代码量较多,有兴趣的朋友可以自己先研究下实现方式。完整的代码我会在20年下半年的新书中给大家完整呈现。

本文中还有一个隐藏知识,就是Python的四舍五入,由于计算机CPU是以二进制来作为标准进行浮点运算的,所以简单的round()函数处理四舍五入,会不精确。这个扩展知识由于对初学者理解难度可能较大,有兴趣的朋友可以自行扩展。

如果大家有更好的提议,或者希望我写什么类型的文章,或者实务当中遇到什么类型的需求希望能通过python实现的,欢迎留言或者私信。我会考虑实现的可能性,给大家提供一些技术方法或思路。

———END———

限 时 特 惠: 本站每日持续更新海量各大最新【内部创业教程】,一年会员只需 98 元,全站资源免费下载 点击查看详情

站 长 微 信: webprojs_com

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注