Introduction
-
目标功能:用户输入产品系列名即可查询到相应的芯片具体型号、内核消息、Flash/RAM大小,封装类型以及工作温度。软件可方便用户进行芯片选型,无需翻找芯片选型手册。
-
现有工具:Pycharm、芯片选型手册PDF
-
需要用到的库:camelot-py、os、sys、json、fire
-
实现思路:
-
芯片选型手册中收录了MM32各个系列共7张表格,首先想到的方法是提取PDF中的这7张表格数据,再对表格数据进行查找。选用了Camelot: PDF Table Extraction for Humans,通过这个轮子,可以方便地提取PDF文件中的表格数据。Camelot具体的使用方法下面会介绍。
-
提取表格数据直接查找有两种实现方法: 1-1 指定表格页码,精确提取相应表格 1-2 提取所有表格,再进行查找
方法1-1需要对每张表格指定页码,不便于后期维护。
方法1-2每次读取PDF中的所有表格耗费时间太长。 -
通过Camelot将提取的表格数据转成json格式,再对json格式进行操作查找。
-
通过Camelot将提取的表格数据转成database格式,存入数据库,再对数据库进行操作查找。
方法1-1、1-2及方法2都已通过代码实现。下文具体介绍方法2。
-
Camelot提取表格
pip安装
pip install camelot-py[cv]
可以使用清华镜像,安装会快很多
pip install camelot-py[cv] -i https://pypi.tuna.tsinghua.edu.cn/simple
将Camelot导入python文件
import camelot.io as camelot
注意在pycharm的setting里要导入的是camelot-py,而不是camelot!如果导错了,记得要把camelot删掉。
但运行报错了……
在「冥更」Python提取PDF中表格数据 中找到了解决办法:需要安装ghostscript,并且去ghostscript官网去下载exe文件安装。
pip install ghostscript
虽然不知道为什么,但照着这么做之后就可以运行啦!
Camelot使用
详细的使用方法可以查阅Camelot Documents,下面介绍几个我用到的功能。
-
创建表格对象
- 读取指定页数的表格
tables = camelot.read_pdf("Mindmotion product selection manual.pdf",pages = '5,6,7')
如果不加pages这项,默认读取PDF的第一页。Camelot会读取指定页数中的所有表格,并从0开始编号。
- 读取全部页数的表格
tables = camelot.read_pdf("Mindmotion product selection manual.pdf",pages = '1-end')
- 补齐合并表格中的列
camelot.read_pdf("Mindmotion product selection manual.pdf", pages='5', copy_text=['v'])
如果补齐行,修改copy_text = [‘h’]
-
查看表格对象
- 查看表格个数
tables.n
- 查看表格形状,需指定表格
tables[0]
- 打印表格中的内容
tables[0].df # type is pandas.core.frame.DataFrame tables[0].data # type is list
-
导出表格内容
- 导出json类型
tables[0].to_json("json/sample.json")
Camelot还支持导出csv、excel、html以及sqlite格式文件,分别使用to_csv、to_excel、to_html、to_sqlite语句。不过,Camelot导出文件是一个表格对应一个文件,合并文件还需要通过python实现。
Camelot的更多高级功能可以查阅Camelot Advanced Usage。
json文件合并
参考了「automate123」python 多个json文件合并,代码如下。
import os
import json
def merge_json():
filedir ='json'
# get the file name list in current folder
filenames=os.listdir(filedir)
# open result.json file in current catalog, create one if it does not exit
f=open('json/result.json','w')
# traverse the filenames
for filename in filenames:
filepath = filedir+'/'+filename
# traverse each file, get the row number
for line in open(filepath):
f.writelines(line)
f.write('\n')
# close the file
f.close()
不过这个合并只是单纯地把json文件内容进行了复制粘贴,合成后的json文件格式需要手动调整一下。
查找芯片型号
- 打开json文件
- 遍历json,查找匹配的系列名称
- 提取匹配的芯片的相应信息存入product_dict
- 将所有匹配的芯片的product_dict合并到product_list
filename = "json/MM32SeriesTable.json"
product_list = []
def search_json(name):
with open(filename) as f:
pop_data = json.load(f)
i = 0
for pop_dict in pop_data:
if(pop_dict['Series'] == "MM32" + name):
i = i + 1
Num_str = str(i) + "."
PartNO_str = pop_dict['PartNO']
Core_str = pop_dict['Core']
Flash_str = pop_dict['Flash']
RAM_str = pop_dict['RAM']
Package_str = pop_dict['Package']
Temp_str = pop_dict['OperationTemp']
product_dict = {
"Num": Num_str,
"PartNO": PartNO_str,
"Core": Core_str,
"Flash": Flash_str,
"RAM": RAM_str,
"Package": Package_str,
"Temp": Temp_str
}
product_list.append(product_dict)
格式化输出
通过以上步骤,已经实现了芯片选型小软件的基本功能,不过现在用户看到的输出信息没有对齐,不美观。
试了很多种方法,最后在「Rambo.John」python中英文输出对齐这里找到的解决方法。解决的思路是让字符串总长度保持一致,不够的补充空格。虽然不是特别好,但可以勉强达到效果。
最后的效果是这样的:
- 判断中英文字符
def isChinese(ch):
if ch >='\u4e00' and ch <= '\u9fa5':
return True
else:
return False
-
计算字符串长度
一个中文所占的字节数是2个字节,相当于两个英文字符。
def lenStr(string):
count = 0
for line in string:
if isChinese(line):
count = count + 2
else:
count = count + 1
return count
- 打印统一的字符串长度
gLen = 15
headList = ["Num","PartNO.","Core","Flash","RAM","Package","OperationTemp"]
def show_result():
name = input("Please Input the Chip Type:")
search_json(name)
if(len(product_list) == 0):
print("Please Check the Input Chip Type")
sys.exit(0)
headStr = "".join([x + " " * (gLen - lenStr(x)) for x in headList])
print(headStr)
print("=" * 110)
for product_dict in product_list:
lineList = [product_dict["Num"], product_dict["PartNO"], product_dict["Core"], product_dict["Flash"], product_dict["RAM"], product_dict["Package"], product_dict["Temp"]]
lineStr = "".join([x + " " * (gLen - lenStr(x)) for x in lineList])
print(lineStr)
Fire生成CLIs命令行运行
python生成命令行接口CLIs后就可以通过命令行进行运行,选用了Python Fire,由谷歌开源,不用改变原始代码就可以生成CLIs。
pip安装
pip install fire
fire的使用
使用非常简单,这里传入的是单个函数,详细的用法可以参考The Python Fire Guide
import fire
if __name__ == '__main__':
fire.Fire(show_result)
pyinstaller生成exe可执行文件
很可惜,还没成功。不过问题总会一个一个一个一个一个地解决的!
py2exe以及pyinstaller都可以将python脚本文件进行打包生成exe文件,这里选用了PyInstaller,可以生成windows、Linux、Mac的可执行文件。
pip安装
pip install pyinstaller
pyinstaller的使用
pyinstaller是在命令行里执行的,详细的用法可以参考Using PyInstaller。
pyinstaller -F mm32_json.py