用Python批量提取Win10锁屏壁纸

使用 Win10 的朋友会发现,每次开机锁屏界面都会有不一样的漂亮图片,这些图片通常选自优秀的摄影作品,十分精美。 但是由于系统会自动更换这些图片,所以就算再好看的图片,也许下次开机之后就被替换掉了。 借助 Python,我们可以用简单的几行代码,批量提取这些精美的锁屏图片。把喜欢的图片设置成桌面背景,就不用担心被替换掉啦。 提取原理 Win10 系统会自动下载最新的锁屏壁纸,并将他们保存在一个系统文件夹中,路径是C:\Users\[用户名]\AppData\Local\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets 直接打开这个文件夹,里面会有随机命名的多个文件,每一个文件就是一张图片。但是由于文件没有扩展名,所以并不能预览。为了不搞坏系统文件,并且把这些文件变成可以预览的格式,我们用 Python 把这些文件复制出来,加上 JPG 作为扩展名。 实现代码 import os, shutil from datetime import datetime # 把这个文件所在目录wallpapers文件夹作为保存图片的目录 save_folder = dir_path = os.path.dirname( os.path.realpath(__file__)) + '\wallpapers' # 动态获取系统存放锁屏图片的位置 wallpaper_folder = os.getenv('LOCALAPPDATA') + ( '\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy' '\LocalState\Assets') # 列出所有的文件 wallpapers = os.listdir(wallpaper_folder) for wallpaper in wallpapers: wallpaper_path = os.path.join(wallpaper_folder, wallpaper) # 小于150kb的不是锁屏图片 if (os.path.getsize(wallpaper_path) / 1024) < 150: continue wallpaper_name = wallpaper + '.jpg' save_path = os.path.join(save_folder, wallpaper_name) shutil.copyfile(wallpaper_path, save_path) print('Save wallpaper ' + save_path) 首先确定系统存放锁屏图片的文件夹位置,由于文件夹位于用户的个人文件夹内,每个用户的用户名是不一样的,所以我们需要通过系统的LOCALAPPDATA变量动态的获取路径。代码会把提取出来的图片保存在 wallpapers 文件夹下,所以代码文件所在的目录没有 wallpapers 文件夹,需要手工创建一个。 ...

三月 26, 2018 · 1 分钟 · Zhiya

15行Python代码,帮你理解令牌桶算法

在网络中传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送,令牌桶算法就实现了这个功能,可控制发送到网络上数据的数目,并允许突发数据的发送。 什么是令牌 从名字上看令牌桶,大概就是一个装有令牌的桶吧,那么什么是令牌呢? 紫薇格格拿的令箭,可以发号施令,令行禁止。在计算机的世界中,令牌也有令行禁止的意思,有令牌,则相当于得到了进行操作的授权,没有令牌,就什么都不能做。 用令牌实现限速器 我们用 1 块令牌来代表发送 1 字节数据的资格,假设我们源源不断的发放令牌给程序,程序就有资格源源不断的发送数据,当我们不发放令牌给程序,程序就相当于被限流,无法发送数据了。接下来我们说说限速器,所谓限速器,就是让程序在单位时间内,最多只能发送一定大小的数据。假设在 1 秒发放 10 块令牌,那么程序发送数据的速度就会被限制在 10bytes/s。如果 1 秒内有大于 10bytes 的数据需要发送,就会因为没有令牌而被丢弃。 改进限速器——加个桶 我们实现的限速器,速度是恒定的,但是在实际的应用中,往往会有突发的传输需求(需要更快速的发送,但是不会持续太久,也不会引起网络拥塞),这种数据碰上我们的限速器,就因为拿不到令牌而无法发送。 对限速器进行一下改动,依然 1 秒产生 10 块令牌,但是我们把产生出来的令牌先放到一个桶里,当程序需要发送的时候,从桶里取令牌,不需要的时候,令牌就会在桶里沉淀下来,假设桶里沉淀了 10 块令牌,程序最多就可以在 1 秒内发送 20bytes 的数据,满足了突发数据传输的要求,并且由于桶里的令牌被用完,下一秒最多依然只能发 10bytes 的数据,不会因为持续发送大量数据,对网络造成压力。 15 行 Python 代码实践令牌桶 令牌桶需要以一定的速度生成令牌放入桶中,当程序要发送数据时,再从桶中取出令牌。这里似乎有点问题,如果我们使用一个死循环,来不停地发放令牌,程序就被阻塞住了,有没有更好的办法? 我们可以在取令牌的时候,用现在的时间减去上次取令牌的时间,乘以令牌的发放速度,计算出桶里可以取的令牌数量(当然不能超过桶的大小),从而避免循环发放的逻辑。 接下来看代码: import time class TokenBucket(object): # rate是令牌发放速度,capacity是桶的大小 def __init__(self, rate, capacity): self._rate = rate self._capacity = capacity self._current_amount = 0 self._last_consume_time = int(time.time()) # token_amount是发送数据需要的令牌数 def consume(self, token_amount): increment = (int(time.time()) - self._last_consume_time) * self._rate # 计算从上次发送到这次发送,新发放的令牌数量 self._current_amount = min( increment + self._current_amount, self._capacity) # 令牌数量不能超过桶的容量 if token_amount > self._current_amount: # 如果没有足够的令牌,则不能发送数据 return False self._last_consume_time = int(time.time()) self._current_amount -= token_amount return True

