Python基础语法3—鱼子酱要买多少?


基础知识

一、函数

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)

大功告成😁😍😁,是不是一个看似很简单的程序,但是程序设计的流程其实是很严谨的,我希望我们可以通过一个简单的程序,去体会程序开发的思想。


文章作者: 彭韦浩
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 彭韦浩 !
  目录