零代码应用开发·第 6 章·3 学时

让它会算

输入、处理、输出,以及那些不报错的错误。

本章精髓 所有工具型软件都是同一个骨架:拿到输入、按规则处理、给出输出。三段里最容易出事的是中间那段:规则没写死,它就替你猜;边界没交代,算出来的数没法拿去用。

学完本章后,你应该能够:

  1. 把一个计算需求拆成输入、公式、取整、边界、校验五行,写成一张规则卡;
  2. 说清为什么输入框里的 8 不能直接参与计算,以及电脑算小数为什么会多出几位;
  3. 指定取整方式与边界处理,并说出不指定的后果;
  4. 认出静默失败:程序不报错、页面正常,只是给出了一个错误的答案;
  5. 用五组极端数据把自己做的工具测一遍,包括正好用满和填汉字。
配套演示文件 第06章演示_翘课计算器.html 第06章演示_取整对照.html 第06章演示_静默失败.html

差一次的后果

成品 · 规则卡 · 给规则不给形容词

先看规则少写一句会怎样,再看规则卡怎么写。

1.1本章成品:《我还能翘几节课》

输入三个数:本课程总课时、已缺勤次数、学校规定的缺勤上限比例。算出还剩几次额度,并按三种情况分别给出提示。

输入
32 4 20%
三个数,从输入框来
按规则处理
32×20÷100 向下取整 − 4
规则全藏在这一段
输出
还剩 2 次
给人看的那句话

所有工具型软件都是这个骨架,换个题目也一样

成品在 第06章演示_翘课计算器.html,双击打开就能试。断网也能算,填的数字全部在本机处理,不会发送出去。

1.2规则少写一句,答案就差一次

把同一组数交给三种不同的取整方式,结果是这样的:

总课时 32 · 上限 20% · 已缺 4 次 → 可缺勤 6.4 次
不取整
2.4000000000000004
电脑算小数就是这个样子,不能直接放到页面上
向下取整
还剩 2 次
保守:可缺勤上限按 6 次算
向上取整
还剩 3 次
冒进:按 7 次算,多给了一次
同一个学生、同一门课,后两个答案差一次。对这名学生而言,这一次可能就是"缺勤无碍"与"取消考试资格"的分界。

这个决定应当由谁来做。规则里不写清取整方式,它就由大模型替你定了。打开 第06章演示_取整对照.html 可以换着数试,看两种取法在哪些数上分开。

讨论如果这是一个算奖学金绩点的工具,取整方式该往哪边靠?换成算体育课免修课时呢?为什么两者的方向可能不同?

1.3规则卡:本章真正的产出物

本章不写需求文档,写规则卡。五行,每一行都是给它的一条硬指令,一个字都不让它猜。

《我还能翘几节课》· 规则卡
输入
总课时(整数)、已缺勤次数(整数)、缺勤上限比例(百分数,填 20 表示 20%) 三项都要写清是什么类型、什么单位
公式
可缺勤次数 = 总课时 × 上限比例 ÷ 100 ; 剩余额度 = 可缺勤次数 − 已缺勤次数 一步一行,不要写成一大串
取整
可缺勤次数向下取整;剩余额度一律显示整数,不出现小数 三种取整必须指定一种。这一行不写,就是让它替你决定
边界
剩余大于 0 显示「还剩 N 次」;等于 0 显示「已用满,再缺一次就超」;小于 0 显示「已超出 N 次」 等于 0 那一格单独写,不要并进大于 0 那一格
校验
三项必填;非数字、负数、比例大于 100 时,在输入框下方红字提示,并且不进行计算 "不进行计算"这五个字要写,否则它提示归提示,仍然会把结果算出来

这张卡上任何一行少写,都会在成品上留下一处问题。五行写完,提示词也就写好了。

1.4本章新技巧:给规则,不给形容词

前几章的需求可以有一定弹性,界面风格大致合适即可。本章不行:计算类的程序,规则差一个字,答案就差一个数,而这个数会被人当真拿去使用。

所以本章的提示词几乎全是硬性规定,没有一句形容词。规则卡有几行,提示词就有几段。

没有写明的每一条规则,它都会替你定一个,而且不会告诉你它定的是什么。

1.5可直接复制的提示词