三月 20, 2018 · 1 分钟 · Zhiya

最爱你的人,会让你不费脑细胞的理解区块链原理

区块链是一个近期非常火的概念,随便走进一个写字楼的电梯,都会听到有人谈论区块链,或者炒币: ) 希望通过这篇文章,能让你对区块链的概念有一个整体的认识,在理解概念后,下一篇文章将用大约 300 行 Python 代码,实现一个区块链网络。 区块 和 链 所谓区块,就是一个块咯(要不然还是什么?),把这些块一个一个连在一起,像链条一样,就称为区块链(别急着打我,先往下看)。 这是一些链条,链条的价值更多的体现在锁楼下小电动车的时候,不过我们再仔细看一下这个链条是不是有点像那什么?⛓ 很聪明,高中生物老师在冲你微笑!这就是传说中的脱氧核糖核酸(DNA),DNA 也是一种链式结构,携带了遗传信息。区块链中的“区块”,就好比 DNA 分子中的脱氧核糖核苷酸(我也不知道自己在说什么),而区块链中的“链”,就好比 DNA 分子的链式结构。 DNA 和链条的价值差异,关键在于 DNA 携带了大量遗传信息,而链条什么都没有携带。对于区块链来说,携带信息也是它的一个重要特点(不携带信息连锁电动车的作用都没有)。 当区块链携带的是账务信息的时候,它就变成了一个特别厉害的东西——账本(我们给他起了个 00 后的名字——比特币)。 Peer-to-Peer 为了显得专业一些,我们祭出比特币的创造者,中本聪的论文《Bitcoin: A Peer-to-Peer Electronic Cash System》,从这篇论文的题目我们可以看到,区块链是基于Peer-to-Peer的,下面就来了解一下什么是 Peer-to-Peer。 Peer-to-Peer,简称 P2P(不是互联网借贷的那个 P2P),它是一种点对点网络,看图(我也不知道该怎么讲)。 图中每一个方脑袋就是一个 Peer(节点),注意一下,这些方脑袋有一个共同点,他们都一毛一样(不仅长得一样,每一个脑袋都跟其它脑袋相连)。这也是 P2P 网络的最大特点——去中心化,P2P 网络中不存在中心节点,所有节点都是平等的,任何一个节点,想跟谁说话就跟谁说话,并且谁(节点)都不能说了算。 共识机制 你和好基友老王,还有你们共同喜欢的一个姑娘阿圆(对,就是圆滚滚的圆),组成了一个三节点的 P2P 网络,根据 P2P 网络定义你们三个人谁都不能说了算。这一天,阿圆生日,你和老王同时给阿圆送了一个大蛋糕,那么问题来了,阿圆先吃哪个呢? 既然没有人能说了算,也不能让你和老王决斗(计算机这么做恐怕人类会毁灭),那么就需要采用一个文明的办法决定——商量。既然商量,就要有规矩,这个规矩叫共识机制。 Proof-of-work 区块链共识机制有很多种,Proof-of-work(POW,工作量证明)是其中一种,所谓工作量证明,有点像是比武招亲。你和老王对阿圆都很好,阿圆也很难抉择到底先吃谁的蛋糕,于是她请了两位武力相当的武林高手,让你和老王分别与高手过招,谁赢了高手,就先吃谁的蛋糕,如果你们都赢了高手,那么谁先赢算数。 把这些捏在一起 了解了 POW、共识机制、P2P、区块、链的概念,我们就可以把他们拼在一起,看看会发生什么了。 我们把 P2P 网络中的每一个节点,赋予一条链,这样网络中所有的链都是平等的了,接下来在其中一条链上增加一个带有信息的区块,P2P 网络会将这个区块同步到所有的链上,也就是这条信息会被存储在所有节点。 把上面的一段话缩成一句(会显得比较厉害): 区块链是用分布式数据库识别、传播和记载信息的智能化对等网络, 也称为价值互联网。 看到这里是不是对区块链略知一二了?

三月 14, 2018 · 1 分钟 · Zhiya

面试不再怕,20行Python代码帮你搞懂LRU算法

