python: 产品选型小软件

Introduction


  • 目标功能:用户输入产品系列名即可查询到相应的芯片具体型号、内核消息、Flash/RAM大小,封装类型以及工作温度。软件可方便用户进行芯片选型,无需翻找芯片选型手册。

  • 现有工具:Pycharm、芯片选型手册PDF

  • 需要用到的库:camelot-py、os、sys、json、fire

  • 实现思路

    1. 芯片选型手册中收录了MM32各个系列共7张表格,首先想到的方法是提取PDF中的这7张表格数据,再对表格数据进行查找。选用了Camelot: PDF Table Extraction for Humans,通过这个轮子,可以方便地提取PDF文件中的表格数据。Camelot具体的使用方法下面会介绍。

    2. 提取表格数据直接查找有两种实现方法: 1-1 指定表格页码,精确提取相应表格 1-2 提取所有表格,再进行查找

      方法1-1需要对每张表格指定页码,不便于后期维护。
      方法1-2每次读取PDF中的所有表格耗费时间太长。

    3. 通过Camelot将提取的表格数据转成json格式,再对json格式进行操作查找。

    4. 通过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)

格式化输出


通过以上步骤,已经实现了芯片选型小软件的基本功能,不过现在用户看到的输出信息没有对齐,不美观。

before formatting

试了很多种方法,最后在「Rambo.John」python中英文输出对齐这里找到的解决方法。解决的思路是让字符串总长度保持一致,不够的补充空格。虽然不是特别好,但可以勉强达到效果。

最后的效果是这样的:

output

  • 判断中英文字符
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
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值