分类目录归档:工具

马赛克还原神器—Depix,真的有那么神吗?

Depix 是用于从马赛克中还原密码/英文数字组合的Python工具。

它的官方效果是这样的:

效果非常令人惊艳,恢复后基本和原文图相差无几。但是真的有那么神吗?

1.怎么做到的?

第一步,作者在编辑器中使用了与原图(带有马赛克的图片)相同的字体设置(文本大小,字体,颜色等设置),然后将 debruinseq.txt 内的文字和数字放入编辑器中并截图,这张截图中的所有文字都将被像素化后作为“搜索集”来识别原图中马赛克的真实内容。

第二步,将原图中的马赛克方块切出来成为一个个单个矩形,然后这些矩形将与“搜索集”中的每个块进行比对,找到最正确的结果。

第三步,在对应位置上对搜索集和原图中周围方块的匹配进行几何比较找到最短距离,重复此过程几次,找到最优结果。

接下来,让咱们试试这个Depix,看看是不是真的那么神。

2. 安装依赖

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

为了使用该项目的源代码,请前往GitHub下载:
https://github.com/beurtschipper/Depix

如果你访问不了GitHub或网速过慢,可以在Python实用宝典公众号后台回复:depix 下载。

解压下载好的文件得到 Depix-main 文件夹,Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),cd 进入 Depix-main 文件夹,输入命令安装依赖:

pip install -r requirements.txt

3.试一试

首先试一下作者的示例,在Depix-main文件夹下运行以下命令,采用作者的打码图作为识别的目标对象:

images/testimages/testimage3_pixels.png

使用作者生成好的图片作为“搜索集”:

images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png

运行以下命令开始识别:

python depix.py -p images/testimages/testimage3_pixels.png -s images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png -o output.png

识别结束后会在当前文件夹生成 output.png

效果还不错,但这是作者提供的图片,如果是我们自己的图片呢?

比如我在编辑器中键入这样的文字再打码,它能识别到吗:

打码:

使用作者的“搜索集”来解码:

python depix.py -p G:\push\20210114\test.png -s images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png -o output.png

结果出来的图基本和打码图没什么变化,基本无效果。

我以为是“搜索集”的问题,比如字体不一样导致无法识别成功。

因此我学作者制作了一个“搜索集”:

然后使用这个搜索集再进行识别:

python depix.py -p G:\push\20210114\test.png -s G:\push\20210114\train1.png -o output.png

依然没有识别成功,出来的结果还是和原图差不多,马赛克基本没少。

后面又试了几次,均没有识别成功。

5.为什么我的马赛克无法被识别

于是我想知道为什么会这样,就用我自己的马赛克工具和作者打的马赛克做了对比:

我发现,使用我的马赛克图像去进行识别的时候,一样没有任何效果

但是识别作者的马赛克图像,效果却很好。

这时候我有理由相信这个算法其实发生了“过拟合”,作者对“搜索集”的每个区块进行打码,这个打码的风格是有一定特征的,如果被识别对象的马赛克不符合这个风格,那识别大概率会失败。

所以被识别对象的马赛克一定要符合“搜索集”的打码风格,这样才能被准确地识别出来,换成其他算法生成的马赛克,作者的模型都可能会失效,就比如我刚刚试的那些例子。

尽管如此,随着技术的进步,在未来类似这样的解码器肯定会越来越强大,所以建议大家还是将马赛克打得厚一点,最好是一整块地填充图像破坏原图,这样才不用担心密码被还原之类的事情,比如下面这样才是最安全的。