LRU 算法在后端工程师面试中,是一个比较常出现的题目,这篇文章带大家一起,理解 LRU 算法,并最终用 Python 轻松实现一个基于 LRU 算法的缓存。 缓存是什么 先看一张图,当我们访问网页,浏览器会给服务器发请求,服务器会经过一系列的运算,把页面返回给浏览器。 当有多个浏览器同时访问的时候,就会在短时间内发起多个请求,而服务器对每一个请求都要进行一系列相同的操作。重复工作不仅浪费资源,还可能导致响应速度变慢。 而缓存则可以把服务器返回的页面保存下来,当有其他的浏览器再访问时候,就不必劳服务器大驾,直接由缓存返回页面。为了保证响应速度,缓存通常是基于比较昂贵的硬件,比如 RAM,这就决定了我们很难用大量的缓存把所有的页面都存下来,当恰好没有缓存浏览器请求的页面时,依然需要请求服务器。由于缓存容量有限,而数据量无限(互联网每天新产生的页面数无法估计),就需要把好刚用在刀刃上,缓存那些最有用的信息。 LRU 是什么 LRU 是一种缓存淘汰算法(在 OS 中也叫内存换页算法),由于缓存空间是有限的,所以要淘汰缓存中不常用的数据,留下常用的数据,达到缓存效率的最大化。LRU 就是这样一种决定“淘汰谁留下谁”的算法,LRU 是 Least recently used 的缩写,从字面意思“最近最少使用”,我们就可以理解 LRU 的淘汰规则。 LRU 的淘汰逻辑 我们用一张图来描述 LRU 的淘汰逻辑,图中的缓存是一个列表结构,上面是头结点下面是尾节点,缓存容量为 8(8 个小格子): 有新数据(意味着数据之前没有被缓存过)时,加入到列表头 缓存到达最大容量时,需要淘汰数据多出来的数据,此时淘汰列表尾部的数据 当缓存中有数据被命中,则将数据移动到列表头部(相当于新加入缓存) 按上面的逻辑我们可以看到,一个数据如果经常被访问就会不断地被移动到列表头部,不会被淘汰出缓存,而越不经常访问的数据,越容易被挤出缓存。 20 行 Python 代码实践 LRU 接下来我们用 Python 来实现一个采用 LRU 算法的缓存。 从前面的文章中我们可以知道,缓存简化下来就两个功能,一个是往里装数据(缓存数据),一个是往外吐数据(命中缓存),所以我们的缓存对外只需要 put 和 get 两个接口就可以了。 按照前面的示意图,缓存内部我们只需要有一个列表(list)就可以实现 LRU 逻辑,不过用列表虽然能实现逻辑,但是在判断是否命中缓存时,速度可能非常慢(列表需要遍历才能知道数据有没有在里面)。在 Python 中,我们可以用基于 hash 的结构,比如字典(dict)或集合(set),来快速判断数据是否存在,解决列表实现的性能问题。但是字典和集合又是没有顺序的,如果能有一种既能排序,又是基于 hash 存储的数据结构,就好了。 在 Python 的 collections 包中,已经内置了这种实用的结构 OrderedDict,OrderedDict 是 dict 的子类,但是存储在内部的元素是有序的(列表的特点)。 ...

三月 6, 2018 · 1 分钟 · Zhiya

60行Python代码,实现多线程PDF转Word

工作中经常会遇到需要提取 PDF 文件中文字的情况,一个 PDF 还好,复制粘贴一下也花不了太多时间,如果需要把大量 PDF 转为 Word,怎么办呢? 今天教大家用 60 行代码实现,多线程批量 PDF 转 Word。没兴趣看具体过程可以直接拉到最后,有代码。 分解任务 把 PDF 转为 Word,分几步?两步,第一步读取 PDF 文件,第二步写入 Word 文件。 是的,就是这么简单,借助 Python 第三方包,可以轻松实现上面两个过程,我们要用到 pdfminer3k 和 python-docx 这两个包。 读取 PDF from pdfminer.pdfinterp import PDFResourceManager from pdfminer.pdfinterp import process_pdf from pdfminer.converter import TextConverter from pdfminer.layout import LAParams resource_manager = PDFResourceManager() return_str = StringIO() lap_params = LAParams() device = TextConverter(resource_manager, return_str, laparams=lap_params) process_pdf(resource_manager, device, file) // file是使用open方法打开的PDF文件句柄 device.close() // 此处content就是转换为文字的PDF内容 content = return_str.getvalue() content 变量存储的就是我们从 PDF 文件中读取出的文字内容,可以看到,使用 pdfminer3k 可以轻松完成这个任务。接下来我们需要把文字内容写入成一个 word 文件。 ...

三月 3, 2018 · 2 分钟 · Zhiya