学习,思考,分享,创造

月份:2019年9月

谁是世界上第一位程序员?

鲸小小是北京是科普资源联盟的成员单位,我们面向中小学生科普的核心是计算机科学相关的知识。9月25日,国庆节前,应该校家委会的邀请,我们去团结湖一小面向五年级和六年级的两个班的学生分别做了一次科普活动。

下面是六年级活动的介绍。

鲸小小的老师们到的时候, 六年级的同学都在操场上运动,教室里显得空荡荡的。

现场家委会的家长知道我们是做编程教育的,表示他们家的孩子学过机器人,挺好玩的。我们给家长介绍要分享的主题, “计算机科学科普—-杂谈”,不讲编程,而是讲计算机和计算机发明者的故事。之所以选择这样的主题,是因为学生们很少有机会接触这样的知识,对于计算机的认识,停留在玩游戏,编程序的使用上面。那些天才计算机的发明者们,所处的时代、经历、个性,以及他们做出发明的创新型想法,也许可以激发更多学生接触科技,学习科技知识的兴趣。 

为了引出话题,我们给学生们展示了一个计算机发展的表格,第一代是真空电子管计算机,ENIAC。 这台计算机是于1946年在美国宾夕法尼亚大学建造成功的。 这个时候,一个同学积极举手,给别的同学兴奋地介绍这台计算机有多大, 有多少真空管。这让我觉得很意外,没有想到有同学对这些知识还很了解,因为她似乎没有学过编程,也没有参加过信息学奥赛。 了解这些知识,说明这位同学的课外阅读非常广泛,对计算机科技的发展比较关注。

(本来准备了波士顿机器人的视频给学生们播放, 可惜呀, 教室里面的PPT比较古老,很遗憾,视频没有放出来。所以,去学校讲课,需要了解一下他们的系统是什么版本的,微软的系统是什么版本的。实在不行,也要问一下教室内的系统,可不可以接自己带的电脑。)

说起来可能不太相信,计算机发明之前,程序代码就已经出现了,同样的,程序员先于计算机出现了。

今天的故事就围绕着世界上第一位程序员,同样也是第一位女程序员Ada展开。

 Ada Byron Lovelace   The First Computer Programmer   1815 – 1852

有关计算机发展史上的关键人物,很多人知道图灵。 比如今天课堂上,当我提到图灵的时候,一个男同学就起立,给同学们分享了他所知道的图灵测试。虽然他有一点点紧张,但是大概意思是非常到位的,为这位同学点赞。但是很少有人知道在图灵之前100年,计算机还没有真正发明的时候,已经有一位女士,提出了计算机程序设计相关的非常重要的概念。

Ada是英国19世纪诗人拜伦(L.Byron)的女儿,既是一位数学家,也是一位发明者。 她继承了诗人父亲天马行空的想象力,同时也在母亲的熏陶和当时数学家的指导下,学习钻研过数学。

(同学们不知道拜伦,但是当我说拜伦是雪莱的朋友时,有些同学的深情有点恍然大悟的意思,似乎了解雪莱要多一点.)

她学习数学的原因,也很出乎人的意料 ”我应该做一些科学方面的事来控制我的想象力,避免胡思乱想“。  每个人都希望培养自己的想象力, Ada是我所知道的第一个想抑制自己想象力的人。她所采用的方法也与众不同,竟然是用大部分人感到头疼,想极力避开的数学来纠正自己。

而且,真的有人给她开了一个药方。

如果你想知道,这个药方是:

  1.  一付欧几里得几何
  2. 一点三角学
  3. 一点代数

在这个时候,给同学们普及了欧几里得几何就是平面几何,就是从公理出发, 通过严格的推理来论证结论,推导新的信息的。举了例子后,有同学开始明白了。

再接下来, 介绍了一下Ada当时生活的时代背景:工业革命。蒸汽机的出现,带动了科技的飞速发展,英国中部出现了很多的工厂。 Ada去参观之后,觉得非常兴奋。其中印象最深的是织布机。 后来, 她又认识了英国几位著名的女数学家和女科学家,在技术的应用上面产生了更多的兴趣。

在丰富想象力的基础之上, Ada可以把想象力应用到科学上,这是她与别人不同的地方。 她的父亲拜伦想象力丰富,但是对待技术的发展,却是一个十足的”反动派”。 他支持”卢德主义”。当时,机器生产逐渐替代手工劳动, 大批手工业者破产,工人失业,工资下跌。于是工人把机器视为贫苦的根源,用捣毁机器作为反对企业主,争取改善劳动条件的手段。 Ada不是这样的,她仔细观察当时先进的织布机,从中吸取重要的设计,这对于她后面的发明(对于分析引擎的设想)非常重要。

