优劣互补! Python+Go结合开发的探讨

1.都说Go语言性能非常强大,那么到底比Python强多少?

为了比较Go语言和Python语言在单线程性能上的差距,我们可以做一个简单实验,从1亿减到1:

Python代码:

import time
def decrement(n):
    while n > 0:
         n -= 1

start = time.time()
decrement(100000000)
end = time.time()
print(f"{end - start}s.")

结果如下:

大约需要4秒-5秒才能完成这项工作,那么Go语言呢?

package main

import "fmt"
import "time"

var c chan int

func decrement(n int) {
    for n > 0 {
        n -= 1
    }
}

func main() {
    start := time.Now()
    decrement(100000000)
    fmt.Println(time.Since(start))
}

结果如下:

确实,两者差了不止100倍,看得出来Go是一个比较有前途的语言,具有强大的性能(除此之外,它还有简单易学、能轻松实现高并发的特点)。

不过,它的社区建设和Python相比还是有很大的差距,许多第三方库依然还没有支持Go语言。因此,它想要替代Python还有非常长的路要走。

2.Go性能强大、Python社区强大,两者能否结合起来?

我们试试看能否在Python中调用Go的方法,在Go中从1亿减到1。

首先,将刚刚go语言版的1亿减到1改为在一个函数中进行,并返回结果:

package main

import (
    "C"
    "time"
)

var c chan int

func decrement(n int) {
    for n > 0 {
        n -= 1
    }
}

//export count_time
func count_time() *C.char {
    start := time.Now()
    decrement(100000000)
    total_time := time.Since(start).String()
    return C.CString(total_time)
}

func main() {}

然后生成动态链接库以便Python调用Go里写的函数:

go build -buildmode=c-shared -o main.so count.go

这样会在当前文件夹中生成 main.so 和 main.h.

在Python中我们需要加载该生成的main.so动态链接库,并配置好输出变量的类型,最后调用方法得到结果:

import time
from ctypes import cdll, c_char_p

start = time.time()

# 加载动态链接库
lib = cdll.LoadLibrary('./main.so')

# 配置输出参数变量类型
lib.count_time.restype = c_char_p

# 调用方法
rest = lib.count_time()

end = time.time()

print(f"Go 内部执行时间:{rest}")
print(f"Python 整体执行时间: {end - start}s")

结果如下:

可以看到,使用这个方案将Python和Go两者结合起来的性能依然非常高,但就是多了一个生成和调用动态链接库的过程,增加了代码的耦合性。

其实,这也是C+Python的开发方式,只不过我们将C换成了Go,因为Go开发起来实在是舒服多了。

如果以后你的Python代码中有某个部分计算特别复杂,你可以尝试将其改写成go,通过动态链接库的方式调用go写的代码,将能大大提高性能。

这样,既能安心享受Python带来的丰富社区资源,又能享受Go语言的性能优势,真的美滋滋。

我们的文章到此就结束啦,如果你喜欢我们今天的Python 实战教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


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

Python moviepy 一个快速视频剪辑编辑神器

你知道吗,用moviepy一行代码就能够快速剪辑视频中某个区间的片段:

clip = VideoFileClip("videoplayback.mp4").subclip(50,60)

这一段代码,能够在3秒内将videoplayback.mp4的50秒-60秒的视频片段提取出来,非常方便。

https://pythondict-1252734158.file.myqcloud.com/home/www/pythondict/wp-content/uploads/2020/06/2020062216500711.webm

不仅如此,moviepy还支持添加字幕、调整音量、片段链接等功能。下面看看详细的操作方法。

1.准备

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

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

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

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

pip install moviepy

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

2.视频剪辑

剪辑个视频,多大点事,比起下载PR,用Python 写3行代码,3秒剪辑不香吗?

from moviepy.editor import *

# 剪辑50-60秒的音乐 00:00:50 - 00:00:60
video = CompositeVideoClip([VideoFileClip("videoplayback.mp4").subclip(50,60)])

# 写入剪辑完成的音乐
video.write_videofile("done.mp4")

3.视频拼接

“哦?Python?哼,那你肯定很难进行拼接工作吧,PR多方便,拖拽即可完成拼接。”

那你可真是太小看Python了,moviepy几行代码随随便便就能拼接许多片段:

from moviepy.editor import VideoFileClip, concatenate_videoclips
clip1 = VideoFileClip("myvideo.mp4")

# 结合剪辑,你甚至能够完全自动化剪辑拼接视频的操作
clip2 = VideoFileClip("myvideo2.mp4").subclip(50,60)

clip3 = VideoFileClip("myvideo3.mp4")
final_clip = concatenate_videoclips([clip1,clip2,clip3])
final_clip.write_videofile("my_concatenation.mp4")

结合剪辑,你甚至能够完全自动化剪辑拼接视频的操作。

4.逐帧变化

“那你能完成针对每一帧图像的快速图像处理吗?PR可是做得到的哦”

我擦,你简直是在侮辱Python,教你如何反转视频每一帧的绿色和蓝色通道:

from moviepy.editor import VideoFileClip
my_clip = VideoFileClip("videoplayback.mp4")

def scroll(get_frame, t):
    """
    处理每一帧图像
    """
    frame = get_frame(t)
    frame_region = frame[:,:,[0,2,1]]
    return frame_region

modifiedClip = my_clip.fl(scroll)
modifiedClip.write_videofile("test.mp4")

5.导出GIF

哇,听起来好像挺牛逼的,那用来导出到GIF吗

当然可以:

from moviepy.editor import *

# 剪辑50-60秒的音乐 00:00:50 - 00:00:60
video = CompositeVideoClip([VideoFileClip("videoplayback.mp4").subclip(50,60)])

my_clip.write_gif('test.gif', fps=12)

扫描下方二维码,可以加入我们的Python互助群哦:

我们的文章到此就结束啦,如果你喜欢我们今天的Python 实战教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


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

Python 自动识别图片文字—OCR实战教程

OCR 是光学字符识别(英语:Optical Character Recognition,OCR)是指对文本资料的图像文件进行分析识别处理,获取文字及版面信息的过程。

很早之前就有同学在公众号后台回复希望出一篇 OCR 相关的文章,今天尝试了一下cnocr和tesseract,给大家分别讲讲两个模块的使用方法和效果。

1.准备

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

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

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

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

(选择一)安装 cnocr:

pip install cnocr

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

如果你只想对图片中的中文进行识别,那么 cnocr 是一个不错的选择,你只需要安装 cnocr 包即可。

但如果你想试试其他语言的OCR识别,Tesseract 是更好的选择。

(选择二)安装 pytesseract:

首先,无论是Windows还是macOS,你都需要安装 pytesseract:

pip install pytesseract

其次,还需要安装Tesseract.

(macOS)Tesseract 在macOS下可以使用brew安装:

brew install tesseract

非常方便,一条命令即可完成安装。

(Windows)安装Tesseract

需要先下载安装tesseract的程序,然后下载中文简体字预训练好的模型包(尽管本教程不会用tesseract,但还是给大家提供了)。

你可以在Python实用宝典公众号后台回复:tesseract 打包下载。

下载完成后,将 tesseract-ocr-setup-4.00.00dev.exe 安装到 Tesseract-OCR 指定目录下,复制该目录路径增加到Path中:

并将训练好的模型文件chi_sim.traineddata放入该目录中,这样安装就完成了。

2.cnocr 识别图片的中文

cnocr 主要针对的是排版简单的印刷体文字图片,如截图图片,扫描件等。目前内置的文字检测和分行模块无法处理复杂的文字排版定位。

尽管它分别提供了单行识别函数和多行识别函数,但在本人实测下,单行识别函数的效果非常糟糕,或者说要求的条件十分苛刻,基本上连截图的文字都识别不出来。

不过多行识别函数还不错,使用该函数识别的代码如下:

from cnocr import CnOcr
ocr = CnOcr()
res = ocr.ocr('test.png')
print("Predicted Chars:", res)

用于识别这个图片里的文字:

效果如下:

如果不是很吹毛求疵,这样的效果已经很不错了。

3.pytesseract 识别图片的英文

如果你的OCR目的不是中文而是英文,是需要别的模型的。这里给大家分享Tesseract-OCR,它是一款由HP实验室开发,由Google维护的开源OCR引擎。

Tesseract-OCR 可扩展性很强,你可以基于它训练属于自己的OCR模型。

现在给大家看看它分类英文的效果,代码如下:

import pytesseract
from PIL import Image

image = Image.open('test2.png')
code = pytesseract.image_to_string(image, lang='eng')
print(code)

识别的图片:

效果如下:

英文效果真的很不错,当然官方预训练好的中文模型效果就比较一般了。

如果你想试试Tesseract识别中文,只需要将代码中的eng改为chi_sim即可。

我们的文章到此就结束啦,如果你喜欢我们今天的Python 实战教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


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

这10篇Python实战教程,你不学可能会后悔

1.Python 一键生成漂亮的生日快乐词云!

2.比PS还好用!Python实战20行代码批量抠图

3.Python实战教程 自动提取电影中所有人脸

4.Python实战教程 一键转化代码为流程图

5.手把手教你树莓派人脸识别开机的Python实战教程

6.人人都能懂的 Python 自动发送邮件实战教程

7.Python 五分钟绘制漂亮的系统架构图实战教程

8.瑞幸VS星巴克,谁的门店最多?Python实战教程告诉你

9.剪辑音乐要很久?3行语句Python实战瞬间搞定

10.Python 多种音乐格式批量转换实战教程

其实还有好多实战教程就不一一列出来了,毕竟Python实用宝典的原创数其实已经快300了。

大家可以在公众号历史页或者下方阅读原文访问Python实用宝典网。搜索自己想要阅读的关键词。


