#章节十九:编程思维:产品思维
章节十九:编程思维:产品思维
学习编程的目的从来不是为了考试,而是要学会用编程能力帮自己解决实际问题。
但我们发现如果只是学习基础知识的话,还是不能解决实际问题。这就好比我们在学校学习了很多公式定理,但却发现它们在生活并没有什么用处。
其中一个原因是因为生活经验和所学知识之间存在脱节,导致知识无法运用到生活中。
编程技能也是如此:
对于编程来说,其实我们每个人都有足够的生活经验,在过去的一段时间里也掌握了基础知识,那么中间缺的究竟是什么呢?
我认为,这道连接编程知识和解决实际问题的桥梁就是“产品思维”。
这里我所说的【产品】,并非百货商场货架上的“产品”,而是“为自己或他人服务的程序”。
1. 流程图
工欲善其事必先利其器,我们首先要学习的是“流程图”,如果不先掌握“流程图”这个分析与思考的工具,就很难实践“产品设计”的相关方法。
相信大家之前一定也接触过流程图,我们可以把流程图理解成“用一种图示描述事物进行的过程”。比如我们去注册使用共享单车的过程,可以画出这样的流程图:
掌握了流程图后,你既可以用它分析思考问题,也可以用它搭建产品框架,还能用它设计代码逻辑。
所有的流程图,总结起来有三种类型:
是不是和我们之前学的条件判断和循环语句,有异曲同工之妙?
接下来让我们一个个来看。
1.1 顺序结构
当一件事情是按顺序进行的时候,我们就用顺序结构。一般会用到三种图形:
有些我们习以为常的行为,也可以拆解成一定的步骤。比如当我们在淘宝剁手的时候,粗糙的流程图是长这样的:
现在请你来思考一下,对于“煮饭”这件事,一个简单的流程图可以怎么画?
流程图画出来之后,可以帮助我们梳理代码逻辑,逐步实现。
比如我们想写一个根据圆的半径(R)来求面积(S)和周长(L)的代码,可以画出以下的流程图:
那就来吧,写写看:
# 定义变量
pi = 3.14
# 按流程图中的步骤写代码
print('欢迎使用圆的面积和周长计算程序。')
R = float(input('请输入圆的半径:'))
S = pi*R*R
L = 2*pi*R
print('圆的面积是:' + str(S) + '\n' + '圆的周长是:' + str(L))
可以看到,代码都是按照流程图中的步骤写出的。
顺序结构,很简单,我们就讲到这里。
1.2 条件结构
接下来,我们继续学习“条件结构”。
“条件结构”主要是为了展现,在不同的条件下如何按不同的逻辑行事。
在这里,我们要补充一个图形,当流程图中遇到需要判断条件的节点时,需要用“菱形”表示。
说起“条件结构”,我就想起了一个“黑”程序员的笑话:
其实,妻子表达的意思,用流程图画出来是这样:
但是,程序员丈夫把妻子的意思理解错了,所以闹出了笑话。
他到底是哪儿弄错了呢?
同样地,写有条件判断结构的代码时也能用流程图帮我们梳理逻辑。
例如你想写一个【求绝对值】的程序,将正数负数都转化为正数。
----- 代码实现效果 -----
输入:5
输出:5
输入:-2
输出:2
输入:-101.22
输出;101.22
这里有一个条件判断,即根据输入的数是正数还是负数会有不同的操作,那么把流程图画出来就是:
你能写出这段流程图的代码么?
print('欢迎使用绝对值计算程序。')
R = float(input('请输入数字:'))
if R>=0:
S = R
elif R<0: # 这里可以用“else:”代替“elif R<0:”
S = -R
print('所求绝对值是:' + str(S))
不难,但是用流程图写代码,真的非常清晰,对吧?好啦,条件结构就讲到这儿啦。
1.3 循环结构
最后一种循环结构,是用来描述在指定情况下,按某种重复的逻辑行事。
在前面“共享单车”的流程图案例中,就有一个循环结构:
以淘宝购物为例,在最后提交订单的时候,也有一个循环结构:
你发现了第二个循环结构和第一个循环结构的不同之处么?
第二个循环结构比第一个多了一处菱形,用来负责“条件判断”,当条件为“不成功”时则继续循环。
现在,三种循环结构你都了解了吧,我们来做一个综合练习巩固一下。请把以下的逻辑,用流程图的形式表现出来。
摩拜单车使用逻辑:
1. 先要注册、交押金并充值
2. 找到摩拜单车,用手机扫码解锁单车,然后开始计费
3. 有时候车是坏的,手机会提示:“此车需要维修,请换一辆车”,这种情况不会进入计费,需要换一辆车再扫码
4. 到目的地后锁车,可以选择余额支付、微信支付、支付宝支付
5. 支付的时候如果余额不足会失败,需要更换其他支付方式。
比如这样:
到这里,三种结构的流程图我们就学完了,我们再来总结一下流程图的图形结构:
有意识地使用流程图,可以锻炼我们的逻辑思维能力,也可以让我们在敲代码前整理思路,有一个明确清晰的指引。
学完流程图后,我们就可以尝试设计产品了。
2. 产品设计
B选项更加可靠。从生活中找到可以用编程解决的问题,再想办法解决,是提高编程实战能力的关键。
对于A选项,积累编程能力很重要,但编程知识范围和体量巨大。如果只从积累编程能力出发,不从生活经验和实际想要解决的问题出发,会让你难以抓住学习重点。建议在积累知识的同时也积累一些对生活经验的思考。
和B选项类似的是,真实世界中的“编程”,与两种角色最为相关——产品经理和程序员。
产品经理负责告诉程序员,要做一个怎样的产品,程序员接到需求后,会制作技术方案,实现代码,最终制作出产品经理所描述的产品。
像这样,产品经理把产品任务提交给程序员的过程,在互联网公司称为【提需求】。就像你去一家餐厅点餐一样,点了菜,大厨给你制作菜品。你给大厨下单的过程就是【提需求】。
如果我们想设计出服务于自己的程序,就需要自己“做自己的产品经理”,兼顾产品经理和程序员两种身份,自己给自己【提需求】。
那我们到底应该如何发现需求,如何提出需求呢?
2.1 如何提需求
要想提出需求,我们首先要学会留意生活和工作中,哪些地方不方便、不爽、存在障碍,也就是我们常说的“痛点”。
根据大家现在的技能水平,有两种需求最值得关注:
我们在平时的工作和生活中都可以尝试思考,是否有“重复性劳动”可以被程序替代?是否能够“制作工具”帮我们解决问题?
我们都知道,编程能够解决重复性劳动。因此,只要我们对“重复性劳动”格外关注,就很容易提出需求:
另一类需求来源是“制作工具解决问题”。有时候,我们可以通过技术手段制作一些实用的工具,提升效率。
到这里,可能有同学会觉得:站着说话不腰疼,提需求容易,但我们只学完了基础语法课,我真的做得出来么?
的确,许多需求完成起来还比较困难。但你应该先记录下来,即使是你现在一时间还无法解决的需求。
记录需求的好处是“建立明确的编程目标”。以实现这些需求为目标,你可以很清晰地感受到自己编程能力的成长,有朝一日你实现自己需求,制作出完整产品的时候,一定会开心得像个两百斤的孩子。
这里,我推荐大家用一张表格做记录:
记录需求的习惯,本质上也可以锻炼我们提需求的能力。此刻,有句话想送给你:
无可否认的是,即使是2020年了,目前我们的劳动状态中,依然有太多重复、单调、无聊的时刻,就连看似光鲜的“脑力劳动”中亦是如此,我们以社畜自嘲,千百次叩问工作的意义为何。
这种强烈的厌倦感可能浮现在你一行行地复制、粘贴、比对数据;一遍遍地用相同的话术去处理客户重复的问题;一次次地费劲地想着这周的工作报告如何写得和上周的不太一样……
但是我想与大家共勉的是,不要对重复性工作习以为常,毕竟,编程存在的目的就是解决人类的问题,不能提升人类社会的效率和幸福感的技术手段都是耍流氓。
不要自我安慰说“反正大家都是这么过来的”,也不要对无奈的生活习以为常,暗自认定“我没有办法解决这个问题”。
程序员可能是世界上最善于解决问题的一群人,相信已入门编程的你,也慢慢会有这种直面问题、解决问题的底气和精神。
2.2 如何设计解决方案
提完需求的下一步,就是设计解决方案。也就是说,我们要设计编程思路,解决之前提出的需求。
设计编程思路解决需求,其实和“求解编程问题”类似。还记得我们之前的求解编程问题的5个步骤吗?
“为需求设计解决方案”其实就是另一种形式的“解编程题”,它们都需要明确目标、思考需要用到的知识、思考切入点、尝试一步步解决。
不过,“为需求设计解决方案”往往比“解编程题”更加复杂,也更加接近生活。为了让我们的思考过程更有结构,在这里我们需要用前面新学到的【流程图】。
第0关我给大家讲过一个小案例:我们公司的行政小姐姐,每个月都需要统计考勤,计算大家的迟到时长和迟到次数。但是这件事枯燥无味,显然是一个重复性劳动。
她要处理的考勤表长这样子:
所以,这里就产生了一个需求:
拿到这个需求,我们就可以制作第一张流程图,拆解、分析这项重复性工作是如何进行的:
在这里,使用流程图分析,可以让自己清晰地看到整个工作过程。这有助于我们接下来思考问题:哪些工作可以被程序替代?
我们知道,程序可以很容易地读写文件、处理信息(比如做计算),所以,在这个案例中,标黄的都可以比较方便地利用程序完成:
我们知道了要用程序去替代这些繁琐的步骤,接下来的任务就是【写出代码逻辑】。
首先我们可以优化一下流程图。比如标记颜色是为了方便人完成工作,机器并不需要这个步骤,用字典存储数据即可。
制作出“改良版流程图”后,我们就可以开始下一步:求解编程问题的5个步骤。
尝试实现代码的过程,是对我们已学知识的检验。但无可避免地会遇到一些卡点:
有些问题是以现有知识还无法解决的,这时需要我们根据需求自学、补充相应知识,我们可以把这些新知识当成进阶之路上的一个小目标,朝着它前进。
比如对于问题1和2,需要我们去自学新的模块(如openpyxl
)。当然,自学总会有坑,未来我们会出一门《自动化办公》的课程,提高你的学习效率。
在解决问题的过程中,你又会产生新的问题,但这都不要紧。相信我,你的编程能力就是在这一轮轮的循环中不断精进。
由于实现这个项目还需要讲解许多新知识,课堂上篇幅有限,老师在此就不做展开,主要感受一下制作“产品”的整体思路即可。
在下一关的最后一个实操项目,我会带着大家实现我司另外一个小姐姐——你很熟悉的助教酱酱自己做出来的的一个程序,主要运用到的是我们之前学过的知识,也算是作为对这门课的一个综合复习。
那么,用流程图总结一下刚刚我们谈论的这些内容,就可以得出产品设计的步骤了:
当然啦,这一关我们展示的【产品】看起来还非常简单,为了做出更高级,或者为更多人服务的程序,未来我们还需要学习更多技能,不断提升编程水平。
3. 习题练习
3.1 习题一
1.练习目标
我们会通过今天的作业,用代码解决生活中实际的一种需求:选择困难,需要帮忙。
2.练习要求
现今社会,每个人每天的生活都充满了各种各样的选择,导致许多人在选择面前纠结万分。
甚至,有不少人将“早饭吃什么?午饭吃什么?晚饭吃什么?”戏称为人生中的三大难题。
所以,我们今天的练习就会以“不知道吃什么”为例,让电脑来帮我们选,而我们只要做决策就好。
电脑推荐我们吃某种菜,我们拒绝后,它就继续推荐,直到我们满意为止。
3.根据生活经验,明确产品需求
为了让产品更好用,我们可以先分析一下问题,将产品需求(即功能)明确一下。
得出产品的三个功能:判断,随机推荐,特定选项中的随机推荐。
4.形成技术方案
明确了需求之后,我们就可以运用学过的知识来定技术方案,可得:
判断: 判断语句+input
随机推荐:random模块+循环+判断
特定选项的随机选项:列表添加+random模块+循环+判断
5.完成程序代码
请你独立在完成这个可称为“帮你做选择”的产品。
对了,你可以用今天学到的流程图帮自己梳理思路。
第一遍写代码时,可先不考虑函数或类,先让代码跑起来吧。
当然,写完之后。如果你发现有哪些可以优化的,也可大胆尝试。
# 帮你做选择之我要吃什么
import random
# 将需要用到的表格和变量放在开头
list_food = ['KFC', '蒸菜馆', '楼下快餐店', '桂林米粉', '东北饺子', '金牌猪脚饭', '三及第汤饭'] # 备选菜单,可自定义。
list_choice = []
# 由于两个原因都包含判断过程,所以,为了让代码更简洁,可将其封装成函数。
def choose(list):
while True:
food = random.choice(list)
judgement = input('去吃【%s】好不好啊?同意的话输入y,不想吃直接回车即可。'%(food))
if judgement == 'y':
print('去吃【%s】!就这么愉快地决定啦!'%(food))
break
# 判断环节
reason = int(input('你不知道吃什么的原因是:1.完全不知道吃什么;2.在几家店之间徘徊(请输入1或2):'))
if reason == 1:
choose(list_food)
elif reason == 2:
add = True
while add:
choice = input('请输入让你犹豫的店名(注:一家一家输,完成后输入y):')
if choice != 'y': # 这个判断语句,是为了不将 y 也添加到菜单里。
list_choice.append(choice)
if choice == 'y':
add = False
choose(list_choice)
else:
print('抱歉,目前还不支持第三种情况——不过,你可以加代码哦。')
3.2 习题二
1.练习目标
我们会通过今天的作业,用代码模拟一种现实中的场景:滚动的广告牌。
2.练习要求
实际生活中,有些广告牌是单行滚动的字体。
这个练习会通过新旧知识的结合,用Python实现对这种效果的模拟。
3.提出产品需求,形成技术方案
由于是练习,所以是没有让每个人根据自己的生活经验来提需求。
而是直接给定了产品需求:用Python代码模拟单行的滚动广告。
初步形成的技术方案是:print+字符串+循环+time模块(控制滚动速度)。
4.完成程序代码
为了让这种模拟和实际的更接近,补充一个模块中的方法。
请你试着运行右侧的代码,然后将其注释掉,再用代码完成对广告牌的模拟,广告词可以自己起。
对了,正常的滚动广告是无限循环的。不过,你可以在代码中设置循环次数,只要保证效果即可。
也可考虑将其封装成函数
import os, time
def main(): # 用函数封装,可复用性会高一些(可在其他的.py文件里调用该函数。)
content = '杨文博是一名运维 ' # 广告词可自定义。
for i in range(8):
# linux/os x系统【清除屏幕】代码(线上使用本代码)
os.system('clear') # 清屏和打印结合起来,形成滚动效果。
# windows系统【清除屏幕】代码
'''
os.system('cls')
'''
print(content)
content = content[1:] + content[0] # 这行代码相当于:将字符串中第一个元素移到了最后一个。
time.sleep(1) # 你可以改下时间,体会“循环周期”和“滚动速度”之间的关联。
if __name__ == '__main__': # 类里面学到的检测方法,在函数中其实也可以用。
main()