当时提花织机织出来的发明者的像

那么,谁给Ada开的药方呢?

是一位叫巴贝奇的发明者(如下图)。 (Charles Babbage)

Charles Babbage

课堂上没有时间讲这位巴贝奇先生在家组织沙龙,邀请各个领域的科学家来讨论和分享科学方面的研究, 他也来宣传自己发明的机器:微分引擎,希望有人能够投资于他。

在给同学们展示了微分引擎机器的照片之后,提到了一点, 该机器是用来计算对数表,三角函数表来设计的。 它把操作分解成非常小的步骤, 每一步都只含加法和减法。这个就是算法的雏形。

然后简单介绍了这个机器如何求平方,验证用加法和减法的方法来求平方。

第一列是N的平方,第二列是相邻两个数的平方差,而第三列是平方的导数。 (虽然没有同学学过微积分,但是看上面的表格没有问题)。 我们知道第三列总是2(当然是,这是平方的导数值) 而第二列的值可以由前面一个数和导数相加得出。

比如, 我们知道了3, 下面一个数就是3+2 = 5, 再下面一个数就是 5+2 = 7 , 以此类推。

那么第一列的值,也就是平方的值,就是前面一个数加上第二列的值, 比如

4 = 1 + 3

9 = 4 + 5

16 = 9 + 7

只要持续计算下去,就能算出任意大的数字的平方值。

这种方法的确每一步都只涉及了加法和减法,用机器来实现就容易多了。

(由于时间有限, 这一部分在讲的时候一带而过,估计很多同学都没有看明白, 如果他们读了本文,可能会恍然大悟。)

巴贝奇先生发明的这个机器,由于在当时非常先进,以至于英国政府要投价值差不多两艘战舰的资金来让他生产。 可是,巴贝奇是一个停不下脚步的创造者,他脑袋中有了新的想法, 提出了设计一台通用计算机的想法,名叫分析引擎(Analytic Engine)。 

通用计算机和这种专门用来计算数值的计算机有本质的区别,因为它会涉及到编程。

巴贝奇在意大利都灵路演的时候,听众中有一位年轻的上尉,名叫路易吉·梅纳(后来成了意大利的首相)。 这位上尉用法语写了一篇文章介绍这太构想中的机器。 后来, Ada把这篇文章翻译成英文,并且添加了自己的一些想法,名为笔记。


路易吉·梅纳布雷亚上尉

Ada 的这篇笔记, 奠定了她计算机研究鼻祖的历史地位。

Scientific Memoirs, 登载Ada笔记的杂志

在这篇文章中, Ada的贡献主要有四个:

  1. 提出了可编程的通用机器的概念
  2. 提出机器不仅能做数学运算, 只要是可以用符号表示的逻辑,都可以用机器来计算
  3. 设计出了一步一步工作的程序,首次提出算法的概念,子程序的概念,递归循环的概念
  4. 发出人工智能第一问:机器能思考吗?  100年后, 图灵同学把这第一问命名为 “Lay Lovelace的反对” 因为Ada认为,机器永远不能有自己的独创的想法,也就是不会思考

最后, 给同学们总结了一下这次分享的故事中,希望学生们能够认识到

有关未来的创造和发明:

1. 数学是计算机科学的基础 (鼓励学生们学好数学)

2. 艺术和技术相结合的时候,更容易出现不同寻常的创造(鼓励学生们不仅要学好艺术,而且要学好 科学技术) ,培养对数学、艺术、技术的兴趣

3. 关注别人是怎么想到的, 别人思考问题的方式

4. 女生是可以学编程的

5. 发现你身边的问题,试着用技术来解决。

后记:

1. 美国国防部据说花了10年的时间,把所需软件的全部功能混合在一种计算机语言中,希望它能成为军方数千种电脑的标准。1981年,这种语言被正式命名为ADA(阿达)语言,以纪念这位“世界上第一位软件工程师”。

2. 计算机科普知识即使对于六年级的学生,采取纯叙述的方式,可能也不是太有效。 尽管如此, 能够发现班上有几位阅读面广的学生, 很是很欣慰的。这些学生如果愿意来学习编程,我们是非常高兴的。