发给 AI本章提示词 · 规则卡直接贴进去
做一个考勤额度计算器,一页,手机优先。 输入:总课时(整数)、已缺勤次数(整数)、缺勤上限比例(百分数,如填 20 表示 20%)。 计算规则: 可缺勤次数 = 总课时 × 上限比例 ÷ 100,向下取整; 剩余额度 = 可缺勤次数 − 已缺勤次数。 边界规定: 剩余额度大于 0 时显示"还剩 N 次"; 等于 0 时显示"已用满,再缺一次就超"; 小于 0 时显示"已超出 N 次"。 校验规定: 三项都必填; 非数字、负数、上限比例大于 100 时,在对应输入框下方用红字提示, 并且不进行计算,不显示任何结果。 显示规定:结果一律显示整数,不出现小数。 全部代码合并到一个 .html 文件,不引用任何外部资源,中文使用 UTF-8。
向下取整
不写明它默认四舍五入,答案可能多给一次
等于 0 时显示"已用满,再缺一次就超"
不单独写,它会并进"还剩 0 次",读起来像是还能缺勤
并且不进行计算,不显示任何结果
只写"提示",它会提示归提示,仍然把结果算出来
结果一律显示整数,不出现小数
页面上出现 2.4000000000000004 那一串

1.6大模型的常见偏差

自己挑了四舍五入 这是它的默认取法,因为四舍五入更常见。对这个题目而言,四舍五入会在某些数上比学校规定多给一次额度。取整方式必须由你来定,写进规则,不要指望它猜中你的意图。
校验只提示不拦截 你写了"填汉字要提示",它就加一行红字,然后继续往下算,页面上同时出现红字和一个算不出来的结果。"并且不进行计算"这句要跟着写。
把边界那一格合并了 三种情况它常写成两种:大于等于 0 一种、小于 0 一种,于是剩 0 次时显示"还剩 0 次"。三格就要写成三格,把等于 0 那一句原话交给它。
备用方案 现场生成不顺时,直接打开 第06章演示_翘课计算器.html;取整对照用 第06章演示_取整对照.html,反面教材用 第06章演示_静默失败.html。三个文件都是现成的,不依赖网络。

三段骨架与数字的真相 本章重点

输入处理输出 · 类型 · 浮点 · 取整

本章的核心内容集中在这一部分和下一部分。

本章要学的术语 · 八个
01输入·处理·输出input / process / output
02字符串与数值string / number
03类型转换type conversion
04浮点数精度floating point
05取整floor / ceil / round
06输入校验validation
07边界值boundary value
08静默失败silent failure

这八个术语会原样出现在报错信息、平台界面与技术文档中。前五个在本部分讲解,后三个在第三、四部分讲解。

2.1五个知识点,一个一个看

01输入·处理·输出:工具型软件的通用骨架
拿到输入
按规则处理最容易出事
给出输出

换成绩点换算器、稿费估算器,还是这三段

现象:几个输入框、一个按钮、一块结果区。

概念:工具型软件都是输入、处理、输出三段。头尾两段一眼能看见,中间那一段藏在代码里:规则、取整、边界全都在这一段,也全靠你写清楚。

类比:投币、机器运转、出货。币投进去了,出来什么,取决于里面那套机关怎么设的。

02字符串与数值:输入框拿到的是文字
"8" + "8""88"
8 + 816

上面那一行不是算错,它根本不是在做加法

现象:两个数相加,结果变成了 88。

概念:输入框里取出来的永远是字符串(string),也就是文字。文字相加是首尾拼接,不是求和。能参与四则运算的是数值(number)。两种类型写出来很相似,区别只在有没有引号

类比:"8"是纸上写的八字,8 是八个苹果。两张纸条粘在一起还是纸条,不会变成十六个苹果。

03类型转换:算之前先把文字转成数字
Number("32")32
Number("三")NaN

转换失败不报错,只是给出一个 NaN

现象:结果区出现了一个叫 NaN 的东西。

概念:把字符串变成数值的过程叫类型转换(type conversion)。转换失败时得到 NaN,含义是"这不是一个数"。转换之后必须紧接着检查是不是 NaN,否则后面每一步计算都会把它一路带下去,最终显示在页面上。

类比:把纸条上的数字读出来记进账本。读不出来的那几张要单独挑开,不能当成 0 记进去。

04浮点数精度:小数末尾会多出几位
你以为 6.4 − 42.4
电脑给的 6.4 − 42.4000000000000004

这几位不是缺陷,是小数在电脑里存不精确

现象:结果区出现一串很长的小数。

概念:电脑用二进制存小数,很多十进制小数存不精确,这叫浮点数精度问题。因此凡是给人看的数字都要指定显示方式:取整,或者保留几位小数。

类比:用计算器算 1÷3,屏幕上是一串 3,永远除不尽。电脑存小数也有除不尽的时候。

05取整:三种做法,结果能差一整个
6.4 向下6
6.4 四舍五入6
6.4 向上7

换成 6.5,四舍五入会跳到 7,向下还是 6

现象:还剩 2.7 次机会,这个数能不能当 3 次用。

概念:取整有三种:向下(舍掉小数)、向上(进一位)、四舍五入。三种在不同的数上给不同结果。规则里不指定,它通常选四舍五入,而"还能缺勤几次"这一类问题,选错方向会造成实际损失。

类比:剩 2.7 次额度,按 2 次用是保守,按 3 次用是冒险。这个决定应当由你来做。

本章方法 先自己拿计算器算一遍,再看程序给的对不对。三组数据核对完,才算它能用。

把不合格的挡在计算之前

校验 · 边界 · 那段代码

出问题的地方几乎都在边界上,正常范围之内反而不容易出错。

3.1另外两个知识点

06输入校验:不通过就不要往下算
填了「三」NaN
填了 −20负数上限
填了 200%上限比总课时还多

三种输入都能填进去,也都算得出东西

现象:填一个汉字进去,结果显示 NaN;填一个负数进去,它也照样给出了答案。

概念:输入校验就是在算之前先检查:填没填、是不是数字、在不在合理范围内。不通过就给出提示并且不进行计算,不能算出一个异常的数却不作说明。

类比:窗口的工作人员会把填错的表退回,不会拿着一张乱填的表继续往下办。

07边界值:正好卡在临界点上的那个数
剩 1 次还剩 1 次
剩 0 次已用满
剩 −1 次已超出 1 次

正好等于 0 的那一格,说法要单独定

现象:剩余额度正好是 0 时,页面上显示"还剩 0 次",这句话读起来像是还能缺勤一次。

概念:边界值是规则的临界点:等于上限算不算超、正好为 0 怎么说、负数怎么显示。出问题的地方几乎都在边界上,正常范围之内反而不容易出错。

类比:报名满 30 人截止,第 30 个人算进还是算不进。这一句不写清楚,现场一定会有争议。

3.2规则卡落到代码上,正好是四段

顺序和卡上一样:拿输入、校验、按规则算、分边界给话。

翘课计算器.html节选 · 计算的那一段
// ① 拿到输入:输入框里取出来的永远是文字
var t = document.getElementById('total').value.trim();
var a = document.getElementById('absent').value.trim();
var p = document.getElementById('rate').value.trim();

// ② 校验:必填、必须是数字、不能为负、比例不能超过 100
if (t === '' || a === '' || p === '') { err.textContent = '三项都要填。'; return; }
var T = Number(t), A = Number(a), P = Number(p);   // 文字转成数值
if (isNaN(T) || isNaN(A) || isNaN(P)) { err.textContent = '请填数字,不要填汉字。'; return; }
if (T <= 0 || A < 0 || P < 0) { err.textContent = '课时要大于 0,次数和比例不能是负数。'; return; }
if (P > 100) { err.textContent = '上限比例不会超过 100。'; return; }

// ③ 按规则计算:向下取整,结果一律是整数
var allow = Math.floor(T * P / 100);
var left  = allow - A;

// ④ 边界:三种情况,三种说法
if (left > 0)       { num.textContent = '还剩 ' + left + ' 次'; }
else if (left === 0) { num.textContent = '已用满'; cap.textContent = '再缺一次就超'; }
else                { num.textContent = '已超出 ' + (-left) + ' 次'; }
Number(t)
把文字转成数值。 不做这一步,两个数相加会变成拼接;转不出来就得到 NaN,所以下一行必须查
return;
校验没过就到此为止。这个词是"不进行计算"那五个字的落实。 少了它,红字照样出现,结果也照样算出,两者同时显示在页面上
Math.floor(…)
向下取整。换成 Math.ceil 就是向上取整,答案差一次。 规则卡上不写取整方式,这里就由它选定,通常选四舍五入
left === 0
等于 0 单独一格。这三行就是条件判断:按不同情况走不同的分支。 不单独写,它会并进"还剩 0 次",读起来像是还能缺勤一次

3.3边界测试表长这样