最后一个问题,这两个被覆盖掉的字是什么?(狗头保命​

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

You-get 万能的音视频下载工具

You-Get 是一个使用Python开发的小型命令行实用程序,可以通过一行命令直接从Web下载媒体内容(视频,音频,图像)等,不用任何配置。

这款工具支持的站点特别多,比如Youtube、优酷、腾讯视频、网易云音乐、Ted、知乎等等主流网站,可以说几乎是万能的,在本文最下方的附录可查看You-Get支持的完整网站列表。

下面是这个万能工具的使用指南。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install you-get

2.使用方法

使用的时候直接在命令行输入:

you-get 媒体链接

就能将媒体内容下载在当前命令行输出的文件夹中,比如下载网易云音乐的歌曲:
https://music.163.com/#/song?id=1811118551

不仅如此,下载B站的视频,它连多part视频都能一并下载:

第一次下载的时候,它会提示这是个多part视频,后缀添加–playlist下载全部part视频:

令人惊喜的是,这个工具在下载视频的同时将弹幕数据也下载了:

弹幕文件通过 danmu2ass 这样的工具处理后,就可以将弹幕数据格式化为ass文件,用播放器播放视频的时候,将ass格式的弹幕文件导入到播放器,就能完美复现B站的体验效果。

知乎的下载比较特别,只支持下载回答和专栏内出现的视频:

3.增值功能

3.1 暂停和继续下载

没错,这个工具支持断点续传,这是为了防止出现下载的视频太长,用户中途停止导致前面下载的内容报废的问题。

1.暂停下载:按 Ctrl+C 可以中断命令,下载目录下会保存有一个以 .download 为扩展名的缓存文件。

2.继续下载:重新执行相同的命令下载任务,如果下载目录下有上次下载保存的缓存文件,则继续上次下载进度。

3.强制重新下载(即使下载完成也会重新写入),带 -f 参数即可:

you-get -f https://www.bilibili.com/video/BV137411n7hY

3.2 选择视频格式和清晰度

用过 -i 参数能获得当前视频所有的清晰度和格式:

拿到格式名称后,如果你想下载高清 1080P的视频,只需要带–format参数就可以下载指定格式的视频:

you-get --format=dash-flv https://www.bilibili.com/video/BV137411n7hY

3.3 本地播放器直接播放网络视频

这也是一个相当强力的特性,如果你受不了网页播放器那些简单的功能,想加一些比如调整屏幕比例为2.35:1之类的自己本地播放器的功能,那你可以尝试这样做:

1.在资源管理器中打开 你的播放器的 安装目录
2.按住Shift并在空白处右击鼠标,选择在此处打开 Powershell 窗口
3.输入下面的 You-Get 播放命令即可

you-get -p 你的播放器.exe https://www.bilibili.com/video/BV1Fa4y1a7jE

3.4 代理设置

你如果有下载油管之类的视频的需求,那么可能需要设置代理才可以下载成功,you-get 也提供了这样的选项:

you-get -x 127.0.0.1:8087 'https://www.youtube.com/watch?v=jNQXAC9IVRw'

-x 参数后接代理的 IP:端口号,再将需要下载的视频链接放到后面就可以了,非常方便。

3.5 设置下载文件的路径

如果你不想把文件下载到当前命令行所处的文件夹中,那么可以用 -o 参数指定下载目录:

you-get -o C:\Users\83493\Downloads 'https://www.bilibili.com/video/BV1Fa4y1a7jE'

大体功能就是这些,相信已经能够覆盖大家的日常使用范围了,喜欢的话请在下方点个赞或者在看让更多的人看到吧!

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

附录:

SiteURL视频图像音频
YouTubehttps://www.youtube.com/
Twitterhttps://twitter.com/
VKhttp://vk.com/
Vinehttps://vine.co/
Vimeohttps://vimeo.com/
Veohhttp://www.veoh.com/
Tumblrhttps://www.tumblr.com/
TEDhttp://www.ted.com/
SoundCloudhttps://soundcloud.com/
SHOWROOMhttps://www.showroom-live.com/
Pinteresthttps://www.pinterest.com/
MTV81http://www.mtv81.com/
Mixcloudhttps://www.mixcloud.com/
Metacafehttp://www.metacafe.com/
Magistohttp://www.magisto.com/
Khan Academyhttps://www.khanacademy.org/
Internet Archivehttps://archive.org/
Instagramhttps://instagram.com/
InfoQhttp://www.infoq.com/presentations/
Imgurhttp://imgur.com/
Heavy Music Archivehttp://www.heavy-music.ru/
Freesoundhttp://www.freesound.org/
Flickrhttps://www.flickr.com/
FC2 Videohttp://video.fc2.com/
Facebookhttps://www.facebook.com/
eHowhttp://www.ehow.com/
Dailymotionhttp://www.dailymotion.com/
Coubhttp://coub.com/
CBShttp://www.cbs.com/
Bandcamphttp://bandcamp.com/
AliveThaihttp://alive.in.th/
interest.mehttp://ch.interest.me/tvn
755
ナナゴーゴー
http://7gogo.jp/
niconico
ニコニコ動画
http://www.nicovideo.jp/
163
网易视频
网易云音乐
http://v.163.com/
http://music.163.com/
56网http://www.56.com/
AcFunhttp://www.acfun.cn/
Baidu
百度贴吧
http://tieba.baidu.com/
爆米花网http://www.baomihua.com/
bilibili
哔哩哔哩
http://www.bilibili.com/
豆瓣http://www.douban.com/
斗鱼http://www.douyutv.com/
凤凰视频http://v.ifeng.com/
风行网http://www.fun.tv/
iQIYI
爱奇艺
http://www.iqiyi.com/
激动网http://www.joy.cn/
酷6网http://www.ku6.com/
酷狗音乐http://www.kugou.com/
酷我音乐http://www.kuwo.cn/
乐视网http://www.le.com/
荔枝FMhttp://www.lizhi.fm/
懒人听书http://www.lrts.me/
秒拍http://www.miaopai.com/
MioMio弹幕网http://www.miomio.tv/
MissEvan
猫耳FM
http://www.missevan.com/
痞客邦https://www.pixnet.net/
PPTV聚力http://www.pptv.com/
齐鲁网http://v.iqilu.com/
QQ
腾讯视频
http://v.qq.com/
企鹅直播http://live.qq.com/
Sina
新浪视频
微博秒拍视频
http://video.sina.com.cn/
http://video.weibo.com/
Sohu
搜狐视频
http://tv.sohu.com/
Tudou
土豆
http://www.tudou.com/
阳光卫视http://www.isuntv.com/
Youku
优酷
http://www.youku.com/
战旗TVhttp://www.zhanqi.tv/lives
央视网http://www.cntv.cn/
Naver
네이버
http://tvcast.naver.com/
芒果TVhttp://www.mgtv.com/
火猫TVhttp://www.huomao.com/
阳光宽频网http://www.365yg.com/
西瓜视频https://www.ixigua.com/
新片场https://www.xinpianchang.com/
快手https://www.kuaishou.com/
抖音https://www.douyin.com/
TikTokhttps://www.tiktok.com/
中国体育(TV)http://v.zhibo.tv/
http://video.zhibo.tv/
知乎https://www.zhihu.com/

jinja2+yagmail 批量定制化渲染发送元旦祝福邮件

上一篇关于邮件的自动发送教程中,我们讲解了如何使用yagmail进行简单的邮件发送。

现实生活中,如果只是发邮件给自己,像上一篇文章那样简陋的格式是可以接受的,但若要针对每个人进行邮件的定制化,群发给公司客户、内部员工、亲戚朋友,则需更加高级的邮件发送方式。

我们可以通过HTML制作一封精美的元旦祝福邮件,但是邮件的内容——比如姓名、祝福语等应该怎样动态渲染呢?答案是jinja2.

jinja2 是一个Python 的模板引擎,使用jinja2,我们能够在邮件HTML中设定占位符,在Python发送邮件的时候,将指定文本渲染到该占位符中,实现动态渲染的目的。

比如举一个jinja2的简单例子:

from jinja2 import Template

name = 'Peter'
age = 34

tm = Template("My name is {{ name }} and I am {{ age }}")
msg = tm.render(name=name, age=age)

print(msg)

使用 {{}} 圈起来的是占位符,称之为模板字符串。模板字符串呈现两个变量:名称和年龄,在这个例子中,硬编码了name和age的值传入模板,得到输出:

My name is Peter and I am 34

在本篇文章中,我将教大家如何通过Html及Python+jinja2给你的好友们定制元旦祝福邮件。

本文所有素材及源代码均可以在此下载:
https://pythondict.com/download/python-new-year-mail/

或Python实用宝典公众号回复:元旦邮件 直接拿到网盘下载链接。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

此外,推荐大家用VSCode编辑器,因为它实在是太方便了:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),准备开始输入命令安装依赖。

pip install jinja2
pip install yagmail

2.编写HTML

将需要发送的邮件模板的HTML编写好。并将占位符变量提前写入HTML中。由于我的HTML文件过大,这里就不完全展示了,只展示几个关键变量。

为简化教程的复杂度,并尽可能覆盖到知识点,这里我们使用4个变量:

1.LOGO图片(让你更好地理解图片是如何渲染到HTMl里并发邮件)
2.背景图片
3.祝福对象
4.祝福语言

首先,是图片变量的配置:

<tr>
    <td valign="left" width="50%" class="logo sub-gd" style="padding-left:0;">
        <h1>
            <img src="data:image/png;base64, {{pythondict_img}}">
        </h1>
    </td>
</tr>

由于我们需要发送html形的邮件,因此像代码这样将图片转码为base64再发送是最方便的。

其中,base64部分用jinja2语法 {{}} 包起来,中间就是变量名,一会render渲染的时候就会将base64渲染进来。

背景图片的配置比较特殊,使用 base64 渲染的话QQ邮箱会自动过滤为#号,因此必须使用url的形式:

<td valign="middle"style="background-image: url({{backgroud}});">

其次是祝福对象和祝福语言的配置:

<h2>
    {{name}}
    <br>
    祝您2021年元旦快乐
</h2>
<p>
    {{bless}}.
</p>

使用 {{}} 包裹变量,name是祝福的对象,bless是祝福语。这里简化了代码,还有许多样式要配置详细的大家可以看源代码中的 index_detail.html.

对了,我们源代码里包括两份html,一份是 index_detail.html 是未经过压缩的源代码,还有一份是 index.html,是被压缩过的源代码。

为什么要压缩HTML呢?因为邮箱客户端在解析HTML的时候,有可能会将换行符解析成<br>,因此压缩HTML不保留任何空格和换行符是最保险的做法。

详细的HTML代码,大家可以看源代码中的 index_detail.html.

3.Python代码

发送邮件的方法,我们在Python 自动发送邮件详细教程中已经详细地讲过了:

class Mail:
    """
    邮件相关类
    """

    def log(self, content):
        now_time = time.strftime(
            "%Y-%m-%d %H:%M:%S", time.localtime()
        )
        print(f'{now_time}: {content}')

    def sendmail(self, html, title, receivers):
        """
        发送邮件
        Arguments:
            html {str} -- 邮件正文(html)
            title {str} -- 邮件标题
            receivers {list} -- 邮件接收者,数组
        """

        yag = yagmail.SMTP(
            host='您的邮箱SMTPHOST', user='您的邮箱',
            password='您的邮箱密码', smtp_ssl=True
        )

        yag.send(receivers, title, html)
        self.log("邮件发送成功")

此外,为了渲染图片,需要将图片转化为base64,这个方法是这样的:

def get_image_base64(path):
    """
    获得图片的base64编码

    Args:
        path (str): 图片路径

    Returns:
        str: base64编码
    """
    import base64
    f = open(path, "rb")
    base64_data = base64.b64encode(f.read())
    f.close()
    return base64_data.decode("utf-8")

当然,最重要的地方是下面,需要针对每个人定制祝福语,我们可以采用字典的数据结构来保存数据:

bless_info = {
    "admin@pythondict.com": {
        "pythondict_img": get_image_base64("./images/pythondict.png"),
        "name": "实用宝典",
        "background": "https://背景图片.jpg",
        "bless": "愿所有的幸运与您不期而遇..",
        "title": "祝宝典哥明年粉丝破十万"
    },
    "test@qq.com": {
        "pythondict_img": get_image_base64("./images/pythondict.png"),
        "name": "老王",
        "background": "https://背景图片.jpg",
        "bless": "祝您女儿明年考研顺顺利利,全家幸福安康..",
        "title": "老王,祝您元旦快乐!"
    },
}

可以看到 bless_info 字典里的每个key是发送对象的邮箱,而这些 key 对应的value 中就有需要渲染到邮件的变量: pythondict_img, name, background 及 祝福语bless. 最后一个变量title,是用于指定邮件标题的。

这样,渲染+发送邮件做起来就方便多了:

tm = Template(open('./index.html', encoding="utf-8").read())
for mail in bless_info:
    msg = tm.render(bless_info[mail])
    Mail().sendmail(html=msg, title=bless_info[mail]["title"], receivers=[mail])

Mail().sendmail():是我们的发送邮件函数,应该不必多说。

bless_info[mail]:是需要渲染的变量,这里面的变量少了可不行,多了没关系。

bless_info[mail][“title”]:就是刚刚在字典里指定的最后一个变量 title

由于 sendmail() 函数里的 receivers 是支持多人的,因此这里需要以数组的形式传入函数。

不过这里还有一个有趣的改进,如果你需要用同一个模板邮件发送给同一家人,你可以这么做:

bless_info = {
    ...,
    "test1@qq.com,test2@qq.com,test3@qq.com": {
        "pythondict_img": get_image_base64("./images/pythondict.png"),
        "name": "老王一家",
        "background": "https://背景图片.jpg",
        "bless": "祝王小女明年考研顺顺利利,老王全家幸福安康,吉祥如意..",
        "title": "老王一家,祝你们元旦快乐!"
    },
}

tm = Template(open('./index.html', encoding="utf-8").read())
for mail in bless_info:
    msg = tm.render(bless_info[mail])
    Mail().sendmail(html=msg, title=bless_info[mail]["title"], receivers=mail.split(","))

没错,只需要在key里将这一家人的邮箱用逗号分隔开,然后receivers里改为mail.split(“,”),你就能实现同一份邮件发给一家人的功能,是不是非常方便?

大家可以自己找喜欢的背景图片,也可以用我在代码里已给大家提供的图片。想要去除LOGO的话,直接将pythondict_img设为空,或者设为你自己的卡片即可。

在源代码目录下​运行代码:

python mail.py

即可成功发送邮件,快打开编辑器试一下吧(记得先测试)!

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

TheFuck—超实用的控制台命令纠正工具

The Fuck 是一款功能强大的、Python编写的应用程序,其灵感来自@liamosaur推文,可用于纠正控制台命令中的错误,如下图所示:

更多示例如:

自动识别没有权限,在命令前面添加 sudo:

➜ apt-get install vim
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?

➜ fuck
sudo apt-get install vim [enter/↑/↓/ctrl+c]
[sudo] password for nvbn:
Reading package lists... Done
...

识别到没有推送到远程分支,自动追加:

➜ git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use
 
    git push --set-upstream origin master

➜ fuck
git push --set-upstream origin master [enter/↑/↓/ctrl+c]
Counting objects: 9, done.
...

识别到拼写错误:

➜ puthon
No command 'puthon' found, did you mean:
 Command 'python' from package 'python-minimal' (main)
 Command 'python' from package 'python3' (main)
zsh: command not found: puthon

➜ fuck
python [enter/↑/↓/ctrl+c]
Python 3.4.2 (default, Oct  8 2014, 13:08:17)
...

而且,如果你不担心fuck修正的结果是错误的,你可以禁用require_confirmation 选项,让fuck自动运行更正的命令:

➜ apt-get install vim
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?

➜ fuck
sudo apt-get install vim
[sudo] password for nvbn:
Reading package lists... Done
...

在开发机上可以这么做,在生产机器上最好是谨慎一点,不推荐这么做。

1.安装

在OS X上,可以通过Homebrew(或在Linux上通过Linuxbrew)安装The Fuck

brew install thefuck

在Ubuntu / Mint上,使用以下命令安装The Fuck

sudo apt update
sudo apt install python3-dev python3-pip python3-setuptools
sudo pip3 install thefuck

在FreeBSD上,使用以下命令安装The Fuck

pkg install thefuck

在其他系统上, 使用pip安装The Fuck

pip install thefuck

2.配置

接下来需要把这个命令写入到 .bash_profile, .bashrc.zshrc 等启动脚本中。

根据你的终端类型,运行相应的命令即可:

Bash

chcp.com 65001 
eval "$(thefuck --alias)"

其中 chcp.com 65001 只有在windows环境下才需要运行。

Zsh:

eval "$(thefuck --alias)"

其他的可见:

https://github.com/nvbn/thefuck/wiki/Shell-aliases

3.原理

其实TheFuck的原理就是规则匹配(正则表达式),如果找到匹配规则的命令,则创建一个命令给用户选择或直接运行。

默认情况下的规则有:

  • cat_dir – 当你尝试cat目录的时候,用ls替换cat;
  • cd_correction – 拼写检查和纠正失败的cd命令;
  • cd_mkdir – 在进入目录之前创建目录;
  • cd_parent – 更改 cd..cd ..
  • dry – 修复类似的重复问题:git git push
  • fix_alt_space – 用空格字符代替Alt + Space;
  • git_checkout–修改分支名称或创建新分支;
  • … ….

等等,具体可以在官方文档中找到:
https://github.com/nvbn/thefuck

4. 创建自己的修复规则

要添加自己的规则,在~/.config/thefuck/rules 创建一个文件名为your-rule-name.py 的规则文件,必须包含两个函数:

match(command: Command) -> bool
get_new_command(command: Command) -> str | list[str]

下面是简单的 sudo 规则示例:

def match(command):
    return ('permission denied' in command.output.lower()
            or 'EACCES' in command.output)


def get_new_command(command):
    return 'sudo {}'.format(command.script)

# Optional:
enabled_by_default = True

def side_effect(command, fixed_command):
    subprocess.call('chmod 777 .', shell=True)

priority = 1000  # Lower first, default is 1000

requires_output = True

如果命令运行结果出现 permission denied 或者 EACCES,则执行 sudo xxx.

此外,还可以配置side_effect,如果你配置了enabled_by_default = True,side_effect函数内的操作将会被执行,本例中是对当前目录下的文件夹执行赋权操作: chmod 777 .​​

大家可以动手试试自己配一个修复命令。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 制作按键触发Windows通知的脚本

​对于键盘没有背光灯的同学而言,切换大小写或控制Num键开关的时候没有提示,经常需要试探性地输入一些字符来判断开关是否打开,体验非常糟糕。

因此,有人就想到自制脚本这一招,一旦触发大小写切换或Num键切换就进行windows通知提示:

https://github.com/skate1512/Toggle_Keys_Notification

