kidult's Python book

Python 小白月,回顾

加入Python学习班竟然超过一个月了!昨晚被大妈现场编程炸裂,又小小反思了一下人生…… 顶着这周作业还没有开始做的罪恶感,觉得及时回顾并调整姿势也许更重要,于是在补做作业前先码字:

一、学到什么

1.编程重要概念

变量 vs 替身

例:

例如:想要写个程序,实现:周一至至周日显示不同的早餐菜单。

我们需要有一个东西来代表“今天是周几”,可能性有 7 种,但是活在当下的只有 1 个,于是需要一个“替身”,框定它的“变身”范围是周一至周日,然后让它根据条件变变变……

这是对编程思维的第一个训练:【抽象】将某种类型、某个范围内变化的“实例”,抽象为一个“代号”。

坑:

  • 变量命名

    大妈在上周的 QA 里面提过,这几乎是一个终极问题…… 我的理解是,这个命名同时承载了占位符、运算对象、功能解释、类型暗示、作用域暗示 等等的使命,短了烧脑,长了烧眼……

  • 理解成本

    虽然程序是自己写的,变量是自己命名的,但是每一次回看程序时,都存在“翻译”变量名的隐性步骤,这个步骤消耗了很多认知资源,相当于脑子里面得有很多对牵线木偶,运行前是一个,运行后是另一个……相信这是老手感受不到/回忆不起的一种状态。尤其当程序长了以后,变量越来越多,记忆变量和管理变量都成问题,还容易犯看错变量名的错误。

填坑:

  • 定义函数时想想丫的用途和变化范围,加注释
  • 避免用三个字母以内的命名,使用一个月后再来仍然能快速理解的命名
  • 变量多的话,分一下组,或者动手画一下它们的关系帮助理清思路

暂时想到这些

数组 vs 分格抽屉

替身虽好,但是有时候还是不好管理,执行命令起来效率有点儿低,因为同质性不够高(虽然替身都是人,但可能年龄、爱好、性取向、左撇右撇、甜豆花派咸豆花派等等都不尽相同)、以及没有按顺序排列。

于是我们需要一个更“军事化”的组织——数组。数组就像一个分格抽屉:从外面看来,一个抽屉就是一个东西(里面能装很多东西);打开抽屉,里面是按照顺序放置的同一类东西,每一格都有位置编号(指针)。

这是对编程思维的第二个训练:【压缩】对同样的东西,折叠再折叠,收纳再收纳。

坑:

  • 抽象

    因为抽象,容易见抽屉而不见格子。写下数组太轻松 array[] ,但是一旦加入到运算中(尤其是循环),脑内演化就容易一团浆糊。

  • 抽屉里面的抽屉

    复杂性上升一维,需要先辨别是哪个抽屉,然后再定位到抽屉内的单元。

    小抽屉为大抽屉增加了多样性,一个抽屉放马卡龙,一个放铜锣烧,一个放...益力多…………

    至于N维数组……

填坑:

  • 克服对数组的心理恐惧,多使用这么简洁高效的工具,嗯
  • 为对抗数组高浓缩占位符的假象,见到数组自动脑补几个空行给它
  • 对循环语句中的数组尤其警惕,试着画一画?

数组一直是我的槛,回头需要再补看视频和笨方法,专门写写数组的笔记。

判断+循环 vs 防伪点钞机

嗯?点钞机?

点钞机工作特点:根据设定的条件,重复同一步骤。这正是 “判断+循环”的精髓。感谢它将我们从机械劳动中解放出来。

下面的代码虽然只有几行,但是综合了变量、运算、循环判断、数组等等,浓缩是浓缩,坑也很多……

    for shapes in shape_list: //Python
        if shapes[1] == "circle":
            canvas.draw_circle(shapes[0],Radius, 1, "Black",shapes[2])
        else:
            canvas.draw_polygon(shapes[0], 1, "Black",shapes[2])

以上对编程思维的第三个训练:【自动化】找出条件,识别共同步骤,循环处理,实现量变到质变。

坑:

  • 抽象 循环里面如果有个函数调用,再来个二维数组,脑子马上就浆糊了

填坑:

函数 vs 百宝袋

每个函数,都是哆啦A梦百宝袋里面的一件宝物!

宝物的特点是什么?实现大雄的一个愿望。至于怎么实现的,大雄并不用担心。当然,想实现多个愿望,最好不要指望于一件宝物,那样往往会出bug……

说回最开始一周早餐菜单的例子。要 print 不同的菜单,我们需要先判断今天是周几,这件事可以写到一个函数 whatIsTheDay() 中。以后一旦要做这件事,就 call 一下这个函数,外包这项任务给它,自己就翘着二郎腿等着它给出结果。一个程序中有多个函数,也就成了一个百宝袋。

函数的强大之处还在于,可以通过参数实现定制化需求。比如我们在函数 whatIsTheDay(year,month,date) 加入三个参数 year 、month 和 date ,告诉函数:“我想知道 某年、某月、某日 是周几 ”

