7:Python入门,新手在犯这个错误,老手却在“无码”编程
https://m.toutiao.com/is/e8U51Ne/
友情提示
1)这是关于编程思路,实践教学的 第7课
2)在专栏里,可以找到之前的课程
3)持续更新,关注不迷路
4)有问必答,不信试试看
回顾
上节课为大家分享了项目文件管理是多么的重要,并且介绍了一些使用技巧。上节课入口:
本次课程,你会学到:
1)大神编写代码时的好习惯2)已经会写代码了,但是就是写不出来的根源3)实践一下用Python把自己的构思实现4)若干能提升自己编码能力的干货
99% 新手的坏习惯?
接着之前的系列课程,在解决“把我们自己复制到虚拟世界里”时。
新手已经在犯错误了!
我还记得刚做开发不久,编写代码解决实际问题时的煎熬时刻。
问题就在我面前,但我总找不到合适的解决办法!
我敲10行代码又回删5行代码,这样一直重复,不知不觉一天就结束了,这种状态伴随了我一段时间。
有了一些工作经验后,我发现有这样经历的不仅仅是我一个人(有同款问题的请点赞)。
造成这样的囧境,是因为我们学会了写代码,但还不会去科学的寻找解决问题的方法!
就像我们学会了开车,但不一定开得好一样。
“哪,什么是正确编写代码的姿势?”
在《高效能人士七习惯》里,讲述了一个原则,它描述任何事情的落地都需要经历两个过程,一个想,一个做,并且是想在前,做在后,缺一不可,顺序不能乱。
我第一次看到这句话的时候,我反省了我经历的事情,貌似确实是这样,任何事情都需要先有个想法,才有有效的行动,(你能找到反例吗?)
“一个关于先想再做的实验”
在全世界最大的程序员论坛里,英特尔公司的一名研发成员做过一个研究。
在我们平常写代码的时候,是边写代码边思考效率高,还是先思考再写代码效率高?
实验邀请了60多名程序员,然后给他们出了10道题目。其中一组人要求先写出解决问题的思路再写代码,另外一组人只能直接写代码。
实验结果一边倒!
先写出解决问题思路在撸代码的人,正确解决问题消耗的时间只是另外一组的 1/6! 代码的质量也更好!
不可思议吧!
“ 为什么会这样!? ”
在这个帖子里,大家都在讨论自己的经验,并且说明为啥先想,再写代码的效率高?
我吃力的看了几页帖子,总结了一下,效率较高的原因如下:
1)大脑想的速度,一定要比你敲代码的速度快很多!2)大脑在想的时候,已经发掘并注意到了一些问题陷阱!3)不用动手也可以动脑!
在工作中,我刻意的去观察了周围效率高的程序员同事,在他们桌上都可以看到一个被画满各种思路的笔记本,他们都是思考的差不多后,再去敲代码。
先想再做,这种行为模式在生活中,也给我带来了很多的效率提升!比如做饭。
在创新一道新菜的时候,我会先在脑袋里过一遍整个流程,然后在脑袋里预判改进,自己觉得差不多的时候在动手。
现在我们先把键盘放到一边,来想想“把自己复制到虚拟世界里”,这个问题。
撸代码前,先撸个思路出来!
“ 要先想,要如何想? ”
这会是新手遇到的另外一个挑战。
不过还好,软件开发领域,提供了很多有用的思想工具,它们是用来专门解决要如何想的问题的。
分别是:
1)用例图2)类图3)对象图4)活动图5)状态图6)序列图7)协作图8)构件图9)部署图
上面这9种图,统称为UML(统一建模图)。每种图都有其特点用来设计程序内部是如何工作的。
我经历过一个和外国人合作的项目,单纯用语言来进行沟通会产生很多歧义和BUG,最后我和外国友人达成一致,在程序编码上,我们使用UML图来沟通,毕竟它就像自己名字一样是统一的。
果然用了UML和老外沟通后,整个合作顺畅多了,少了很多误会,他们甚至用UML的时序图画了一个我的作息时间,真是有意思。
现在就试试用UML类图来“无码”编程!
“把我们自己复制到虚拟世界里”
我们重新审视一下这个问题。
虚拟地球需要有人,人需要会互动,这样的虚拟世界才有意思嘛,在之前的课程我们介绍了我们通过“类”这个概念来构思虚拟地球,同样现在使用这个概念把“人”放到虚拟世界里。
不过这节课,我们将使用UML里的类图来完成这个设计工作。
我们先来看看最基本的UML这个图长什么样子:
可以看到这个大方块,由三个小方块叠放而成。
第一个小方块:放的是类的名称。第二个小方块:放的是类的属性,也就是类的变量。第三个小方块:放的是类的方法,也就是这个类的动作。
属性和方法前的加号“+”,减号“-”,代表的是它们的性质。
“+”:代表这个属性或方法,是“公用的”,就像你的名字,你的朋友们都知道。
“-”: 代表这个属性或方法,是“私有的”,就像你的秘密,只有你知道。
UML类图,也告诉了我们,一个类的概念需要有,名字、属性、方法来组成。
“ 那,人类的类图长什么样子呢?”
我静静的思考了一下,根据自己的生活经验,反观一下自己,于是就有了下面的人类类图:
我想让虚拟地球上,虚拟人有趣一点、热闹一点,所以给他们设计了社群关系比如
friend_listmarriage
属性等。它们同样有寿命,所以有了
age
lifetime
等属性。它们会在虚拟的地球里争夺地盘,所以有了
health
min_damage
max_damage
等属性。它们有自己的性格,所以有了
character
这个属性。
目前所有的属性都是“公有”的,用“+”来表示,这样设计是方便后面的教学,减低复杂度。
关于“公有”、“私有”的概念和用法,有很多有趣的理念。后续的课程为大家慢慢道来,关注我不迷路。
我们虚拟人类的构思算是有点眉目了,其中一些属性,比如 location(位置)、marriage(对象)、character(个性) 几个属性很难用基本的变量类型来表达,所以我们同样可以用类的方式“构思”他们。
如下图:
当我们把这个图思考出来后,虚拟世界里的“自己”有点模样了,但感觉还差点什么?貌似人、区域、性格这些类,不是孤立存在的,所以我们需要想办法把它们关联起来。
UML类图给我们提供了一些工具,用来标准化的表达类之间的关系,如下图:
我们可以看到,在类图里加入了一些箭头和线条,这两个元素就是用来精准表述类关系。
虚线箭头:
它代表了一种依赖关系,比如上图,人(People)的存在离不开区域(location)、性格的存(character)在。
实现箭头:
它代表了一种关联关系,比如上图,人(People)的存在可以是独立的,可以不需要朋友(friend_list)和对象(marriage)。
这种关系里面,还有一些细节,如下图:
0. .1
这种关联表达了,可有可无,如果有只能有一个,就像上面的图。人可以没有对象,如果有只能有一个(响应国家政策,我就这么设计了)。
0. .n
这种关联表达了,可有可无,如果有可以有很多。就像上面的图。人可以没有朋友,但也可以有很多朋友。
除了上面两种箭头线条外,UML类图还提供了其他一些标准的关系描述。
泛化关系:
老虎,和猫都属于猫科动物,猫科动物和人都属于生物。描述这种大类包含小类的关系就叫做泛化关系,这种关系经常发生在类的继承使用上。
实现关系:
我有一台Android手机,续航不是很好,出门在外经常找充电宝。不过还好由于Android手机都是标准充电接口,只要充电的设施 “实现” 了这个接口,我就可以方便地充电。
实现关系就是用来描述,统一接口和接口解决方案的关系。
组合关系:
每次说到这个关系,我就会看看自己的身体。因为我的身体器官,比如心脏、肝脏、肺等等组成了我维持生存的完整机能,但这些器官却不能单独的生存。
这种关系就用“组合关系”来描述比较恰当。
聚合关系:
我每天做饭的时候,饭菜的关系就是聚合关系。各种各样的调料、新鲜的美食、健康的油搅拌在一起,再来点大火,最后一波操作猛如虎,一道色香味俱全的菜就出来了。
乍一看它和组合关系一样,但不同的是聚合关系里的元素,可以单独的存在。比如调料、油,它们不会因为不组合在一起而失去意义。
如果你坚持看到这里。
关于UML类的所有知识现在你都掌握了,知识就是要活学活用,我们把之前“虚拟”地球的部分类图也加进来,现在的类图就变成这个样子了。
到这个时候,我觉得我们思考的也差不多了,先思考后执行的含义并不是要思考到完美,才执行,我们需要找个合适的度,现在我就觉得这个度就差不多了。
如何通过这个图,快速的敲代码?
我在平常的工作中,构思好UML图后,我会用同事写的工具(这个工具就是用Python写的),直接把这些UML图生转换成Python代码,然后再在这些代码里做修改。
在我平常做项目的时候,我简单的统计了一下,一个产品库里可能有1/3的代码是通过一些专业工具生成的,有1/3的代码是其他类似项目COPY过来的,有1/3的代码是自己写的。
在现在这个时代,优秀的编程人员和软件工程师,都是善于使用别人的资源,站在巨人的肩膀上完成自己的使命。
但对于刚开始入门的小白,我建议还是自己老老实实敲一遍代码,暂时远离这些智能的代码生成工具,打牢基础,后面才会潇洒自如。
下面的代码,就是按照上面思考的UML类图,手动敲出来的(敲完后发现也不多)。
Location 这个类的代码
# 导入环境这类from model.env.Env import Envclass Location: ''' 位置类的构建 ''' # 位置标示 id = 0 # 位置名称 name = '' # 大小 size = 0 # 人口基数 population = 0 # 环境 env = Env()
Character 这个类的代码
class Character: ''' 人类性格模型的构建 ''' # 理性 intellect = 100 # 感性 mood = 100 # 意志力 volition = 100 # 独立性 independent = 100 # 顺从 compliance = 100
People 这个类的代码
# 导入动物基础类,个性类,位置类from model.biology.Animal import Animalfrom model.people.Character import Characterfrom model.people.Location import Locationclass People(Animal): ''' 人类的模型构建 ''' # id 唯一表示,就像我们身份证一样 id = 0 # 人的名字 name = '' # 出生年月 birth = None # 出生位置 location = Location() # 等级 level,等级越高,越厉害 level = 0 # 经验教训,影响等级,通过击败对手获得 exp = 0 # 血量,血量为 0 这个人就消失 health = 0 # 最小伤害,对别人产生的最小伤害 min_damage = 1 # 最大伤害,对别人产生的最大伤害 max_damage = 10 # 我抵抗伤害的值 defense = 100 # 我闪避伤害的几率 agility = 100 # 我的朋友列表 friend_list = [] # 我的对象 marriage = None # 性格 character = Character() # 年龄 age = 0 # 生命周期,这只到 0 这个人就结束生命了 lifetime = 100
项目的组织结构图
我自己记了个时,我思考这个模型花了 37分钟,然后根据这个模型写代码用了 8分钟左右,也就是说我解决 “把自己映射到虚拟世界里” ,一共用了45分钟。
整个过程,我是先思考,再编码的。但如果我一遍思考,一遍编码,整个过程会超过45分钟。
所以建议大家在实际工作中,试试这样的习惯,你会感同身受的!
知识点的总结
这次课程耐心学完你学到了什么知识。
1)一种能提高编程效率的习惯,先思考再执行。2)一种用于协助我们思考代码该怎么写的工具UML图。3)UML类图的使用规则。4)类的几种关系。5)UML类图的具体使用方法。6)私有变量,公有变量的认识。7)根据类图来写代码。
下一课的内容
系统的学习一个重要概念,掌握了这个重要概念后,你就知道游戏里角色放技能、生活中手机购物下订单是怎么通过代码实现的了。