今天我们来试试这个脚本,此外,我们还可以基于这个项目,扩展成任意一个按键被触发或切换都进行 windows 通知的脚本:

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

此外,推荐大家用VSCode编辑器,因为它可以在编辑器下方的终端运行命令安装依赖模块:Python 编程的最好搭档—VSCode 详细指南。

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install win10toast

除此之外,我们需要下载作者的代码,如果你能联通GitHub,请前往以下地址下载:
https://github.com/skate1512/Toggle_Keys_Notification

如果不能联通GitHub,或者网络速度比较慢,请在Python实用宝典公众号后台回复:按键触发通知 下载本文完整源代码。

2.源码使用与解析

2.1 源码使用

作者的项目可以在 Toggle_Keys_Notification 项目内,运行 notify.py 启动监听:

python notify.py

启动后点击一下大小写切换键,触发通知则说明代码正常运转:

2.1 源码分析

该项目通过win32gui和win32con实现了弹出toast进行通知的功能,最核心的_show_toast代码位于 toast.py 中,下面是这个函数的部分代码剖析:

注册和创建 window :

        message_map = {WM_DESTROY: self.on_destroy, }
        # 注册Window
        self.wc = WNDCLASS()
        self.hinst = self.wc.hInstance = GetModuleHandle(None)
        self.wc.lpszClassName = str("PythonTaskbar") # 定义该窗口结构的名称
        self.wc.lpfnWndProc = message_map
        try:
            self.classAtom = RegisterClass(self.wc)
        except:
            pass 
        # Window格式
        style = WS_OVERLAPPED | WS_SYSMENU
        # 创建Window
        self.hwnd = CreateWindow(self.classAtom, "Taskbar", style,
                                 0, 0, CW_USEDEFAULT,
                                 CW_USEDEFAULT,
                                 0, 0, self.hinst, None)
        UpdateWindow(self.hwnd)

所使用到的win32模块解析如下。

GetModuleHandle: 获取一个应用程序或动态链接库的模块句柄。
WM_DESTROY: 是关闭程序。
RegisterClass: 将定义好的Window属性保存保存下来。
WS_OVERLAPPED: 重叠式窗口,该式样窗口 带有一个标题栏和边框。
WS_SYSMENU: 具有 SYSTEM 菜单栏的样式
CW_USEDEFAULT: 采用系统默认位置

CreateWindow这个函数具有非常多的参数,甚至有一个百度百科来详细解析每一个参数的具体作用,大家感兴趣可以移步:
https://baike.baidu.com/item/CreateWindow/5076220

了解win32这些模块名称的意义后,理解上述代码的逻辑便很轻松了。

图标加载及任务栏图标显示配置:

        # 图标
        if icon_path is not None:
            # 获取图标地址
            icon_path = path.realpath(icon_path)
        else:
            icon_path = resource_filename(Requirement.parse("win10toast"), "win10toast/data/python.ico")
        # 加载格式
        icon_flags = LR_LOADFROMFILE | LR_DEFAULTSIZE
        try:
            hicon = LoadImage(self.hinst, icon_path, IMAGE_ICON, 0, 0, icon_flags)
        except Exception as e:
            logging.error("Some trouble with the icon ({}): {}"
                          .format(icon_path, e))
            hicon = LoadIcon(0, IDI_APPLICATION)

        # 任务栏图标
        flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
        nid = (self.hwnd, 0, flags, WM_USER + 20, hicon, "Tooltip")
        Shell_NotifyIcon(NIM_ADD, nid)
        Shell_NotifyIcon(NIM_MODIFY, (self.hwnd, 0, NIF_INFO, WM_USER + 20, hicon, "Balloon Tooltip", msg, 200, title, NIIF_ICON_MASK))
        
        # 等待一会后销毁
        sleep(duration)
        DestroyWindow(self.hwnd)
        UnregisterClass(self.wc.lpszClassName, None)

这部分控制了通知弹出框的展示和销毁。如果你希望通知弹出框久一点再消失,可以适当修改传入的 duration 变量值。

DestroyWindow后,通知弹出框便消失了,整个 show_toast 的过程结束。

其实非常简单,从 CreateWindow 到 DestroyWindow 处理弹出框的各种属性,然后注销窗体,完成整个弹出流程。

3.扩展触发通知

为了扩展监听的按键,并能监听按键触发,需要先了解 notify.py 是如何检测到按键变化的。

获取按键状态:

keyboard = ctypes.WinDLL("User32.dll")
VK_NUMLOCK = 0x90
VK_CAPITAL = 0x14
def get_capslock_state():
    """Returns the current Caps Lock State(On/Off)"""
    return "Caps Lock On" if keyboard.GetKeyState(VK_CAPITAL) else "Caps Lock Off"


def get_numlock_state():
    """Returns The current Num Lock State(On/Off)"""
    return "Num Lock On" if keyboard.GetKeyState(VK_NUMLOCK) else "Num Lock Off"

可以看到,获取按键状态是通过 keyboard.GetKeyState(XXXX) 实现的。

而这个XXXX是对应的按键的十六进制,比如VK_NUMLOCK是Num键,对应的16进制代码是0x90,VK_CAPITAL是大小写按键,对应的十六进制代码是0x14.

变量名是可以用户自定义的,比如大小写键有些人习惯称之为VK_CAPITAL,也有些人喜欢称之为VK_CAPITAL,都可以,只要其最终对应的变量值为十六进制的0x14即可。

完整的按键16进制清单如下:

常数名称十六进制值十进制值对应按键
VK_LBUTTON011鼠标的左键
VK_RBUTTON022鼠标的右键
VK-CANCEL033Ctrl+Break(通常不需要处理)
VK_MBUTTON044鼠标的中键(三按键鼠标)
VK_BACK088Backspace键
VK_TAB099Tab键
VK_CLEAR0C12Clear键(Num Lock关闭时的数字键盘5)
VK_RETURN0D13Enter键
VK_SHIFT1016Shift键
VK_CONTROL1117Ctrl键
VK_MENU1218Alt键
VK_PAUSE1319Pause键
VK_CAPITAL1420Caps Lock键
VK_ESCAPE1B27Ese键
VK_SPACE2032Spacebar键
VK_PRIOR2133Page Up键
VK_NEXT2234Page Domw键
VK_END2335End键
VK_HOME2436Home键
VK_LEFT2537LEFT ARROW 键(←)
VK_UP2638UP ARROW键(↑)
VK_RIGHT2739RIGHT ARROW键(→)
VK_DOWN2840DOWN ARROW键(↓)
VK_Select2941Select键
VK_PRINT2A42Print键
VK_EXECUTE2B43EXECUTE键
VK_SNAPSHOT2C44Print Screen键(抓屏)
VK_Insert2D45Ins键(Num Lock关闭时的数字键盘0)
VK_Delete2E46Del键(Num Lock关闭时的数字键盘.)
VK_HELP2F47Help键
VK_030480键
VK_131491键
VK_232502键
VK_333513键
VK_434524键
VK_535535键
VK_636546键
VK_737557键
VK_838568键
VK_939579键
VK_A4165A键
VK_B4266B键
VK_C4367C键
VK_D4468D键
VK_E4569E键
VK_F4670F键
VK_G4771G键
VK_H4872H键
VK_I4973I键
VK_J4A74J键
VK_K4B75K键
VK_L4C76L键
VK_M4D77M键
VK_N4E78N键
VK_O4F79O键
VK_P5080P键
VK_Q5181Q键
VK_R5282R键
VK_S5383S键
VK_T5484T键
VK_U5585U键
VK_V5686V键
VK_W5787W键
VK_X5888X键
VK_Y5989Y键
VK_Z5A90Z键
VK_NUMPAD06096数字键0键
VK_NUMPAD16197数字键1键
VK_NUMPAD26298数字键2键
VK_NUMPAD36299数字键3键
VK_NUMPAD464100数字键4键
VK_NUMPAD565101数字键5键
VK_NUMPAD666102数字键6键
VK_NUMPAD767103数字键7键
VK_NUMPAD868104数字键8键
VK_NUMPAD969105数字键9键
VK_MULTIPLY6A106数字键盘上的*键
VK_ADD6B107数字键盘上的+键
VK_SEPARATOR6C108Separator键
VK_SUBTRACT6D109数字键盘上的-键
VK_DECIMAL6E110数字键盘上的.键
VK_DIVIDE6F111数字键盘上的/键
VK_F170112F1键
VK_F271113F2键
VK_F372114F3键
VK_F473115F4键
VK_F574116F5键
VK_F675117F6键
VK_F776118F7键
VK_F877119F8键
VK_F978120F9键
VK_F1079121F10键
VK_F117A122F11键
VK_F127B123F12键
VK_NUMLOCK90144Num Lock 键
VK_SCROLL91145Scroll Lock键

