函数 | 自在学
函数
函数是编程世界中的重要概念,它就像是一个可重复使用的代码块,专门设计来完成特定的任务。
当我们需要执行某个特定操作时,只需要调用对应的函数即可,而不必重复编写相同的代码。
在实际编程中,函数扮演着至关重要的角色。无论是简单的数据处理,还是复杂的业务逻辑,我们都可以通过函数来组织和管理代码。
通过合理地划分功能模块,程序的结构将变得更加清晰,调试和修改也会变得更加容易。
这节课我们将探讨Python中函数的定义、调用、参数传递、返回值处理等核心概念,帮助你构建模块化的程序设计思维。
函数的定义
函数的本质是将一系列相关的操作封装在一起,形成一个独立的功能单元。这种封装思想不仅体现了程序设计的模块化原则,也为代码的重用奠定了基础。
当我们定义一个函数时,实际上是在创建一个可以被反复调用的代码模板。
函数定义的基本语法
在Python中,函数的定义使用def关键字,这个关键字告诉Python解释器我们即将定义一个新函数。让我们通过一个简单的例子来理解函数的基本结构:
def welcome_student ():
"""显示欢迎信息给学生"""
print ( "欢迎来到Python编程世界!" )
welcome_student()
这个例子展示了函数定义的基本要素。def关键字后跟函数名welcome_student,随后是一对圆括号,最后以冒号结束。函数名的选择应该具有描述性,能够清楚地表达函数的功能。圆括号用于容纳参数信息,即使函数不需要参数,圆括号也是必需的。
函数体由缩进的代码块组成,这些代码定义了函数被调用时要执行的具体操作。在这个例子中,函数的功能很简单——输出一条欢迎信息。三重引号包围的字符串是文档字符串(docstring),用于描述函数的功能,这是良好编程习惯的体现。
当我们调用这个函数时,只需要写出函数名并加上圆括号即可。Python会执行函数体内的代码,输出相应的信息。
向函数传递信息
函数的真正力量在于它能够接收外部信息并据此执行相应的操作。通过参数机制,我们可以让同一个函数处理不同的数据,从而大大提高代码的灵活性和重用性。
def greet_student (student_name):
"""向指定学生显示个性化问候"""
print ( f "你好, { student_name } 同学!欢迎学习Python编程。" )
greet_student( "小明" )
greet_student( "小红" )
在这个改进的版本中,函数greet_student接受一个参数student_name。当我们调用函数时,传入的具体值(如小明或"小红")会被赋给这个参数,函数随后使用这个值来生成个性化的问候信息。
函数的设计理念是通用性与特殊性的结合。函数的逻辑结构是通用的,但通过不同的参数值,它可以产生特殊化的结果。
在函数的使用过程中,经常会遇到参数和实参这两个概念:
参数(parameter)是函数定义时声明的变量,它们是函数接收信息的占位符。在上面的例子中,student_name就是一个参数。参数定义了函数期望接收什么样的信息,以及这些信息在函数内部如何被引用。
实参(argument)则是函数调用时实际传递给函数的具体值。当我们调用greet_student("小明")时,字符串"小明"就是一个实参。实参是参数的具体化,它们为函数的执行提供了必要的数据。
参数传递的多种方式
Python提供了多种参数传递方式,每种方式都有其适用的场景和优势。掌握这些不同的传递方式,能够让我们写出更加灵活和易用的函数。
位置参数的使用
位置参数是最直观的参数传递方式,它要求实参的传递顺序与函数定义中参数的声明顺序完全一致。这种方式的优点是简洁直观,缺点是对参数顺序有严格要求。
def introduce_course (course_name, instructor_name, duration):
"""介绍课程信息"""
print ( f "课程名称: { course_name } " )
print ( f "授课教师: { instructor_name } " )
print ( f "课程时长: { duration } 小时" )
introduce_course( "Python编程基础" , "张老师" , 40 )
在这个例子中,函数调用时必须按照课程名称、教师姓名、课程时长的顺序传递参数。如果顺序颠倒,就可能产生意想不到的结果。
当我们需要重复调用函数处理不同的数据时,位置参数表现出了良好的效率。每次调用只需要按顺序提供相应的值即可,代码简洁明了。
关键字参数的优势
关键字参数通过明确指定参数名称和对应的值来传递信息,这种方式消除了对参数顺序的依赖,让函数调用更加清晰和安全。
def register_student (student_id, name, major, grade):
"""注册学生信息"""
print ( f "学号: { student_id } " )
print ( f "姓名: { name } " )
print ( f "专业: { major } " )
print ( f "年级: { grade } " )
# 使用关键字参数,顺序可以灵活调整
关键字参数的最大优势在于它提高了代码的可读性和安全性。当函数有多个参数时,使用关键字参数可以让代码的意图更加明确,也避免了因参数顺序错误而导致的问题。
默认参数值的设计
默认参数值是一种优雅的设计模式,它允许某些参数在函数调用时可以省略。这种机制让函数既能处理简单的调用场景,也能应对复杂的定制需求。
def create_profile (name, age, city = "北京" , occupation = "学生" ):
"""创建用户档案"""
profile = f " { name } , { age } 岁,来自 { city } ,职业是 { occupation } "
return profile
# 使用默认值的简单调用
print (create_profile( "王小明" , 20 ))
# 覆盖部分默认值
设计默认参数值时,我们需要将最常用的值设置为默认值,同时确保有默认值的参数位于参数列表的末尾。这样的设计让函数既简单易用,又保持了足够的灵活性。
函数调用的等价形式
由于Python支持多种参数传递方式,同一个函数往往可以用多种等价的形式来调用。理解这种等价性有助于我们选择最适合特定情况的调用方式。
def order_book (title, price, category = "编程" , is_new = True ):
"""订购图书"""
status = "新书" if is_new else "二手书"
print ( f "订购 { category } 类 { status } :《 { title } 》,价格: { price } 元" )
# 以下调用方式都是等价的
order_book( "Python入门"
选择合适的调用方式取决于具体的使用场景。当参数较少且含义明确时,位置参数更简洁;当参数较多或含义可能不够清晰时,关键字参数更安全。
Python 参数传递演示
返回值的处理与应用
函数不仅能够执行操作,还能够返回结果。返回值机制让函数能够将处理后的数据传递给调用者,这是构建复杂程序逻辑的基础。通过返回值,我们可以将程序的计算任务分解到不同的函数中,让每个函数专注于特定的数据处理任务。
简单返回值的使用
最基本的返回值形式是返回单个数据。这种模式适用于大多数的数据处理和计算场景。
def calculate_total_score (chinese, math, english):
"""计算三科总分"""
total = chinese + math + english
return total
def calculate_average_score (chinese, math, english):
"""计算三科平均分"""
total = calculate_total_score(chinese, math, english)
average = total / 3
return round (average, 2 )
# 使用函数进行成绩计算
student_total = calculate_total_score( 95 ,
这个例子展示了函数如何通过返回值来传递计算结果。calculate_total_score函数处理基础的加法计算,而calculate_average_score函数则在前者的基础上进一步计算平均值。这种分层设计让代码逻辑更加清晰,也提高了代码的重用性。
可选参数的高级应用
在实际应用中,函数往往需要处理可选的输入信息。通过巧妙地使用默认参数值,我们可以设计出既灵活又易用的函数接口。
def format_name (first_name, last_name, middle_name = "" ):
"""格式化姓名,中间名为可选"""
if middle_name:
full_name = f " { last_name } { first_name } { middle_name } "
else :
full_name = f " { last_name } { first_name } "
return full_name.title()
# 处理只有姓和名的情况
这种设计模式在处理用户数据时特别有用,因为现实世界中的数据往往是不完整或不统一的。通过可选参数,函数能够优雅地处理这些变化。
返回复杂数据结构
函数不仅可以返回简单的数值或字符串,还可以返回列表、字典等复杂的数据结构。这种能力让函数能够处理更加复杂的数据组织和处理任务。
def analyze_student_data (name, scores):
"""分析学生成绩数据"""
total_score = sum (scores)
average_score = total_score / len (scores)
max_score = max (scores)
min_score = min (scores)
# 返回包含多种分析结果的字典
analysis_result = {
'name' : name,
'total' : total_score,
'average' : round (average_score, 2 ),
通过返回字典,函数能够同时提供多种分析结果,调用者可以根据需要选择使用其中的任何信息。这种模式在数据分析和报告生成中特别常见。
列表与函数的协作
列表作为Python中最重要的数据结构之一,与函数的结合使用能够产生强大的数据处理能力。理解如何在函数中有效地处理列表,是编写实用程序的重要技能。
向函数传递列表
当我们需要对一组相关数据进行批量处理时,将列表传递给函数是最自然的选择。函数可以通过循环来处理列表中的每个元素,实现高效的批量操作。
def print_course_list (courses):
"""打印课程清单"""
print ( "本学期课程安排:" )
for i, course in enumerate (courses, 1 ):
print ( f " { i } . { course } " )
def calculate_study_hours (course_hours):
"""计算总学习时间"""
total_hours = sum (course_hours)
average_hours = total_hours
这个例子展示了函数如何处理不同类型的列表数据。通过将数据组织成列表并传递给专门的处理函数,我们可以构建出清晰而高效的数据处理流程。
函数对列表的修改
当函数接收到列表参数时,它实际上获得了对原始列表的引用。这意味着函数内部对列表的修改会直接影响到原始数据。理解这一点对于正确使用函数处理列表数据至关重要。
def process_task_queue (pending_tasks, completed_tasks):
"""处理任务队列,将待处理任务移动到完成列表"""
print ( "开始处理任务..." )
while pending_tasks:
current_task = pending_tasks.pop( 0 ) # 取出第一个任务
print ( f "正在处理: { current_task } " )
completed_tasks.append(current_task) # 添加到完成列表
print ( "所有任务处理完成!" )
def show_task_status (pending, completed):
这个例子模拟了一个任务处理系统,展示了函数如何通过修改列表来管理数据状态的变化。理解函数与列表之间的这种关系,有助于我们设计出更加高效的数据处理算法。
保护原始数据的策略
在某些情况下,我们希望函数能够处理列表数据,但又不想改变原始列表。Python提供了列表切片的机制来创建列表的副本,这样可以在保护原始数据的同时进行必要的处理。
def analyze_score_distribution (scores):
"""分析成绩分布,不修改原始数据"""
# 创建分数列表的副本进行排序
sorted_scores = sorted (scores) # sorted()函数创建新列表
# 计算各种统计信息
total_students = len (sorted_scores)
median_score = sorted_scores[total_students // 2 ]
# 分析分数段分布
excellent = sum ( 1 for score in scores if score >= 90 )
这种数据保护策略在处理重要数据时特别有用,它让我们既能进行复杂的数据分析,又能确保原始数据的完整性。
列表引用与副作用实验室
可变参数的高级应用
在实际编程中,我们经常遇到需要处理不确定数量参数的情况。Python提供了灵活的可变参数机制,让函数能够适应各种不同的调用需求。
任意数量位置参数的处理
使用星号(*)前缀的参数可以接收任意数量的位置参数,这些参数会被自动组织成元组形式。这种机制特别适合于需要处理数量不定的同类型数据的场景。
def calculate_statistics ( * numbers):
"""计算一组数字的统计信息"""
if not numbers:
print ( "没有提供数据" )
return
count = len (numbers)
total = sum (numbers)
average = total / count
maximum = max (numbers)
minimum = min (numbers)
print
混合参数类型的函数设计
在复杂的函数设计中,我们可能需要同时使用固定参数和可变参数。这种设计需要注意参数的排列顺序,确保Python能够正确地解析参数。
def generate_report (title, author, * content_sections, ** metadata):
"""生成报告文档"""
print ( f "报告标题: { title } " )
print ( f "作者: { author } " )
print ( "=" * 40 )
# 处理内容章节
for i, section in enumerate (content_sections, 1 ):
任意关键字参数的应用
双星号(**)前缀的参数可以接收任意数量的关键字参数,这些参数会被组织成字典形式。这种机制在构建灵活的配置系统或用户资料系统时特别有用。
def create_student_profile (name, student_id, ** additional_info):
"""创建学生档案,支持任意额外信息"""
profile = {
'name' : name,
'student_id' : student_id
}
# 添加额外信息
profile.update(additional_info)
print ( f "学生档案: { name } (学号: { student_id } )" )
print ( "-" * 30 )
模块化编程与函数组织
随着程序规模的增长,将所有代码放在单一文件中会变得难以管理。模块化编程通过将相关函数组织到独立的文件中,提供了更好的代码组织方式。这种方法不仅提高了代码的可维护性,还促进了代码的重用。
创建和使用模块
模块是包含Python代码的文件,通常以.py为扩展名。通过将相关功能的函数组织到同一个模块中,我们可以构建出结构清晰的程序系统。
# 假设这是 student_utils.py 模块的内容
def calculate_gpa (grades, credits):
"""计算学分绩点"""
if len (grades) != len ( credits ):
return None
total_points = sum (grade * credit for grade, credit in zip (grades, credits ))
total_credits = sum ( credits )
return round (total_points
模块导入的不同方式
Python提供了多种导入模块的方式,每种方式都有其适用场景。选择合适的导入方式可以让代码更加清晰和高效。
# 方式一:导入整个模块
import student_utils
# 使用模块中的函数
gpa = student_utils.calculate_gpa([ 85 , 90 , 88 ], [ 3 , 4 , 3 ])
info = student_utils.format_student_info( "张三" , "2024001" , "计算机科学" , gpa)
# 方式二:导入特定函数
from student_utils import calculate_gpa, format_student_info
# 直接使用函数名
gpa = calculate_gpa([ 85
模块化设计的最佳实践
良好的模块化设计需要遵循一定的原则,这些原则有助于创建易于理解和维护的代码结构。
# 数学计算模块 (math_tools.py)
def calculate_factorial (n):
"""计算阶乘"""
if n < 0 :
return None
if n <= 1 :
return 1
return n * calculate_factorial(n - 1 )
def is_prime (n):
"""判断是否为质数"""
if n < 2 :
return False
for
函数设计的最佳实践
编写高质量的函数需要遵循一些重要的设计原则。这些原则不仅能提高代码的可读性和可维护性,还能减少出错的可能性。
函数命名与文档规范
良好的函数命名应该能够清晰地表达函数的功能,而完善的文档则为函数的使用提供了必要的说明。
def analyze_student_performance (scores, passing_grade = 60 ):
"""
分析学生成绩表现
参数:
scores (list): 学生各科成绩列表
passing_grade (int): 及格分数线,默认为60分
返回:
dict: 包含分析结果的字典,包括:
- total_subjects: 总科目数
- passed_subjects: 及格科目数
- average_score: 平均分
- performance_level: 表现等级
示例:
>>> scores = [85, 78, 92, 67, 89]
>>> result = analyze_student_performance(scores)
>>> print(result['performance_level'])
良好
"""
错误处理与参数验证
健壮的函数应该能够妥善处理各种异常情况,并提供清晰的错误信息。参数验证是确保函数正确运行的重要环节。
def calculate_course_grade (assignments, exams, participation, weights = None ):
"""
计算课程总成绩
参数:
assignments (list): 作业成绩列表
exams (list): 考试成绩列表
participation (float): 课堂参与分数
weights (dict): 权重配置,默认为平均权重
"""
# 参数验证
if not isinstance (assignments, list ) or not assignments:
raise ValueError ( "作业成绩必须是非空列表" )
if not isinstance (exams,
函数的单一职责原则
每个函数都应该专注于完成一个特定的任务,这样的设计让代码更容易理解、测试和维护。当一个函数试图做太多事情时,我们应该考虑将其拆分成多个更小、更专注的函数。
def load_student_data (filename):
"""从文件加载学生数据"""
try :
students = []
with open (filename, 'r' , encoding = 'utf-8' ) as file :
for line in file :
parts = line.strip().split( ',' )
if len (parts) >= 3 :
student =
通过将复杂的任务分解成多个简单的函数,我们创建了一个结构清晰、易于维护的程序。每个函数都有明确的职责,可以独立地进行测试和修改。
习题
A. def
B. function
C. create
D. make
A. return
B. give
C. send
D. output
A. 位置参数
B. 关键字参数
C. 默认参数
D. 以上都可以
A. *args
B. **kwargs
C. *params
D. **args
A. 文档字符串
B. 注释
C. 函数说明
D. 帮助文档
A. True
B. False
C. 取决于参数类型
D. 取决于函数设计
8. 函数定义和默认参数
编写一个函数,计算面积,其中height为可选参数(默认值为1)。
def calculate_area (length, width, height = 1 ):
"""计算面积,height为可选参数"""
return length * width * height
# 调用函数
area1 = calculate_area( 5 , 3 ) # 使用默认height
print ( f "面积1: { area1 } " ) # 输出:面积1:15
area2 = calculate_area( 5 , 3 , height
9. 可变参数函数
编写一个函数,接收任意数量的参数,找出所有参数中的最大值。
def find_maximum ( * numbers):
"""找出所有参数中的最大值"""
if not numbers:
return None
return max (numbers)
# 调用示例
result1 = find_maximum( 3 , 7 , 2 , 9 , 1 )
print ( f "最大值1: { result1 } " ) # 输出:最大值1:9
result2
10. 图书管理函数
编写一个图书管理函数,接受书名、作者、价格三个参数(价格有默认值30),返回包含图书信息的字典。
def manage_books (title, author, price = 30 ):
"""管理图书信息
参数:
title: 书名
author: 作者
price: 价格(默认30)
返回:
包含图书信息的字典
"""
book_info = {
'title' : title,
'author' : author,
'price' : price
}
return book_info
# 调用示例 - 使用默认价格
book1 = manage_books( "Python编程"
register_student( name = "李小华" , student_id = "2023001" , grade = "大一" , major = "计算机科学" )
print (create_profile( "张小丽" , 22 , city = "上海" ))
# 覆盖所有默认值
print (create_profile( "陈小华" , 25 , city = "深圳" , occupation = "工程师" ))
,
58
)
order_book( title = "Python入门" , price = 58 )
order_book( "Python入门" , 58 , category = "编程" , is_new = True )
order_book( price = 58 , title = "Python入门" , is_new = True , category = "编程" )
87
,
92
)
student_average = calculate_average_score( 95 , 87 , 92 )
print ( f "总分: { student_total } 分" )
print ( f "平均分: { student_average } 分" )
name1
=
format_name(
"小明"
,
"王"
)
print (name1)
# 处理包含中间名的情况
name2 = format_name( "德华" , "刘" , middle_name = "志" )
print (name2)
'highest' : max_score,
'lowest' : min_score,
'subject_count' : len (scores)
}
return analysis_result
# 分析学生成绩
student_scores = [ 88 , 92 , 85 , 96 , 79 ]
result = analyze_student_data( "张小明" , student_scores)
print ( f "学生: { result[ 'name' ] } " )
print ( f "总分: { result[ 'total' ] } 分" )
print ( f "平均分: { result[ 'average' ] } 分" )
print ( f "最高分: { result[ 'highest' ] } 分" )
print ( f "最低分: { result[ 'lowest' ] } 分" )
/
len
(course_hours)
print ( f "总学习时间: { total_hours } 小时" )
print ( f "平均每门课程: { average_hours :.1f } 小时" )
return total_hours
# 课程数据
my_courses = [ "Python编程" , "数据结构" , "数据库原理" , "Web开发" ]
hours_per_course = [ 40 , 56 , 48 , 64 ]
print_course_list(my_courses)
print ()
total_study_time = calculate_study_hours(hours_per_course)
"""显示任务状态"""
print ( f "待处理任务: {len (pending) } 个" )
print ( f "已完成任务: {len (completed) } 个" )
if completed:
print ( "已完成的任务:" , " | " .join(completed))
# 任务数据
pending_tasks = [ "编写文档" , "代码测试" , "功能优化" , "部署系统" ]
completed_tasks = []
print ( "处理前的状态:" )
show_task_status(pending_tasks, completed_tasks)
print ()
process_task_queue(pending_tasks, completed_tasks)
print ()
print ( "处理后的状态:" )
show_task_status(pending_tasks, completed_tasks)
good = sum ( 1 for score in scores if 80 <= score < 90 )
fair = sum ( 1 for score in scores if 70 <= score < 80 )
poor = sum ( 1 for score in scores if score < 70 )
print ( f "参与学生: { total_students } 人" )
print ( f "中位数成绩: { median_score } 分" )
print ( f "优秀(90+): { excellent } 人" )
print ( f "良好(80-89): { good } 人" )
print ( f "一般(70-79): { fair } 人" )
print ( f "需要改进(<70): { poor } 人" )
# 测试数据保护
class_scores = [ 85 , 92 , 78 , 88 , 95 , 73 , 82 , 90 , 87 , 94 ]
print ( "原始成绩单:" , class_scores)
print ()
analyze_score_distribution(class_scores)
print ()
print ( "分析后的原始数据:" , class_scores) # 确认原始数据未被修改
(
f
"数据个数:
{
count
}
"
)
print ( f "总和: { total } " )
print ( f "平均值: { average :.2f } " )
print ( f "最大值: { maximum } " )
print ( f "最小值: { minimum } " )
return {
'count' : count,
'sum' : total,
'average' : average,
'max' : maximum,
'min' : minimum
}
# 可以传递任意数量的参数
print ( "单科成绩统计:" )
calculate_statistics( 85 )
print ()
print ( "多科成绩统计:" )
calculate_statistics( 85 , 92 , 78 , 90 , 88 )
print ()
print ( "全班成绩统计:" )
calculate_statistics( 85 , 92 , 78 , 90 , 88 , 95 , 83 , 87 , 91 , 89 )
print ( f "第 { i } 章: { section } " )
print ( "=" * 40 )
# 处理元数据
if metadata:
print ( "报告信息:" )
for key, value in metadata.items():
print ( f " { key } : { value } " )
# 生成学习报告
generate_report(
"Python学习进度报告" ,
"张小明" ,
"基础语法学习" ,
"数据结构掌握" ,
"项目实践经验" ,
date = "2024年1月" ,
duration = "3个月" ,
level = "初级"
)
for key, value in profile.items():
if key not in [ 'name' , 'student_id' ]:
print ( f " { key } : { value } " )
return profile
# 创建不同详细程度的学生档案
profile1 = create_student_profile(
"李小华" ,
"2024001" ,
major = "计算机科学" ,
grade = "大一" ,
phone = "13800138000"
)
print ()
profile2 = create_student_profile(
"王小明" ,
"2024002" ,
major = "软件工程" ,
grade = "大二" ,
hometown = "北京" ,
hobby = "编程" ,
gpa = 3.85
)
/
total_credits,
2
)
if
total_credits
>
0
else
0
def format_student_info (name, student_id, major, gpa):
"""格式化学生信息显示"""
return f " { name } ( { student_id } )- { major } 专业,GPA: { gpa } "
def generate_transcript (student_name, courses_data):
"""生成成绩单"""
print ( f " { student_name } 的成绩单" )
print ( "=" * 40 )
total_credits = 0
for course, grade, credit in courses_data:
print ( f " { course } : { grade } 分( { credit } 学分)" )
total_credits += credit
print ( "=" * 40 )
print ( f "总学分: { total_credits } " )
,
90
,
88
], [
3
,
4
,
3
])
info = format_student_info( "张三" , "2024001" , "计算机科学" , gpa)
# 方式三:使用别名
from student_utils import calculate_gpa as calc_gpa
import student_utils as utils
# 使用别名调用
gpa = calc_gpa([ 85 , 90 , 88 ], [ 3 , 4 , 3 ])
info = utils.format_student_info( "张三" , "2024001" , "计算机科学" , gpa)
i
in
range
(
2
,
int
(n
**
0.5
)
+
1
):
if n % i == 0 :
return False
return True
def fibonacci_sequence (n):
"""生成斐波那契数列"""
if n <= 0 :
return []
elif n == 1 :
return [ 0 ]
elif n == 2 :
return [ 0 , 1 ]
sequence = [ 0 , 1 ]
for i in range ( 2 , n):
sequence.append(sequence[i - 1 ] + sequence[i - 2 ])
return sequence
# 主程序文件使用模块
from math_tools import calculate_factorial, is_prime, fibonacci_sequence
def demonstrate_math_tools ():
"""演示数学工具的使用"""
print ( "数学工具演示" )
print ( "=" * 30 )
# 阶乘计算
n = 5
factorial_result = calculate_factorial(n)
print ( f " { n } 的阶乘: { factorial_result } " )
# 质数判断
numbers = [ 17 , 25 , 29 , 30 ]
print ( "质数判断:" )
for num in numbers:
result = "是" if is_prime(num) else "不是"
print ( f " { num } { result } 质数" )
# 斐波那契数列
fib_count = 10
fib_sequence = fibonacci_sequence(fib_count)
print ( f "前 { fib_count } 项斐波那契数列:" )
print ( " " + " " .join( map ( str , fib_sequence)))
if __name__ == "__main__" :
demonstrate_math_tools()
if
not
scores:
return { "error" : "成绩数据不能为空" }
total_subjects = len (scores)
passed_subjects = sum ( 1 for score in scores if score >= passing_grade)
average_score = sum (scores) / total_subjects
# 确定表现等级
if average_score >= 90 :
performance_level = "优秀"
elif average_score >= 80 :
performance_level = "良好"
elif average_score >= 70 :
performance_level = "一般"
elif average_score >= passing_grade:
performance_level = "及格"
else :
performance_level = "不及格"
return {
"total_subjects" : total_subjects,
"passed_subjects" : passed_subjects,
"average_score" : round (average_score, 2 ),
"performance_level" : performance_level,
"passing_rate" : round (passed_subjects / total_subjects * 100 , 1 )
}
# 使用示例
student_scores = [ 85 , 78 , 92 , 67 , 89 , 94 , 73 ]
analysis = analyze_student_performance(student_scores)
print ( "学生成绩分析报告:" )
print ( f "总科目数: { analysis[ 'total_subjects' ] } " )
print ( f "及格科目数: { analysis[ 'passed_subjects' ] } " )
print ( f "平均分: { analysis[ 'average_score' ] } " )
print ( f "及格率: { analysis[ 'passing_rate' ] } %" )
print ( f "表现等级: { analysis[ 'performance_level' ] } " )
list
)
or
not
exams:
raise ValueError ( "考试成绩必须是非空列表" )
if not isinstance (participation, ( int , float )) or not ( 0 <= participation <= 100 ):
raise ValueError ( "课堂参与分数必须是0-100之间的数值" )
# 检查成绩范围
all_scores = assignments + exams + [participation]
if any (score < 0 or score > 100 for score in all_scores):
raise ValueError ( "所有成绩必须在0-100分之间" )
# 设置默认权重
if weights is None :
weights = {
'assignments' : 0.4 ,
'exams' : 0.5 ,
'participation' : 0.1
}
# 验证权重
weight_sum = sum (weights.values())
if abs (weight_sum - 1.0 ) > 0.001 : # 允许小的浮点误差
raise ValueError ( f "权重总和必须为1,当前为 { weight_sum } " )
# 计算各部分成绩
avg_assignments = sum (assignments) / len (assignments)
avg_exams = sum (exams) / len (exams)
# 计算加权总成绩
final_grade = (
avg_assignments * weights[ 'assignments' ] +
avg_exams * weights[ 'exams' ] +
participation * weights[ 'participation' ]
)
return {
'assignments_avg' : round (avg_assignments, 2 ),
'exams_avg' : round (avg_exams, 2 ),
'participation' : participation,
'final_grade' : round (final_grade, 2 ),
'letter_grade' : get_letter_grade(final_grade)
}
def get_letter_grade (score):
"""将数字成绩转换为等级"""
if score >= 90 :
return 'A'
elif score >= 80 :
return 'B'
elif score >= 70 :
return 'C'
elif score >= 60 :
return 'D'
else :
return 'F'
# 使用示例与错误处理
try :
# 正常使用
result = calculate_course_grade(
assignments = [ 85 , 90 , 78 , 92 ],
exams = [ 88 , 85 ],
participation = 95 ,
weights = { 'assignments' : 0.3 , 'exams' : 0.6 , 'participation' : 0.1 }
)
print ( "课程成绩计算结果:" )
print ( f "作业平均分: { result[ 'assignments_avg' ] } " )
print ( f "考试平均分: { result[ 'exams_avg' ] } " )
print ( f "课堂参与: { result[ 'participation' ] } " )
print ( f "最终成绩: { result[ 'final_grade' ] } ( { result[ 'letter_grade' ] } )" )
except ValueError as e:
print ( f "输入错误: { e } " )
except Exception as e:
print ( f "计算过程中发生错误: { e } " )
{
'name' : parts[ 0 ],
'student_id' : parts[ 1 ],
'scores' : [ float (score) for score in parts[ 2 :]]
}
students.append(student)
return students
except FileNotFoundError :
print ( f "文件 { filename } 不存在" )
return []
except Exception as e:
print ( f "读取文件时发生错误: { e } " )
return []
def calculate_student_statistics (student_data):
"""计算单个学生的统计信息"""
scores = student_data[ 'scores' ]
if not scores:
return None
return {
'name' : student_data[ 'name' ],
'student_id' : student_data[ 'student_id' ],
'average' : round ( sum (scores) / len (scores), 2 ),
'highest' : max (scores),
'lowest' : min (scores),
'total_courses' : len (scores)
}
def generate_class_report (students_data):
"""生成班级报告"""
if not students_data:
print ( "没有学生数据" )
return
print ( "班级成绩报告" )
print ( "=" * 50 )
all_statistics = []
class_averages = []
for student in students_data:
stats = calculate_student_statistics(student)
if stats:
all_statistics.append(stats)
class_averages.append(stats[ 'average' ])
# 显示个人成绩
for stats in all_statistics:
print ( f " { stats[ 'name' ] } ( { stats[ 'student_id' ] } ):" )
print ( f " 平均分: { stats[ 'average' ] } " )
print ( f " 最高分: { stats[ 'highest' ] } " )
print ( f " 最低分: { stats[ 'lowest' ] } " )
print ( f " 科目数: { stats[ 'total_courses' ] } " )
print ()
# 显示班级统计
if class_averages:
print ( "班级总体情况:" )
print ( f " 班级平均分: {round ( sum (class_averages) / len (class_averages), 2 ) } " )
print ( f " 最高平均分: {max (class_averages) } " )
print ( f " 最低平均分: {min (class_averages) } " )
print ( f " 学生总数: {len (all_statistics) } " )
def main ():
"""主程序函数"""
# 模拟数据(实际使用时从文件读取)
sample_data = [
{ 'name' : '张小明' , 'student_id' : '2024001' , 'scores' : [ 85 , 90 , 78 , 92 ]},
{ 'name' : '李小红' , 'student_id' : '2024002' , 'scores' : [ 88 , 85 , 91 , 87 ]},
{ 'name' : '王小华' , 'student_id' : '2024003' , 'scores' : [ 92 , 89 , 94 , 90 ]}
]
generate_class_report(sample_data)
if __name__ == "__main__" :
main()
=
2
)
# 指定height
print ( f "面积2: { area2 } " ) # 输出:面积2:30
height=1是默认参数,如果调用时不提供height的值,会使用默认值1
第一个调用只提供了length和width,height使用默认值1
第二个调用使用关键字参数height=2明确指定了height的值
=
find_maximum(
15
,
8
,
23
)
print ( f "最大值2: { result2 } " ) # 输出:最大值2:23
result3 = find_maximum()
print ( f "最大值3: { result3 } " ) # 输出:最大值3:None
*numbers表示接收任意数量的位置参数,所有参数会被收集到numbers元组中
if not numbers:检查是否传入了参数,如果没有参数则返回None
max(numbers)使用内置函数max找出元组中的最大值
,
"张三"
)
print ( f "图书1: { book1 } " )
# 调用示例 - 指定价格
book2 = manage_books( "Java入门" , "李四" , price = 45 )
print ( f "图书2: { book2 } " )
# 调用示例 - 使用关键字参数
book3 = manage_books( author = "王五" , title = "数据结构" , price = 50 )
print ( f "图书3: { book3 } " )
图书1: { ' title ': ' Python编程 ', ' author ': ' 张三 ', ' price ': 30}
图书2:{' title ': ' Java入门 ', ' author ': ' 李四 ', ' price ': 45}
图书3:{' title ': ' 数据结构 ', ' author ': ' 王五 ', ' price ': 50}
函数接受三个参数,其中price有默认值30
函数返回一个包含图书信息的字典
展示了三种不同的参数传递方式:位置参数、部分关键字参数、全部关键字参数