用矩阵管理成绩表 - App Inventor 2 矩阵块入门案例

« 返回首页

你要做的是什么

这一篇我们做一个成绩表查询小工具:4 名学生 × 3 门科目的一张成绩表,能查任意一格、改成绩、算某一行(某名学生)的平均分、还能把整张表”横过来”看。做的过程中,矩阵块的创建、读写、行列、维度四大本事就全练到了。

每一关都是”搭块 → 点按钮 → 看到现象”的完整闭环,跟着做一定能跑通。块的基本概念(矩阵是什么)不清楚的,先花两分钟看参考文档的开头一节。

第 0 关:准备器材

  1. 新建一个项目,命名为 成绩表(名字随意,中英文都行)。
  2. 在设计视图里放入 5 个组件,从上到下排好:
组件(调色板名) 改名为 用途 建议属性
标签 标签_结果 显示各关的结果 字号 20,文本先随便填一句
按钮 按钮_查询 第 2 关:查单元格 文本:查询
按钮 按钮_修改 第 3 关:改成绩 文本:修改
按钮 按钮_平均 第 4 关:算平均分 文本:平均分
按钮 按钮_转置 第 5 关:转置表格 文本:转置

提示:在设计视图点组件名字(或右侧面板的”组件名称”)就能改名。中文命名是本站推荐做法,一眼能认。

连上 AI 伴侣准备随时测试(编译 APK 也行,就是验证慢一些)。

第 1 关:把成绩表装进矩阵

目标:程序启动时,创建一个 4×3 的矩阵存进全局变量 成绩表——第 1 名学生到第 4 名学生各占一行,语文、数学、英语各占一列:

  语文 数学 英语
学生 1 90 85 92
学生 2 78 90 88
学生 3 95 88 94
学生 4 82 76 90

搭块步骤(切到代码块视图):

  1. 从变量抽屉拖一个 初始化全局变量 出来,把名字改成 成绩表。
  2. 从矩阵抽屉拖一个 创建矩阵,塞进它的值插槽。
  3. 点块左上角蓝色齿轮,把矩阵调成 4 行 3 列(行数在前、列数在后)。
  4. 按上面的表格,把 12 个分数从左到右、从上到下填进格子(不用填的格子默认是 0)。

搭好后把整段放进 Screen1 的初始化事件里(从 Screen1 组件抽屉拖”当 Screen1 初始化”):

<xml xmlns="http://www.w3.org/1999/xhtml"><block type="component_event"><mutation component_type="Form" instance_name="Screen1" event_name="Initialize"></mutation><field name="COMPONENT_SELECTOR">Screen1</field><statement name="DO"><block type="lexical_variable_set"><field name="VAR">global 成绩表</field><value name="VALUE"><block type="matrices_create"><mutation rows="4" cols="3" matrix="[[90,85,92],[78,90,88],[95,88,94],[82,76,90]]"></mutation><field name="ROWS">4</field><field name="COLS">3</field><field name="MATRIX_0_0">90</field><field name="MATRIX_0_1">85</field><field name="MATRIX_0_2">92</field><field name="MATRIX_1_0">78</field><field name="MATRIX_1_1">90</field><field name="MATRIX_1_2">88</field><field name="MATRIX_2_0">95</field><field name="MATRIX_2_1">88</field><field name="MATRIX_2_2">94</field><field name="MATRIX_3_0">82</field><field name="MATRIX_3_1">76</field><field name="MATRIX_3_2">90</field></block></value></block></statement></block></xml>

中途验证:连着 AI 伴侣时,右键点 初始化全局变量 块选 Do It(执行),能直接看到矩阵的内容。也可以先往下走,第 2 关搭完一起看现象。

第 2 关:查任意一格的成绩

目标:点 按钮_查询,显示”第 2 行第 3 列的分数:88”(学生 2 的英语成绩)。

搭块步骤:

  1. 从 按钮_查询 的组件抽屉拖出 当 按钮_查询.被点击 事件。
  2. 里面放一个 设 标签_结果.文本 为(从标签抽屉拖)。
  3. 值用文本抽屉的 合并文本:前一段放文本块”第 2 行第 3 列的分数:”。
  4. 后一段放矩阵抽屉的 获取矩阵单元格:矩阵 槽放 取全局变量 成绩表,行索引 2、列索引 3。