再来看看监听逻辑:

caps_curr = get_capslock_state()
num_curr = get_numlock_state()

while True:
    caps_change = get_capslock_state()
    num_change = get_numlock_state()

    if caps_curr != caps_change:
        if caps_change == "Caps Lock On":
            pop_up("Caps Lock On", "CapsLock_On.ico")
        else:
            pop_up("Caps Lock Off", "CapsLock_Off.ico")
        caps_curr = caps_change
        time.sleep(0.1)

    if num_curr != num_change:
        if num_change == "Num Lock On":
            pop_up("Num Lock On", "NumLock_On.ico")
        else:
            pop_up("Num Lock Off", "NumLock_Off.ico")
        num_curr = num_change
    time.sleep(0.2)

在刚开始运行监听脚本时,先获取到按键的状态,在循环体中,不断地获得当前按键状态,如果发生了状态变化,则触发pop_up函数,弹出刚刚我们提到的show_toast 函数:

def pop_up(body, icon):
    """Generates Pop-up notification when state changes"""
    notification = ToastNotifier()
    notification.show_toast("Lock Key State", body, icon_path="assets\\"+icon, duration=1.5)

整套监听并通知的机制还是非常简单的,如果我们想要自定义一些按键,你只需要在开头添加对应的按键的十六进制编码。

比如我们想监听 ESC 按键被按下:VK_ESCAPE=0x1B,使用 keyboard 模块添加一个钩子函数,监听按键:

import keyboard as kb
def hook_esc(button):
    """Alert if ESC button is pressed"""
    esc_button = kb.KeyboardEvent('down', VK_ESCAPE, 'ESC')
    if button.event_type == 'down' and esc_button.name == button.name:
        pop_up("ESC Pressed", "CapsLock_On.ico")
        # 敲击后回填为None
        button.event_type = None

然后再在循环体内添加判断逻辑:

kb.hook(hook_esc)

效果如下:

当然,图标和标题还可以进一步优化:

def pop_up(body, icon, toast_title="Lock Key State"):
    """Generates Pop-up notification when state changes"""
    notification = ToastNotifier()
    notification.show_toast(toast_title, body, icon_path="assets\\"+icon, duration=1.5)

比如将Lock Key State这个标题用 toast_title 变量替代,默认为Lock Key State。这样在调用pop_up函数的时候就能自定义标题了,效果如下:

总而言之,能扩展的东西非常多,这只是一个学习的例子,如果大家感兴趣的话可以在 Python实用宝典 公众号后台回复 按键触发通知 下载完整源代码进行改造。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

接近完美的监控系统—普罗米修斯

普罗米修斯(Prometheus)是一个SoundCloud公司开源的监控和告警系统。当年,由于SoundCloud公司生产了太多的服务,传统的监控已经无法满足监控需求,于是他们在2012决定着手开发新的监控系统,即普罗米修斯。

普罗米修斯(下称普罗)的作者 Matt T.Proud 在2012年加入该公司,他从google的监控系统Borgmon中获得灵感,与另一名工程师Julius Volz合作开发了开源的普罗,后来其他开发人员陆续加入到该项目,最终于2015正式发布。

普罗基于Go语言开发,其架构图如下:

其中:

  • Prometheus Server: 用数据的采集和存储,PromQL查询,报警配置。
  • Push gateway: 用于批量,短期的监控数据的汇报总节点。
  • Exporters: 各种汇报数据的exporter,例如汇报机器数据的node_exporter,汇报MondogDB信息的 MongoDB_exporter 等等。
  • Alertmanager: 用于高级通知管理。

1.怎么采集监控数据?

要采集目标(主机或服务)的监控数据,首先就要在被采集目标地方安装采集组件,这种采集组件被称为Exporter。prometheus.io官网上有很多这种exporter:exporter列表,比如:

Consul exporter (official)
Memcached exporter
 (official)
MySQL server exporter
 (official)
Node/system metrics exporter
 (official)
HAProxy exporter
 (official)
RabbitMQ exporter

Grok exporter

InfluxDB exporter
 (official)

等等…

这些exporter能为我们采集目标的监控数据,然后传输给普罗米修斯。这时候,exporter会暴露一个http接口,普罗米修斯通过HTTP协议使用Pull的方式周期性拉取相应的数据。

不过,普罗也提供了Push模式来进行数据传输,通过增加Push Gateway这个中间商实现,你可以将数据推送到Push Gateway,普罗再通过Pull的方式从Push Gateway获取数据。

这就是为什么你从架构图里能看到两个 Pull metrics 的原因,一个是采集器直接被Server拉取数据(pull);另一个是采集器主动Push数据到Push Gateway,Server再对Push Gateway主动拉取数据(pull)。

采集数据的主要流程如下:

1. Prometheus server 定期从静态配置的主机或服务发现的 targets 拉取数据(zookeeper,consul,DNS SRV Lookup等方式)

2. 当新拉取的数据大于配置内存缓存区的时候,Prometheus会将数据持久化到磁盘,也可以远程持久化到云端。

3. Prometheus通过PromQL、API、Console和其他可视化组件如Grafana、Promdash展示数据。

4. Prometheus 可以配置rules,然后定时查询数据,当条件触发的时候,会将告警推送到配置的Alertmanager。

5. Alertmanager收到告警的时候,会根据配置,聚合,去重,降噪,最后发出警告。

2.采集的数据结构与指标类型

2.1 数据结构

了解普罗米修斯的数据结构对于了解整个普罗生态非常重要。普罗采用键值对作为其基本的数据结构:

Key是指标名字,Value是该指标的值,此外Metadata(元信息)也非常重要,也可称之为labels(标签信息)。这些标签信息指定了当前这个值属于哪个云区域下的哪台机器,如果没有labels,数据有可能会被丢失。

2.2 指标类型

普罗米修斯的监控指标有4种基本类型:

1.Counter(计数器):

计数器是我们最简单的指标类型。比如你想统计某个网站的HTTP错误总数,这时候就用计数器。

计数器的值只能增加或重置为0,因此特别适合计算某个时段上某个时间的发生次数,即指标随时间演变发生的变化。

2.Gauges

Gauges可以用于处理随时间增加或减少的指标,比如内存变化、温度变化。