对了,如果你在实战的过程中有任何疑问,可以加我们的讨论群,里面有许多同学都能提供帮助:

我们的文章到此就结束啦,如果你喜欢我们今天的Python 实战教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


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

我们也有Python学习互助群啦!

最近问我问题的同学越来越多,平台越来越分散,很难进行管理,可能无意中漏了某些同学的问题,请见谅~

为了解决这个问题,我觉得还是搭建一个群,把大家都集中起来比较好。

这样做有几个好处:

一是交流容易、反馈容易,文章有问题大家可以直接@我,这样我就能进行快速的修改。

二是文章发布能被大家及时看到,现在我一般都在早上发布文章,文章有几率会被大家的公众号信息流覆盖掉。

三是更能帮助大家学习Python,有任何问题都能在群里问,我或者其他群友都会尽可能帮你。

四是沟通交流对于我们的学习非常重要,集思广益,各抒己见,人人都尽其所能,你知道我所不知道的,我知道你所不知道的,这样问题就变得容易解决。

群二维码:

另外,再提供一个微信个人号,有什么问题可以直接加我微信问我,有时间的话我会耐心解答的。

如果群二维码过期了,大家也可以直接加我微信,密我“进群”,然后我会拉你进群的。

最后,希望大家能开开心心学Python,学会用Python处理生活中的事~

Django-oscar 快速搭建商城网站

Django是一个相对容易学习的框架,并且已经发展了许多年,拥有相对活跃的开源环境。像豆瓣、Instagram,Spotify,YouTube等官方网站都是基于Django搭建的,今天我们来学着用它搭建一个商城网站。

Python实用宝典 曾经发表过Django的实战教程:

Python Django快速开发音乐高潮提取网(1)

Python Django快速开发音乐高潮提取网(2)

Python Django快速开发音乐高潮提取网(3)

不过,这三篇文章是基于原生Django开发的。

今天我们来尝试使用他人搭建好的框架 Django-oscar,开发一个商城网站。

1.准备

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

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),准备开始第2步操作。

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

2.构建虚拟环境

为了防止不同环境下的Python包互相影响,在开始之前你应该先构建虚拟环境:

使用conda:

conda create -n mywebsite python=3.6

或使用virtualenv:

virtualenv --no-site-packages mywebsite 

如果是使用conda创建的虚拟环境,这样进入虚拟环境中:

Windows:

activate mywebsite 

Mac/Linux:

source activate mywebsite

使用virtualenv的话,一般虚拟环境会被安装到命令当前的目录下,使用以下方式进入虚拟环境:

Windows:

source mywebsite/scripts/activate

Mac/Linux:

source mywebsite/bin/activate 

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

pip install django-oscar

看到 Successfully installed xxx 则说明安装成功,注意这里并不需要先安装Django, 因为Django-oscar中附有依赖的Django版本。

3.安装项目

成功安装依赖后,运行以下命令安装Django项目,我起名为easyshop:

django-admin startproject easyshop

然后进入项目中:

cd easyshop

编辑easyshop.easyshop.settings.py文件,将以下代码复制到settings.py的顶部

from oscar.defaults import *
from oscar import INSTALLED_APPS as OSCAR_APPS
# Path helper
location = lambda x: os.path.join(os.path.dirname(os.path.realpath(__file__)), x)

然后修改TEMPLATES变量以添加模板配置:

TEMPLATES = [
    {
        'BACKEND':'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'templates'),
            OSCAR_MAIN_TEMPLATE_DIR
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.template.context_processors.i18n',
                'django.contrib.messages.context_processors.messages',
                'oscar.apps.search.context_processors.search_form',
                'oscar.apps.checkout.context_processors.checkout',
                'oscar.apps.customer.notifications.context_processors.notifications',
                'oscar.core.context_processors.metadata',
            ],
        },
    },
]

然后在INSTALLED_APPS变量中添加:

django.contrib.sites
django.contrib.flatpages
widget_tweaks

并增加一个SITE_ID变量以便oscar框架识别:

# 此处可能会有重复,因此转化一遍
INSTALLED_APPS = list(set([
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    'django.contrib.flatpages',
    'widget_tweaks',
] + OSCAR_APPS))

SITE_ID = 1

再添加两个中间件到中间件MIDDLEWARE变量:

'oscar.apps.basket.middleware.BasketMiddleware',
'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',

最后添加身份验证和搜索引擎:

AUTHENTICATION_BACKENDS = (
    'oscar.apps.customer.auth_backends.EmailBackend',
    'django.contrib.auth.backends.ModelBackend',
)
HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.simple_backend.SimpleEngine',
    },
}

4.项目运行

为了能正常访问oscar框架提供的后台,还需要配置一下 easyshop.easyshop.urls.py 文件:

from django.apps import apps
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(apps.get_app_config('oscar').urls[0])),
]

执行以下命令来运行项目:

python manage.py migrate
python manage.py createsuperuser
python manage.py runserver