课堂照片:

白小迎曦分校Python社团课

周三上午从杭州出差回来,回家稍作休整之后,就直接来到了白小迎曦南校。今天是学校四年级学生Python编程社团的日子。

这个社团是鲸小小2019年面向学校合作的第二个合作成果。 学校的校长在收到我们的提议后,非常支持编程社团的开办,放手让老师们安排。虽然由于校区计算机室资源的问题,有些曲折,但是整体效率是非常高的。 老师们在帮助学生接触新的知识和技能,非常努力积极地在工作。

跟着负责这个项目的高老师,从教学楼的西边楼梯上二楼,辗转穿过教学楼,到了最东边的计算机教室。 教室里整整齐齐的摆着5排电脑,井井有条。

高老师介绍说,由于社团成立的时间比其他社团要晚,一开始担心与其它社团活动时间冲突,报名人数会比较少。

没想到的是,消息一经发出,就有来自于5个班的12位四年级的同学积极地选择了Python编程社团。

时间差不多了,同学们三三两两地陆续到来。

有同学一进来,就迫不及待地大声说:“老师,你知道我报了几个社团吗? 算上编程,有三个了!”

还有个同学说,她特别想来编程社团, 虽然班主任老师专门给高老师打了招呼,说她已经很忙了。但是她仍旧是来了。 这个同学进门之后兴奋地跟我讲了这么多。

这第一节课,课堂目标最主要的是:

1) 了解一下学生的水平。因为我知道,每个孩子接触电脑的机会是不一样的,使用电脑的程度参差不齐

2) 让学生们了解一下Python编程大概是怎么回事,为什么要学,要展示一个具体的例子

3) 介绍一下课程的安排和上课的一些基本规则

“多提问, 多尝试, 多分享”这样的三多理念当然也是要给同学们讲到的。除此以外, 在讲到多尝试的时候,补充了一下。

“在Python编程社团里面,你们不要轻易相信任何人的话,只有自己动手尝试过确认以后才能相信” 估计这帮孩子从来没有听到过课堂上的老师这么讲过,着实懵了一下下。经过解释之后,他们还是连连点头的。

孩子们需要开始更多地接触独立思考,独立验证这样的习惯了。技术方面来不得弄虚作假,大部分时间对就是对,错就是错。 学生们有了计算机工具,思维上再强化一下自主意识,自学意识,对于他们个人的发展也是很有帮助的。

这些学生中,有的上过计算机信息技术课,所以使用键盘输入,鼠标操作都非常熟练。有的很少接触电脑,也没有上过计算机信息技术课,所以在电脑上敲字挺费劲的。


教编程,真正地从零开始了。教如何输入大写字母,标点符号,汉字等等。 不知道孩子们在家有多少时间练习一下呀!


没有教他们安装Python软件包,而是课前早就请鲸小小的老师和高老师安装好了。 如果第一天教安装,对于电脑系统操作不熟悉的孩子,在短短的40多分钟中,估计大部分时间都是迷糊的,万一学习编程的热情遭受了打击, 罪过就大了。


在情绪调动起来之后,孩子们开始敲人生第一行代码。 首先教他们怎么打开Python的IDLE, 然后输入print()这样的指令。 熟悉键盘操作的学生一下就好了,不熟悉的就费点劲, 需要到他的位置上指导。 “Hello World” 这样的一行程序,有的同学需要漫长的时间才能敲好,有的三下五除二就好了。 然后为了让他们互相认识一下,就让他们编程给左手边的同学打招呼,然后再给右手边的同学打招呼。 一个同学挺投入, 完成之后,写程序给妈妈打招呼。做好了以后,把手举得高高地,让我过去看。


千里之行,始于足下。只要开始了,就有机会走得很远很远。

Cason 老师

受计算机室资源所限,我们只开了Python班。如果将来时机成熟了, 低年级的Scratch班, 高年级的C++班, Arduino班,Micro:bit班,都可以做起来。 希望编程社团能够做得越来越受欢迎, 很可能未来有一天,他们在大学中学习的课目,或者未来从事的工作,都会受益于这个社团的活动内容呢!

同学们加油!

解数独,学编程-Python 4

python

上一篇我们使用了列表的生成方法, 用一条语句就可以根据现有的数据生成一个新的列表,避免了显式的循环,让代码显得非常简洁。

本次我们会继续分析cross这个函数的使用, 并用它来生成含有所有单元的列表的列表。