这可能是最常见的指标类型,不过它也有一定缺点:如果系统每5秒发送一次指标,普罗服务每15秒抓取一次数据,那么这期间可能会丢失一些指标,如果你基于这些数据做汇总分析计算,则结果的准确性会有所下滑。

3.Histogram(直方图)

直方图是一种更复杂的度量标准类型。它为我们的指标提供了额外信息,例如观察值的总和及其数量,常用于跟踪事件发生的规模。

比如,为了监控性能指标,我们希望在有20%的服务器请求响应时间超过300毫秒时发送告警。对于涉及比例的指标就可以考虑使用直方图。

4.Summary(摘要)

摘要更高级一些,是对直方图的扩展。除了提供观察的总和和计数之外,它们还提供滑动窗口上的分位数度量。分位数是将概率密度划分为相等概率范围的方法。

对比直方图:

直方图随时间汇总值,给出总和和计数函数,使得易于查看给定指标的变化趋势。

而摘要则给出了滑动窗口上的分位数(即随时间不断变化)。

3.实例概念

随着分布式架构的不断发展和云解决方案的普及,现在的架构已经变得越来越复杂了。

分布式的服务器复制和分发成了日常架构的必备组件。我们举一个经典的Web架构,该架构由3个后端Web服务器组成。在该例子中,我们要监视Web服务器返回的HTTP错误的数量。

使用普罗米修斯语言,单个Web服务器单元称为实例(主机实例)。该任务是计算所有实例的HTTP错误数量。

事实上,这甚至可以说是最简单的架构了,再复杂一点,实例不仅能是主机实例,还能是服务实例,因此你需要增加一个instance_type的标签标记主机或服务。

再再复杂一点,同样的IP,可能存在于不同云区域下,这属于不同的机器,因此还需要一个cloud标签,最终该数据结构可能会变为:

cpu_usage {job=”1″, instance=”128.0.0.1″, cloud=”0″, instance_type=”0″}

4.数据可视化

如果使用过基于InfluxDB的数据库,你可能会熟悉InfluxQL。普罗米修斯也内置了自己的SQL查询语言用于查询和检索数据,这个内置的语言就是PromQL。

我们前面说过,普罗米修斯的数据是用键值对表示的。PromQL也用相同的语法查询和返回结果集。

PromQL会处理两种向量:

即时向量:表示当前时间,某个指标的数据向量。

时间范围向量:表示过去某时间范围内,某个指标的数据向量。

如针对8核CPU的使用率:

知道怎么提取数据后,可视化数据就简单了。

Grafana是一个大型可视化系统,功能强大,可以创建自己的自定义面板,支持多种数据来源,当然也支持普罗米修斯。

通过配置数据源,Grafana会使用相应的SQL拉取并绘制图表,能直接看到普罗米修斯的各个指标数据图表:

更方便的是,Grafana有很多仪表盘模板供你使用,只要import模板进行简单的配置,就能得到以下效果:

5.应用前景

普罗米修斯非常强大,可以应用到各行各业。

5.1 DevOps

为了观察整个服务体系是否在正常运转,运维非常需要监控系统。在实例的创建速度和销毁速度一样快的容器世界中,灵活配置各类容器的监控项并迅速安装启动监控是非常重要的。

5.2 金融行业

金融服务巨头Northern Trust于2017年6月选择普罗米修斯,不是为了进行应用程序的监视,而是为了更好地了解其某些硬件的运作情况。Northern Trust使用普罗米修斯监控其平台上的750多种微服务。

5.3 汽车行业

Life360是一款用于定位、行车安全和家庭成员之间共享信息的移动应用程序,他们需要给用户提供稳定的定位服务,而原有的监控方案都非常局限,无法监视到所有组件的工作状态。

因此该公司使用普罗米修斯来监视其MySQL多主群集和一个12节点的Cassandra环,该环可容纳约4TB的数据。普罗米修斯在初步测试中表现良好。

在普罗米修斯的有限部署之后,Life360报告了监控方面的巨大进步,并设想在其数据中心基础架构的其他部分中使用它。 

总而言之,普罗米修斯这样的分布式监控系统,在未来的世界中用处可能会越来越大,它或许将会成为监控领域寡头式的存在,希望我们能熟悉这个工具,并在以后的架构和实践中使用它解决系统和应用监控的问题。

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

healthchecks, 基于Django监控Cron任务的神器

在运维服务器的时候经常会用到一些Crontab任务。

当你的Crontab中的任务数超过10个的时候,你会发现这些任务管理起来非常困难。

尤其是当这些Cron任务执行失败的时候,比如 Python 实用宝典网 每个月初都会执行一次https证书刷新,有一次协议更新之后,我的脚本失效了三个月,导致证书过期时网站宕机了一天,直到我发现并修复了这个问题。

这就是Crontab任务的一个劣势:没有方便的通知功能。

不过,现在有一个非常方便的开源Django项目能在这些Crontab失效的时候通知你,它就是healthchecks.

它通过一个回调接口判断你的Crontab任务有没有顺利执行。

比如说你有一个python脚本定时执行,healthchecks给定的回调URL是:

http://localhost:8000/ping/880cb4d2

在配置Crontab脚本的时候,就需要这么写:

8 6 * * * python /home/user/test.py && curl -fsS -m 10 --retry 5 -o /dev/null http://localhost:8000/ping/880cb4d2

如果未按时调用回调接口,healthchecks将会通过邮件等通知方式告警。

那么这个“未按时”能否设定宽限呢?比如我有个任务要跑1个小时左右,那么这个任务应该是预计在一个半小时内调用(Ping)回调接口,超过一个半小时如果没有调用回调接口则告警。答案是肯定的。

上图中Period指的是两次Ping之间的时间间隔。下方Grace表示“宽限期”,自从上次Ping以来的时间已超过Period+Grace则会发送告警通知。

如果你用不习惯这种可视化的选择器,它还提供了Crontab表达式给你定义Period和Grace:

真乃神器啊!支持的通知方式如下:

国内用户可能一般只会用到Email和Teams,高级点的用户可能会用到IFTTT的Webhooks和普罗米修斯。总之,按你的爱好来就行。

本地开发

下面教大家如何在本地搭建这个项目:

1. 下载项目

https://github.com/healthchecks/healthchecks

如果你访问不了github,可在【Python 实用宝典】公众号后台回复 healthchecks 下载完整源代码

2.创建虚拟环境

推荐使用Python 3.6+,如果你有conda,那就非常方便了,创建healthchecks虚拟环境:

conda create -n healthchecks python=3.6
activate healthchecks

如果你没有conda,你需要先安装Python3.6,然后使用pip安装virtualenv,在终端输入以下命令创建healthchecks虚拟环境

python3 -m venv healthchecks
source healthchecks/bin/activate

不同系统中命令可能不太一样,遇到问题多利用搜索引擎查询就好了。

3.安装依赖

进入到上述创建好的虚拟环境后,cd进入项目根目录,输入以下命令安装依赖:

pip install -r requirements.txt

4.数据库配置(可选)

该项目默认使用SQLite,这意味着你不需要特殊配置也可照常运转。

如果你需要配置MySQL或PostgreSQL,请阅读hc/local_settings.py.example文件进行配置即可。

5.数据表迁移

Django项目当然少不了这个环节,虚拟环境下,在根目录里运行以下命令进行数据表的迁移:

python manage.py migrate

当然,还要创建超管用户:

python manage.py createsuperuser

6.运行项目

大功告成,输入以下命令即可运行项目:

python manage.py runserver

点击右上角login in登录到超管用户就可以开始使用了。

