基础知识
一、函数
1.函数的定义与参数传递
先来创建一个最基本的函数吧
def study():
print('我爱学习编程')
study()
我们可以传递一些参数进去
def study(name,school):
print(f'我的名字叫做{name},我在{school}学习编程')
study('小明','海盐职教中心')
当然,参数应该按照顺序放进去,不信就试一下下面这段代码。
def study(name,school):
print(f'我的名字叫做{name},我在{school}学习编程')
study('海盐职教中心','小明')
我们也可以对参数进行指定,不按照顺序传递。
def study(name,school):
print(f'我的名字叫做{name},我在{school}学习编程')
study(school='海盐职教中心',name='小明')
还可以给参数设置默认的值
def study(name,school = '海盐职教中心'):
print(f'我的名字叫做{name},我在{school}学习编程')
study(name='小明')
默认参数的值是可以修改的
def study(name,school = '海盐职教中心'):
print(f'我的名字叫做{name},我在{school}学习编程')
study('小明','清华大学')
如果不确定参数的数量,我们可以设置一种特殊的不定长参数。
def study(name,school,*course):
print(f'我的名字叫做{name},我在{school}学习{course}')
study('小明','海盐商贸学校','编程','PS')
这种不定长参数会返回一种元组类型,如果你觉得不好看,我们可以用循环将其依次取出。
def study(name,school,*course):
for i in course:
print(f'我的名字叫做{name},我在{school}学习{i}')
study('小明','海盐商贸学校','编程','数学')
🐱🐉试一试,定义一个函数,要求把第一个参数设置为不定长参数。
看一下prints()函数的文档,第一个参数是不是就是不定长参数
print('我', '正在', '学习编程', sep = '+', end = '\n')
print('我', '正在', '学习编程', sep = '+', end = '\n')
2.函数的返回值
def wage(month):
if month < 3:
money = 5000 * month
else:
money = 6000 * month
return money
month = int(input('你工作了多少个月:'))
money = wage(month)
print(f"你的工资为{money}")
函数也可以返回多个值,但需要注意,不要依次写多个return,因为遇到第一个return,函数就结束了,后面的程序不会执行。
def wage(month):
bonus = 1000 * month
if month < 3:
money = 5000 * month
else:
money = 6000 * month
return money,bonus
month = int(input('你工作了多少个月:'))
money = wage(month)
print(money)
项目实战
一、任务需求
假设你是联合国主席兼世界首富,想要捐助你的母校海盐商贸学校若干箱鱼子酱,以改善同学们的伙食,但是买得少了不够吃,买得太多吃不完,过了保质期会造成浪费,所以需要一个程序来计算数量,计算方式有两种。
- 已知每位同学每月能够吃10箱鱼子酱。
- 计算方式1:时间计算
🐱👤例如输入10000箱鱼子酱、共有100位同学,程序帮我们计算出鱼子酱可以供同学们食用10个月。 - 计算方式2:人力计算
🐱👤例如输入10000箱鱼子酱,但是保质期只有两个月了,程序帮我们计算出至少需要找500位同学才能按时吃完。二、初始版本
# 已知每位同学每个月能吃完10箱鱼子酱 # 时间计算、已知有食堂买了多少箱鱼子酱,以及有多少位同学,计算鱼子酱供学生食用多少个月。 def JiSuan_month(yzj_num,student_num): month = yzj_num/(student_num*10) print(f"如果食堂采购了{yzj_num}箱鱼子酱,且有{student_num}位同学,那么鱼子酱课供学生食用{month}个月") # 人力计算、已知有食堂买了多少箱鱼子酱,以及鱼子酱的保质期,计算需要找多少位同学来吃,才能在保质期内按时吃完。 def JiSuan_student_num(yzj_num,month): student_num = yzj_num/(month*10) print(f"如果食堂采购了{yzj_num}箱鱼子酱,且保质期为{month}个月,至少需要找{student_num}位同学才能按时吃完") JiSuan_month(10000,200) #调用时间计算函数 JiSuan_student_num(10000,5) #调用人力计算函数
三、修复BUG
在使用一段时间之后,我们发现了一个bug,举例来说,当采购了10000箱鱼子酱,保质期为三个月,程序计算出需要至少找333.3个同学来吃才能够按时吃完,我们没有办法去找0.3位同学,所以这个时候可以向上取整。
向上取整我们可以使用math.ceil()函数,使用之前记得import。
#已知每位同学每个月能吃完10箱鱼子酱
import math
#时间计算、已知有食堂买了多少箱鱼子酱,以及有多少位同学,计算鱼子酱供学生食用多少个月。
def JiSuan_month(yzj_num,student_num):
month = yzj_num/(student_num*10)
print(f"如果食堂采购了{yzj_num}箱鱼子酱,且有{student_num}位同学,那么鱼子酱课供学生食用{month}个月")
#人力计算、已知有食堂买了多少箱鱼子酱,以及鱼子酱的保质期,计算需要找多少位同学来吃,才能在保质期内按时吃完。
def JiSuan_student_num(yzj_num,month):
student_num = math.ceil(yzj_num/(month*10))
print(f"如果食堂采购了{yzj_num}箱鱼子酱,且保质期为{month}个月,至少需要找{student_num}位同学才能按时吃完")
JiSuan_month(10000,200) #调用时间计算函数
JiSuan_student_num(10000,3) #调用人力计算函数
四、合并函数
现在程序已经没有BUG了,但是需要分别调用两个函数,比较麻烦,我们能不能想办法把两个函数合并为一个函数呢?
#已知每位同学每个月能吃完10箱鱼子酱
import math
def JiSuan(yzj_num,student_num=None,month=None):
# 时间计算、已知有食堂买了多少箱鱼子酱,以及有多少位同学,计算鱼子酱供学生食用多少个月。
if student_num != None and month == None:
month = yzj_num/(student_num*10)
print(f"如果食堂采购了{yzj_num}箱鱼子酱,且有{student_num}位同学,那么鱼子酱课供学生食用{month}个月")
# 人力计算、已知有食堂买了多少箱鱼子酱,以及鱼子酱的保质期,计算需要找多少位同学来吃,才能在保质期内按时吃完。
elif student_num == None and month != None:
student_num = math.ceil(yzj_num/(month*10))
print(f"如果食堂采购了{yzj_num}箱鱼子酱,且保质期为{month}个月,至少需要找{student_num}位同学才能按时吃完")
else:
print('函数参数设置有误')
JiSuan(1000,student_num=20)
JiSuan(1000,month=2)
JiSuan(1000)
JiSuan(1000,student_num=20,month=2)
五、增进体验
虽然现在函数的调用变简单了,但是对于用户来说还是太难了,因为这个程序只能是程序员会用,只有程序员才知道函数括号里的参数应该怎么填,应该怎么改。如果我们现在要交付给用户使用,应该如何改进呢?🤷♂️
#已知每位同学每个月能吃完10箱鱼子酱
import math
def JiSuan(yzj_num,student_num=None,month=None):
# 时间计算、已知有食堂买了多少箱鱼子酱,以及有多少位同学,计算鱼子酱供学生食用多少个月。
if student_num != None and month == None:
month = yzj_num/(student_num*10)
print(f"如果食堂采购了{yzj_num}箱鱼子酱,且有{student_num}位同学,那么鱼子酱课供学生食用{month}个月")
# 人力计算、已知有食堂买了多少箱鱼子酱,以及鱼子酱的保质期,计算需要找多少位同学来吃,才能在保质期内按时吃完。
elif student_num == None and month != None:
student_num = math.ceil(yzj_num/(month*10))
print(f"如果食堂采购了{yzj_num}箱鱼子酱,且保质期为{month}个月,至少需要找{student_num}位同学才能按时吃完")
else:
print('函数参数设置有误')
while True:
user_choice = input('请输入计算的类型(1、时间计算 2、人力计算):')
yzj_num = int(input('请输入食堂一共采购了多少箱鱼子酱:'))
if user_choice == '1':
student_num = int(input('请输入学生的数量:'))
JiSuan(yzj_num,student_num=student_num)
elif user_choice == '2':
month = int(input('请输入鱼子酱的保质期(月):'))
JiSuan(yzj_num,month=month)
else:
print('输入有误,请重新输入')
六、结构化设计
现在用户的确可以使用了,但是对于程序员来说,又不符合程序设计的结构性原则,不仅自己很难维护,别人也很难阅读,我们需要按照逻辑的划分对代码进行封装。
#已知每位同学每个月能吃完10箱鱼子酱
import math
def JiSuan(yzj_num,student_num=None,month=None):
# 时间计算、已知有食堂买了多少箱鱼子酱,以及有多少位同学,计算鱼子酱供学生食用多少个月。
if student_num != None and month == None:
month = yzj_num/(student_num*10)
print(f"如果食堂采购了{yzj_num}箱鱼子酱,且有{student_num}位同学,那么鱼子酱课供学生食用{month}个月")
# 人力计算、已知有食堂买了多少箱鱼子酱,以及鱼子酱的保质期,计算需要找多少位同学来吃,才能在保质期内按时吃完。
elif student_num == None and month != None:
student_num = math.ceil(yzj_num/(month*10))
print(f"如果食堂采购了{yzj_num}箱鱼子酱,且保质期为{month}个月,至少需要找{student_num}位同学才能按时吃完")
else:
print('函数参数设置有误')
#获取用户输入
def UserInput():
while True:
user_choice = input('请输入计算的类型(1、时间计算 2、人力计算):')
if user_choice == '1':
yzj_num = int(input('请输入食堂一共采购了多少箱鱼子酱:'))
student_num = int(input('请输入学生的数量:'))
month = None
break
elif user_choice == '2':
yzj_num = int(input('请输入食堂一共采购了多少箱鱼子酱:'))
month = int(input('请输入鱼子酱的保质期(月):'))
student_num = None
break
else:
print('输入有误,请重新输入')
return yzj_num,student_num,month
while True:
user_input = UserInput()
yzj_num = user_input[0]
student_num = user_input[1]
month = user_input[2]
JiSuan(yzj_num=yzj_num,student_num=student_num,month=month)
大功告成😁😍😁,是不是一个看似很简单的程序,但是程序设计的流程其实是很严谨的,我希望我们可以通过一个简单的程序,去体会程序开发的思想。