接下来我们在看两个例子:

# first column list , then row list, then 4x4 unit #
UNITLIST = ([cross(ROWS, c) for c in COLS] + [cross(r, COLS) for r in ROWS] + [cross(rs, cs) for rs in ('ABC','DEF','GHI') for cs in ('123','456','789')])

这条语句形成了一个新的列表,由三部分列表组成。

[cross(ROWS, c) for c in COLS]

编程时当遇到在一个抽象基础上累加另外一个抽象的时候,看起来就比较复杂了。 但是当我们抓住抽象的本质,就能理解代码的真实意图。

上面代码就是针对每个COLS中来的c,都做一下与ROWS中元素的组合。假如c为1, 则cross(ROWS, ‘1’) 就会生成 [‘A1’, ‘B1’, ‘C1’, ‘D1’ … ‘I1’] 这正好是第一列

如果c为2,则生成第二列, 所以 [cross(ROWS, c) for c in COLS] 生成的就是所有列组成的一个列表。

如果反回来思考,如何生成一个包含所有列的列表呢?

首先我们要明白, cross()函数的第二个参数不能是一个列表,因为该函数的算法是先取第一个参数中的一个元素不变,逐个与第二个参数中的某个元素组合。 如果第二个参数是列表且有多个元素, 新生成的列表元素第二部分就是变化的,不会像上面分析的结果一样,第二部分是不变的。

所以就先从列中取一个元素,作为cross函数的第二个参数。

那么,如何生成包含所有行的列表呢? 就是 [[‘A1’, ‘A2′,’A3’, ‘A4’ ,… ‘A9’], [‘B1’, ‘B2’, ‘B3’, … ‘B9’], … [‘I1’, ‘I2’, ‘I3’ … ‘I9’] ]?

cross(‘A’, COLS) , cross(‘B’, COLS) … cross(‘I’, COLS)

再把变化的部分抽出来,就变成了

[cross(r, COLS) for r in ROWS ]

这正好是 UNITLIST 中第二个部分,所有行的列表组合

下面我们来看如何生成3×3的方格的单元。 左上角的是[‘A1′,’A2′,’A3’, ‘B1’, ‘B2’, ‘B3’, ‘C1’, ‘C2’, ‘C3’], 中间的是 [‘A4’, ‘A5’, ‘A6’, ‘B4′,’B5′,’B6′,’C4′,’C5′,’C6’] 右上角的是 [‘A7′,’A8′,’A9’, ‘B7′,’B8’,’B9’, ‘C7’, ‘C8’, ‘C9’]

我们能找到什么规律呢?

我们可以看到,cross()的第一个参数‘ABC’, 第二个参数是 (‘123’,’456′, ‘789’)

中间一行最左边3×3单元是: [‘D1′,’D2’, ‘D3’, ‘E1’, ‘E2’, ‘E3’, ‘F1’, ‘F2’, ‘F3] 中间一个单元是 [‘D4′,’D5’, ‘D6’, ‘E4’, ‘E5, ‘E6’, ‘F4’, ‘F5’, ‘F6’] , 最右边的单元是 [‘D7′,’D8’, ‘D9’, ‘E7′,’E8′,’E9′]。cross()的第一个参数是‘DEF’, 第二个参数是 (‘123’,’456’, ‘789’)

由此,我们可以大胆地假设, 最后一行3×3单元, cross()的第一个参数是‘GHI’, 第二个参数是 (‘123’,’456′, ‘789’)

这正好是: [cross(rs, cs) for rs in (‘ABC’,’DEF’,’GHI’) for cs in (‘123′,’456′,’789’)]

所以看到了吧, UNITLIST 就是所有的单元, 包括行, 列,以及3×3的方格。所有这些单元,都保存在了UNITLIST这个变量里面了。

如果你仔细观察的话, 生成的列表中,有几个列表元素, 第一个参数就有几个元素。

本篇的主题就是根据cross函数和要实现的目的,来构造列表的生成式了。

看起来很复杂,只要理解了cross函数的本质,就容易掌握了。 只所以要学列表的生成式, 因为Python语言里面用得比较多,这样做简介,显得更加像Python程序员写的程序。

作业

根据cross()函数的定义,要实现 [‘A1’, ‘A2’, ‘A3’, ‘A4’], 应该怎么写构造列表的生成式呢?

cross(‘A’, [‘1′,’2′,’3′,’4’])

Powered by WordPress & Theme by Anders Norén