以上是对编程思维的第四个训练:【模块化】分产承包,责任到户;结果导向,过程自理。

坑:

  • 贵圈太乱

    函数的调用关系复杂,你调我,它调你,你调你自己……

  • 参数传递和返回结果

    参数传递引入了新变量(认知内存中又要处理多一套对应关系 >_<),容易跟全局变量、函数内的局部变量混淆。而返回结果又是一个隐式的变量,不可见但影响重大。

  • 交叉并行路径

    如果只有一个明确起点,调用关系也单纯的程序就很好办。但事实往往是有多个起点入口,调用关系也复杂,偏偏程序是线性写下来的,不能按照从头到尾的顺序去读。于是到底程序从哪里开始,zeng 地蹿到了哪里,很让人头疼……

  • 自定义函数和内置函数

    内置函数的说法不对,因为那时还没有了解类,所以觉得类似frame.start()这种东西从哪来的,就把丫们看成内置函数。因为丫们不是自己亲生的,所以经常觉得陌生,尤其搞不清楚丫们之间的关系。

填坑:

  • 明确函数功能,加注释
  • 牢记函数的输入(函数参数)和输出(返回值)
  • 多进行局部调试,print 函数返回值
  • 函数之间的调用关系,通过可视化帮助理解

暂时想到的是这些

类 vs 招聘职位

每一个类都包含属性(变量和值)和行为(函数)。对比一下:

JD(招聘职位描述):

WXG01-微信高级交互设计师(广州)

工作职责:

- 参与微信相关产品从概念到原型的设计过程,输出相关设计文档;
- 对产品持续进行设计优化,提升用户体验;
- 协调和推动可用性测试及用户研究,以验证现有和将来的功能设计;
- 负责设计前瞻性的相关研究。

工作要求:

- 工业设计、心理学、计算机、视觉传达相关背景,本科及以上学历;
- 3年以上工作经验,主导过1000万+用户的移动互联网产品的设计,具备多领域设计工作相关经验,如产品设计、硬件设计、视觉设计等;
- 对互联网交互设计有深刻理解,具备完整的理论和技术体系;
- 优秀的产品意识,良好的全局观、前瞻性和判断力;
- 同理心强烈,擅长换位及独立思考,卓越的情景还原能力;
- 优秀的沟通、组织和项目管理能力;
- 性格乐观向上,兴趣爱好广泛。

类:

    class Character:
       def __init__(self, name, initial_health):   # __int__ 初始化对象
           self.name = name                    # self 是新的对象的引用
           self.health = initial_health    # name 和 health 是self对象中的域(field)
           self.inventory = []

       def __str__(self):
           s  = "Name: " + self.name
           s += " Health: " + str(self.health)
           s += " Inventory: " + str(self.inventory)
           return s

       def grab(self, item):            # methond defines the behaviors of objects
           self.inventory.append(item)

       def get_health(self):            # method 所有方法的第一个参数都是self
           return self.health

工作要求其实就相当于类的“属性”,作为这类人,本身需要具备什么样的条件和素质;工作职责相当于类的“行为”,这类人要干什么事情。

类和函数的区别在于,类只能操作某个类型的对象,而不能通过其他方法直接被调用。

面向对象编程的强大之处,对于一个类,理解其接口和已实现的方法,就可以使用了。

这是对编程思维的第五个训练:【面向对象】:打包成型,封装上架

坑:还没有真正练习过 囧,待踩。

2.编程思维模式

就这一个月(加上以前多次未果的编程学习尝试)的折腾而言,目前的理解如下

  1. 【抽象】将某种类型、某个范围内变化的“实例”,抽象为一个“代号”

    推而广之:思考问题时,尝试多总结共性,抽取出有用(而不是同义反复!)的抽象概念。

  2. 【压缩】对同样的东西,折叠再折叠,收纳再收纳

    推而广之:区分问题层面,宏观时 fold 细节,微观时 unfold 出来。

  3. 【自动化】找出条件,识别共同步骤,循环处理,实现量变到质变

    推而广之:不要死磕!体力劳动一定有办法简化或外包或提高效率。注意自动化是有条件、有成本的。

  4. 【模块化】分产承包,责任到户;结果导向,过程自理

    推而广之:overwhelming 时 Don't panic 。识别模块,各个击破。

  5. 【面向对象】:打包成型,封装上架

    推而广之:有用的东西包装成作品,发挥价值,产生交流。

3.工具升级

好人会武术,流氓挡不住~ 有了它们,生活真的美好了许多~

  • 版本管理:Git
  • 代码仓库:Github
  • 在线书籍:Gitbook
  • 发问吐槽:Mailling-list
  • 文本编辑:Markdown
  • 代码编辑:Sublime Text
  • 操作台:iTerm/bash
  • 工作流:Alfred
  • 小抄:Cheatsheet/Dash

当然,前提是有大白管家 Macbook Pro! XD

二、重新审视学习动机

