文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python 代码一键转流程图---python=>flowchart-dsl=>流程图

2023-10-02 17:12

关注

简介:

这个项目是基于大名鼎鼎的 flowchart.js

下面贴几张运行图片:

 如果直接输入dsl代码,再进行转化就可以很好的画出流程图

 

 

 

flowchart.js

如果你使用 Typora,可能知道在 Typora 中用 flow 可以用一种简单的文本语言来写流程图,根据 Typora 的文档,这个功能来自开源的 flowchart.js。 

我的方案就是把 Python 代码转化成这种 flowchart 语言,然后你就可以借助 flowchart.js.orgTypora、 francoislaberge/diagrams 等等工具来生成流程图了。

st=>start: Start:>http://www.google.com[blank]e=>end:>http://www.google.comop1=>operation: My Operationsub1=>subroutine: My Subroutinecond=>condition: Yesor No?:>http://www.google.comio=>inputoutput: catch something...para=>parallel: parallel tasksst->op1->condcond(yes)->io->econd(no)->parapara(path1, bottom)->sub1(right)->op1para(path2, top)->op1

 

PyFlowchart

下面简要介绍如何使用我实现的 PyFlowchart,更详细的说明请看项目的 README

安装 PyFlowchart:

$ pip3 install pyflowchart

写一个 simple.py 文件:

def foo(a, b):    if a:        print("a")    else:        for i in range(3):            print("b")    return a + b

运行 PyFlowchart:

$ python3 -m pyflowchart simple.py

它会输出 flowchart 代码:

st4439920016=>start: start fooio4439920208=>inputoutput: input: a, bcond4439920592=>condition: if asub4439974736=>subroutine: print('a')io4439974672=>inputoutput: output:  (a + b)e4439974352=>end: end function returncond4439974224=>operation: print('b') while  i in range(3)st4439920016->io4439920208io4439920208->cond4439920592cond4439920592(yes)->sub4439974736sub4439974736->io4439974672io4439974672->e4439974352cond4439920592(no)->cond4439974224cond4439974224->io4439974672

访问 flowchart.js.org,把上面生成的代码粘贴到文本框里,右边就会自动生成流程图了:

 

当然,你也可以直接把这些代码放到 Typora 的 flow 代码块里,也会自动生成流程图。如果你喜欢使用命令行,也可以用 francoislaberge/diagrams 来生成流程图。

如果生成的流程图有让人不满意的地方(比如,线条重叠)或者你喜欢指定样式,参考 flowchart.js.org,手动修改一下生成的 flowchart 就可以了,非常方便。
 

实现原理

1. 得到 flowchart - DSL

 

PyFlowchart 利用 Python 内置的 ast包,把代码转化成 AST(抽象语法树),然后把 AST 转化成自己定义的 Node 组成的图,每个 Node 对应一个 flowchart 中的 node,遍历这个图就可以得到流程图了。

关于 ast 包,可以看看这篇文章:AST 模块:用 Python 修改 Python 代码,虽然很老,但十分简单易懂。总而言之,利用 ast 包,我们可以把一段 Python 代码转化为一个数据结构:

>>> import ast>>> expr = """... def add(a, b):...     return a + b... """>>> expr_ast = ast.parse(expr)>>> expr_ast<_ast.Module object at 0x10c773e10>>>> ast.dump(expr_ast)# p.s. 这里手动做了格式化Module(body=[FunctionDef(name='add',  args=arguments(    args=[      arg(arg='a', annotation=None),      arg(arg='b', annotation=None)],    vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]),  body=[Return(value=BinOp(    left=Name(id='a', ctx=Load()),    op=Add(),    right=Name(id='b', ctx=Load())))],  decorator_list=[],  returns=None)])

学会了这个东西,接下来的工作就是把这个 expr_ast (_ast.Module 对象) 翻译成流程图了。我们用面向对象来的方法来实现:

pyflowchart.node

 

Node 是最最基础的类,表示流程图中的一个节点,其他一切都继承自它。Node 有节点类型、名称、内容等属性,提供的 fc_definition()fc_connection() 方法可以把自己转化为 flowchart 语言的字符串。另外的 __visited _traverse() 是用来遍历图的。与 flowchart 中的 node types 对应,我们实现了各种 Node 的子类:StartNode、EndNode、OperationNode…

