给小朋友的加减公式

家里的小朋友,开始学习加减法
在我们看来是简单不过的事情,但对于小朋友来说,却是一个全新的世界。虽然掌握起来并不困难,但是计算的速度很慢。
而我们也很清楚,(结果为)10 以内的加减法是基础中的基础。

练习用的小册子,并没有专门针对这方面的反复练习,所以,我们现在要用代码来完成这件事情,大抵要求是:

  1. 加减法的每一项要在 10 以内 (包括 10)
  2. 加减法的最终结果要在 10 以内 (包括 10)
  3. 加减法混排,并且排序是随机的

分割线: 你可以自己尝试先去实现这个代码,而不是直接看下面的参考源码,因为真的很简单。


我们先看如何获得加法的算式,其实就是建立 2 个连续的循环,一个 i、一个 j,然后看两者相加的结果:

def get_additions():
    equations = []
    for i in range(0, 11):
        for j in range(0, 11):
            if i+j <= 10:
                equations.append([i, j])
    s_equations = []
    for i, j in random.sample(equations, len(equations)):
        s_equations.append('%s + %s = ' % (i, j))
    return s_equations

Python 是靠缩进来实现语法上的层次结构,但我们还是应该尽可能避免每多一行就多一个缩进层次的代码,看起来很像倒金字塔。你可以尝试换一种方式来获得 加法算式,下面呈现的就是另外一种方式,从结果出发,x + y 里的 x、y 都是 0~10,那么除了边界问题 (10+0、0+10) 之外,xy 这个 99 以内的整数就能代表一个算式了。
参考代码:

def get_additions_2():
    equations = []
    for i in range(100):
        s = str(i).zfill(2)
        i, j = list(s)
        i, j = int(i), int(j)
        if i + j <= 10:
            equations.append([i, j])
    equations += [[10, 0], [0, 10]]
    s_equations = []
    for i, j in random.sample(equations, len(equations)):
        s_equations.append('%s + %s = ' % (i, j))
    return s_equations

get_additions_2 这个函数是值得我们思考的:
它让结构变得扁平但实际上又没有什么性能层面的提升,还要手工考虑另外一个情况 [10, 0], [0, 10],它的适用性又过于局限 (两项相加,任何一项超过 10 都不再适用),还不如倒金字塔的写法。
但不能忽略的一个重点,就是它也解决了问题。当我们以后面对一个难题无法解决的时候,换一个思路说不定问题的解决方案就自动浮现出来。


减法等式的逻辑,跟加法等式的逻辑基本一样:

def get_subtractions():
    equations = []
    for i in range(0, 11):
        for j in range(0, 11):
            if i - j >= 0:
                equations.append([i, j])
    s_equations = []
    for i, j in random.sample(equations, len(equations)):
        s_equations.append('%s - %s = ' % (i, j))
    return s_equations

最后,将所有等式混合起来,并随机乱排:

if __name__ == '__main__':
    eqs = get_subtractions() + get_additions()
    eqs = random.sample(eqs, len(eqs))
    for eq in eqs:
        print(eq)

对了,此时你应该也发现了,之前加减法公式分别都调用的 random.sample 函数,其实是无用功。这『无用功』到底是好是坏,你觉得呢?


最后,等式获得了,就可以打印出来。这里的打印是用打印机物理性地打印,而不是 print 这个函数的调用。
此时,也可以考虑在 Python 的程序内,对最终的输出再做特别的 print,可以让竖版 A4 纸,一行可以排下 3 个等式。但是呢,没有这个必要的,使用 Pages、Word,都有分栏的功能,就不用多写无价值的代码了。
而 『无价值』对于新手而言,也是有价值的,或许你可以试一试。