5 Key Concepts of Programming | 学编程?从五个思维训练开始

in #cn7 years ago

geek-icon.png

学编程?WHY?

因为,这是未来的语言。如果你想创造任何数字化的作品,只有掌握一些编程语言,才能体会到真正的创作自由。

毕竟,这是一门语言

编程语言虽说跟自然语言类似,但有一些本质的区别,如果不理解这些区别,编程所独有的一些们槛会始终把你挡在门外。这篇文章尝试以 Python 为例,用比喻的方法来讲解几个关键概念。你并不需要懂得 Python 的语法,只需要用一种开放的心态看待编程,尝试理解它的独特之处。

一、变量 vs 替身

变量是学习编程语言时第一道标志性的认知门槛。因为在日程使用的语言中,所有句子中的词语都是既定的,你说了 「Great minds think alike」,这个句子不会变成 「Great mouse think alike」。但是在编程语言中,某些词语会「变化」。这种会变化的词语,叫做「变量」。

例如

想要写个程序,显示一周七天不同的早餐菜单

我们需要有一个东西来代表「今天是周几」。可能性有 7 种,但是当下只有 1 种,比如今天是周五。那么需要一个「替身」,来限定它的「变身」范围是周一至周日,然后让它根据条件变变变……

这是对编程思维的第一个训练:

抽象

将某种类型、某个范围内变化的「实例」,抽象为一个「代号」。

变量的陷阱

  • 变量命名

    这几乎是一个终极问题…… 因为命名同时承载了占位符、运算对象、功能解释、类型暗示、作用域暗示 等等的使命,于是短了烧脑,长了烧眼……

  • 理解成本

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

填坑:

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

二、数组 vs 分格抽屉

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

于是我们需要一个更「军事化」的组织——数组。数组就像一个分格抽屉:

从外面看来,一个抽屉就是一个东西(里面能装很多东西);打开抽屉,里面是按照顺序放置的同一类东西,每一格都有位置编号(指针)。

这是对编程思维的第二个训练:

压缩

对同样的东西,折叠再折叠,收纳再收纳。

抽屉的陷阱

  • 抽象

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

  • 抽屉里面的抽屉

    多维数组又是编程学习中一道难以逾越的门槛。每增加一维,复杂性成本增加。需要先辨别是哪个抽屉,然后再定位到抽屉内的单元。

    MaximeBrunelle-2.jpg

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

    至于N维数组……

    604e48d0jw1eqr3oey2dcj205e05kq3c.jpg

填坑:

  • 克服对数组的心理恐惧,多使用这么简洁高效的工具,嗯
  • 数组都是高浓缩占位符,占地小,内涵大,如果见到数组,可以自动脑补更大的空间给它
  • 对循环语句中的数组尤其警惕,试着画一画逻辑关系

三、判断+循环 vs 防伪点钞机

嗯?点钞机?

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

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

for shapes in shape_list:
    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 地蹿到了哪里,很让人头疼……

  • 自定义函数和原生函数

    因为原生函数不是自己亲生的,所以经常觉得陌生,尤其搞不清楚原生函数之间的关系。

填坑:

  • 明确函数功能,勤加注释
  • 牢记函数的输入(函数参数)和输出(返回值)
  • 多进行局部调试,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
  • 工作要求其实就相当于类的「属性」,作为这类人,本身需要具备什么样的条件和素质;
  • 工作职责相当于类的「行为」,这类人要干什么事情。

类和函数的区别在于,类只能操作某个类型的对象,而不能通过其他方法直接被调用。面向对象编程的强大之处,对于一个类,理解其接口和已实现的方法,就可以使用了。

这是对编程思维的第五个训练:

面向对象

打包成型,封装上架。

面向对象的陷阱

  • 哪些对象、函数需要组织成类,类如何在一开始就做好规划
  • 类和子类的继承关系太复杂
  • 类如何管理

关于类、实例、方法等问题,后面再深入讨论。

今天先到这~ 可能有很多不恰当的类别,请各位程序猿轻拍~

You might be also interested in:


@kidult00 . Thanks for Upvoting !

Sort:  

准备重新学一学编程,谢谢你的分享~

Coin Marketplace

STEEM 0.16
TRX 0.16
JST 0.030
BTC 58171.46
ETH 2472.55
USDT 1.00
SBD 2.42