如果你需要对这个项目进行大规模的改动,建议使用Pycharm作为编程工具,因为使用Pycharm来写Django实在是太爽了,详细可以参考这篇文章:《Pycharm+Django 安装及配置指南》

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应红字验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

想成为时间管理大师?试试番茄工作法!

番茄工作法,是一种时间管理方法。

没错,掌握了它,或许你能成为时间管理大师。

当然,除非你天赋异禀,想成为罗志祥还是有一定难度的。

番茄工作法有五个基本步骤:

1.决定待完成的任务
2.设定番茄工作法定时器至 n 分钟(通常为25分钟)。
3.持续工作直至定时器提示,记下一个x。
4.短暂休息3-5分钟。
5.每四个x,休息15-30分钟。

四个x被称为一个完整的番茄周期。

番茄工作法的原理有专业的心理学解释(来自wiki):

番茄工作法的关键是规划,追踪,记录,处理,以及可视化。在规划阶段,任务被根据优先级排入”To Do Today” list。 这允许用户预计每个任务的工作量。当每个番茄时结束后,成果会被记录下来以提高参与者的成就感并为未来的自我观察和改进提供原始数据。

番茄时意指每个工作时段的时长。当任务完成后,所有番茄计时器剩下的时间会被用于过度学习。短休息时间可以辅助达到心理学上的同化作用,3-5分钟的短休息间隔开每个番茄工作时段。四个番茄工作时组成一组。一个15-50分钟的长休息间隔开每组作业。

这一时间管理技术的本质目的是减少内生和外在的干扰对意识流的影响。一个单位的番茄工作时不可再细分。当在番茄工作时中被打断的情况下,只可能有两种情况:干扰的活动被推迟(告知 – 协商 – 安排日程 – 回访),或者当前的番茄工作时废弃,必须重新开始。

其中,完成任务后所剩下的时间会被用于过度学习。这里的过度学习指的是达到一次完全正确再现后仍继续识记的记忆,也就是复习。

番茄工作法这么好用,不试试怎么行?实际生活中,我们可以通过电脑/手机/手表来通知自己每个番茄时的完成。下面给大家细数几个好用的APP:

1.Flat Tomato

Flat Tomato应该是我最强烈推荐的,APP做的很用心,操作简洁、人性化,音效、动画看起来非常舒服。支持苹果全家桶的所有设备(iPhone、Mac、iPad、iWatch)。

免费版的Flat Tomato没有任何广告,支持基础的定时器、提醒、打断记录功能,如果你只是为了使用番茄工作法来让自己保持自律,免费版的功能完全够你使用,而且非常简单,没有花里胡哨的功能。

Pro版支持时间线呈现、统计图表以及时间支出类别,这些功能有助于自己回顾时间的利用率,并加以改进时间管理能力。

美中不足的是,它不支持Windows和安卓机器。

更加详细的介绍可以看少数派的推荐:
https://sspai.com/post/34014

2.小番茄

小番茄的强大之处在于,它支持所有设备:

  • Android
  • Android Tablet
  • iPhone
  • iPad
  • Apple Watch
  • Mac
  • Windows
  • Chrome Extension

没错,甚至是Chrome的扩展程序它都支持。

它还能定期发送日报、周报、月报总结自己的工作或学习情况,查看定制目标的完成度。

美中不足的是它缺少打断记录功能,这同时使得它的报表功能相对鸡肋。在功能的使用上也相对而言比较复杂,没那么容易上手。

免费版的功能限制较多,相比于Flat Tomato还是逊色一些。

3.Python写的?

关于番茄工作法相关的软件实在太多了,我也没办法给大家一个个都去试,大家如果觉得以上两个APP还是满足不了自己,可以继续在APP Store或少数派上寻宝。

作为一个技术类公众号,当然要教大家用上Python写的计时器啦!

不过我也不想做重复性的工作,用“Python Pomodoro”关键词一搜,你会发现网上一大堆开源代码。

如果你想在PC机或笔记本上实现我们文首提到的最最最基本的番茄工作法,你只需要安装tomato-clock:

pip install tomato-clock

然后在终端或命令行中输入以下任意一个语句即可开始计时:

$ tomato         # 开启一个25分钟的番茄计时器 + 5分钟休息时间
$ tomato -t      # 开启一个25分钟的番茄计时器
$ tomato -t <n>  # 开启一个<n>分钟的番茄计时器
$ tomato -b      # 休息5分钟
$ tomato -b <n>  # 休息<n>分钟
$ tomato -h      # 帮助

美中不足的是,tomato不支持图表统计。

没关系,我们还有大杀器 pomodoro-cli,它不仅支持计时,还支持图表统计,安装方式:

pip install pomodoro-cli

使用方式,终端输入命令:

pomodoro 60 5 --notif=True --alarm=False

这个语句的意思是,工作时长60分钟,每5分钟休息一次,消息框启用、警告不启用。

每次执行完番茄周期,它都会将数据记录在Home/.pomodoro中,要可视化统计这些信息,可以使用pomostat:

pomostat overall
pomostat week
pomostat thisweek
pomostat lastweek
pomostat week --weekof='2018-01-01'
pomostat stats
pomostat weeks
pomostat today
pomostat yesterday

给大家展示一个pomostat lastweek的效果:

效果还是很不错的。当然,离专业的APP如Flat Tomato还有比较大的差距,但是,这样的一个最简单的功能,或许就够我们用了。

总之,番茄工作法真的是一个让自己保持自律的好工具,强烈推荐大家试一试,严格按照步骤走,很快你就会成为一个高效的人。

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 批量生成PDF文档, 办公效率火箭般提升

日常办公中,经常会使用PDF文档,难免需要对PDF文档进行编辑,有时候PDF文档中的大部分内容都是一样的,只是发送对象不同。

这种模板套用的场景下,使用Python进行自动化就尤为方便,用最短的时间办最高效的事。

今天就给大家讲讲如何用Python自动套用模板批量生产PDF文档。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),准备开始输入命令安装依赖。

当然,我更推荐大家用VSCode编辑器,把本文代码Copy下来,在编辑器下方的终端运行命令安装依赖模块,多舒服的一件事啊:Python 编程的最好搭档—VSCode 详细指南。

在终端输入以下命令安装我们所需要的依赖模块:

pip install fpdf

看到 Successfully installed xxx 则说明安装成功。

完整源代码可在【Python实用宝典】公众号后台回复:批量生成pdf 下载

2.基本使用

PyPDF是从PHP移植到Python的第三方模块。其主要特点有:

1.非常容易使用和扩展
2.提供了许多简单示例
3.没有外部依赖项
4.不需要安装变异其他库(DLL)

它的基本功能有:

1.调整PDF精度、页面格式、边距
2.管理页眉、页脚
3.自动分页符、自动换行和文本对齐
4.支持图像、颜色、超链接文本
5.支持压缩

一个最简单的生成示例:

from fpdf import FPDF

pdf = FPDF()
# add_page() 增加一页
pdf.add_page()
# set_font 调整字体
pdf.set_font('Arial', 'B', 16)
# 输出Hello World,宽度40,高度10
pdf.cell(40, 10, 'Hello World!')

# 输出文件
pdf.output('tuto2.pdf', 'F')

生成的效果如下:

这只是一个压缩后的图片,真实PDF比这大得多。

把生成的文本变复杂一点:

from fpdf import FPDF

pdf = FPDF()
# add_page() 增加一页
pdf.add_page()
# set_font 调整字体
pdf.set_font('Arial', 'B', 16)
# 输出Hello World,宽度40,高度10
pdf.cell(40, 10, 'Hello World!')