<xml xmlns="http://www.w3.org/1999/xhtml"><block type="component_event"><mutation component_type="Button" instance_name="按钮_查询" event_name="Click"></mutation><field name="COMPONENT_SELECTOR">按钮_查询</field><statement name="DO"><block type="component_set_get"><mutation component_type="Label" instance_name="标签_结果" property_name="Text" set_or_get="set" is_generic="false"></mutation><field name="COMPONENT_SELECTOR">标签_结果</field><field name="PROP">Text</field><value name="VALUE"><block type="text_join"><value name="ADD0"><block type="text"><field name="TEXT">第 2 行第 3 列的分数:</field></block></value><value name="ADD1"><block type="matrices_get_cell"><mutation items="2"></mutation><value name="MATRIX"><block type="lexical_variable_get"><field name="VAR">global 成绩表</field></block></value><value name="DIM0"><block type="math_number"><field name="NUM">2</field></block></value><value name="DIM1"><block type="math_number"><field name="NUM">3</field></block></value></block></value></block></value></block></statement></block></xml>

跑通看现象:连上伴侣,点 查询 按钮,标签显示 第 2 行第 3 列的分数:88。把行、列索引换成别的数字再点,能查到任何一格。

记住:矩阵索引从 1 开始。行 2 列 3 就是”第 2 行的第 3 个”,不存在第 0 行。

第 3 关:改成绩(原地修改)

目标:点 按钮_修改,把第 2 行第 3 列改成 100,并在标签上确认。

搭块步骤:

  1. 拖出 当 按钮_修改.被点击 事件。
  2. 放矩阵抽屉的 设置矩阵单元格:矩阵 槽放 取全局变量 成绩表,值 填 100,行 2、列 3。
  3. 下面再接一条 设 标签_结果.文本 为 "已把第 2 行第 3 列改成 100"。
<xml xmlns="http://www.w3.org/1999/xhtml"><block type="component_event"><mutation component_type="Button" instance_name="按钮_修改" event_name="Click"></mutation><field name="COMPONENT_SELECTOR">按钮_修改</field><statement name="DO"><block type="matrices_set_cell"><mutation items="2"></mutation><value name="MATRIX"><block type="lexical_variable_get"><field name="VAR">global 成绩表</field></block></value><value name="VALUE"><block type="math_number"><field name="NUM">100</field></block></value><value name="DIM0"><block type="math_number"><field name="NUM">2</field></block></value><value name="DIM1"><block type="math_number"><field name="NUM">3</field></block></value><next><block type="component_set_get"><mutation component_type="Label" instance_name="标签_结果" property_name="Text" set_or_get="set" is_generic="false"></mutation><field name="COMPONENT_SELECTOR">标签_结果</field><field name="PROP">Text</field><value name="VALUE"><block type="text"><field name="TEXT">已把第 2 行第 3 列改成 100</field></block></value></block></next></block></statement></block></xml>

跑通看现象:先点 修改,再点 查询——第 2 行第 3 列已经从 88 变成 100。这就是”原地修改”:设置矩阵单元格 直接改矩阵本身,不需要再”把结果存回变量”。

第 4 关:算某一行(某名学生)的平均分

目标:点 按钮_平均,算出第 2 行三个分数的平均值。

这一关用到两个新朋友:

  • 获取矩阵行:整行取出来,得到的是一个列表(这里就是 [78, 90, 88]——如果你第 3 关改过,就是 [78, 90, 100])。
  • 从列表循环:遍历列表累加。

搭块步骤:

  1. 拖出 当 按钮_平均.被点击 事件。
  2. 先 设 全局变量 累计 为 0(从变量抽屉拖”设置”,或先拖”初始化全局变量”再改成 set)。
  3. 放一个 对于 列表 中的每个 分数 循环:列表槽放 获取矩阵行(矩阵=成绩表,行=2),循环体里 设 全局变量 累计 为 累计 + 分数。
  4. 循环结束后 设 标签_结果.文本 为 合并文本("第 2 行平均分:",累计 ÷ 列表长度)——列表长度用列表抽屉的 列表长度 块,统计的还是那一行。
<xml xmlns="http://www.w3.org/1999/xhtml"><block type="component_event"><mutation component_type="Button" instance_name="按钮_平均" event_name="Click"></mutation><field name="COMPONENT_SELECTOR">按钮_平均</field><statement name="DO"><block type="lexical_variable_set"><field name="VAR">global 累计</field><value name="VALUE"><block type="math_number"><field name="NUM">0</field></block></value><next><block type="controls_forEach"><field name="VAR">分数</field><value name="LIST"><block type="matrices_get_row"><value name="MATRIX"><block type="lexical_variable_get"><field name="VAR">global 成绩表</field></block></value><value name="ROW"><block type="math_number"><field name="NUM">2</field></block></value></block></value><statement name="DO"><block type="lexical_variable_set"><field name="VAR">global 累计</field><value name="VALUE"><block type="math_add"><value name="NUM0"><block type="lexical_variable_get"><field name="VAR">global 累计</field></block></value><value name="NUM1"><block type="lexical_variable_get"><field name="VAR">分数</field></block></value></block></value></block></statement><next><block type="component_set_get"><mutation component_type="Label" instance_name="标签_结果" property_name="Text" set_or_get="set" is_generic="false"></mutation><field name="COMPONENT_SELECTOR">标签_结果</field><field name="PROP">Text</field><value name="VALUE"><block type="text_join"><value name="ADD0"><block type="text"><field name="TEXT">第 2 行平均分:</field></block></value><value name="ADD1"><block type="math_division"><value name="A"><block type="lexical_variable_get"><field name="VAR">global 累计</field></block></value><value name="B"><block type="lists_length"><value name="LIST"><block type="matrices_get_row"><value name="MATRIX"><block type="lexical_variable_get"><field name="VAR">global 成绩表</field></block></value><value name="ROW"><block type="math_number"><field name="NUM">2</field></block></value></block></value></block></value></block></value></block></value></block></next></block></next></block></statement></block></xml>

