zoukankan      html  css  js  c++  java
  • 数字日期和时间

    数字的四舍五入

    问题:

      你想对浮点数执行指定精度的舍入运算。

    解决方法:

      对于简单的舍入运算,使用内置的round(value, ndigits) 函数即可。比如:

     1 #保留小数点后1位数,因为比1.25小,所以四舍五入,取小的
     2 r1 = round(1.23, 1)
     3 print(r1)
     4 
     5 #保留小数点后1位数,因为比1.25大,所以四舍五入,所以取大的
     6 r2 = round(1.27, 1)
     7 print(r2)
     8 
     9 #保留小数点后1位数,因为比-1.25小,所以四舍五入,所以取小的
    10 r3 = round(-1.27, 1)
    11 print(r3)
    12 
    13 #保留小数点后3位数,因为比1.253大,所以四舍五入,所以取大的 
    14 r4 = round(1.25361, 3)
    15 print(r4)

    以上代码执行的结果为:

    1.2
    1.3
    -1.3
    1.254

    执行精确的浮点数运算

    问题:

      你需要对浮点数执行精确的计算操作,并且不希望有任何小误差的出现。

    解决方案:

      浮点数的一个普遍问题是它们并不能精确的表示十进制数。并且,即使是最简单的数学运算也会产生小的误差,比如:

     1 a = 4.2
     2 b = 2.1
     3 c = a + b
     4 
     5 if c == 6.3:
     6     print('True')
     7 else:
     8     print('False')
     9     print(c)
    10 
    11 #解决方案,如果你想更加精确(并能容忍一定的性能损耗),你可以使用decimal 模块
    12 print('*'*30)
    13 from decimal import Decimal
    14 a = Decimal('4.2')
    15 b = Decimal('2.1')
    16 c = a + b
    17 print(c)

    以上代码运行的结果为:

    False
    6.300000000000001
    ******************************
    6.3

    即便如此,你却不能完全忽略误差。数学家花了大量时间去研究各类算法,有些处理误差会比其他方法更好。你也得注意下减法删除已经大数和小数的加分运算所带来的影响。比如:

    1 nums = [1.23e+18, 1, -1.23e+18]
    2 #返回的结果是0.0,是错误的结果
    3 print('错误的结果为:', sum(nums))
    4 
    5 #解决上面的问题办法
    6 import math
    7 print('正确的结果为:', math.fsum(nums))

    以上代码运行的结果为:

    错误的结果为: 0.0
    正确的结果为: 1.0

    总结:

      总的来说, decimal 模块主要用在涉及到金融的领域。在这类程序中,哪怕是一点小小的误差在计算过程中蔓延都是不允许的。因此, decimal 模块为解决这类问题提供了方法。当Python 和数据库打交道的时候也通常会遇到Decimal 对象,并且,通常也是在处理金融数据的时。

    数字的格式化输出

    问题:

      你需要将数字格式化后输出,并控制数字的位数、对齐、千位分隔符和其他的细节。

    解决方案:

      格式化输出单个数字的时候,可以使用内置的format() 函数,比如:

     

     1 x = 1234.56789
     2 print(format(x, '0.2f'))
     3 
     4 #右对齐10个字符并保留小数点后一位
     5 print("右对齐十个字符:", format(x, '>10.1f'))
     6 
     7 #左对齐10个字符并保留小数点后一位
     8 print("左对齐十个字符:", format(x, '<10.1f') + '!')
     9 
    10 #居中对齐
    11 print("居中对齐十个字符:", format(x, '^10.1f'))
    12 
    13 #分离器,分离千万
    14 print("分离的格式:", format(x, ','))
    15 
    16 print(format(x, '0,.1f'))

     

    以上代码运行的结果为:

    1234.57
    右对齐十个字符:     1234.6
    左对齐十个字符: 1234.6    !
    居中对齐十个字符:   1234.6  
    分离的格式: 1,234.56789
    1,234.6

    二八十六进制整数

    问题:

      你需要转换或者输出使用二进制,八进制或十六进制表示的整数。

     

    解决方案:

      为了将整数转换为二进制、八进制或十六进制的文本串,可以分别使用bin() ,oct() 或hex() 函数:

     1 x = 1234
     2 
     3 #二进制格式的
     4 print(bin(x))
     5 
     6 #八进制格式的
     7 print(oct(x))
     8 
     9 #十六进制格式的
    10 print(hex(x))
    11 
    12 #如果你不想输出0b , 0o 或者0x 的前缀的话,可以使用format() 函数
    13 print(format(x, 'b'))
    14 print(format(x, 'o'))
    15 print(format(x, 'x'))

    以上代码运行的结果为:

    0b10011010010
    0o2322
    0x4d2
    10011010010
    2322
    4d2

    字节到大整数的打包与解包

    问题:

      你有一个字节字符串并想将它解压成一个整数。或者,你需要将一个大整数转换为一个字节字符串。

    解决方案:

      假设你的程序需要处理一个拥有128 位长的16 个元素的字节字符串。比如:

     1 data = b'x00x124Vx00xx90xabx00xcdxefx01x00#x004'
     2 
     3 print('data的长度为:', len(data))
     4 
     5 r1 = int.from_bytes(data, 'little')
     6 print(r1)
     7 
     8 r2 = int.from_bytes(data, 'big')
     9 print(r2)
    10 
    11 #为了将一个大整数转换为一个字节字符串,使用int.to bytes() 方法,并像下面这样指定字节数和字节顺序
    12 x = 94522842520747284487117727783387188
    13 r3 = x.to_bytes(16, 'big')
    14 print(r3)
    15 
    16 r4 = x.to_bytes(16, 'little')
    17 print(r4)

    以上代码运行的结果为:

    data的长度为: 16
    69120565665751139577663547927094891008
    94522842520747284487117727783387188
    b'x00x124Vx00xx90xabx00xcdxefx01x00#x004'
    b'4x00#x00x01xefxcdx00xabx90xx00V4x12x00'

    分数运算

    问题:

      你进入时间机器,突然发现你正在做小学家庭作业,并涉及到分数计算问题。或者你可能需要写代码去计算在你的木工工厂中的测量值。

    解决方案:

      fractions 模块可以被用来执行包含分数的数学运算。比如:

     1 from fractions import Fraction
     2 
     3 #除法 等同于5/4 7/16
     4 a = Fraction(5, 4)
     5 b = Fraction(7, 16)
     6 
     7 r1 = a * b
     8 print(a + b)
     9 print(a * b)
    10 
    11 #被除数
    12 r = a * b
    13 print(r.numerator)
    14 
    15 #除数
    16 print(r.denominator)
    17 
    18 #结果
    19 print(float(r))

    以上代码运行的结果为:

    27/16
    35/64
    35
    64
    0.546875

    大型数组运算

    问题:

      你需要在大数据集(比如数组或网格) 上面执行计算

    解决方案:

      涉及到数组的重量级运算操作,可以使用NumPy 库。NumPy 的一个主要特征是它会给Python 提供一个数组对象,相比标准的Python 列表而已更适合用来做数学运算。下面是一个简单的小例子,向你展示标准列表对象和NumPy 数组对象之间的差别:

     1 x = [1, 2 ,3 , 4, 5]
     2 y = [6, 7, 8, 9, 10]
     3 
     4 #x列表的乘以2的效果
     5 print("x*2:", x * 2)
     6 
     7 #做列表拼接
     8 print('x+y:', x + y)
     9 
    10 import numpy as np
    11 # print("数组".center(40, "*"))
    12 print('{:*^40}'.format('数组'))
    13 
    14 ax = np.array([1, 2, 3, 4])
    15 ay = np.array([5, 6, 7, 8])
    16 
    17 #数组的每个元素都乘以2
    18 print('ax*2 :', ax * 2)
    19 print('ax+10:', ax + 10)
    20 print('ax+ay:', ax + ay)
    21 print('ax*ay:', ax * ay)

    以上代码运行的结果为:

    x*2: [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
    x+y: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    *******************数组*******************
    ax*2 : [2 4 6 8]
    ax+10: [11 12 13 14]
    ax+ay: [ 6  8 10 12]
    ax*ay: [ 5 12 21 32]

    总结:

      正如所见,两种方案中数组的基本数学运算结果并不相同。特别的, NumPy 中的标量运算(比如ax * 2 或ax + 10 ) 会作用在每一个元素上。另外,当两个操作数都是数组的时候执行元素对等位置计算,并最终生成一个新的数组。

    矩阵与线性代数运算

    问题:

      你需要执行矩阵和线性代数运算,比如矩阵乘法、寻找行列式、求解线性方程组等等。

    解决方案:

      NumPy 库有一个矩阵对象可以用来解决这个问题。

     1 import numpy as np
     2 
     3 m = np.matrix([[1, -2, 3], [0, 4, 5], [7, 8, 9]])
     4 
     5 print(m.T)
     6 print(''.center(40, '*'))
     7 
     8 print(m.I)
     9 print(''.center(40, '-'))
    10 
    11 v = np.matrix([[2], [3], [4]])
    12 print(v)
    13 
    14 print(''.center(40, '~'))
    15 print(m * v)

    以上代码运行的结果为:

    [[ 1  0  7]
     [-2  4  8]
     [ 3  5  9]]
    ****************************************
    [[ 0.02531646 -0.26582278  0.13924051]
     [-0.22151899  0.07594937  0.03164557]
     [ 0.17721519  0.13924051 -0.02531646]]
    ----------------------------------------
    [[2]
     [3]
     [4]]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    [[ 8]
     [32]
     [74]]

    随机选择

    问题:

      你想从一个序列中随机抽取若干元素,或者想生成几个随机数。

    解决方案:

      random 模块有大量的函数用来产生随机数和随机选择元素。比如,要想从一个序列中随机的抽取一个元素,可以使用random.choice() :

     1 import random
     2 
     3 values = list(range(10))
     4 
     5 #从values中提取单个元素
     6 print('提取单个元素'.center(15, '*'))
     7 print(random.choice(values))
     8 print(random.choice(values))
     9 print(random.choice(values))
    10 print(random.choice(values))
    11 
    12 #从values中提取N个不同的元素
    13 print('提取N个元素'.center(15, '*'))
    14 print(random.sample(values, 3))
    15 print(random.sample(values, 3))
    16 print(random.sample(values, 3))
    17 
    18 print('打乱values的元素顺序'.center(15, '*'))
    19 print('打乱之前的values:', values)
    20 random.shuffle(values)
    21 print("打乱以后的values:", values)

    以上代码运行的结果为:

    *****提取单个元素****
    1
    2
    7
    0
    *****提取N个元素****
    [3, 5, 0]
    [4, 8, 2]
    [4, 9, 3]
    *打乱values的元素顺序*
    打乱之前的values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    打乱以后的values: [1, 8, 7, 2, 9, 5, 3, 4, 0, 6]

    基本的日期与时间转换

    问题:

      你需要执行简单的时间转换,比如天到秒,小时到分钟等的转换。

    解决方案:

      为了执行不同时间单位的转换和计算,请使用datetime 模块。比如,为了表示一个时间段,可以创建一个timedelta 实例,就像下面这样:

     1 from datetime import timedelta, datetime
     2 
     3 a = timedelta(days=2, hours=6)
     4 b = timedelta(hours=4.5)
     5 c = a + b
     6 
     7 print('biubiu天~:', c.days)
     8 
     9 print('biubiu秒~:', c.seconds)
    10 
    11 print('小时:', c.seconds / 3600)
    12 
    13 print('总共经过多少小时:', c.total_seconds() / 3600)
    14 
    15 a1 = datetime(2017, 8, 3)
    16 #在当前时间上加10天
    17 print(a1 + timedelta(days=10))
    18 
    19 b1 = datetime(2017, 12, 21)
    20 c1 = b1 - a1
    21 #两个时间点相差多少天
    22 print(c1)
    23 
    24 print(c1.days)
    25 
    26 print('当前时间'.center(30, '*'))
    27 now = datetime.today()
    28 print(now)
    29 
    30 print('当前时间往后推8个小时'.center(26,"*"))
    31 print(now + timedelta(hours=8))
    32 
    33 print('当前时间往后推30分钟'.center(27, '*'))
    34 print(now + timedelta(minutes=30))

    以上代码运行的结果为:

    biubiu天~: 2
    biubiu秒~: 37800
    小时: 10.5
    总共经过多少小时: 58.5
    2017-08-13 00:00:00
    140 days, 0:00:00
    140
    *************当前时间*************
    2017-08-03 14:42:28.002825
    *******当前时间往后推8个小时********
    2017-08-03 22:42:28.002825
    ********当前时间往后推30分钟********
    2017-08-03 15:12:28.002825

    计算最后一个周五的日期

    问题:

      你需要查找星期中某一天最后出现的日期,比如星期五。

    解决方案:

      Python 的datetime 模块中有工具函数和类可以帮助你执行这样的计算。下面是对类似这样的问题的一个通用解决方案:

     1 from datetime import datetime, timedelta
     2 
     3 weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
     4             'Friday', 'Saturday', 'Sunday']
     5 
     6 def get_previous_byday(dayname, start_date=None):
     7     if start_date is None:
     8         start_date = datetime.today()
     9     day_num = start_date.weekday()
    10     day_num_target = weekdays.index(dayname)
    11     days_ago = (7 + day_num - day_num_target) % 7
    12     if days_ago == 0:
    13         days_ago = 7
    14     target_date = start_date - timedelta(days=days_ago)
    15     return target_date
    16 
    17 
    18 print(get_previous_byday('Monday'))
    19 print(get_previous_byday('Tuesday'))
    20 print(get_previous_byday('Friday'))
    21 get_previous_byday('Sunday', datetime(2017, 12, 21))

    以上代码运行的结果为:

    2017-07-31 14:58:38.092831
    2017-08-01 14:58:38.092945
    2017-07-28 14:58:38.092975
    2017-12-24 00:00:00

    上面的算法原理是这样的:先将开始日期和目标日期映射到星期数组的位置上(星期一索引为0),然后通过模运算计算出目标日期要经过多少天才能到达开始日期。然后用开始日期减去那个时间差即得到结果日期

     

    计算当前月份的日期范围

    问题:

      你的代码需要在当前月份中循环每一天,想找到一个计算这个日期范围的高效方法

    解决方案:

      在这样的日期上循环并需要事先构造一个包含所有日期的列表。你可以先计算出开始日期和结束日期,然后在你步进的时候使用datetime.timedelta 对象递增这个日期变量即可

     1 from datetime import datetime, date , timedelta
     2 import calendar
     3 
     4 def get_month_range(start_date=None):
     5     if start_date is None:
     6         start_date = date.today().replace(day=1)
     7     _, days_in_month = calendar.monthrange(start_date.year, start_date.month)
     8     end_date = start_date + timedelta(days=days_in_month)
     9     return (start_date, end_date)
    10 
    11 a_day = timedelta(days=1)
    12 first_day, last_day = get_month_range()
    13 
    14 while first_day < last_day:
    15     print(first_day)
    16     first_day += a_day

    以上代码运行的结果为:

    017-08-01
    2017-08-02
    2017-08-03
    2017-08-04
    2017-08-05
    2017-08-06
    2017-08-07
    2017-08-08
    ................

    结合时区的日期操作

    问题:

      你有一个安排在2012 年12 月21 日早上9:30 的电话会议,地点在芝加哥。而你的朋友在印度的班加罗尔,那么他应该在当地时间几点参加这个会议呢?

    解决方案:

      对几乎所有涉及到时区的问题,你都应该使用pytz 模块。这个包提供了Olson 时区数据库,它是时区信息的事实上的标准,在很多语言和操作系统里面都可以找到

     1 from datetime import datetime
     2 from pytz import timezone, utc
     3 
     4 #初始化时间
     5 d = datetime(2017, 8, 3, 11, 20, 38)
     6 print("本地时间:", d)
     7 
     8 #转换成芝加哥时间
     9 central = timezone("US/Central")
    10 loc_d = central.localize(d)
    11 print("芝加哥的时间:", loc_d)
    12 
    13 #班加罗尔的时间 pytz.utc是utc时间,asctimezone中可以替换成这个
    14 bang_d = loc_d.astimezone(timezone('Asia/Kolkata'))
    15 #bang_d = loc_d.astimezone(utc)
    16 print("班加罗尔的时间:", bang_d)

    以上代码运行的结果为:

    本地时间: 2017-08-03 11:20:38
    芝加哥的时间: 2017-08-03 11:20:38-05:00
    班加罗尔的时间: 2017-08-03 21:50:38+05:30
  • 相关阅读:
    测试方案
    如何编写一个好的测试计划
    一个好的测试过程
    java后台生成echarts图表并保存图片
    Javascript数组排序,并获取排序后位置对应的原索引(堆排序实现)
    修改tomcat编码方式
    json序列化反序列化后function丢失
    Mysql数据库存取性能优化
    java创建文件
    Java POI导出ppt简单实现
  • 原文地址:https://www.cnblogs.com/demon89/p/7274490.html
Copyright © 2011-2022 走看看