# 居中输出Powered by FPDF.宽度60,高度10
# border=1 设置显示文本框的框,
# ln=1 代表在这个文本框后换行
# align='C' 则表明文本居中。
pdf.cell(60, 10, 'Powered by FPDF.', border=1, ln=1, align='C')

# 输出文件
pdf.output('tuto2.pdf', 'F')

注意cell的参数:
1. border 取值为0或1,代表是否显示边框。
2. ln 是指在生成该文本框之后焦点移动到的位置,0 代表到该文本框的右边,1 代表换行,2 代表文本框的正下方。
3. align 是指文本对齐格式,C为居中、L为左对齐、R为右对齐。

因此上述代码会生成类似这样的PDF文档:

cell还有2个参数:

1. fill 参数用于设置文本框的背景,TRUE时为白色,False为透明。
2. link 参数用于添加超链接

下面看一个比较复杂的例子,带图片LOGO作为页眉,带页数作为页脚的PDF文档:

看看要怎么实现这个PDF文档的生成。

首先需要继承FPDF类,以用于自定义页眉和页脚。

from fpdf import FPDF

class PDF(FPDF):
    """
    继承FPDF类,以自定义页眉也页脚
    """
    def header(self):
        """
        设置页眉
        """
        # 添加logo
        self.image('pythondict_logo.png', 10, 8, 33)
        # 设置字体
        self.set_font('Arial', 'B', 15)
        # 移动焦点至右边
        self.cell(80)
        # 添加标题
        self.cell(30, 10, 'Title', 1, 0, 'C')
        # 换行
        self.ln(20)

    def footer(self):
        """
        设置页脚
        """
        # 底部以上1.5厘米
        self.set_y(-15)
        # 设置字体
        self.set_font('Arial', 'I', 8)
        # 页码
        self.cell(0, 10, 'Page ' + str(self.page_no()) + '/{nb}', 0, 0, 'C')

这样设置完页眉也页脚后,只要你使用该类定义PDF文档,便会自动带上页眉页脚。

# 使用上述继承并进行了自定义的类
pdf = PDF()
pdf.alias_nb_pages()
pdf.add_page()
pdf.set_font('Times', '', 12)
# 填充内容
for i in range(1, 41):
    pdf.cell(0, 10, 'Printing line number ' + str(i), 0, 1)
pdf.output('tuto2.pdf', 'F')

真的是非常方便。

3.批量生成PDF

接下来在Python实用宝典网站(https://pythondict.com)上随机抽取了5位注册了账号的同学的ID批量制作祝福PDF文档。

这里可以复用咱刚自定义完成的页眉和页尾。不过,为了显示中文,需要在继承的类里面添加并设置字体为本地中文字体,如:

from fpdf import FPDF

class PDF(FPDF):
    """
    继承FPDF类,以自定义页眉也页脚
    """
    def header(self):
        """
        设置页眉
        """
        # 添加logo
        self.image('pythondict_logo.png', 10, 8, 33)
        # 设置字体
        self.add_font('yuanti','','yuanti.ttf', True)
        self.set_font('yuanti')
        # 移动焦点至右边
        self.cell(80)
        # 添加标题
        self.cell(30, 10, 'Python实用宝典祝福您', 0, 0, 'C')
        # 换行
        self.ln(20)

注意,add_font第一个参数是该字体注册进FPDF的名字,之后set_font的时候都使用该名字。

然后将用户名都放到一个数组里,遍历该数组,填充用户名,循环批量生成PDF.

for user in users:
    pdf = PDF()
    pdf.alias_nb_pages()
    pdf.add_page()
    pdf.set_font('yuanti', '', 12)
    pdf.cell(0, 10, 'Dear ' + str(user) + ': ', 0, 1)
    # 填充内容
    for i in range(len(texts)):
        pdf.cell(5)
        pdf.multi_cell(0, 10, texts[i], 0)
    pdf.output(f'output/{user}.pdf', 'F')

最终效果如下:

完整源代码可在【Python实用宝典】公众号后台回复:批量生成pdf 下载

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Pycharm+Django 安装及配置指南

虽然平时我极力推荐使用简单、轻便、灵活的VSCode编辑器进行开发。

但是对于大型Web项目(Django、Tornado等框架)开发,我还是推荐大家使用Pycharm.

Pycharm拥有强大的配置工具、Git版本管理工具、代码补全工具、Debug工具等等,这些都是进行大型项目开发的利器。

尤其是今天的主角Django,由于太过于重要了,Pycharm甚至专门给其提供了配置模板:

能直接在新建项目的时候选择Django并新建一个独立的虚拟环境:

从新建到编码测试,一套流程用起来都极其方便。

1.下载Pycharm

在jetbrains官网选择相应的系统下载Pycharm:
https://www.jetbrains.com/pycharm/download/

这里强烈推荐下载Professional版(专业版),激活方法可以自行在网上查询,推荐知了哥的文章(zhile.io)。

安装完成后,根据你是否需要新建Django项目分为两种配置方式。

1.1 新建Django项目

File-New Project 新建一个Django项目:

强烈推荐新建一个环境,默认新建环境的工具是Virtualenv, 我这里用的是conda,效果其实都差不多。区别在于,conda可以选择Python版本

输入好location(安装位置)后点击create,即可生成Django项目。

1.2 配置已开发的Django项目

Pycharm中适配已开发的Django项目也非常容易,因为它为这种情况专门提供了配置模板:

点击右上角的配置框选择 Edit Configurations

进来后先输入Name 项目名称,然后在Python Interpreter选择你的代码所属环境的编译器,最后选择Fix,弹出Django配置页。

在点击Fix后出现的配置页中,输入这三项:

第一个是项目根目录,第二个是settings.py文件的位置,第三个是manage.py的位置。三者缺一不可。搞定后点击OK,配置完成。

2.运行项目

Pycharm运行Django项目只需要点击右上角这两者之一即可:

第一个是普通的启动方式,第二个是Debug启动方式,推荐第二个,因为开发的时候如果需要跟踪代码流程,Debug模式非常方便。

点击后会自动生成启动Django的命令,你可以在console里查看该语句,出现以下的输出即启动完成:

访问http://127.0.0.1:8000/就是网站的首页了。

这里默认使用的端口号是8000,你可以在配置页修改默认的域名和端口,只不过其他域名你需要在hosts中将其定向到127.0.0.1, 比如:

修改hosts文件,增加:dev.goldenstone.com 127.0.0.1

保存后修改右上角的configurations配置:

在settings.py中,将dev.goldenstone.com这个域名加入到 ALLOWED_HOSTS 中:

这样就可以通过 http://dev.goldenstone.com:5555/ 访问你的开发环境了:

3.工具

下面介绍一些Pycharm中独有的、特别的工具:

3.1 查看文件历史修改及提交记录非常方便:

点击每一个提交,都能看到每次提交的内容。

3.2 选择指定的commit行

VCS-Commit,它可以自由选择你需要提交的代码块:

3.3 自动格式化代码

3.4 全局搜索

尽管VSCode也有全局搜索,但相信我,他们两个不是一个概念:

windows下选择 Ctrl+shift+F 即可在Pycharm中全局搜索,或者在Edit-Find-Find in Path 找到该功能:

界面如下,它不仅仅是全局搜索,还能指定模块、目录进行搜索。

指定文件名搜索,高级过滤器中还能搜索指定除注释以外的符合关键词的句子等等,是一个非常强大的搜索工具。

这个搜索工具对于我而言,使用频率仅次于Debug工具。


Pycharm中非常有用的生产工具还有很多,简直是用都用不完,下次再给大家详细介绍一番!

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典