7

注意:标记为社区 wiki。

有没有很好的分析为什么可视化编程语言还没有起飞?这些天我们仍然在一个 80x25 的文本窗口中“线性”编码;而我们所代表的概念(数据结构、算法)似乎可以更直观地在视觉上表示。

4

6 回答 6

2

我想到了两种不仅仅是简单文本的编程方法:

我认为结构化编辑非常有趣,因为它采用了“带有标识的大括号”约定,这已被证明对于保持代码的组织非常有用,达到了逻辑上的极致。我认为它可能真的是一些东西,如果有人要(从可用性的角度)实现它的出色实现。

另一方面,LabView 方法并没有让我很兴奋。与文本相比,视觉习语似乎不够强大和明显。不过我没怎么用过 LabView,所以它可能比我想象的要好。

于 2010-03-16T08:51:42.853 回答
1

不要忘记 VS 2010 (.NET 4),它现在支持多显示器,这意味着您现在可以允许将编辑器、设计器和工具窗口移动到顶级窗口之外,并放置在您想要的任何位置到您的任何显示器上系统。

于 2010-03-16T08:43:57.880 回答
0

一个 80x25 的文本窗口?真的吗?不是比较大小,但我的文本窗口比这大得多。但不管怎样,我个人无法想象有一种可视化编程语言会令我满意。对于技术信息,文本比视频信息密集得多。我宁愿浏览一篇关于技术主题的文章,也不愿花五倍的时间观看关于该主题的视频(说真的,伙计们,已经用视频把它搞砸了)。

以类似的方式,我宁愿花几秒钟输入几行代码,也不愿花几分钟拖放东西来完成同样的事情。这是关于简洁性和表现力。根据我的经验,可视化编程语言没有它。适合教授编程基础知识吗?当然。爱丽丝很整洁。但不适用于日常工作。

在一个有点相关的注释中,Code Bubbles是改进“80x25 文本窗口”的一个有趣的尝试。

于 2010-03-16T08:29:10.927 回答
0

有相当多的混合和匹配。

例如,人们确实使用像 NetBeans Matisse 或 VS.Net 这样的 GUI 编辑器,因为有些东西比编码更容易绘制。有些人使用 GUI 数据模型编辑器:它比编写 DDL容易、更快并且(我认为)产生更好的结果。即使在您编写代码时,您也可以使用各种图形工具来帮助您了解自己在做什么(例如,eclipse 层次结构视图)。

另一方面,我们仍然使用与 30 年前人们在我们的很多工作中使用的类似的文本编辑器。:) 很明显,两者都有价值。

于 2010-03-16T08:54:16.637 回答
0

simulink 是 matlab 的一部分,非常适合解决工程问题

于 2012-02-29T21:58:56.823 回答
0

可视化编程语言从未起飞,因为还没有人做得对。就像 C++ / Visual Studio 在人们出现时是正确的技术一样。

然而,与我们的机器交谈(Alex 语音服务)以及使用比文本编辑器更好的工具进行编程的时代已经来临。

这是我正在研究的一个开始。我正在尝试引导我的项目,因为如果您正在制作一个很酷的编程工具,为什么工具本身最终不会用该工具的输入语言编写。我一开始确实是用 PyQt5 / QGraphicsScene 渲染我自己的图形,但调试 2D 场景实际上非常困难——除非你有一个可视图形来代替编程!因此,在我可以运行基本的图表之后,渲染我自己的图表并编写图表编辑器。我最喜欢的通用图形编辑器是 yEd。它输出 .graphml 很好,因为 python 的 networkx 库已经可以读取 .graphml (唯一的问题是加载图形颜色+位置以外的其他属性;所以功能将等到我们自己绘制图形)。

这是一个示例输入图: 在此处输入图像描述

这是运行它的一些基本代码:

import networkx as nx
from PyQt5.QtCore import QThread, QObject, pyqtSignal
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
import re
import sys

EDAT = 2
NDAT = 1

class CodeGraphThread(QThread):
    ifRgx = r'^if\s+(.+)\s*$'
    elseRgx = r'\s+|^$'

def __init__(self, graph, parent=None):
    super(CodeGraphThread, self).__init__(parent)
    self._nodes = {}
    self.setGraph(graph)
    self._retVal = None
    self._locals = []