读完经验的疆界后,反思了学 Python 前并没有细想的问题:

“我要学编程”是一个门槛特别低的想法,每年都会来脑子里转悠几回,但最终什么都没有发生。如果用“学习”的核心问题自我检验一下:

  1. Gap是什么

    • 不会编程和会编程的区别是什么?

      能用编程语言实现想法,产生作品。

      • 技能区别有哪些?

        语法;编程环境;debug;发问和找答案

      • 思维区别有哪些?

        抽象,压缩,自动化,模块化,面向对象;逻辑,全面,精炼

    • 怎么判断学会编程了?

      写出可用程序

    • 有明确的级别区分吗?

      参考 The Eight Levels of Programmers - Coding Horror

    • 想达到哪种级别?

      按作品要求来定

    • 理想中,学会编程可以干哪些事情?

      • 做自己的网站
      • 写小程序/实用插件,如 Alfred 的 workflow, Sketch 的 plugin
      • 做互动装置
      • 做好玩的智能硬件
      • 跟程序猿更好进行沟通
      • 升级微信订阅号为服务号
      • ……
    • 自己在什么情况下需要干这些事情?真的会用编程的方法而不是其他途径解决吗?

      打造作品+寻找乐趣。大部分其实可以通过现成半现成的开源资料实现,但前提是得进入那个世界,并且掌握那里的沟通方式。

  2. 要改变什么?

    • 停止/减少干一些(很多)事情,把时间挪用于编程学习;
    • 不再对编程相关的事物有抵触/畏难心理;
    • 改变以往的一些学习习惯;
    • 学会使用新的工具;
    • 接受编程的思维训练,并且在合适的情形下改用这种思维来思考;
    • 挑选一种语言作为入门;
    • 学习-练习-作品-总结 的无限循环
    • ……

任何的学习行为,其实都是一种 commitment 。在回答“I Do”之前,需要认真诚实地过一遍这些问题,不然很快就会卡在“我要改变什么”,被扑面而来的不适和付出的索求而吓跑。

不仅需要在学习前自问,更重要的是在学习的整个过程中,不停调整“做什么、如何做、如何评估”。

三、现存问题

舒适魔障

还是选择了较 easy 的模式,自虐程度远远不够:

  • 只实现最基本的要求,实现后也没有继续优化
  • 卡壳后没有深入分析,就开始找资料,或者 peek 同学的作业
  • 总有想逃回舒适区的念头

时间魔障

其实是舒适魔障的另一个版本……

目前投入时间少:周一至五每天不足半小时(甚至连续3、4天完全不碰),周末如果再加个班,学习时间只剩一天。

说明并没有做好充分的时间规划,时间管理和行动意图都需要加强。

理解魔障

  • 不同模块的代码行数和运算量、重要性严重不对等,二八原则无处不在
  • 代码线性,运行却非线性
  • 缺乏对算法的了解

认知魔障

  • 内心仍然认为编程难学
  • 渴望有一个全景的 map ,然后再开始;如果没有,总觉得内心不安

社群魔障

  • 认真发问所耗费精力,比粗浅解决问题更多,所以“懒得”问
  • 工作日基本没有进展,难以参与讨论
  • 周末基本在埋头赶作业,难以参与讨论

四、旗舰班为什么有效

其实,这已经是我第 n 次尝试学编程了。大学时学过 C 和 VB,工作后敲过 Codecademy 的 JS 课程,自己还看了 Processing 和 Arduino 的东西。但是为什么为什么一直没有学会??

参加了旗舰班以及听了铜叔的讲座,给到自己一个说法:

  • 没有明确目标
  • 对投入没有充分的估计和准备
  • 没有作品目标!没有输出!
  • 没有同辈压力!
  • 姿势不对 (顺序/思路/找资料/发问/解决问题/心态,各种问题)
  • easy模式,舒适区

旗舰班一股脑把这些都解决了!反转教学保证输出,同辈压力保证要求,社群/Mailling-list/QA 纠正探索姿势。剩下不可控的都是自己的因素了:目标,沉浸度,舒适区。

一个月,又让我重燃希望。感谢大妈,感谢班长和助教,感谢各位炸裂的小伙伴!

五、改改改

根据现在发现的问题,以及参考铜叔讲座中的方法,在后面的学习中做出调整:

  • 明确目标:作品
  • 持续和沉浸:每天保证时间-
  • 增加输入:视频+笨方法+书+mailling-list+公众号
  • 增加输出:冷却后再提取输出,尝试表格和信息图整理法
  • 扔掉拐杖:少偷看同学作业,先尽量自己写出来
  • 拆分技能单元:例如函数内包含数组的循环怎么写更好?-
  • 提高要求:实现更多功能,用更少代码,自己给自己设置障碍-
  • 可视化思考:将思考和问题、逻辑和关系等,用各种方式可视化
  • 思考和提问的正确姿势:问题是什么?思路是什么?有哪些不确定待查的信息?解决不了,可能的原因是什么?