然后访问网址:http://127.0.0.1:8000/dashboard/

会出现一个用户登录框,输入刚createsuperuser时创建的超管用户即可:

进去后,就是网站的后台了:

这个框架给定的功能其实蛮全的,但对于我们中文站来说,你还需要做翻译,因为实质上该框架的国际化并不是很完善。

此外还需要补充微信支付和支付宝支付,这两个需要有商家权限才能开通。你可以从微信的官方SDK中导入相应代码,并结合到框架中。

总而言之,这是一个很不错的Django商城项目,有兴趣的话可以拿它来开发一个简单的商城。更多功能请关注官方文档:

https://django-oscar.readthedocs.io/en/latest/internals/getting_started.html

我们的文章到此就结束啦,如果你喜欢我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


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

同事要我帮忙补写178份Word日报!Python自动化办公实战教程

作者:Ryoko

来源:凹凸数据

不久前,一个同事有个项目要向领导交差,其中一部分工作是根据 excel 表中的每日数据,按格式整理成日报写入 word。

好家伙!足足 178 天的量要补,如果要靠复制粘贴,岂不是肝到吐血,(你给我自己解决啊!)

好吧ojbk,是时候祭出 Python 办公自动化了。

一、基础数据整理

首先让我们来看看数据样本和输出文档的需求(敏感数据已做和谐处理):原始 excel 文件中有 n 个子表,每个子表为一天的数据,存在无记录和有记录(部门数 ≥ 1,每个部门记录数 ≥ 1)两种情况,需分别整理成两种日报,一为纯文本描述,二为附带表格的文档。

撸起袖子,开骂!

哦不,开始写代码!

先将子表合成一个,便于统一观察每日数据记录的规律,也方便后期处理。使用 xlrd 库读表,获取工作簿中的活动表名,再使用 pandas 库遍历子表以合并,dataframe 格式的数据对 excel 表的相性绝佳。

def merge_sheet(filepath): # 合并多个同表头的子表
    wb = xlrd.open_workbook(filepath)
    sheets = wb.sheet_names()
    df_total = pd.DataFrame()
    for name in sheets:
        df = pd.read_excel(filepath, sheet_name=name)
        df_total = df_total.append(df)
    df_total.to_excel("merge.xlsx", index=False)

二、输出两种日报

(一)纯文本文档

根据需要输出的日报样式,输出无记录的日报只需读取【日期】列和【填报部门】列,将【填报部门】列为无的日期段按每日输出即可。观察原表数据,直接筛选无填报记录的数据丢到命名为“无”的子表里。

这里也可以利用 .groupby() 对【填报部门】列分组,取“无”的那一组,可是要注意一点:虽然 Python 很强大,但不需要将所有事情都交给 Python 做。

导入库和模块如下:

import pandas as pd
import xlrd
from docx import Document
from docx.shared import Pt
from docx.shared import Inches
from docx.oxml.ns import qn
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.section import WD_ORIENTATION

基本流程很简单,读入无填报记录的数据,按日期输出 word 文档。

def wu_to_word(filepath):
    df = pd.read_excel(filepath, sheet_name="无")
    date_list = list(df['日期'])
    for d in date_list:
        filename = wordname+str(d)+").docx"  # 输出的word文件名
        title = "("+str(d)[:4]+"."+str(d)[4:6]+"."+str(d)[6:8]+")"  # 副标题日期XXXX.XX.XX
        word = str(d)[:4]+"年"+str(d)[4:6]+"月"+str(d)[6:8]+"日"  # 开头、落款日期XXXX年XX月XX日
        wu_doc(title, word, filename)
        print(f"文件:{filename},{title},{word} 已保存")

每份文档都会用到的同样的内容也可以先设定好。

