python自定义函数求差_利用Python脚本实现固定格式时间差值精确计算(Decimal)

前些天测试程序,需要记录下程序不同模块的各自运行时间。

由于各个模块之间有各自的关联,运行时间会受到数据量大小的影响,所以只能一步一步运行并记录下时间再根据需要进行差值计算。

时间格式如此:  XX(小时):XX(分钟):XX.XXX(秒)  [注:秒精确到千分位]

但个别程序由于数据量过大,运行十分缓慢,需要记录的时间差值也很多,重复过程繁琐。

虽说算差值不是什么难事,都是些简单的数值计算,但是在面对上百个需要测试的程序,我实在是懒得去一个一个算。

正所谓“懒惰为人类进步的阶梯(误)”,因此,我萌生了使用Python编写一个可以进行时间差计算的小程序的想法。(2333...)

一、确定思路

1.在本程序中,我采用的是统一单位的方法。即先将时间统一为秒,再对其进行减法运算。那么我们只需要将这个过程通过代码复现即可。

2.在经过差值计算后,我们仍需要将结果重新格式化为原规定格式(XX:XX:XX.XXX)

3.鉴于需要重复使用,可以考虑加入循环,特定条件退出运算

二、拟定程序结构

本程序有五大部分:

(1).计算主函数

(2).格式化函数

(3).单位转换函数

(4).程序主函数

(5).调用主函数

三、编写程序

但是,在开始之前,我们需要知晓一件事。

我们程序在进行差值计算时,会精确到秒的千分位,按理说我们定义浮点数据类型即可。

然而,在计算机中,采用浮点数进行计算无法达到“精确到xx位小数点”的精度。

为什么呢?我们实验一下:

首先定义两个浮点数

然后我们进行加法运算

这里就出了问题,答案并不是我们想要的6.3,而是不知什么鬼的6.300000000000001。

这里面最重要的原因就是,计算机采用二进制存储数据,使用浮点数并不能很好的表示十进制数据,会有一些"小误差"。

那我们如何才能做到十进制精确计算呢?

答案就是使用Python内置模块decimal,它可以帮助我们把浮点数转化为十进制类型,并且支持所有常用数学运算

示例:

1 from decimal importDecimal2

3 a = Decimal('4.2')4 b = Decimal('2.1')5

6 print(a + b)

结果:

我们发现,结果不再是鬼畜的6.300000000000001,是正常的6.3。

而且可以观察到,经过Decimal转化得到的是一个Decimal对象,使用时需要注意,在转化浮点数时,需要其字符串化。

那么解决了精确运算的问题,我们现在可以进行程序的编写了。

1.首先是计算主函数:

我们进行时间差计算,需要两个参数,起始时间和结束时间

然后将两参数单位统一,得到统一单位后的时间差值,再对其进行格式化以及格式的还原即可

本程序中计算主程序即是对参数单位进行统一的函数,代码如下:

(当然在程序开头要声明引入Decimal)

1 def Time_Cal(): #定义函数

2 print("----------------XX:XX:XX----------------") #打印分行符

3 #程序运行后在这里输入起始时间和结束时间

4 start_time = input("Enter your Start Time:")5 stop_time = input("Enter your Stop Time:")6 #使用split方法对输入的字符串以“:”为分隔符进行分割处理,并存为列表

7 start_list = start_time.split(':')8 stop_list = stop_time.split(':')9 #再通过不同单位划分三个部分,分别从列表获取小时、分钟、秒的值

10 start_hour =Decimal(start_list[0])11 start_minu = Decimal(start_list[1])12 start_sec = Decimal(start_list[2])13 stop_hour =Decimal(stop_list[0])14 stop_minu = Decimal(stop_list[1])15 stop_sec = Decimal(stop_list[2])16 #这里就是对获取到的各个部分的值进行单位统一(基本单位为秒)

17 value_start = start_hour * 3600 + start_minu * 60 +start_sec18 value_stop = stop_hour * 3600 + stop_minu * 60 +stop_sec19 returnvalue_stop,value_start20 #返回单位统一后的起始时间和结束时间,此时这两个参数均以秒数为单位

2.格式化函数:

这里格式化的原因是因为在我们计算结束后,有些位置的值为各位数,因标准格式(XX:XX:XX.XXX)规范,这里直接对缺位处进行补零

但这里有三点要考虑,即:小时位是否需要补零、分钟位是否需要补零、秒位是否需要补零

所以我们需要对小时、分钟、秒三部分进行判断:

同样,当时间值只有分钟秒数甚至只有秒数时也要进行类似判断。

那么在这种情况下,我们则优先对秒数处格式化函数进行定义,这样在后面判断分钟和小时是否需要补零时可以直接调用函数,减少代码量。

代码:

1 defS_Formatting(len_s,s):

2 #这里我们先定义对秒处进行格式化函数

3 if len_s < 2: #判断秒数位是否为个位数

4 s_sec = '0' + s #个位则补零

5 else:

6 s_sec = s #反之则直接向下传递

7 return s_sec #返回秒数位置的最终值

之后对分钟和小时处判断,直接调用即可:

对分钟:

1 def M_Formatting(len_m,m,len_s,s): #注意这里参数要包含秒数位的值

2 if len_m < 2:3 s_minu = '0' +m4 s_sec = S_Formatting(len_s,s) #判断秒数位时直接调用即可

5 else:6 s_minu =m7 s_sec =S_Formatting(len_s,s)8 return s_minu,s_sec #返回分钟和秒数的最终值

对小时:

1 def H_Formatting(len_h,h,len_m,m,len_s,s): #参数同样要包含分钟和秒数值

2 if len_h < 2:3 s_hour = '0' +h4 s_minu,s_sec = M_Formatting(len_m,m,len_s,s) #调用分钟格式化函数

5

6 else:7 s_hour =h8 s_minu,s_sec =M_Formatting(len_m,m,len_s,s)9   return s_hour,s_minu,s_sec #返回小时、分钟、秒数的最终值

3.单位转换函数:

单位转换函数是在单位统一后,格式化之前,对传入的起始时间和结束时间进行差值运算后,通过秒数值的大小判断分钟或者秒数位是否需要进位。

并在转换单位后调用格式化函数并将其组合为规定格式(XX:XX:XX.XXX)返回最终值。

代码:

1 def Switch(value_stop,value_start): #这里传入转化为秒的起始时间和结束时间

2 D_value = Decimal(value_stop - value_start) #计算得到时间差,为达到精确计算,调用Decimal方法

3 #从这里开始对是否需要进位进行判断

4 if D_value >= 3600: #这里是小时位需要进位的情况

5 D_hour = int(D_value) #取整,去掉小数点

6 hour = D_hour // 3600 #同样取整,做除

7 D_minu = D_hour - hour * 3600 #得到包含分钟位的值

8 minu = D_minu // 60 #取整,做除

9 sec = D_value - hour * 3600 - minu * 60 #用时间差减去得到的小时和分钟就是秒数的值

10

11 #调用格式化函数

12 s_hour,s_minu,s_sec =H_Formatting(len(str(hour)),str(hour),len(str(minu)),str(minu),len(str(int(sec))),str(sec))13 print("The Time Difference is:" + s_hour + ':' + s_minu + ':' + s_sec) #组合为规范格式输出

14 elif 60 <= D_value < 3600: #这里是分钟位进位的情况,小时值为零

15 minu = D_value // 60

16 sec = D_value - minu * 60

17 s_minu,s_sec =M_Formatting(len(str(minu)),str(minu),len(str(int(sec))),str(sec))18 print("The Time Difference is:" + '00:' + s_minu + ':' +s_sec)19 else: #仅有秒数值的情况

20 sec =D_value21 s_sec =S_Formatting(len(str(int(sec))),str(sec))22 print("The Time Difference is:" + '00:' + '00:' + s_sec)

最后编写主函数调用函数即可。

运行结果:

1 from decimal import Decimal #调用Decimal模块

2

3 defTime_Cal():4 print("----------------XX:XX:XX----------------")5 start_time = input("Enter your Start Time:")6 stop_time = input("Enter your Stop Time:")7 start_list = start_time.split(':')8 stop_list = stop_time.split(':')9 start_hour =Decimal(start_list[0])10 start_minu = Decimal(start_list[1])11 start_sec = Decimal(start_list[2])12 stop_hour =Decimal(stop_list[0])13 stop_minu = Decimal(stop_list[1])14 stop_sec = Decimal(stop_list[2])15 value_start = start_hour * 3600 + start_minu * 60 +start_sec16 value_stop = stop_hour * 3600 + stop_minu * 60 +stop_sec17 returnvalue_stop,value_start18

19 defS_Formatting(len_s,s):20 if len_s < 2:21 s_sec = '0' +s22 else:23 s_sec =s24 returns_sec25

26 defM_Formatting(len_m,m,len_s,s):27 if len_m < 2:28 s_minu = '0' +m29 s_sec =S_Formatting(len_s,s)30 else:31 s_minu =m32 s_sec =S_Formatting(len_s,s)33 returns_minu,s_sec34

35 defH_Formatting(len_h,h,len_m,m,len_s,s):36 if len_h < 2:37 s_hour = '0' +h38 s_minu,s_sec =M_Formatting(len_m,m,len_s,s)39 else:40 s_hour =h41 s_minu,s_sec =M_Formatting(len_m,m,len_s,s)42 returns_hour,s_minu,s_sec43

44 defSwitch(value_stop,value_start):45 D_value = Decimal(value_stop -value_start)46 if D_value >= 3600:47 D_hour =int(D_value)48 hour = D_hour // 3600

49 D_minu = D_hour - hour * 3600

50 minu = D_minu // 60

51 sec = D_value - hour * 3600 - minu * 60

52

53 s_hour,s_minu,s_sec =H_Formatting(len(str(hour)),str(hour),len(str(minu)),str(minu),len(str(int(sec))),str(sec))54 print("The Time Difference is:" + s_hour + ':' + s_minu + ':' +s_sec)55 elif 60 <= D_value < 3600:56 minu = D_value // 60

57 sec = D_value - minu * 60

58 s_minu,s_sec =M_Formatting(len(str(minu)),str(minu),len(str(int(sec))),str(sec))59 print("The Time Difference is:" + '00:' + s_minu + ':' +s_sec)60 else:61 sec =D_value62 s_sec =S_Formatting(len(str(int(sec))),str(sec))63 print("The Time Difference is:" + '00:' + '00:' +s_sec)64

65 def main(): #定义主函数

66 running =True67 print("Hello ~~ !")68 while running: #通过循环方便输入和计算

69 value_stop,value_start = Time_Cal() #调用计算主函数

70 Switch(value_stop,value_start) #调用单位转换函数

71 action = input("Go on ? Y/N:")72 if action == 'Y' or action == 'y':73 running =True74 elif action == 'N' or action == 'n':75 running =False76 print("Goodbye~~")77

78 if __name__ == '__main__': #调用主函数

79 main()

查看完整代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值