NodesGroup 是一个特殊的 Node,它自己不会出现在生成的 flowchart 中,但它可以包含一些其他 Node。这个设计是受到 Android 的 View、ViewGroup 的启发,有了这个 NodesGroup,if 语句、for / while 循环这样有嵌套的 body 的情况就很容易处理了。

AstNode 表示一个从 AST 对象得到的 Node。构造 AstNode,就是把某个 AST 对象翻译成一个 Node(也可以是 NodesGroup)。其子类就和各种 ast 对象对应(也就和 Python 的各种语句对应): If、Loop、Return …

Flowchart 代表一张流程图。流程图就是一堆连在一起的节点嘛,所以 Flowchart 是 NodesGroup 的子类。在其 from_code() 中方法中,实现了用 ast 包解析 Python 代码,得到 ast 对象的工作。在 flowchart() 方法中,遍历图,拿到所有节点的 flowchart 表示,汇总成一张完整的 flowchart 流程图。

其实这个东西很简单,更具体的实现看源码就很好理解了,在此不做赘述。总结一下:

Flowchart 中利用 ast 包实现了 code to ast;
AstNode 及其子类实现了 ast to node graph;
Node 及其子类实现了 node graph to flowchart。

2. 通过Diagrams转化为流程图

我这里使用了Diagrams将flowchart转化为流程图

diagrams需要使用下面的命令下载,这样下载的diagrams是全局的,需要先下载node
npm install -g diagrams

下载好后在项目文件夹下执行下面的命令即可生成流程图

diagrams flowchart input.flowchart flowchart.svg

 

3. 界面显示

思路:

关于graphviz的详细解释可以看:Python生成决策树的.dot文件以及使用graphviz将其转化为png等图片格式

下面是一部分代码:

Diagrams.py

import osimport tkinter as tkfrom tkinter import filedialog#选择保存路径root = tk.Tk()root.withdraw()file_path = filedialog.asksaveasfilename(defaultextension=".svg")#保存 SVG 文件os.system(f"diagrams flowchart simple.flowchart {file_path}")#将 SVG 文件转换为 PNG 格式png_path = os.path.splitext(file_path)[0] + ".png"os.system(f"cairosvg {file_path} -o {png_path}")#打开 PNG 文件os.startfile(png_path)

GUI.py

    def convert(self):        code = self.textbox.get("1.0", "end-1c")        chart = Flowchart.from_code(code)        self.result_textbox.delete("1.0", "end")        self.result_textbox.insert("1.0", chart.flowchart())        # 保存流程图到文件        with open("input.flowchart", "w") as f:            f.write(chart.flowchart())    def save(self):        # 获取文本框内容        content = self.result_textbox.get("1.0", "end-1c")        # 将内容保存到文件        with open("input.flowchart", "w") as f:            f.write(content)    def ok(self):        # 选择保存路径        root = tk.Tk()        root.withdraw()        file_path = filedialog.asksaveasfilename(defaultextension=".svg")        # 保存 SVG 文件        os.system(f"diagrams flowchart simple.flowchart {file_path}")        # 将 SVG 文件转换为 PNG 格式        png_path = os.path.splitext(file_path)[0] + ".png"        os.system(f"cairosvg {file_path} -o {png_path}")        # 打开 PNG 文件        # os.startfile(png_path)        # 显示图片        self.show_image(png_path)    def show_image(self, png_path):        # 打开图片        img = Image.open(png_path)        # 调整图片大小        width, height = img.size        if width > height:            new_width = 1000            new_height = int(height * (new_width / width))        else:            new_height = 800            new_width = int(width * (new_height / height))        img = img.resize((new_width, new_height))        # 将图片显示到标签中        self.image = ImageTk.PhotoImage(img)        self.image_label.config(image=self.image)        self.image_label.image = self.image

参考文章:

Python 代码一键转流程图_python代码转流程图_CDFMLR的博客-CSDN博客

Python生成决策树的.dot文件以及使用graphviz将其转化为png等图片格式(附本人自己编写的具体函数源码)_ななみ けんと的博客-CSDN博客

seflless/diagrams: Generate Flowcharts, Network Sequence Diagrams, GraphViz Dot Diagrams, and Railroad Diagrams (github.com) 

来源地址:https://blog.csdn.net/weixin_45897172/article/details/131003591

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