wordname = “XX公司业务数据表(日报”
all_title = ” XX公司业务报告”

生成 word 内容,不加表格的情况下还是比较容易实现的,注意调整好格式。

def wu_doc(title,word,filename):  # 传入副标题日期,文段开头及落款的日期,文件名
    doc = Document()  # 创建文档对象
    section = doc.sections[0]  # 获取页面节点
section.orientation = WD_ORIENTATION.LANDSCAPE  # 页面方向设为横版
new_width, new_height = section.page_height, section.page_width  # 将原始长宽互换,实现将竖版页面变为横版
    section.page_width = new_width
    section.page_height = new_height
    # 段落的全局设置
    doc.styles['Normal'].font.name = u'宋体'  # 字体
    doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')  # 中文字体需再添加这个设置
    doc.styles['Normal'].font.size = Pt(14)  # 字号 四号对应14
    t1 = doc.add_paragraph()  # 添加一个段落
    t1.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 居中
    _t1 = t1.add_run(all_title)  # 添加段落内容(大标题)
    _t1.bold = True  # 加粗
    _t1.font.size = Pt(22)
    t2 = doc.add_paragraph()  # 再添加一个段落
    t2.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 居中
    _t2 = t2.add_run(title + "\n")  # 添加段落内容(副标题)
    _t2.bold = True
    doc.add_paragraph(word + "无记录。\n\n").paragraph_format.first_line_indent = Inches(0.35)  # 添加段落同时添加内容,并设置首行缩进
    doc.add_paragraph(word).paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT  # 落款日期右对齐
    doc.save(dir+filename)  # 按路径+文件名保存

执行!104 份无填报记录的日报就写好啦,干脆就这样交差吧,剩下的不想研究了哈哈哈。

(二)附表格文档

有报送记录的数据处理起来相对复杂一点,先看一下原始数据。

比如 X 年 X 月 X 日,有 N 个部门填报了数据,根据文档样例,文段描述部分需要整理成如下格式:

部门 A:“报送内容1” X条记录;“报送内容2” Y条记录;部门 B:……;部门 C:……;

而附件表格部分需整理成如下格式,可以预想把每一行需要的数据整理一个 list,按行写入表格:

一级指标 二级指标 三级指标 四级指标 各部门报送情况 备注
lalala hahaha balabala 若为空则沿用上级 部门A:报送内容1 有记录未上传,没报,系统崩了
aaa bbb ccc ddd 部门A:报送内容2 已上传,报的好
部门B:报送内容1

基本流程类似,读表后先按日期分组,每一组含一天中的一个或多个部门数据,再生成某一天的附件需要的表格,接着整理文段描述,最后按日期输出每一天的 word 文档。

def what_to_word(filepath):
    df = pd.read_excel(filepath, sheet_name="有")
    df.fillna('', inplace=True)  # 替换nan值为空字符
    dates = []  # 日期列表
    df_total = []  # 分日期存的所有df
    list_total = []  # 每一份word中需要的表数据合集
    for d in df.groupby('日期'):
        dates.append(d[0])
        df_total.append(d[1])
    for index,date in enumerate(dates):
        list_oneday = []  # 某一个word所需的表数据
        for row in range(len(df_total[index])):
            list_row = get_table_data(df_total, index, row)  # 其中一行数据
            list_oneday.append(list_row)
        list_total.append(list_oneday)
    for index, date in enumerate(dates):
        filename = wordname+str(date)+").docx"  # 输出的word文件名
        title = "("+str(date)[:4]+"."+str(date)[4:6]+"."+str(date)[6:8]+")"  # 副标题日期XXXX.XX.XX
        word = str(date)[:4]+"年"+str(date)[4:6]+"月"+str(date)[6:8]+"日"  # 开头、落款日期XXXX年XX月XX日
        sentence = get_sentence(df_total, index)  # 某一天的文段描述
        what_doc(title, word, sentence, list_total[index], filename)  #传入需要的内容后输出文档
        print(f"文件:{filename} 已保存")

下面让我们分别看看整理表格、整理文段、输出文档是如何实现的。

1、整理表格

获取 excel 表中的一行数据(说明df_total[df_index] 为一个 dataframe,其 values 为一个二维的 numpy 数组),整理各级指标、各部门报送情况和备注,返回一个列表。

def get_table_data(df_total, df_index, table_row):
    list1 = df_total[df_index].values[table_row]  # excel表中的一行
    list2 = list1[3:7]  # 一至四级指标
    for i in range(len(list2)):  # 当前指标为空则沿用上级指标
        if list2[i] == '空' and i != 0:
            list2[i] = list2[i - 1]
    content = list1[2] + ":\n" + list1[-4]  # 报送内容
    if '否' in list1[-2]:  # 备注
        remark = '有记录未上传,' + str(list1[-1])
    else:
        remark = '已上传'
    list3 = list2.tolist()  # 需填入word中的表数据,由numpy数组转为list列表
    list3.append(str(content))
    list3.append(str(remark))
    return list3

2、整理文段

对当日数据中的【填报部门】列中的唯一值计数,得知有 N 个部门填报了数据。对部门分组,获取其相关信息,组合成 [(报送内容,记录数,是否上报,备注)] 的格式,再整理出形如 “有N个部门报送了数据:部门X:“ 报送内容XXX ” X条记录;… …” 的描述串。

def get_sentence(df_total, df_index):
    df_oneday = df_total[df_index]
    num = df_oneday['填报部门'].nunique()  # 部门的数量
    group = []  # 部门名称
    detail = []  # 组合某个部门的数据,其中元素为元组格式(, , , )
    info = ''  # 报送情况描述
    for item in df_oneday.groupby('填报部门'):
        group.append(item[0])
        detail.append(
            list(
                zip(
                    list(item[1]['报送内容']),
                    list(item[1]['记录数']),
                    list(item[1]['是否上报']),
                    list(item[1]['备注'])
                )
            )
        )
    for index, g in enumerate(group):  # 整理每个部门的填报情况
        mes = str(g)+':'  # 部门开头
        for i in range(len(detail[index])):
            _mes = detail[index][i]
            if int(_mes[1])>0:
                mes = mes + f'“{_mes[0]}{_mes[1]}条记录;'
        info = info + mes
    info = info[:-1]+"。"  #将最后一个分号替换成句号
    sentence = f"有{num}个部门报送了数据:{info}"
    return sentence

3、输出文档

(耐心警告!)调整 word 中的文本和表格样式的操作比较繁琐,需一步一步设置,预设表头如下:

table_title = [‘一级指标’, ‘二级指标’, ‘三级指标’, ‘四级指标’, ‘各部门报送情况’, ‘备注’]

其他详见代码注释。

def what_doc(title, word, sentence, table, filename):  # 传入副标题日期,开头/落款日期,文段,表数据,文件名
    doc = Document()
    section = doc.sections[0]
    new_width, new_height = section.page_height, section.page_width
    section.orientation = WD_ORIENTATION.LANDSCAPE
    section.page_width = new_width
    section.page_height = new_height
    # 段落的全局设置
    doc.styles['Normal'].font.name = u'宋体'  # 字体
    doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')  # 中文字体需再添加这个设置
    doc.styles['Normal'].font.size = Pt(14)  # 字号 四号对应14
    t1 = doc.add_paragraph()  # 大标题
    t1.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 居中
    _t1 = t1.add_run(all_title)
    _t1.bold = True
    _t1.font.size = Pt(22)
    t2 = doc.add_paragraph()  # 副标题
    t2.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 居中
    _t2 = t2.add_run(title + "\n")
    _t2.bold = True
    doc.add_paragraph(word + sentence +"\n\n").paragraph_format.first_line_indent = Inches(0.35)  # 首行缩进
    doc.add_paragraph(word).paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT  # 右对齐
    doc.add_paragraph("各部门具体报送情况见附件:")

    doc.add_page_break()  # 分页---------------------------------------------------------------
    fujian = doc.add_paragraph().add_run("\n附件")
    fujian.bold = True
    fujian.font.size = Pt(16)
    t3 = doc.add_paragraph()  # 附件大标题
    t3.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 居中
    _t3 = t3.add_run("XX公司业务数据表")
    _t3.bold = True
    _t3.font.size = Pt(22)

    rows = len(table)+1
    word_table = doc.add_table(rows=rows, cols=6, style='Table Grid')  # 创建rows行、6列的表格
    word_table.autofit=True  # 添加框线
    table = [table_title] + table  # 固定的表头+表数据
    for row in range(rows):  # 写入表格
        cells = word_table.rows[row].cells
        for col in range(6):
            cells[col].text = str(table[row][col])
    for i in range(len(word_table.rows)):    # 遍历行列,逐格修改样式
        for j in range(len(word_table.columns)):
            for par in word_table.cell(i, j).paragraphs:  # 修改字号
                for run in par.runs:
                    run.font.size = Pt(10.5)
            for par in word_table.cell(0, j).paragraphs:  # 第一行加粗
                for run in par.runs:
                    run.bold = True
    doc.save(dir+filename)

执行!74份有记录的日报也写好啦,一共178份。

一顿操作猛如虎,总算是批量生成了日报,盒饭该加个鸡腿子了吧… …

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

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

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

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

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

Python 多种音乐格式转换(批量)实战教程

Pydub是一个基于ffmpeg的Python音频处理模块,封装了许多ffmpeg底层接口,因此用它来做音乐歌曲文件格式转换会非常方便,如果你阅读过我们之前的文章:Python 超方便超快速剪辑音乐 你就知道它有多么强大了。

今天给大家介绍它的音乐文件格式转换功能,几乎支持所有音乐音频格式,非常强大。

1.安装

安装Pydub前需要先安装ffmpeg:

Mac (打开终端(Terminal), 用 homebrew 安装):

brew install ffmpeg --with-libvorbis --with-sdl2 --with-theora

Linux:

apt-get install ffmpeg libavcodec-extra

Windows:

1. 进入 http://ffmpeg.org/download.html#build-windows,点击 windows 对应的图标,进入下载界面点击 download 下载按钮,
2. 解压下载好的zip文件到指定目录
3. 将解压后的文件目录中 bin 目录(包含 ffmpeg.exe )添加进 path 环境变量中

上述ffmpeg安装成功后就可以打开命令提示符(cmd),安装pydub:

pip install pydub

1.mp3转wav或其他格式

将单个mp3音频文件转化为wav音频格式:

from pydub import AudioSegment
def trans_mp3_to_wav(filepath):
    """
    将mp3文件转化为wav格式

    Args:
        filepath (str): 文件路径
    """
    song = AudioSegment.from_mp3(filepath)
    filename = filepath.split(".")[0]
    song.export(f"{filename}.wav", format="wav")

可以继续封装该函数,将单个mp3文件转化为任意其他音乐音频格式:

from pydub import AudioSegment
def trans_mp3_to_any_audio(filepath, audio_type):
    """
    将mp3文件转化为任意音频文件格式

    Args:
        filepath (str): 文件路径
        audio_type(str): 文件格式
    """

    song = AudioSegment.from_mp3(filepath)
    filename = filepath.split(".")[0]
    song.export(f"{filename}.{audio_type}", format=f"{audio_type}")

如ogg格式:

trans_mp3_to_any_audio("Alone.mp3", "ogg")

只要是ffmpeg支持的音乐音频格式,它都可以转换,支持的格式长达几十个,我简单列一些:

wavavimp4flv
oggflacapemp2
aiffvocau

2.更加通用的转换函数

刚刚是mp3转任意音频格式,我希望把它写成任意音频格式转任意音频格式:

from pydub import AudioSegment
def trans_any_audio_types(filepath, input_audio_type, output_audio_type):
    """
    将任意音频文件格式转化为任意音频文件格式

    Args:
        filepath (str): 文件路径
        input_audio_type(str): 输入音频文件格式
        output_audio_type(str): 输出音频文件格式
    """

    song = AudioSegment.from_file(filepath, input_audio_type)
    filename = filepath.split(".")[0]
    song.export(f"{filename}.{output_audio_type}", format=f"{output_audio_type}")

比如将ogg音乐音频格式转化为flv音乐音频格式:

trans_any_audio_types("Alone.ogg", "ogg", "flv")

或者MP4格式,总之,一般而言你需要的格式它都能满足。

trans_any_audio_types("Alone.ogg", "ogg", "mp4")

3.批量转化音频格式

现在,尝试将一个文件夹下的所有非mp3音频格式的文件转化为mp3音频格式:

def trans_all_file(files_path, target="mp3"):
    """
    批量转化音频音乐格式

    Args:
        files_path (str): 文件夹路径
        target (str, optional): 目标音乐格式. Defaults to "mp3".
    """

    for filepath in os.listdir(files_path):
        # 路径处理
        modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
        datapath = os.path.join(modpath, files_path + filepath)

        # 分割为文件名字和后缀并载入文件
        input_audio = os.path.splitext(datapath)
        song = AudioSegment.from_file(datapath, input_audio[-1].split(".")[-1])

        # 导出
        song.export(f"{input_audio[0]}.{target}", format=target)

只要输入文件夹名称,即可全部转化该文件夹下的音乐文件格式为mp3格式:

trans_all_file("F:\\push\\20200607\\music\\")

我们的文章到此就结束啦,如果你喜欢我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


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

Python 开发任天堂Switch程序??奉上教程!

用Python开发Switch程序,在你的Switch上运行Python代码,你需要用到一个名为PyNX的开源工具,操作流程如下:

1.用读卡器将SD卡插入开发设备(电脑or笔记本)中

2.将PyNX的Zip版本的内容复制到SD卡的/switch目录下

3.编辑main.py文件, 将你的代码逻辑写入该文件中

4.将SD卡插入Switch

5.在Homebrew菜单中运行PyNX

听起来挺简单,不过其中第5步的Homebrew菜单你需要通过特殊的方法来绕过Switch的限制,这里不过多描述,可以看这篇文章:
https://switch.homebrew.guide/

1.准备

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

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

当然,我更推荐大家用VSCode编辑器,写代码可惬意了:Python 编程的最好搭档—VSCode 详细指南。

按照流程,接下来你需要下载源代码的Zip版本:

https://github.com/nx-python/PyNX/archive/master.zip

无法下载请在Python实用宝典后台回复: Switch 获取​网盘链接。​

解压后将其复制到SD卡的/switch目录下。

2.编写简单的备份工具

接下来就可以编写该源代码中的main.py文件了,这个就是我们DIY程序的主要代码。

首先,需要导入一些库以开始在我们的自制应用程序上工作,主要用到了作者的nx包。此外,我们还想向用户显示选择菜单,因此我们也应该导入AnsiMenu:

import nx
from nx.utils import AnsiMenu

接下来,创建常量来存储《塞尔达传说:狂野的呼吸》和《超级马里奥·奥德赛》的名称ID:

# title IDs are hexadecimal numbers
BOTW_TITLE_ID = 0x01007EF00011E000
SMO_TITLE_ID = 0x0100000000010000

创建两个列表,将其用于菜单栏。用户可以选择的标题名称在中title_nametitle_ids用于以相同顺序存储游戏ID:

title_names = ["The Legend of Zelda - Breath of the Wild", "Super Mario Odyssey"]
title_ids = [BOTW_TITLE_ID, SMO_TITLE_ID]

设置完列表后就可以使用AnsiMenu实用程序类创建菜单。此菜单将允许用户选择将保存数据备份的游戏名称:

select_title_menu = AnsiMenu(title_names)

每个Python程序的主要执行流程最好进行如下包装:

if __name__ == '__main__':

现在可以使用其query方法呈现查询菜单:

selected_index = select_title_menu.query()

query方法返回用户选择的索引(index),该索引现在存储在selected_index变量中。由于我们先前创建的两个列表的顺序相等,因此我们可以使用索引从title_ids列表中获取游戏ID :

selected_title_id = title_ids[selected_index]

selected_title_id现在包含所选的游戏ID。现在,我们可以使用此游戏ID创建一个功能Title对象:

selected_title = nx.titles[selected_title_id]

现在,我们需要备份所选择的游戏数据。为此,我们需要挂载游戏的savedata。这需要通过selected_title对象的savedata来完成:

with selected_title.savedata as savedata:
    savedata.backup()

这将创建数据备份/backups/savedata/{title_id}/。当然你还可以提供自己的备份路径,如下所示:

with selected_title.savedata as savedata:
    savedata.backup('/savedata_backups/{}/'.format(title_names[selected_index]))

完整代码如下:

import nx
from nx.utils import AnsiMenu


# title IDs are hexadecimal numbers
BOTW_TITLE_ID = 0x01007EF00011E000
SMO_TITLE_ID = 0x0100000000010000
title_names = ["The Legend of Zelda - Breath of the Wild", "Super Mario Odyssey"]
title_ids = [BOTW_TITLE_ID, SMO_TITLE_ID]

select_title_menu = AnsiMenu(title_names)

if __name__ == '__main__':
    selected_title = select_title_menu.query()

    selected_title = title_ids[selected_title]
    selected_title = nx.titles[selected_title]

    with selected_title.savedata as savedata:
        savedata.backup('/savedata_backups/{}/'.format(title_names[selected_index]))

恭喜,你已使用Python创建了第一个Switch自制程序!

文章增删改自作者的tutorial, 感谢他:
https://nx-python.readthedocs.io/en/latest/getting_started/tutorial.html

我们的文章到此就结束啦,如果你喜欢我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


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

Python 任意系统找回wifi密码

经常遇到这样一种情况:家里来了客人,问你要wifi密码。

尴尬的是,你忘了wifi密码。

不过你的其他设备已经连接过WiFi,这时候你怎么利用这些设备重新获取WiFi密码呢?

有一种方法是登录路由器管理页面,但是如果你连路由器密码也忘了,那就非常尴尬。

还有一种方法是通过iCloud钥匙串,但这个方法非常麻烦,需要通过备份获取。

今天告诉大家一个最简单的方法:通过Python来找回当前使用的wifi密码。

1.准备

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

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

此外,你需要一台已经连接了Wifi的电脑,macOS和windows都可以。

2.原理解析

实质上,获取密码是使用命令的方式,比如Windows下获取WiFi密码:

netsh wlan show profile name=Wifi名称 key=clear | findstr 关键内容

macOS下获取WiFi密码:

sudo security find-generic-password -l wifi名称 -D 'AirPort network password' -w

Linux下获取WiFi密码:

sudo cat /etc/NetworkManager/system-connections/wifi名称| grep psk=

通过这三种命令就可以获取得到当前使用的WiFi名称。

3.代码编写

首先封装命令:

def fetch_password(system, wifi_name):
    """
    用于获取命令

    Arguments:
        system {str} -- 系统类型
        wifi_name {str} -- wifi名

    Returns:
        str -- 密码

    Author: Python 实用宝典
    """

    if system == "linux":
        command = f"sudo cat /etc/NetworkManager/system-connections/{wifi_name}| grep psk="
    elif system == "macos":
        command = f"sudo security find-generic-password -l{wifi_name} -D 'AirPort network password' -w"
    elif system == "windows":
        command = f"netsh wlan show profile name={wifi_name} key=clear | findstr 关键内容"
    result = fetch_result(system, command)
    return result

其中,fetch_result 用于执行命令获得数据:

def fetch_result(system, command):
    """
    用于执行命令获取结果

    Arguments:
        system {str} -- 系统类型
        command {str} -- 命令

    Returns:
        str -- 解码后的密码

    Author: Python 实用宝典
    """
    result, _ = subprocess.Popen(
        command, stdout=subprocess.PIPE, shell=True
    ).communicate()
    return decode_result(system, result)

decode_result用于解码命令:

def decode_result(system, result):
    """
    解码密码

    Arguments:
        system {str} -- [系统类型]
        result {str} -- [输出]

    Returns:
        [str] -- [解码后的密码]
        
    Author: Python 实用宝典
    """

    if system == "windows":
        # cmd命令得到的结果是bytes型,需要decode
        result = result.decode("gb2312")
    result = result.strip('\r|\n')
    if result != "":
        result = result.replace(" ", "")
        result = result[result.find(":") + 1:]
    result = result[result.find("=") + 1:]
    return result

大功告成,你只需要执行:

print(fetch_password('系统类型', 'wifi名称'))

即可获得密码。

如果你的电脑连接过其他wifi,并且没有删除过相关的网络配置,实际上也可以使用该函数获取其他wifi的密码。以上就是完整源代码,如果你懒得再打一遍,可访问github链接获取:
https://github.com/Ckend/pythondict-tools/tree/master/2.wifi-password

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

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

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

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

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