【问题标题】:convert the python dictionary output into a flowchart将python字典输出转换为流程图
【发布时间】:2014-12-28 02:14:20
【问题描述】:

我有一个文件(请参阅下面代码中的状态变量),我想将其转换为流程图(附件)。我的 python 脚本将“状态”转换为字典。如何将该字典转换为流程图或图形? 我的代码:

status = """
Object car {
Name honda;
From Richland;
To Seattle;
Distance 160;
Configuration road_travel;
}

Object bus {
Name greyhound;
From pasco;
To richland;
Distance 15;
Configuration road_travel;
}

Object aeroplane {
Name united;
From miami_airport;
To pasco;
Distance 1000;
Configuration air_travel;
}

Object train {
Name gas_train;
From beach;
To miami_airport;
Distance 30;
Configuration train_travel;
}
"""
sale_number = ''

sales = collections.defaultdict(list)

for line in status.split('\n'):
    line = line.strip()
    if line.startswith("set"):
         continue
    elif (line.startswith("Object") or line.startswith("object")):
         sale_number = line.split(' ')[1].strip()
    elif not line or line.isspace() :
         continue
    else:
         # you can also use a regular expression here
         sales[sale_number].append(line.split())

for sale in sales:
    print sale+str(dict(sales[sale][:-1]))

这会产生:

car{'To': 'Seattle;', 'Configuration': 'road_travel;', 'From': 'Richland;', 'Name': 'honda;', 'Distance': '160;'}
train{'To': 'miami_airport;', 'Configuration': 'train_travel;', 'From': 'beach;', 'Name': 'gas_train;', 'Distance': '30;'}
aeroplane{'To': 'pasco;', 'Configuration': 'air_travel;', 'From': 'miami_airport;', 'Name': 'united;', 'Distance': '1000;'}
bus{'To': 'richland;', 'Configuration': 'road_travel;', 'From': 'pasco;', 'Name': 'greyhound;', 'Distance': '15;'}

我想将上面的 python 输出转换成如下图所示的图片。我不想使用 Giffy 或 MS-Visio 手动执行此操作,因为我的实际案例有大约 1000 个对象(此示例在“状态”中有 4 个对象)

【问题讨论】:

  • @Jivan 我一直在做的事情是我编写了一个 python 脚本,将具有“状态”内容的文件转换为 .dot 文件,然后将其导入到 graphviz 中以对其进行可视化。随着对象数量的增加,这变得庞大而复杂,因此我想将内容转换为图形消除 graphviz 方法。到目前为止,我将文件内容转换为字典,我想将“key”和“values”导入 tkinter 或 D3 或其他一些可视化库(python 或 javascript),但我不确定如何做到这一点。
  • @Jivan 我也尝试按照pythonhaven.wordpress.com/2009/12/09/… 中的示例使用“pydot”库,但其中很多都涉及硬编码,这对这个问题没有帮助

标签: javascript python dictionary tkinter flowchart


【解决方案1】:

只专注于将格式怪异的status 字符串转换为dict 已经够难了,难道你不能将它转换成像 JSON 这样更合理、更流行的格式吗?

import re
def Status2dict(status):
    result = {}
    current = {}
    lines = status.splitlines()
    for line in lines:
        line = line.strip()
        if not line: 
            continue
        mo = re.match(r'Object (\w+) {', line)
        if mo:
            curk = mo.group(1)
            current = {curk: {}}
        elif re.match('}', line):
            result.update(current)
            current = {}
        else:
            mo = re.match(r'(\w+)\s+([\w\s]+);', line)
            if not mo:
                raise ValueError('cannot match {!r}'.format(line))
            current[curk][mo.group(1)] = mo.group(2)
    if current:
        result.update(current)
    return result

import pprint    
pprint.pprint(Status2dict(status))

此代码试图在推断语法的小变化上稍微健壮,您可能希望根据情况将其调高。不过,总比没有好。

【讨论】:

  • 我试过这个。它不工作。 current 字典总是空的,所以永远不要输入 if current 的情况。第一行是Object car {,由于current 是空的并且没有},它会点击else,然后再次执行re.match 并失败,因为{ 不在其中。所以没有任何东西写到curk。你能看一下吗?
  • 评论 if current 消除了错误并生成了一个 JSON 文件,生成了我添加到您的答案中的输出。你为什么用if current检查?
  • @SrinGupta ,现在固定缩进。你说得对,if current: 检查是多余的,因为result.update({}) 无论如何都是无操作的,为了简单起见,现在将其删除。
  • 我有一个问题:如果我的对象名称有_,程序就会失败。所以,我更改了第一个mo=re.match(...),但看起来我做错了什么,如果对象名称有任何下划线则无法匹配。 (注意:我将第一个 mo 更改为类似于第二个 mo... 我的意思的一个例子是:如果对象线看起来像:object aeroplane_unit_crewobject bus_set etc
  • 仅匹配不是Object _ {Object 行可以通过许多简单的方式完成,但在这种情况下,您希望该块的其余部分发生什么并不清楚。评论很拥挤:最好编辑 Q,准确显示您现在正在使用的代码,它的作用,您希望它做什么;更好的是接受这个A,它确实解决了你提出的问题!然后为这个新问题打开一个新问题。
【解决方案2】:

如果您已经将代码转换为点文件,则可以使用 graphviz 的 tk 导出在 tkinter 画布上可视化您的图形。您可以查看this other question 了解其他库。

dot -Ttk这样输出tcl代码

# a
$c create oval 5.33 53.33 77.33 5.33 -fill white -width 1 -outline black -tags {1node1}
$c create text 41.33 30.3 -text {a} -fill black -font {"Times" 14} -tags {0node1}
# c
$c create oval 53.33 149.33 125.33 101.33 -fill white -width 1 -outline black -tags {1node2}
$c create text 89.33 126.3 -text {c} -fill black -font {"Times" 14} -tags {0node2}
#(...)

您可以通过调用 tcl 解释器将其显示在 tkinter 画布上,如下例所示:

from Tkinter import *
import subprocess

graph = "digraph g { a-> c ; b -> c ; c -> d }"

ps = subprocess.Popen(('dot', '-Ttk'),stdin=subprocess.PIPE, stdout=subprocess.PIPE)
out, err = ps.communicate(input=graph)

canvas = Canvas()
canvas.pack(expand=YES, fill=BOTH)

#the output of graphiz assume thazt the canvas in variable $c
out = "set c .{}\n".format(canvas._name) + out
#tk.eval expect command one by one
map(canvas.tk.eval, out.split("\n"))

canvas.mainloop()

【讨论】:

  • 到目前为止,我一直在做类似的事情。我编写了一个 python 脚本将“状态”转换为 .dot 文件,然后我导入到 GraphVIZ 以获取流程图/图表,但我正试图摆脱它。经过一番阅读,我想通过将其转换为JSON,然后我可以以某种方式在 D3 中将其可视化或使用一些 python 库,因为最终我想将其转换为交互式图形。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 2017-10-09
  • 2013-02-19
  • 2016-10-16
  • 1970-01-01
  • 2020-06-30
相关资源
最近更新 更多