以翘课计算器为例,总课时 32、上限 20%,可缺勤 6 次:

输入
期望的表现
已缺 5
还剩 1 次
已缺 6
已用满,再缺一次就超(不是"还剩 0 次")
已缺 7
已超出 1 次
已缺 −1
红字提示不能是负数,且不出结果
已缺「三」
红字提示请填数字,且不出结果

换成自己的题目时,把左边那一列换成本题的临界值即可。第二行和第五行最容易通不过:正好卡在临界点,以及填了汉字,是这类工具最常出问题的两处。

静默失败:不报错的错误

不中断 · 页面正常 · 答案是错的

这一类问题从本章起会一路跟到学期末。

4.1反面教材:三个实验

打开 第06章演示_静默失败.html,这一版没写校验也没写取整。按上面的提示做三个实验,三次都能看到不同的毛病。

直接点「算一算」
没有取整,浮点数多出来的位数直接显示在页面上
显示「还剩 2.4000000000000004 次」
把已缺勤次数改成汉字「三」
没有校验,转换失败得到 NaN
显示「还剩 NaN 次」,使用者完全不知道 NaN 是什么
把上限比例改成 −20 或 200
没有查范围,负数和超过 100 都照算
算出负的上限,或者上限比总课时还多

4.2第八个知识点

08静默失败:它不喊疼,只是给错了数
程序崩掉 满屏红字你知道要修
静默失败 页面一切正常你可能直接采信

后一种更危险,因为它看上去没有问题

现象:上面那三个毛病有个共同点:都不报错、不中断,页面显示正常,只是给出了一个错误的答案。

概念:行业里把这一类叫静默失败。程序照常运行,没有任何异常提示,错误会被下游一路当真用下去。崩掉时你知道要修;给出一个错的数,你可能就直接采信了。

类比:秤没坏,只是少了两百克。它照样报数,你也照样付钱。

这一条从本章起会反复出现:凡是程序算出来的数,先自己核一遍,再拿去用。工具越好用,这个习惯越重要。
讨论NaN 这三个字母出现在页面上,一个不懂技术的用户会怎么想?如果是你做的工具,他会来问你,还是直接不用了?

4.3前沿三分钟:算错一个数的代价

每章固定栏目 · 一条与当章内容相关的行业动态

软件出的错分两种。一种是程序中断、打不开、报出一屏红字,这一种其实不可怕,一眼就知道要修。另一种是它照常运行,只是给出了一个错的数,页面显示正常,没有任何异常提示。

金融、医疗、计量这些领域最怕后一种,因为错误会被下游一路当真用下去,等到发现时,中间已经经手了很多人。取整方向、边界归属、单位换算是这类问题最集中的三个地方,恰好就是本章讲的三条。

所以本章的方法不是技巧,是习惯:先自己用计算器算一遍,再看程序给的对不对。这个习惯不会随工具变好而失效,反而随工具变好而更重要,因为它给出的数字看上去越来越可信。

上机实验

三选一 · 规则卡 · 五组边界

上机环节由此开始,当堂完成并提交。

5.1三个题目,任选其一

题目 A
绩点换算器

输入各科分数与学分,算加权绩点;支持两种换算规则切换。

通用
题目 B
稿费与字数估算器

输入字数、千字单价、体裁系数,算税前税后稿费。

偏文科
题目 C
试剂稀释配比计算器

输入原浓度、目标浓度、目标体积,算需要的原液和溶剂量。

偏理工

三个题目都要有取整或保留小数的规定至少三条边界规定完整的输入校验。允许更换题材,验收标准不变。

5.2上机六步

照着走,每一步都有产出。第一步和第四步是本章的关键:第一步促使你把规则想清楚,第四步促使你去试那些通常不会有人填的数。

1
写规则卡,五行,暂时不要用大模型
输入、公式、取整、边界、校验。取整那一行写不出来,说明这个工具自己还没有想清楚
产出:五行规则卡
2
规则卡整段贴进提示词,生成并另存
末尾补单文件与不引外部资源。存成 .html,双击打开
产出:一个能打开的计算器
3
人工核对三组数据
用计算器先算一遍写在纸上,再输进程序比对。对不上就回规则卡查是哪一行没落实
产出:三组核对记录
4
五组边界数据,逐个试并填表
正好卡在临界值、超出一点点、填 0、填负数、填汉字。每种记下期望什么、实际什么
产出:五行边界测试表
5
把取整方式改一个词,重新生成,比结果
只改规则卡上那一个词,用同一组数据计算,看相差多少
产出:两版结果的差值
6
组内互测:交换工具,用对方的规则卡验
照着卡上五行逐条验收,尤其是边界那三格。有一行对不上就当场告知对方
产出:互测记录