def setGraph(self, graph):
    self._graph = graph
    G = graph.G()
    nodes = [x for x in G.nodes(data=True) if x[NDAT]['label'] == 'start']
    if nodes:   self._setStart(nodes[0][0])

def _setStart(self, nstr):
    self._nodes['start'] = nstr

def start(self):
    self._running = True
    self._nodes['current'] = self._nodes['start']
    QThread.start(self)

def _exec(self, codeText):
    try:
        exec('self._retVal=' + codeText)
    except:
        try: 
            exec(codeText)
        except:
            self.codeGraph().errorMessage.emit('Coudln\'t execute code: "' + codeText + '"')

def returnVal(self):
    return self._retVal

def run(self):
    while self._running:
        cg = self.codeGraph()
        G = cg.G()
        current = self._nodes['current']
        #TODO transfer over to regex system
        data = [d for x,d in G.nodes(data=True) if x == current and 'label' in d and d['label'] not in ['start']]
        if data:  
            codeText = data[0]['label']
            self._exec(codeText)
        rgx = self.ifRgx
        edges = cg.edgesFr(current, rgx)
        if edges:
            e= edges[0]
            ifArg = cg.matches(rgx).group(1)
            self._exec(ifArg)
            if self.returnVal():
                self._nodes['current'] = e[1]
                continue
        rgx = self.elseRgx
        edges = cg.edgesFr(current, rgx)
        edges += cg.edgesFr(current, None)
        if edges:
            e = edges[0]
            self._nodes['current'] = e[1]
            continue
        break

def codeGraph(self):
    return self._graph


class CodeGraph(QObject):
    errorMessage = pyqtSignal(str)
    statusMessage = pyqtSignal(str)
    _rgxMemo = {}

def __init__(self, gmlpath=None):
    QObject.__init__(self)
    if gmlpath != None:
        self.loadGraphML(gmlpath)
    else:
        self._gmlpath = None
        self._G = nx.MultiDiGraph()
    self._thread = CodeGraphThread(self) 

def G(self):
    return self._G

def loadGraphML(self, gmlpath):
    self._gmlpath = gmlpath
    self._G = nx.read_graphml(gmlpath)

def saveGraphML(self, gmlpath):
    self._gmlpath = gmlpath
    nx.write_graphml(self._G, gmlpath)

def debugPrintNodes(self):
    print(self._G.nodes(data=True))

def debugPrintEdges(self):
    print(self._G.edges(data=True))

def matches(self, rgx):
    if rgx in self._rgxMemo:
        return self._rgxMemo[rgx][1]
    return None

def rgx(self, rgx):
    if rgx not in self._rgxMemo:
        self._rgxMemo[rgx] = [re.compile(rgx), None]
    return self._rgxMemo[rgx][0]

def rgxMatch(self, rgx, string):
    if rgx not in self._rgxMemo:
        rgx_ = self.rgx(rgx)
    else:
        rgx_ = self._rgxMemo[rgx][0]
    match = self._rgxMemo[rgx][1] = rgx_.match(string)
    return match       

def edgesFr(self, n0, rgx):     
    if rgx != None:  
        return [(u,v,d) for u,v,d in self.G().edges(data=True) if u == n0 and 'label' in d and self.rgxMatch(rgx, d['label'])]
    else:
        return [(u,v,d) for u,v,d in self.G().edges(data=True) if u == n0 and 'label' not in d]

if __name__ == '__main__':
cg = CodeGraph('unnamed0.graphml')
cgthread = CodeGraphThread(cg)
def printError(errorMsg):
    print(errorMsg)
cg.errorMessage.connect(printError)    
# Qt application reqd for QThread testing
app = QApplication(sys.argv)
win = QMainWindow()
win.setWindowTitle('PyGraphML Practice 0')
button0 = QPushButton('Start thread running')
button0.clicked.connect(cgthread.start)
win.setCentralWidget(button0)
win.show()
sys.exit(app.exec_())

当前问题:Python 3 不能很好地处理 exec / locals()(因此使用 self.x 而不仅仅是 x),因此考虑使用 3rd-party python 解释器或只是静态修改代码。

并不是说我的工具做对了。为了把事情做好,还必须有自动重构工具、调试等。

于 2016-07-14T16:14:48.760 回答