集算器初体验

【摘要】

        集算器专注于结构化数据分析与处理, 是一门新型的快速开发语言,它有什么特性呢?去乾学院看个究竟:集算器初体验!

alt 文本

1、从经典的 Hello, world! 开始

先看图(1):

集算器初体验
图(1)

新建 p1 程序文件,在 A1 格子中输入 =output(“Hello, world!”)。点击图(1)中红圈圈住的三角按钮,执行 p1 的代码,就可以在控制台中看到输出结果,如红色方框所示。

从这个例子可以看出,集算语言不同于传统语言,没有 main 函数入口,也没有引入类、或者头文件。那么程序是如何工作的呢?从图(1)可以看到,代码是写在类似 Excel 命名的格子里面的。既然有了行列,集算语言就按照“先行后列”的顺序开始计算。所以程序的入口就是 A1 格,依次执行 B1 直到最后一列,再从 A2 开始,直到最后一个包含代码的格子为止。

2、变量都去哪了?

无论是 C 语言还是 Java,都有一个变量声明的概念。例如,我们要用到一个字符串时,需要先定义好名字以及类型,就像:

char* msg=”Hello,world!”;   //C   风格

String msg=”Hello,world!”;   //Java 风格

而在集算语言中,这个例子会写成表(1):

A
1 Hello,world!
2 =output(A1)

表(1)

运行后,输出结果一样。但我们并没有将“Hello,world! ”先赋值给某个变量。而是在 A2 中直接引用了格子的名字 A1,也就是说,集算语言中格子的名字就可以直接用作变量名。所以集算语言中初看并没有“变量”,实际是集算语言自动使用了格子名字作为缺省变量名,这样一方面可以省去我们为变量取名的烦恼,同时也让代码看起来更加简便和整洁。

但是,你可能会说:“那我要取一个有意义的名字来作为变量,支持不?”

——当然支持!

很显然,如果全是字母加数字的变量名而变量又很多,想要寻找某个有特殊含义的变量时,结果一定是你在众里寻它千百度,它却问你的眼镜有没有千百度,这就尴尬了……所以,我强烈建议:只针对真正有意义的变量进行命名!

那么,要取个有含义的变量名,是不是在 A1 中写入 String msg=”Hello,world!” 就可以了? 这个问题我先给出答案:“输入错误。”至于原因嘛,下面第 4 节再讲。别急,先让我们熟悉一下语法。

3、格子内容的几种表示方法

我们知道,传统程序文件通常都是由常量、变量、关键字、函数名、函数体、语句和注释等部分构成。集算语言也不例外,也有上述各种组成部分,只不过组织结构有点不同。

首先,有别于传统 C 语言,集算语言中一个文件只能定义一个函数,且文件名就是函数名。而 C 语言的一个文件中是可以定义多个函数的。

另外,由于集算语言的代码都位于格子中,而为了区分格子中代码的不同类型,我们需用不同的字符开头来表示不同的代码类型,具体来说有:

1、单或双斜杠开头

这个跟常规语言类似,斜杠后面直接跟注释,不过在集算语言中,单斜杠表示注释当前格,双斜杠表示注释当前格以及该行后面的所有格,这类格子我们称作 “注释格” 。参考表(2):

A B
1 / 这是一个集算语言注释格 /A1 为一个 注释格
2 // 这是一行注释 因为 A2 是双斜杠,B2 后面都是注释格

表(2)

2、直接输入内容

这部分包括常量(但在集算语言中,常量被赋值后仍然是可变的),这样的格子我们称作 “常数格” ;关键字开头的语句(比如表示循环的 for,返回值的 return 等),这类格子我们称作 “语句格” 。参考表(3):

A B
1 Hello,world! /A1 为一个 常数格
2 return A1 /A2 为一个 语句格,返回 A1 的内容

表(3)

3、等号开头

凡是需要计算一下的代码,或者说表达式都可以由等号开头。包括定义一个变量、计算一个表达式或者执行一个函数。这类格子我们称作 “计算格 。参考表(4):

A B
1 =msg=”Hello,world!” /A1 为一个 计算格,计算后产生变量 msg,值为字符串 Hello,world!同时 A1 格子的值也为 Hello,world!
2 =to(1,100) /A2 为一个 计算格,计算后 A2 的值为 1 到 100 的一个序列

表(4)

4、大于号开头

同样是要计算一下的代码,但计算过后,如果有返回值,会直接扔掉忽略,并不返回给格子变量,这样的代码我们也叫做代码块,这类格子我们称做 “执行格” 。参考表(5):

A B
1 >msg=”Hello,world!” /A1 为一个 执行格,执行后产生变量 msg,值为字符串 Hello,world! 不同于计算格,此时的 A1 并没有值
2 >output(A1) /A2 为一个 执行格,执行后在控制台输出 A1 的内容 Hello,world!

表(5)

上述计算格和执行格两种类型,后面跟的都是要执行的语句,那么它们之间到底有何区别,又该如何使用呢?一般来说,我们会根据有返回值和没返回值两种情况,对语句或者表达式进行区分。

对于有返回值的语句,一般规范为使用计算格,例如给当前格赋值:=3.14。但是如果返回值在后面不再使用时,建议使用执行格,以减少内存占用。

对于无返回值的语句,一般规范是使用执行格。例如:> output(“Hello world!”)

下面用表(6)来对上面描述的各种格子类型进行一下总结:

A B C
1 // 这是一个示例代码 由于 A1 是双斜杠的注释,所以 C1 也是注释格
2 Hello,world! / 给 A2 格赋常量初值
3 >output(A2) / 使用 output 函数输出 A2 的内容
4 >msg=”Hello,world!” /A4 定义了一个名为 msg 的字符串变量
5 >output(msg) /output 函数没有返回值,所以采用执行格
6 =to(1,100) /A6 使用 to 函数返回 1 到 100 的整数集合,返回序列对象到当前格。由于后面需要引用 A6,故此格只能为计算格
7 =summary=0 / 定义名为 summary 整数型变量,并赋初值为 0。虽然有返回值,但我们只用 summary 变量,故此格定义为计算格,执行格均可以
8 for A6 /A8 为一个 for 关键字开头的语句,表示循环遍历序列 A6。关键字不需要任何标记开头,是为语句格
9 >summary=summary+A8 / 执行高斯同学的加法,没有高斯聪明,挨个加。注意,代码 B9 是循环体内容,相对于 for 关键字要退一格,据说 Python 也有强制退格,这样子,层次更分明。
10 return summary / 该函数返回计算后的值

表(6)

4、变量的类型

前面已经提到,格子的名称可以直接作为变量使用,也就是定义变量时,在格子里面输入值就行了。那么变量的类型如何确定呢?熟悉 JS 的同学都知道,不管什么类型的变量都用 Var 来定义,至于值到底是什么类型,取决于值的写法。集算语言比 JS 更简便,Var 都不用写,那么集算语言的基本变量类型有哪些呢?

1、整数

直接输入数字即可,例如:100

2、长整数

数字后面加上字母 L,例如:100L

3、浮点数

直接输入带小数的数值,例如:3.14

4、布尔数

用 true 或 false 来表示,当然也可以是一个比较条件,例如:true、a>b

5、日期

缺省用连接符‘-’分开的年月日表示法,例如:2018-1-31。但是在表达式中引用时,得用日期函数转换。例如:=date(“2018-1-31”)。

注意: 用连接符‘-’分开的年月日是集算器缺省的格式,可以通过菜单“工具 > 选项”打开选项对话框,在“环境”页面的“日期格式”的一致,否则集算器无法解析,就会被当成普通字符串,而在表达式中引用时,就会报解析异常。

6、时间

缺省用冒号‘:’分开的时分秒表示法,例如:20:30:50。同样地,在表达式中需要用时间函数来转换。例如:=time(“20:30:50”)。

注意:和日期类型一样, 时间的格式也必须和选项对话框中的“时间格式”选项设置的格式一致。

7、字符串

直接输入字符串即可,例如: Hello,world!。但是对于有歧义的字符,比如电话号码,直接输入时,会被当成长整数,此时需要用单引号开头表示后面跟的是字符串,例如:’13901020888。在表达式中时则需要加上双引号。

下图是这些基本数据类型的一个汇总:

集算器初体验 
图(2)

这里简单介绍一下这里例子中用到的 debug 函数,在集算语言中,它用于调试输出中间变量的值。但是有些值,比如 100,光看到值我们分不清它是普通整数 100,还是长整数的 100,甚至可能是字符串 100。这时可以加上函数选项 @t,将变量的类型也一并输出。

上述 7 种基本数据类型是集算语言中能够直接使用的,但是光有它们,计算的便利性远远不够。集算语言发明出来就是用来应对数据计算的。所以,集算语言自身提供了一些专门用于计算的对象,只要使用对象的内置方法就能很轻松地完成大部分数据运算。

不过,集算语言自身还不算是一门通用程序语言,还不能像 Java 一样自定义对象。

8、对象

集算语言针对数据的处理,预置了很多的对象,常用的有数据库、序列、记录、序表、排列和游标等。

其中,序列、记录、序表和排列尤为常用,这里先简单介绍一下。

序列: 就是一堆数据的集合,但同时成员是有序的,相应地,你也可以理解为 Java 中的数组 Array。上面表(6)例子中,A6 格子的表达式“=to(1,100) ”返回的就是一个序列。此时我们知道,对 A6 的求和,只要调用序列的“sum”方法即可,就像这样:“=A6.sum()”。

记录 跟数据库中的记录相同,即一个由表结构描述的一组数据。通常由一些字段组成。

序表: 是序列的子集,当序列中的全部成员都是记录时,我们称之为序表。序表跟数据库中的数据表类似。用数据库对象的“query”方法查询出来的表就是序表。

排列: 是序表经过过滤运算后,得到的一张引用序表成员的序表。有点拗口,意思就是排列仍然是序表,只不过排列里面的记录跟计算出它的源表的记录是同一个对象。通常情况下,不用刻意区分排列和序表,只需要注意到修改排列里面字段的内容时,它的源表字段也会跟着改掉,因为本来就是同一条记录。

5、是时候演示真正的数据处理了

数据处理最常见的当然是从数据库取数,使用 SQL 查询出自己想要的数据表。我们来看看使用集算语言如何做这些事情。

首先当然得有数据库,我们在这里直接使用集算器现成的示例数据库。找到“安装路径 \esproc\bin\startDataBase.bat”,双击它启动示例数据库。下面按步骤来:

第 1 步,连接到数据源。这里是连接到一个叫 demo 的数据源,连接信息已经由安装包事先配置好了。如果要用自定义的数据源,只需打开菜单“工具 > 数据连接”,然后在弹出的“数据源”对话框中增加自己的数据源。那么如何连接它呢?会不会像 Java 一样要先使用 DriverManager 去注册 Driver,然后获取 Driver 再获得连接?……听着就有点晕,又是注册,又是连接什么的。集算语言可不会这么干,直截了当,一句 connect 就已足够,如图(3)中 A3 所示,根本不用去懂那么多大道理。

集算器初体验
 图(3)

第 2 步,查询取数。demo 同样地,不会像 Java 一样要构建什么 Statement 、设参数、再执行查询得到结果集,然后遍历结果集才能取数。在集算语言中,仍然是一句话的事,直接使用数据库对象的查询方法 query 就好,执行过后,直接得到序表对象,如图(3)中 A4 所示。

第 3 步,过滤序表。这一步看似多余(你完全可以打击我,在上面第 2 步的 SQL 中加上 WHERE 条件不就行了么?何必多此一举?嘿嘿,不带这样打击人的。我的例子是帮你入门,目的是让你了解集算语言的特点和结构。真要弄一个只能通过多步 SQL 才能算出结果的实例来时,我们就绕到例子里面出不来了)……但不要着急,这“多余”的一步正是体现了集算语言是为了 SQL 的分步计算而设计的。在后续章节的很多例子中,你会学习到面对令人头疼的复杂 SQL 时,使用分步运算将是一件多么爽心悦目、轻松愉快的事。回到主题,这一步过滤出库存量少于 10(斤)的商品,看看哪些商品比较畅销,函数仍然简单,一句 select 加上条件,如图(3)中 A5 所示。

第 4 步,修改商品值。从第 3 步得到的排列中,取出需要修改值的记录,由于记录就是序表的成员,所以只要像引用数组一样,给出坐标就可以得到记录对象。区别于 Java 中用中括号“[]” 进行数组引用,序表是一个对象,获取它的成员时,采用小括号“()”,如图(4)的 A6 格所示。可以看到该记录是花生,把这条记录的 “单价” 字段修改为 20(元),直接引用属性的字段名并赋值。如图(3)的 A7 所示。

另外,图(3)中还有 A1 跟 A2 两个格子,是为了演示集合的 sum 运算。

现在我们来看看执行结果,单击图(1)红圈中的三角形按钮,代码很快运行完毕,算完后,A 列格子的背景都从白色变成了黄色,这说明 A 列格子里面都有了返回值。


不过这样一次性从头到尾的执行,不利于我们更好地理解排列跟序表之间的成员关系。因此我们使用分解动作,一步步执行,每走一步停下来看看当前的执行结果。为此我们只要重复单击图(1)中蓝色圆圈里的单步执行按钮。

单步执行第一步,算出 A1 的结果如图(4):

集算器初体验 
图(4)

可见 A1 是一个序列对象,它的成员为 1 到 100 的整数。

第二步,A2 为 A1 对象 sum 后的结果,返回的就是一个整数值,如图(5):

集算器初体验
图(5)

第三步,A3 为数据库对象,执行后可以看到数据库的一些属性设置,如图(6):

集算器初体验
图(6)

第四步,A4 为从数据库对象 A3 中执行查询方法 query 后得到的序表对象,列出各种产品以及库存,如图(7):

集算器初体验
图(7)

注意图(7)的红圈表示,此时花生的单价为 10(元)。

第五步,A5 为从序表 A4 中,过滤出库存量不到 10(斤)的产品。返回一个排列,内容如图(8):

集算器初体验
图(8)

第六步,A6 为从排列 A5 中取出第 3 条记录,返回一条记录,内容如图(9):

集算器初体验
图(9)

第七步,经过 A7 中对花生的单价重新赋值后,A6 格中记录的单价字段变为了 20(元),如图(10):

image011jpg

图(10)

上面第七步看似只是修改了排列中第 3 条记录的单价,但我们再回头看看序表 A4 的内容,发现序表中的花生的单价也变为了 20(元)。这就说明,排列和序列中的记录,其实就是同一条记录,A4 格的内容此时如图(11):

image012png

图(11)

经过本例的学习,我们对集算语言已经有了一个大致印象,也了解了集算语言在进行数据处理时使用的一些最基础的概念。当然,作为一门专业的数据处理语言,集算语言还有很多概念需要熟悉,还有很多函数需要了解。但这些都不是问题,老话不是说,磨刀不误砍柴工嘛,让我们通过后面的教程把刀磨得越来越锋利吧。