跑通看现象:点 平均分 按钮,显示 第 2 行平均分:85.333...(没改过成绩时)。想看整数的,给除法外面套一个数学抽屉的 四舍五入 块。

动动脑:想算”数学这门课的全班平均”怎么办?——把 获取矩阵行 换成 获取矩阵列,列号填 2(”列表长度”也跟着换成那一列的)。行是学生、列是科目,转个方向统计就换了个问题。

第 5 关:整表转置,横过来看

目标:点 按钮_转置,把 4×3 的表变成 3×4(行变列、列变行),并显示新维度。

搭块步骤:

  1. 拖出 当 按钮_转置.被点击 事件。
  2. 放 设 全局变量 成绩表 为,值放矩阵抽屉的 转置矩阵 块(拉开”矩阵操作”块的下拉也可以选转置),矩阵槽放 取全局变量 成绩表——把转置的结果重新存回变量。
  3. 下面接 设 标签_结果.文本 为 合并文本("转置后维度:",获取矩阵维度 成绩表)。
<xml xmlns="http://www.w3.org/1999/xhtml"><block type="component_event"><mutation component_type="Button" instance_name="按钮_转置" event_name="Click"></mutation><field name="COMPONENT_SELECTOR">按钮_转置</field><statement name="DO"><block type="lexical_variable_set"><field name="VAR">global 成绩表</field><value name="VALUE"><block type="matrices_operations"><field name="OP">TRANSPOSE</field><value name="MATRIX"><block type="lexical_variable_get"><field name="VAR">global 成绩表</field></block></value></block></value><next><block type="component_set_get"><mutation component_type="Label" instance_name="标签_结果" property_name="Text" set_or_get="set" is_generic="false"></mutation><field name="COMPONENT_SELECTOR">标签_结果</field><field name="PROP">Text</field><value name="VALUE"><block type="text_join"><value name="ADD0"><block type="text"><field name="TEXT">转置后维度:</field></block></value><value name="ADD1"><block type="matrices_get_dims"><value name="MATRIX"><block type="lexical_variable_get"><field name="VAR">global 成绩表</field></block></value></block></value></block></value></block></next></block></statement></block></xml>

跑通看现象:点 转置,标签显示 转置后维度:(3 4)。注意转置和第 3 关的”设置单元格”不一样:转置是返回新矩阵,所以要”存回变量”;之后再点 查询,”第 2 行第 3 列”查到的已经是转置后的另一格了。想转回去?再点一次 转置 就行。

排错表

症状 多半是因为 怎么办
点查询没反应 事件块没接上按钮,或索引槽空着 检查事件是 按钮_查询.被点击;两个索引槽都要填数字
运行时报 Matrix Access Error 索引越界(比行数/列数大)或用了 0 索引从 1 开始,最大到行数/列数
查到的格子”不对” 行列写反了,或第 5 关转置后没意识到含义变了 行在前、列在后;转置后重新数一下
改完成绩查询还是旧值 用了”创建矩阵”返回新矩阵的思路,没改到原表 第 3 关的原地修改不需要存回变量;检查是不是把变量整个换成了新矩阵
平均分一长串小数 除法没取整 除法外面套数学抽屉的 四舍五入 块

你已经学会了

创建矩阵(变形器调行列)、取单元格、设置单元格(原地修改)、取行/列当列表、循环统计、转置(返回新矩阵要存回)、看维度——矩阵块最常用的本领全过了一遍。

下一步:

  • 把案例改成你自己的:换成商品价格表、课程表、游戏地图(0 表示空地、1 表示墙)。
  • 想让耗时的大表计算不卡界面?接着玩匿名过程入门:倒计时与回调,学会”后台运行 + 回调”。
  • 块的完整说明见参考文档:矩阵块。
文档反馈