讨论问题:为什么Visual Programming Languages从未被取消?

时间:2010-03-16 08:15:49

标签: visual-programming

注意:标记为社区维基。

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

6 个答案:

答案 0 :(得分:2)

编程的两种方法不仅仅是简单的文字:

我认为结构化编辑非常有趣,因为它采用了“带有标识的大括号”惯例,这种惯例已被证明对于保持代码组织非常有用,符合逻辑极限。我认为它真的可能是某种东西,如果有人要从它的可用性角度(从可用性的角度来看)实现它。

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

一个80x25的文本窗口?真?不要比较大小,但我的文本窗口比这要大很多。但无论如何,我个人无法想象一种能让我满意的视觉编程语言。对于技术信息,文本比视频信息密集得多。我宁愿浏览一篇关于技术主题的文章,而不是在五倍的时间内观看关于该主题的视频(认真的家伙,已经用视频敲掉了)。

以类似的方式,我宁愿花几秒钟输入几行代码,而不是几分钟拖放东西来完成同样的事情。这是关于简洁和表达的。根据我的经验,可视化编程语言根本就没有它。有助于教授编程基础吗?当然。 Alice非常整洁。但不是为了日常工作。

在一个有点相关的说明中,Code Bubbles是改进“80x25文本窗口”的有趣方法。

答案 3 :(得分:0)

有一些混合和匹配。

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

另一方面,我们仍然使用类似的文本编辑器来处理人们30年前用于我们大量工作的文本编辑器。 :)显而易见,两者都有价值。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

可视化编程语言从未起飞,因为还没有人做到这一点。就像C ++ / visual studio在他们出现时对人们来说是正确的技术一样。

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

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

这是一个示例输入图: enter image description here

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

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),所以考虑使用第三方python解释器或只是静态修改代码。

不是说我的工具还没有做任何事情。要做好正确的事情,还必须有自动重构工具,调试等。