实践练习——python装饰器及模块

一. 记录日志装饰器练习题

好的日志对一个软件的重要性是显而易见的。如果函数的入口都要写一行代码来记录日志,这种方式实在是太低效了。 那么请你创建一个装饰器,功能实现函数运行时自动产生日志记录。 日志格式如下:

程序运行时间 主机短名 程序名称: 函数[%s]运行结果为[%s]

产生的日志文件并不直接显示在屏幕上,而是保存在 file.log 文件中,便于后期软件运行结果的分析。

 

编写的程序如下,可供参考:

import os,time,sys
def add_log(fun):
    def wrapper(*args, **kwargs):
        result = fun(*args, **kwargs)
        now_time = time.ctime()
        hostname = os.uname().nodename.split('.')[0]
        process_full_name = sys.argv[0]
        process_name = os.path.split(process_full_name)[-1]
        info = "函数%s运行结果为%s" %(fun.__name__, result)
        log1 = ' '.join([now_time, hostname, process_name])
        log2 = ':'.join([log1, info])
        file = open('file.log', 'a+')
        file.write(log2)
        file.close()
        print(log2)
        return result
    return wrapper

@add_log
def add_num(a, b):
    return a+b

add_num(4,5)

程序运行之后,就会创建一个file.log文件,并会把结果存放进去,如下所示:

 


二. 斐波那契数列的装饰器练习: 实现高速缓存递归

在数学上,费波那契数列是以递归的方法来定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)。

用文字来说,就是费波那契数列由 0 和 1 开始,之后的费波那契系数就是由之前的两数相加而得出。首几个费波那契系数是:

0,1,1,2,3,5,8,13,21,34,55,89,144,233......(OEIS 中的数列 A000045) 

装饰器 1: 添加高速缓存的装饰器 num_cache
如果第一次计算 F(5) = F(4) + F(3) = 5
第二次计算 F(6) = F(5) + F(4)
显然 F(5)已经计算过了, F(4)也已经计算了,我们可否添加一个装饰器,专门用来存储 费波那契数列已经计算过的缓存,后期计算时,判断缓存中是否已经计算过了, 如果计算过,直接用缓存中的计算结果。如果没有计算过,则开始计算并将计算的结果保存在缓存中。

装饰器 2: 程序运行计时器的装饰器 timeit
该装饰器用来测试有无高速缓存求斐波那契数列,它们两者运行的时间效率高低。

编写程序如下,可供参考:

import time
def timmer(fun):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = fun(*args, **kwargs)
        end_time = time.time()
        print("%s run %.5f" %(fun.__name__, end_time-start_time))
        return result
    return wrapper

def num_cache(fun):
    cache = {}
    def wrapper(num):
        if num in cache:
            result = cache.get(num)
            return result
        else:
            result = fun(num)
            cache[num] = result
            return result
    return wrapper

@num_cache
def fib(num):
    if num <= 2:
        return 1
    else:
        return fib(num - 1)+fib(num - 2)

@timmer
def fun1():
    result = fib(20)
    print('F(20)=', result)

@timmer
def fun2():
    result = fib(25)
    print('F(25)=', result)

fun1()
fun2()

 运行结果如下:


三. Leetcode 字符串练习题目: 比较版本号

比较两个版本号 version1 version2
如果 version1 version2 返回 1,如果 version1 version2 返回 -1, 除此之外返回 0

你可以假设版本字符串非空,并且只包含数字和 . 字符。

 . 字符不代表小数点,而是用于分隔数字序列。

例如,2.5 不是“两个半”,也不是“差一半到三”,而是第二版中的第五个小版本。

你可以假设版本号的每一级的默认修订版号为 0。例如,版本号 3.4 的第一级(大版本)和第二级(小版本)修订号分别为 34。其第三级和第四级修订号均为 0

提示:
1). 版本字符串由以点 (.) 分隔的数字字符串组成。这个数字字符串可能有前导零。
2). 版本字符串不以点开始或结束,并且其中不会有两个连续的点。

编写程序如下,可供参考:

def fun2(v1,v2):
    li1 = v1.split('.')
    li2 = v2.split('.')
    flag = 0
    while True:
        if flag == len(li1) and flag==len(li2):
            return 0
        if len(li1)==flag:
            li1.append(0)
        if len(li2)==flag:
            li2.append(0)
        if int(li1[flag])>int(li2[flag]):
            return 1
        elif int(li1[flag])<int(li2[flag]):
            return -1
        flag += 1

print(fun2('0.1', '1.1'))
print(fun2('1.0.1', '1'))
print(fun2('7.5.2.4', '7.5.3'))
print(fun2('1.01', '1.001'))
print(fun2('1.0', '1.0.0'))

输出结果为:


四. 模块与包练习题: 微信好友数据分析与展示

1. 已知 itchat 可以获取好友的信息, 此处统计好友的省份分布;
2. 获取分布好友最多的 5 个省份;
3. 将省份分布的数量基于 pyecharts 模块以条形图的方式展示;
附加需求: 将每个省份的好友备注名(RemarkName)存入依次存入对应省份的文件中;
e.g.
文件: 陕西省.txt
文件: 山东省.txt
4. 将上述 编写的代码封装为模块, 并实现模块的制作与发布。

编写程序如下,可供参考:

import itchat
from pyecharts import Bar

itchat.auto_login(hotReload=True)
friends = itchat.get_friends()
prov_dict = {}
for friend in friends[1:]:
    province = friend['Province']
    if province != '':
        if province not in prov_dict.keys():
            prov_dict[province] = 1
        else:
            prov_dict[province] += 1

prov_dict_top5 = sorted(prov_dict.items(), key=lambda x: x[1], reverse=True)[0:5]
prov_dict_top5 = dict(prov_dict_top5)
bar = Bar("好友省份分布")
bar.add("人数", list(prov_dict_top5.keys()), list(prov_dict_top5.values()))
bar.render('doc/province.html')

输出结果示例如下:

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值