5.3共同验收标准

规则卡五行齐全 输入、公式、取整、边界、校验,一行不缺 照着卡上每一行,都能在成品上指出对应的表现
取整方式明确指定 向下、向上、四舍五入,选定一种并写明 自问:为什么选这个方向。答得上来才算通过
结果不出现长串小数 整数或指定位数的小数 任取几组数试算,看有没有多余的小数位
五组边界全部通过 临界值、超出、0、负数、汉字 边界测试表五行都打上勾
校验不通过时不出结果 只有红字提示,结果区保持空白 填个汉字点计算,看结果区是不是空的
三组数据人工核对通过 自己先算的答案和程序给的一致 纸上的三个数和屏幕上的三个数逐一对
断网也能算 全部在本机计算,不依赖任何网上的资源 关掉网络连接刷新,再算一次

5.4常见错误与处理

结果是一长串小数
没指定取整或保留位数
在规则里补上"结果一律显示整数,不出现小数"
结果显示 NaN
输入转不成数字,又没有校验
补上"非数字时红字提示并且不进行计算"
两个数相加变成了拼接
没做类型转换,还是当文字在处理
要求它检查是否先把输入转成数值再计算
剩 0 次显示"还剩 0 次"
边界那一格被并进了大于 0
把等于 0 那一句原话再给它一遍,要求三格分开写
红字出现了,结果也照样显示
校验只提示没拦截
补上"并且不进行计算,不显示任何结果"
算出来的数比预期多一次
它用了四舍五入
在规则里写明"向下取整",重新生成
填负数也能算出答案
范围没查
补上"次数和比例不能是负数,比例不超过 100"
改了取整方式,结果没变
它没有重新生成,或那一句被埋在过长的提示词里
整段规则重发一次,写明"其余不变,只把向下取整改成向上取整"

5.5上机时容易卡住的三处

取整方向定不下来 自问一句:算多了谁承担后果,算少了谁承担后果。缺勤额度算多了由学生承担,所以向下取整;配试剂算少了浓度不够,可能就要向上取整。定不了方向,说明还没有想清楚这个工具给谁用。
三组数据自己也算不明白 那就先不要做工具,先把公式在纸上算通。自己算不出来的东西,无法验收它算得对不对,它给什么你都只能采信。
边界表里第二行总是挂 "正好用满"这一格,它多数情况下会并进"大于等于 0"。把那一句原样再发一遍,要求三种情况分三段写。

5.6提交内容

规则卡
五行:输入、公式、取整、边界、校验
写在作业文档最前面
作品文件
一个 .html,断网可用
单个文件,不要压缩
核对与边界表
三组人工核对加五行边界测试,都要有勾
两张表贴进作业文档
取整对照
改一个词前后的两个结果
两张截图加一句差多少

提交方式:按教师提供的作业模板(Word)填写,文档开头注明所选题目。提交渠道见课堂通知。当堂提交。

5.7再进一步(选做)

给你的工具加一个规则切换:比如绩点换算器支持四分制和五分制两种算法,用一个下拉框切换。

加完之后会发现一件事:规则卡要写两份,公式、取整、边界都可能不同。实际工作中的工具大多如此,同一个界面下面藏着好几套规则,而每一套都要有人把它写清楚。

本章小结
本章五条结论
  1. 工具型软件都是输入、处理、输出三段。看得见的是头尾,出问题的在中间:规则、取整、边界都藏在那一段。
  2. 输入框拿到的是文字,不是数字。要先做类型转换,转不出来会得到 NaN;电脑算小数会多出几位,所以给人看的数字都要指定显示方式。
  3. 取整方向要由你来定,不定它就替你定。定的时候自问一句:算多了谁承担后果,算少了谁承担后果。
  4. 出问题的地方几乎都在边界上:正好卡在临界点、填 0、填负数、填汉字。这四种通常不会有人填,但总会有人填。
  5. 不报错,但结果不对,比崩掉危险得多。崩掉时你知道要修;给出一个错的数,你可能就直接采信了。所以先自己算一遍,再看它算的对不对。
本章脉络