这篇文章我们将使用blockly来做一个完整的项目。

这篇教程涵盖以下内容:

  • 从拼搭好的积木块中,生成(generate)python代码
  • 自定义自己的积木块, 并生成对应python代码
  • 在浏览器中运行python代码
  • 整合以上部分,使用积木块驱动turtle

效果展示

生成的代码为:

关于turtle

turtle是编程教学中的一个经典概念(另一个经典概念是(来自Scratch)),turtle最初由Papert在他的Logo语言引入,Logo内置一套海龟绘图(Turtle Graphics)系统,通过向海龟发送命令,用户可以直观地学习程序的运行过程,关于这块的历史沿革,可以参考我之前的文章Scratch的前世今生

利用blockly generate python代码

如何使用blockly generate代码,我们已经在blockly开发之生成并运行js代码(1)做了手把手教学。

blockly开发之生成并运行js代码(1)中,我们将积木块generate成js代码。blockly默认支持将积木块generate成以下6种代码:

  • JavaScript
  • Python
  • PHP
  • Lua
  • Dart
  • XML

你可以在Code Editor中体验

本章的目标是generate出python代码,过程十分简洁,你只需要做2件事:

  1. 引入python_compressed.js
  2. generate出python代码:var code = Blockly.Python.workspaceToCode(demoWorkspace);

完整的代码参考:blockly_3_1_generate_python

你要做的只有这些

自定义自己的积木块

blockly只提供了基础的积木块(基本的语言结构),你常常需要定义自己的积木块。

自定义积木块时你实际在做两件事:

  1. 定义积木的外观
  2. 定义出当前积木对应的代码

判断一袋狗粮好不好吃的一种方法是看制造者自己吃不吃,我们知道Python社区用Python实现了Python(pypi)。blockly社区中自定义积木外观的工具也是用blockly实现的: Blockly Developer Tools,文档参考:Blockly Developer Tools docs

通过拖拽积木,你就能轻松定义出积木的外观。

截图中有两处值得注意:

红色框中是你自定义积木外观的代码描述,有两种风格你可以选择(js/json),使用json风格你会得到一个好处:可以随时将json贴回Blockly Developer Tools,从而得到对应的积木。在你生成自定义积木的时候,建议取得分享链接,以便于日后对积木做调整。

而绿色框中则是该积木generate出的代码,你可以选择目标语言,在此我选择Python

blockly_3_2_custom_block_generate_python中展示了一个完整的自定义积木,如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
//外观 使用js风格的描述
Blockly.Blocks.draw_stamp = {
    init: function() {
        this.setColour(160),
        this.appendDummyInput().appendField("stamp"),
        this.setPreviousStatement(!0),
        this.setNextStatement(!0)
    }
},

//generate Python
Blockly.Python.draw_stamp = function(a) {
    Blockly.Python.definitions_.import_turtle = "import turtle\nturtle=turtle.Turtle()";
    return "turtle.stamp()\n"
}

关于自定义积木的话题很大,我们找机会专门讨论,在此就不展开

浏览器中运行python

目前有好几个项目允许你在浏览器中运行python,其中最流行的解决方案是:skulpt,也许也是目前最成熟的解决方案,好些大型项目都在用它,诸如:

浏览器无处不在,如果能在浏览器中直接运行python,不仅免去了新用户安装环境的麻烦,教学者还可以利用js的动态性,灵活地设计课程并与用户交互,很方便对用户做引导。skulpt的主要使用场景是教学,以上便是原因。

skulpt使用js实现了python解释器(python2.x),让python能运行在所有主流浏览器中,如此一来,你就可以轻松在pc/手机/ipad的浏览器中学习python

skulpt是一个强大而灵活的项目,自带很多电池,且有很好的可扩展性(自定义模块),如果你有兴趣,可以参考:skulpt官网

turtle是skulpt自带的模块,你可以在Our First Turtle Program体验它

在浏览器中使用python驱动turtle,官方给出了示例源码:simpleskulpt

整合

经过上边的一圈探索,来看看我们现在能够做到哪些事:

  • 从拼搭好的积木块中,生成(generate)python代码
  • 自定义自己的积木块, 并生成对应python代码
  • 在浏览器中运行python代码
  • 使用python控制浏览器中turtle

接下来,整合以上部分,使用blockly积木块来驱动turtle,最小原型参考:blockly_4_run_python_in_browser_simple

上边的最小原型修改自simpleskulpt。修改之处仅有: 把var prog = document.getElementById("yourcode").value; 改为blockly生成的代码:var prog = Blockly.Python.workspaceToCode(demoWorkspace); , 如此干净整洁!

这个例子中,我们可以看出blockly的灵活性,如我们在blockly入门与介绍中所言,blockly是个编辑器,只负责生成代码,至于代码之后用与干吗,它通通不关心。如此一来,就不产生耦合了。

要了让blockly能做出丰富的东西,我们需要把turtle的所有操作原语全都暴露为积木块,这个工作我偷了个懒,直接抠了trinket的源码。完整的代码参考:blockly_5_run_python_in_browser_turtle_finish。积木部分参考:my_blocks.js(js代码中变量被压缩过,可读性不大好)

如此一来我们就完成了整个项目.

这个项目很有代表性,使用blockly制作一个application的步骤,我们在以上过程中都经历了

这些步骤官方描述为:

  • 集成blockly编辑器
  • 定义你的app里的功能块(block)
  • 构建app的其余部分,blockly仅充当代码生成器,你需要决定这些用户生成的代码用于做什么,这也是你的app的核心功能所在

关于最后一点,blockly官方说的很笼统,针对少儿编程这一领域,第三点往往可以拆解为几类典型问题。这方面我们之后有空再谈

相关源码

以下源码展示了渐进的学习过程: