Python五天极限复习
Day 0: Python 课程概览与环境安装
1. 课程基本信息
- 课程名称: Preparatory Training in Computer Programming (Python)
- 课程目标:
- 重温计算机编程的基础概念
- 通过 Python 体验如何利用编程进行数据分析和解决问题
2. 课程内容安排
天数 | 主题 |
---|---|
0 | 课程概览和环境搭建 (Overview and Setup the Environment) |
1 | 基础知识: 变量、条件语句 (Basics: Variables, Conditional Statements) |
2 | 循环与数据结构: While & For 循环, 列表 (Looping & Data Structure: While & For Loops, Lists) |
3 | 函数: 定义、变量作用域 (Function: def, Scope of Variables) |
4 | 文件与可视化: 文件输入输出、图表绘制 (File & Visualization: File I&O, Graph Plotting) |
5 | 应用: 包、金融数据分析 + 小测验 (Application: Packages, Financial Data Analysis + Quiz) |
3. Python 简介与应用
- 官方网站: www.python.org
4. 编程环境搭建
4.1. 所需组件
搭建一个Python编程环境需要以下三个核心组件:
- Python 解释器 (Python Interpreter)
- 集成开发环境 (IDE)
- 包 (Packages)
本课程推荐的组合是 Python + PyCharm
4.2. Python 安装步骤
- 下载: 从官网 https://www.python.org/downloads/ 下载最新的 3.x.x 版本
- 安装:
- 运行下载好的
.exe
文件 - 非常重要: 在安装界面,务必勾选 “Add Python 3.X to PATH” 选项
- 运行下载好的
4.3. PyCharm 安装步骤
- 定义: PyCharm 是一个专为 Python 设计的集成开发环境 (IDE)
- 下载: 从官网 https://www.jetbrains.com/pycharm/download/ 下载
- 安装:
- 运行下载好的
.exe
文件 - 根据安装向导,持续点击 “Next” 完成安装
- 运行下载好的
5. 第一个 Python 程序:基本输入与输出
5.1. 核心函数
print()
: 用于将数据输出到控制台input()
: 用于从键盘获取用户输入
5.2. 代码示例
-
简单输出:
# Simple output using print() print("hello world !!") print("I hate study" + "code") #当您向 print() 传递多个参数时(例如 'A' 和 'B'),默认情况下它会:将这些参数用空格分隔并在所有参数输出后自动换行 print('A','B') #会输出:A B
-
获取文本输入:
# Ask the user for an input name = input("Please enter a name: ") print("I hate " + name)
-
获取整数输入:
- 使用
int()
函数将文本输入转换为整数
# Let's ask user for an input name = input("Please enter a name: ") age = int(input("Enter the age of the person above: ")) print("I hate " + name + ", I believe he is ", age, "years old.")
- 使用
6. 变量 (Variables)
变量是用来存储值的容器。
-
创建与赋值:
message = "Hello Python" print(message)
Python 输出:
Hello Python
-
打印多个变量:
message = "Hello Python" message2 = "and welcome to the training" print(message, message2) # print both messages in one line #会以空格间隔(如果没有特殊标注)
Python 输出:
Hello Python and welcome to the training
6.1. 变量命名规则与最佳实践
-
规则:
- 只能包含字母、数字和下划线
_
。 - 可以以字母或下划线
_
开头,但不能以数字开头。 - 不能包含空格,通常用下划线
_
代替,例如student_name
。 - 不能使用 Python 的保留字(关键字)作为变量名。
- 只能包含字母、数字和下划线
-
最佳实践:
- 变量名应具有描述性,但不要太长。
- 注意区分小写字母
l
和数字1
,以及大写字母O
和数字0
。
6.2. Python 保留字
以下单词是 Python 的保留字,不能用作变量名:
False
, class
, finally
, is
, return
, None
, continue
, for
, lambda
, try
, True
, def
, from
, nonlocal
, while
, and
, del
, global
, not
, with
, as
, elif
, if
, or
, yield
, assert
, else
, import
, pass
, break
, except
, in
, raise
。
7. 字符串 (Strings)
字符串是文本数据,可以用单引号 '
或双引号 "
括起来。
7.1. 字符串操作
-
大小写转换:
.title()
: 首字母大写。.upper()
: 全部大写。.lower()
: 全部小写。
first_name = 'anthony' print(first_name.title()) print(first_name.upper()) last_name = "Sum" print(last_name.lower())
Python 输出:
Anthony ANTHONY sum
-
字符串拼接 (Concatenation): 使用
+
号连接字符串。first_name = 'anthony' last_name = "Sum" full_name1 = first_name.title() + " " + last_name print("Instructor's full name is =", full_name1)
Python 输出:
Instructor's full name is = Anthony Sum
-
移除空白 (Stripping White Spaces):
.lstrip()
: 移除左侧空白。.rstrip()
: 移除右侧空白。.strip()
: 移除两侧空白。
name = " CUHK " print("stripping left of the string, name=" + "***" + name.lstrip() + "***") print("stripping right of the string, name=" + "***" + name.rstrip() + "***") print("stripping both sides of the string, name=" + "***" + name.strip() + "***")
Python 输出:
stripping left of the string, name=***CUHK *** stripping right of the string, name=*** CUHK*** stripping both sides of the string, name=***CUHK***
7.2. 控制字符 (Control Characters)
\t
: 制表符 (Tab)。\n
: 换行符 (Newline)。
Python 输出:full_name1 = "Anthony Sum" print(full_name1, "\tis nice") print("\n", full_name1, "\n\t\tis nice")
Anthony Sum is niceAnthony Sum is nice
8. 数字 (Numbers) 与运算符
8.1. 基本算术运算
-
+
: 加法 -
-
: 减法 -
*
: 乘法 -
/
: 除法 -
**
: 幂运算print(2+3*4) print((2+3)*4)
Python 输出:
14 20
8.2. 特殊运算符
//
: 整除 (Floor Division),返回商的整数部分(相当于取下整floor)。%
: 取余 (Modulo),返回除法的余数。
Python 输出:print(4 // 3) # gives floor print(17 % 3) # gives remainder
1 2
9. 注释 (Comments)
- 在 Python 中,
#
号后面的内容被视为注释。 - 注释用于解释代码的逻辑,帮助自己和他人理解代码。
Python 输出:# This line is a comment. print(5 - 3) # Note that # can also be put after a computational statement
2
10. 条件语句 (Conditional Statement)
10.1. 逻辑运算符
运算符 | 描述 |
---|---|
< | 小于 |
> | 大于 |
<= | 小于等于 |
>= | 大于等于 |
== | 等于 |
!= | 不等于 |
not | 逻辑非 |
and | 逻辑与 |
or | 逻辑或 |
注意还有in和not in这样的运算,注意不是is in或者is not in。
10.2. if
语句结构
-
if-elif-else
结构用于根据不同条件执行不同代码块。 -
elif
和else
是可选的。 -
注意:
- 每个条件后面必须有冒号
:
。 - 条件成立后要执行的 “action” 语句块必须缩进。
# Example: Use if statement to select one choice choice = 3if choice == 1:print('You choose Cola')out = 'Coke' elif choice == 2:print('You choose Lemon tea')out = 'Lemon Tea' elif choice == 3:print('You choose Orange juice')out = 'Orange Juice' else:print('Invalid choice!')print('choose again')
Python 输出:
You choose Orange juice
- 每个条件后面必须有冒号
11. 循环 (Loops)
循环用于重复执行一段代码块。
Python 中主要有两种循环:while
循环和 for
循环。
while用于执行不知道运行多少次的循环。for用于执行特定次数的循环。
11.1. while
循环
只要指定的条件为 True
,while
循环就会持续执行代码块。
-
基本示例:
# Print x as long as x is less than 6 x = 1 # initialize x while x < 6: # set the condition for the while loopprint(x) # print xx += 1 # increase x by 1
Python 输出:
1 2 3 4 5
-
break
语句:break
语句可以用来提前终止循环,即使用于循环的条件仍然为True
。# Exit the loop when x is 3 x = 1 while x < 6:print(x)if x == 3:breakx += 1
Python 输出:
1 2 3
BREAK 和 CONTINUE 的区别
break 和 continue 都是用于循环控制的关键字,但作用不同:
- break: 完全终止整个循环
- continue: 跳过当前迭代,继续下一次循环
#==================== BREAK 示例 ====================
print("=== BREAK 示例 ===")
for i in range(5):if i == 3:print(f"遇到 i=3,break 终止循环")break # 完全退出循环print(f"当前 i = {i}")
输出:
当前 i = 0
当前 i = 1
当前 i = 2
遇到 i=3,break 终止循环
# ==================== CONTINUE 示例 ====================
print("\n=== CONTINUE 示例 ===")
for i in range(5):if i == 3:print(f"遇到 i=3,continue 跳过此次循环")continue # 跳过当前迭代,继续下一次print(f"当前 i = {i}")
输出:
当前 i = 0
当前 i = 1
当前 i = 2
遇到 i=3,continue 跳过此次循环 #不执行标记点后面的print语句了
当前 i = 4
11.2. for
循环
for
循环用于遍历一个序列(如列表、字符串、元组等)中的每个项目。
-
遍历字符串:
for x in "banana":print(x)
Python 输出:
b a n a n a
-
遍历列表:
fruits = ["apple", "banana", "cherry"] for x in fruits:print(x)
Python 输出:
apple banana cherry
11.3. range()
函数
range()
函数用于生成一个数字序列,常用于控制 for
循环的次数。
-
语法:
range(start, stop, step)
start
: 序列的起始数字(包含)。stop
: 序列的结束数字(不包含)。step
: 序列中数字之间的间隔。
-
range()
示例:# from 0 to 9 since 10 will not be included print(list(range(10)))# from 1 to 10 since 11 will not be included print(list(range(1, 11)))# step 5 print(list(range(0, 30, 5)))#最后一个5可以理解为每五个值为一组,一组里输出一个值
Python 输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [0, 5, 10, 15, 20, 25]
还有几种特殊情况:
# range() 函数的三种参数特殊情况示例# 1. 步长为负数(递减序列)print("=== 步长为负数 ===")print(list(range(10, 0, -1))) # 从10递减到1(不包含0)print(list(range(20, 10, -2))) # 从20递减到12,步长为-2print(list(range(5, -5, -1))) # 从5递减到-4# 2. 起始值大于结束值(正常递减)print("\n=== 起始值大于结束值(正常)===")print(list(range(8, 3, -1))) # [8, 7, 6, 5, 4]print(list(range(100, 90, -1))) # [100, 99, 98, 97, 96, 95, 94, 93, 92, 91]# 3. 起始值大于结束值但步长为正(空序列)print("\n=== 起始值>结束值但步长为正 ===")print(list(range(10, 5, 1))) # 空列表,因为无法从10递增到5print(list(range(100, 50, 2))) # 空列表# 4. 起始值小于结束值但步长为负(空序列)print("\n=== 起始值<结束值但步长为负 ===")print(list(range(1, 10, -1))) # 空列表,因为无法从1递减到10print(list(range(0, 100, -5))) # 空列表# 5. 步长为0(错误)print("\n=== 步长为0(会报错)===")try:print(list(range(0, 10, 0))) # ValueError: range() arg 3 must not be zeroexcept ValueError as e:print(f"错误: {e}")# 6. 浮点数参数(错误)print("\n=== 浮点数参数(会报错)===")try:print(list(range(0.5, 5.5, 1))) # TypeError: 'float' object cannot be interpreted as an integerexcept TypeError as e:print(f"错误: {e}")# 7. 单参数形式(从0开始)print("\n=== 单参数形式 ===")print(list(range(5))) # [0, 1, 2, 3, 4]print(list(range(-3))) # 空列表,因为从0到-3需要负步长# 8. 双参数形式(指定起始和结束)print("\n=== 双参数形式 ===")print(list(range(3, 8))) # [3, 4, 5, 6, 7],默认步长为1print(list(range(-2, 3))) # [-2, -1, 0, 1, 2]# 9. 边界值测试print("\n=== 边界值测试 ===")print(list(range(0, 0))) # 空列表print(list(range(5, 5))) # 空列表print(list(range(0, -5, -1))) # [0, -1, -2, -3, -4]print(list(range(-5, 0, 1))) # [-5, -4, -3, -2, -1]# 10. 大步长测试print("\n=== 大步长测试 ===")print(list(range(0, 100, 30))) # [0, 30, 60, 90]print(list(range(100, 0, -30))) # [100, 70, 40, 10]
其实理解一下:
- 第一个参数是起点
- 第二个参数是终点(不包括这个值)
- 第三个参数正负代表方向,绝对值代表几个一组
12. 列表 (Lists)
列表是 Python 中用于在单个变量中存储多个项目的一种数据结构。 列表使用方括号 []
创建。
12.1. 列表的特性
- 有序 (Ordered): 列表中的项目有明确的顺序。
- 可变 (Changeable): 列表创建后,可以更改、添加和删除其中的项目。
- 允许重复值 (Allows Duplicate): 列表中可以包含具有相同值的项目。
- 有索引 (Indexed): 列表中的第一个项目索引为
[0]
,第二个为[1]
,以此类推。
12.2. 列表索引与切片
-
索引:
- 正向索引从
0
开始。 - 反向索引从
-1
开始,表示最后一个元素。
squares = [1, 4, 9, 16, 25] print(squares[-1]) # the last item print(squares[-4]) # the last forth item
Python 输出:
25 4
- 正向索引从
-
切片 (Slicing): 用于访问列表中的一个子集。
squares = [1, 4, 9, 16, 25] print(squares[-3:]) # all items from the last third item print(squares[:3]) # all items before the item[3] print(squares[:]) # all items
Python 输出:
[9, 16, 25] [1, 4, 9] [1, 4, 9, 16, 25]
12.3. 列表操作
-
拼接与追加:
+
: 连接两个列表。.append()
: 在列表末尾添加一个元素。
squares = [1, 4, 9, 16, 25] squares = squares + [36, 49, 64, 81, 100] print(squares) squares.append(121) print(squares)
Python 输出:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121]
-
修改与删除:
- 可以通过切片赋值来修改多个元素。
- 可以通过将切片赋值为空列表来删除元素。
- 仍然是不包括最后一个位置!!!
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] letters[2:5] = ['X', 'Y', 'Z'] # Slice Changing print(letters) letters[2:5] = [] # Slice Removal print(letters)
Python 输出:
['a', 'b', 'X', 'Y', 'Z', 'f', 'g'] ['a', 'b', 'f', 'g']
-
获取长度:
len()
函数可以返回列表中的项目数。letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] print(len(letters))
Python 输出:
7
12.4. 列表迭代
enumerate()
函数: 在遍历列表时,同时获取索引和对应的值。这一点类似于dictionary的item()既返回key又返回value。
Python 输出:cse_teachers = ['john c. s. lui', 'patrick p. c. lee', 'james cheng', 'anthony sum'] # use enumerate for index, teacher in enumerate(cse_teachers):position = str(index)print("Position: " + position + " Teacher:" + teacher.title())
Position: 0 Teacher:John C. S. Lui Position: 1 Teacher:Patrick P. C. Lee Position: 2 Teacher:James Cheng Position: 3 Teacher:Anthony Sum
12.5. 列表推导式 (List Comprehension)
列表推导式提供了一种更简洁的语法,用于基于现有列表创建新列表。一般是for循环加上if条件判断,在for循环中符合if条件的元素被保留在列表中。
- 示例: 创建一个新列表,只包含
fruits
列表中含有字母 “a” 的水果。
Python 输出:fruits = ["apple", "banana", "cherry", "kawi", "mango"] # Option 2: Using list comprehension newlist = [x for x in fruits if "a" in x]#特别是用于检查str中是否有某个部分或者列表中是否有某个元素 print(newlist)
['apple', 'banana', 'kawi', 'mango']
13. 字符串再探 (Strings Revisited)
-
不可变性 (Immutable): 字符串一旦被创建就不能被修改。如果尝试修改字符串中的某个字符,会引发
TypeError
。 如果想修改就要把字符串执行列表取元素的操作然后进行拼接(Concatenation)。不像print,+是直接拼起来没有空格。word = 'Fin' + 'Tech' # word[0] = 'f' # This would cause a TypeError# But we can create a new string instead newWord = 'f' + word[1:] print(newWord)
Python 输出:
finTech
-
重复 (Repeating): 使用
*
操作符可以重复一个字符串。word = 'Fin' + 'Tech' print(word * 2 + " is the best!")
Python 输出:
FinTechFinTech is the best!
14. 字典 (Dictionary)
字典是一种用于存储 键:值
(key:value) 对的集合。
-
特性:
- 有序: 从 Python 3.7 版本开始,字典是有序的。
- 可变: 字典是可修改的。
- 不允许重复键: 字典中不允许有重复的键。
-
创建与访问:
dict = {"brand": "Toyota", "model": "Ractis", "year": 2020} print(dict) print(dict["brand"])
字典会优先寻找key,返回value。
Python 输出:
{'brand': 'Toyota', 'model': 'Ractis', 'year': 2020} Toyota
-
删除元素: 使用
del
关键字可以删除字典中的一个元素。dict = {"brand": "Toyota", "model": "Ractis", "year": 2020} del dict["model"] print(dict)
Python 输出:
{'brand': 'Toyota', 'year': 2020}
-
遍历一个字典:
- 字典默认遍历的是键。
dict = {"brand": "Toyota", "model": "Ractis", "year": 2020} print("--- 遍历所有的键 ---") for key in dict:print(key)
- 返回:
brand model year
- 当然也可以只遍历值,使用字典的 .values() 方法可以遍历所有的值。
dict = {"brand": "Toyota", "model": "Ractis", "year": 2020}print("\n--- 遍历所有的值 ---") for value in dict.values(): print(value)
- 返回:
Toyota Ractis 2020
- 遍历所有的键值对 (Iterating Through All Key-Value Pairs)
dict = {"brand": "Toyota", "model": "Ractis", "year": 2020}print("\n--- 遍历所有的键值对 ---") for key, value in dict.items(): print(f"Key: {key}, Value: {value}")
- 返回:
Key: brand, Value: Toyota Key: model, Value: Ractis Key: year, Value: 2020
-
列表 (List) 与字典 (Dictionary) 操作对比
操作 列表 (List) 字典 (Dictionary) 增 (Add) list.append(item)
: 在末尾添加单个元素。list.insert(index, item)
: 在指定索引处插入元素。list.extend(another_list)
: 将另一个列表的多个元素追加到末尾。list1 + list2
: 通过拼接创建新列表。dict[key] = value
: 添加或更新一个键值对。如果key
已存在,则更新其value
;如果不存在,则创建新的键值对。dict.update(another_dict)
: 用另一个字典的键值对来更新当前字典。删 (Delete) del list[index]
: 删除指定索引的元素。list.pop(index)
: 移除并返回指定索引的元素(默认为最后一个)。list.remove(item)
: 删除第一个匹配到的指定元素。del dict[key]
: 删除指定key
的键值对。dict.pop(key)
: 移除并返回指定key
对应的value
。dict.clear()
: 清空字典,删除所有键值对。改 (Modify) list[index] = new_value
: 直接通过索引修改单个元素的值。list[start:end] = new_iterable
: 通过切片修改多个元素。dict[key] = new_value
: 直接通过key
修改其对应的value
。查 (Retrieve) list[index]
: 通过索引访问单个元素。list[start:end]
: 通过切片访问多个元素。item in list
: 检查元素是否存在于列表中。list.index(item)
: 查找元素的索引。list.count(item)
: 统计元素出现的次数。dict[key]
: 通过key
访问其对应的value
(若key
不存在会报错)。dict.get(key, default_value)
: 通过key
访问value
(若key
不存在则返回None
或指定的default_value
)。key in dict
: 检查key
是否存在于字典中。dict.keys()
: 获取所有键。dict.values()
: 获取所有值。dict.items()
: 获取所有键值对。
15. 模块与函数 (Modules and Functions)
15.1. 导入模块 (Importing Modules)
Python 提供了许多内置函数,如 print()
和 len()
。对于更复杂的功能,我们可以通过导入模块来扩展程序的能力。
-
常见模块:
math
: 提供数学相关函数。random
: 用于生成随机数。sys
: 提供系统相关的工具,如程序退出。
-
import
语句: 使用import
关键字来导入整个模块。调用模块中的函数时,需要使用模块名.函数名()
的格式。import math# Calculate the square root of a number x = 16 print("square root =", math.sqrt(x))
Python 输出:
square root = 4.0
-
from ... import
语句: 可以从模块中只导入特定的函数,或者使用*
通配符导入所有函数。这样调用函数时就不需要加模块名前缀。- 注意: 在大型项目中不推荐使用
from ... import *
,因为它可能导致命名冲突。
from random import randint # only import randintfor i in range(5):print(randint(1, 6))
Python 输出: (每次运行结果可能不同)
2 4 2 1 6
- 注意: 在大型项目中不推荐使用
15.2. 自定义函数 (User-Defined Functions)
我们可以创建自己的函数来封装可重用的代码。
-
函数语法:
- 使用
def
关键字定义函数。 functionName
: 函数的名称。parameters
: 传递给函数的信息。"""docstring"""
: 函数的文档字符串,用于解释函数的功能 。return
: 从函数中退出并可选地返回一个值。
def functionName(parameters):"""function docstring"""statementsreturn [expression]
- 使用
-
定义与调用:
- 函数必须在使用前被定义。
- 函数可以被多次调用。
def printBar():print("*****************")printBar() print(" Hello World!") printBar()
Python 输出:
*****************Hello World! *****************
15.3. 参数传递 (Parameter Passing)
-
形参 (Formal Parameters): 定义函数时,在括号中声明的变量,用于接收传入的值。
-
实参 (Actual Arguments): 调用函数时,传递给函数的具体值、变量或表达式。
-
传值 (Pass by Value):
- 适用于简单的数值类型,如整数和浮点数。
- 函数接收的是实参值的副本。
- 重要!!!在函数内部修改形参,不会影响到函数外部的实参。
def bar(n):print("n is {}".format(n))n = n + 1x = 10 bar(x) print("x is {}".format(x))
Python 输出:
n is 10 x is 10
-
传引用 (Pass by Reference):
- 适用于列表、字典等复杂数据类型。
- 函数接收的是实参的引用(内存地址)。在函数内部对形参的修改会直接影响到函数外部的实参。
def bar(n):print(n)n.append(5) # This modification will affect the original listx = [1, 2, 3, 4] bar(x) print(x)
Python 输出:
[1, 2, 3, 4] [1, 2, 3, 4, 5]
15.4. return
语句与返回值
-
return
语句用于从函数中返回一个值,并立即终止函数的执行。 -
如果函数没有
return
语句,或者return
后面没有跟任何值,它会自动返回一个特殊的值None
。def cube(x):return x * x * xprint("Cube of 3 is {}".format(cube(3)))
Python 输出:
Cube of 3 is 27
def answerNothing():print("do something")returncode = answerNothing()#code不接收任何返回的值 print(code == None)
Python 输出:
do something True
15.5. 变量作用域 (Scope)
-
局部变量 (Local Variables):
- 在函数内部定义的变量,只在该函数内部有效。
- 函数执行完毕后,其局部变量会被销毁。
- 如果在函数外尝试访问局部变量,会引发
NameError
。
def foo():x = 0 # This is a local variable,这个局部变量是调用这个函数时计算机给其分配的一个新的地址。名称和全局变量不冲突,无所谓名称的冲突问题。这个函数用完之后就立即销毁。print("In foo(): x =", x)x = 5 # This is a global variable print("Before: In main program: x =", x) foo() print("After: In main program: x =", x)
Python 输出:
Before: In main program: x = 5 In foo(): x = 0 After: In main program: x = 5
-
全局变量 (Global Variables):
- 在所有函数之外定义的变量,具有全局作用域。
global
关键字: 如果想在函数内部修改一个全局变量的值,必须使用global
关键字进行声明。
def scopeTest():global bb = 4 # This modifies the global variable bprint('inside func, b is', b)b = 2 # Global variable,在这一步b是2 scopeTest()#调用到b=4时b就已经是4了,调用完成返回none之后b并不销毁 print('after func, b is', b)
Python 输出:
inside func, b is 4 after func, b is 4
15.6. Lambda 函数
- Lambda 函数是一种小型的匿名函数,当需要一个简单的函数时,可以使用它来简化代码,而无需使用
def
关键字进行正式定义。
Python 输出:a = [1, 2, 3, 4, 5]# Use a lambda function with filter() to get even numbers print(list(filter(lambda x: x % 2 == 0, a)))
[2, 4]
filter(function, iterable) 函数用于过滤序列,过滤掉不符合条件的元素,
返回由符合条件元素组成的新迭代器。
参数:
- function: 判断函数,返回布尔值
- iterable: 可迭代对象(如列表、元组等)
工作原理:filter() 会将 iterable 中的每个元素传递给 function 函数,只保留返回 True 的元素。即iterable不断迭代,给出候选的元素,将候选的元素放进fuction进行判断,True就保留,False就不保留。
16. 文件输入/输出 (File I/O)
文件是磁盘上用于永久存储数据的命名位置。基本的文件操作包括打开、读取、写入和关闭。
16.1. 文本文件操作
-
打开文件:
open()
函数返回一个文件对象(句柄。- 语法:
file_object = open(filename, mode)
mode
:'r'
表示读取,'w'
表示写入(会覆盖已有内容)。
- 语法:
-
读取文件:
f.read()
: 读取整个文件的内容。f.readline()
: 读取文件中的一行。
# Assuming 'test.txt' contains text f = open("test.txt", 'r') # open the file for reading print(f.read()) f.close()
-
写入文件:
f.write()
: 将字符串写入文件。
f = open("test.txt", 'w') # open the file for writing f.write("Hello Python\n") # f.write("Hello World") # f.close()
-
关闭文件: 使用
f.close()
是一个好习惯,可以释放文件资源。 -
创建与删除文件:
- 使用
open()
并指定'w'
模式可以创建一个新文件。 os.remove()
用于删除文件。删除前最好使用os.path.exists()
检查文件是否存在。要不然会因为路径不存在报错。os.path.exists()
会判断括号内的路径是否存在,返回True或False。
import os if os.path.exists("file.txt"):os.remove("file.txt")print("File deleted successfully") else:print("The file does not exist")
- 使用
16.2. 异常处理 (Exception Handling)
文件操作可能会产生错误(如 IOError
)。使用 try...except
块可以优雅地处理这些错误,防止程序崩溃。
try:f = open('input.txt')
except IOError as e: # This block runs if the file cannot be openedprint('unable to open the file with error: "{}"'.format(e.args[-1]))
else:# This block runs if 'try' was successfulprint('continue with processing') f.close()
捕捉错误的格式:
try:想运行的代码
except 如果出现某种类型的错误 as e:print('{}'.format(e.args[-1]))# e.args[-1])用于捕捉错误的信息
else:如果try中的语句能够正常运行,则继续执行else下面的代码。
17. Pickle: Python 对象序列化
Pickle 用于序列化和反序列化 Python 对象结构。序列化是将内存中的对象转换为字节流的过程,便于存储或网络传输。
相较于我们平常见到的文件格式,例如csv、txt、pdf如此,pkl文件可以保存python中的出现的数据类型,这是我们平常见到的文件格式是不一样的。例如一个df能够保存为csv,也可以保存为pkl,但是一个字典能保存为pkl但是不能保存为csv。pkl是更通用的python文件的保存形式。
-
Pickling (序列化): 使用
pickle.dump()
将对象写入二进制文件 ('wb'
)。import pickle fruits_dict = {'Orange': 3, 'Apple': 8, 'Melon': 1} f = open('filename', 'wb') # write in binary mode pickle.dump(fruits_dict, f) f.close()
-
Unpickling (反序列化): 使用
pickle.load()
从二进制文件 中读取并重建对象。import pickle f = open('filename', 'rb') # read in binary mode new_dict = pickle.load(f) f.close()
Pickle也和一般的文件I/O一样,也包括了打开、读取、写入、关闭四个操作。打开和关闭操作和一般的文件操作一样,读取和写入有区别。
读取:
f = open('filename', 'rb') #rb
new_dict = pickle.load(f) #用load而不用read
写入:
fruits_dict = {'Orange': 3, 'Apple': 8, 'Melon': 1}f = open('filename', 'wb') #wbpickle.dump(fruits_dict, f) #使用dump而不用read,第一个参数是python对象,第二个参数是对象想要存放的位置,需要使用open创建
18. CSV 文件操作(不使用pd)
CSV (Comma Separated Values) 是一种以纯文本形式存储表格数据的格式。
-
读取 CSV: 使用
csv
模块的reader
对象逐行读取数据 。next()
函数可以用来跳过或读取表头。import csv f = open('test_data.csv', 'r') csvData = csv.reader(f) header = next(csvData) data = [] for row in csvData:data.append(row) print(data) f.close()
-
使用csv读取csv的操作流程:
- 引入csv的module
- 使用open打开文件
- 使用csv的reader读取文件。(和txt的read作用一样)
- 获取表头单独进行操作
-
对于需要将csv的内容读入进列表,你不仅需要上述读取csv的操作,还需要使用循环逐行的引入csv的信息存储在一个列表中,有时为了将列表中相同的信息放在同一个子列表中,你还需要使用矩阵的转置操作:
import numpy as npnumpy_matrix = np.array(matrix)#将列表转换为数组 numpy_transposed = numpy_matrix.T#对数组的数据类型进行转置print("\n转置后的矩阵 (方法3 - NumPy):") print(numpy_transposed)
-
写入 CSV: 使用
csv.writer()
对象的writerow()
方法将数据逐行写入文件。import csv f = open('test_data_out.csv', 'w', newline='') writer = csv.writer(f) data = [['ID', 'Open', 'Close'], ['1', '100', '105'], ['2', '110', '115']] for row in data: writer.writerow(row) f.close()
-
newline=’'的作用
newline=’’ 的主要作用是防止在写入 CSV 文件时出现多余的空行。
这要从不同操作系统如何表示“换行”说起:-
操作系统的差异:
-
在 Windows 系统中,换行由两个字符表示:回车符 (\r) 和换行符 (\n),即 \r\n。
-
在 Linux 和 macOS 系统中,换行仅由一个换行符 (\n) 表示。
-
-
Python 的默认行为:
当您以文本模式 (‘w’) 打开文件时,Python 的文件处理机制会自动将代码中的 \n 转换为当前操作系统的标准换行符。例如,在 Windows 上,它会将 \n 转换为 \r\n。
-
csv 模块的行为:
csv 模块为了遵循 CSV 标准,在写入每一行数据时,会自动在行尾添加 \r\n。
-
问题的产生:
当您在 Windows 系统上,使用 open(‘file.csv’, ‘w’) (没有 newline=’’)来写入 CSV 文件时,会发生两次换行处理:
-
csv.writer 写入一行数据,并在末尾加上 \r\n。
-
Python 的文件处理机制接收到 csv.writer 传来的数据,它看到里面的 \n,然后执行自己的默认转换,将其变为 \r\n。
-
最终,写入文件的换行符就变成了 \r\r\n。这个多出来的 \r 在大多数电子表格软件(如 Excel)中会被解释为一个空行。
-
-
-
写入csv的步骤:
- open打开,使用w和newline=’'参数。
- 定义向谁写入writer = csv.writer(f)。
- 将数据保存为列表,每个元素正好对应每一行。
- 使用for循环每个元素逐个使用writer.writerow(row)写入。
- 关闭文件。
19. Pandas DataFrame
Pandas DataFrame 是一种二维数据结构,类似于带行列的表格。
-
创建 DataFrame: 可以从字典等结构创建 DataFrame。
import pandas as pd data = { "Open": [200, 210, 240], "Close": [220, 230, 280] } #使用字典正好能够对应df中列和元素的对应关系 df = pd.DataFrame(data)#直接将字典转化为df print(df)
-
定位行 (Locating Rows): 使用
.loc[]
属性来选择行。# df is the DataFrame from the previous example print(df.loc[0]) # Locate one row, e.g. Row 0 print(df.loc[[0, 2]]) # Locate Row 0 and 2 only,和切片和for循环不同,这个是取特定索引位置的行。使用 `.loc`(基于标签)或 `.iloc`(基于整数位置)。 #.loc两端是闭合的,iloc右端是不闭合的,和切片和for循环一样。 selected_rows = df.loc[0:100] #等价于 selected_rows = df.iloc[0:101]
-
从 CSV 加载数据:
pd.read_csv()
是一个强大的函数,可以直接将 CSV 文件读入 DataFrame。import pandas as pd df = pd.read_csv('data.csv') print(df)
20. 数据可视化 (Plotting Charts)
使用 matplotlib
库可以将数据绘制成图表进行可视化。
-
基本绘图:
import matplotlib.pyplot as plt
: 导入绘图库。plt.plot()
: 绘制线性图表。plt.show()
: 显示图表。
import matplotlib.pyplot as plt data = [110, 100, 120, 110, 105, 130] plt.plot(data) plt.show()
-
样式与标记:
plot()
函数接受一个格式化字符串来定义颜色、标记和线条样式'b+'
: 蓝色十字标记。'go--'
: 绿色圆形标记和虚线。
-
子图 (Subplots):
plt.subplots()
可以创建一个包含多个子图的图形窗口,方便对比展示。import matplotlib.pyplot as plt import numpy as np # 2x100 random numbers with normal distribution data = np.random.randn(2, 100)fig, axs = plt.subplots(2, 2, figsize=(5, 5))#fig代表整个画布,axs代表每个子图axs[0, 0].hist(data[0]) axs[1, 0].scatter(data[0], data[1]) axs[0, 1].plot(data[0], data[1]) axs[1, 1].hist2d(data[0], data[1])plt.show()
课程作业复习
课程作业一: Python_lab01.pdf (变量与条件)
练习 1 - 标准输出
-
作业要求: 编写一个 Python 程序,在屏幕上打印三行特定的文字,并确保文本中的单引号和双引号能正确显示。
-
涉及知识点:
print()
函数:用于在控制台输出文本。- 字符串 (String):Python 中处理文本的数据类型。
- 特殊字符处理:如何在字符串中正确地包含引号。一种常见方法是使用不同类型的引号来包裹字符串(例如,用单引号包裹含有双引号的字符串)。
-
解决思路:
- 使用三个独立的
print()
语句来输出三行不同的内容,以满足换行要求。 - 对于包含单引号
'
的第一行和第二行,可以使用双引号"
来定义整个字符串。 - 对于包含双引号
"
的第三行,可以使用单引号'
来定义整个字符串。
- 使用三个独立的
-
示例代码:
# 练习 1: 标准输出 print("I'm a CUHK MSc in FinTech student.") print("Hello everybody in this course!") print('Let\'s solve problem "a" by programming in Python.')
-
预期输出:
I'm a CUHK MSc in FinTech student. Hello everybody in this course! Let's solve problem "a" by programming in Python.
练习 2 - 最大值和最小值
-
作业要求: 编写一个程序,接收用户输入的四个整数,然后找出并打印这四个数中的最大值和最小值。
-
涉及知识点:
input()
: 从用户处获取键盘输入(输入内容为字符串)。int()
: 将字符串或数字转换为整数。- 列表 (List): 一种可以存储多个值的数据结构。
- 内置函数
min()
和max()
: 分别用于查找序列(如列表)中的最小值和最大值。 - f-string: 一种格式化字符串的便捷方法,可以在字符串中直接嵌入变量。
-
解决思路:
- 创建一个空列表,用于存储用户输入的数字。
- 使用一个循环(或者重复四次代码)来提示用户输入四个数字。
- 每次获取输入后,使用
int()
将其转换为整数,并添加到列表中。 - 使用
max()
和min()
函数直接从列表中获取最大值和最小值。 - 使用 f-string 格式化并打印最终结果,使其与样本输出完全一致 。
-
示例代码:
# 练习 2: 最大值和最小值# 创建一个空列表来存储数字 numbers = []# 获取四个用户输入 num1 = int(input("Input 1:\n")) numbers.append(num1)num2 = int(input("Input 2:\n")) numbers.append(num2)num3 = int(input("Input 3:\n")) numbers.append(num3)num4 = int(input("Input 4:\n")) numbers.append(num4)# 使用 min() 和 max() 函数找到最值 min_val = min(numbers) max_val = max(numbers)# 格式化输出 print(f"The minimum value is {min_val} whereas the maximum value is {max_val}.")
-
预期输出 (以 Sample 1 为例):
Input 1: 12 Input 2: 7 Input 3: 3 Input 4: 16 The minimum value is 3 whereas the maximum value is 16.
练习 3 - 日期时间格式转换
-
作业要求: 编写一个程序,将用户输入的总分钟数(一个非负整数)转换为“天、小时、分钟”的格式。
-
涉及知识点:
- 算术运算符:特别是整除
//
和取余%
。 - 变量:用于存储中间计算结果。
input()
和int()
:获取和转换用户输入。
- 算术运算符:特别是整除
-
解决思路:
- 定义常量:一天有
24 * 60 = 1440
分钟,一小时有60
分钟。 - 获取用户输入的总分钟数。
- 使用整除
//
计算总共有多少天:days = total_minutes // 1440
。 - 使用取模
%
计算除去整天后还剩多少分钟:remaining_minutes = total_minutes % 1440
。 - 用剩余的分钟数计算有多少小时:
hours = remaining_minutes // 60
。 - 最后用剩余分钟数对60取模,得到最终的分钟数:
minutes = remaining_minutes % 60
。 - 按照 “X Days Y Hours Z Minutes” 的格式打印结果。
- 定义常量:一天有
-
示例代码:
# 练习 3: 日期时间格式转换# 获取用户输入 total_minutes = int(input("Please input minutes: "))# 定义常量 MINUTES_PER_HOUR = 60 HOURS_PER_DAY = 24 MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY #像这样的计算定义好基本的元素之后使用代码进行计算# 计算天数 days = total_minutes // MINUTES_PER_DAY# 计算剩余的分钟数 remaining_minutes = total_minutes % MINUTES_PER_DAY# 计算小时数 hours = remaining_minutes // MINUTES_PER_HOUR# 计算最终的分钟数 minutes = remaining_minutes % MINUTES_PER_HOUR# 格式化输出 print(f"{days} Days {hours} Hours {minutes} Minutes")
-
预期输出:
Please input minutes: 12345 8 Days 13 Hours 45 Minutes
课程作业二: Python_lab02.pdf (循环与列表)
练习 1 - 猜数字游戏
-
作业要求: 实现一个双人猜数字游戏。玩家1秘密输入一个[-100, 100]的整数,玩家2最多有6次机会来猜。程序需要根据猜测给出“太高”或“太低”的提示。如果猜对,显示尝试次数并结束。如果6次都猜错,显示正确答案并结束。
-
涉及知识点:
while
或for
循环:用于限制猜测次数。if/elif/else
条件判断:用于比较猜测的数字和答案。break
语句:在用户猜对时提前终止循环。- 循环计数器:记录用户尝试的次数。
getpass.getpass()
: (根据提示) 用于隐藏玩家1的输入,使其在屏幕上不可见。
-
解决思路:
- 导入
getpass
模块。 - 使用
getpass.getpass()
获取玩家1的秘密数字,并转换为整数。 - 初始化一个计数器
tries = 0
。 - 使用一个
for
循环,迭代6次 (for i in range(6):
)。 - 在循环内部,让玩家2输入猜测的数字,并递增计数器。
- 使用
if/elif/else
判断:- 如果猜对了,打印成功信息(包含尝试次数),然后使用
break
退出循环。 - 如果猜错了,判断是“太高”还是“太低”,并打印相应提示。
- 如果猜对了,打印成功信息(包含尝试次数),然后使用
- (可选,使用
for...else
结构) 在循环结束后,如果循环是正常结束(即没有被break
),则执行else
块,打印6次都猜错的信息。
- 导入
-
示例代码:
import getpass# 练习 1: 猜数字游戏# 玩家1 输入秘密数字 secret_number = int(getpass.getpass("Player 1, write down your number secretly: "))# 玩家2 开始猜测 for i in range(1, 7): # 循环6次,i 代表尝试次数guess = int(input("Player 2, input your guess: "))if guess == secret_number:print(f"You are right after trying for {i} times and program ends.")breakelif guess < secret_number:print("Your guess is too low!")else: # guess > secret_numberprint("Your guess is too high!") else:# 如果 for 循环正常结束 (没有被 break),则执行这里的代码print(f"You have tried 6 times and it is still wrong! The answer is {secret_number} and program ends.")
-
预期输出 (以 Sample 为例):
Player 1, write down your number secretly: Player 2, input your guess: 0 Your guess is too low! Player 2, input your guess: 100 Your guess is too high! Player 2, input your guess: 12 Your guess is too high! Player 2, input your guess: 9 You are right after trying for 4 times and program ends.
练习 2 - 素数提取器
-
作业要求: 用户输入两个正整数a和b(范围2-200),程序需要打印出[a, b]闭区间内所有的素数,并用逗号分隔。
-
涉及知识点:
- 嵌套循环:外层循环遍历[a, b]区间的每个数,内层循环判断该数是否为素数。
- 素数判断逻辑:一个大于1的自然数,如果除了1和它自身外,不能被其他自然数整除,那么这个数就是素数。
- 列表:用于存储找到的素数。
- 字符串的
.join()
方法:将列表中的元素用指定的分隔符连接成一个字符串。
-
解决思路:
- 获取用户输入的 a 和 b。
- 创建一个空列表
prime_numbers
来存放结果。 - 外层循环
for num in range(a, b + 1):
。 - 在循环内,首先判断
num > 1
,因为素数必须大于1。 - 内层循环
for i in range(2, num):
来寻找因子。 - 如果
num % i == 0
,说明num
能被i
整除,因此它不是素数,使用break
退出内层循环。 - 使用
for...else
结构:如果内层循环正常结束(未被break
),说明没有找到任何因子,num
是素数。此时,将num
添加到prime_numbers
列表中。 - 所有循环结束后,将列表中的所有数字转换为字符串,并使用
", ".join()
将它们连接起来打印输出。
-
示例代码:
# 练习 2: 素数提取器a = int(input("Input a:\n")) b = int(input("Input b:\n"))prime_numbers = []# 遍历从 a 到 b (包含 b) 的所有数字 #这个循环的目的是判断是否是素数 for num in range(a, b + 1):# 素数必须大于 1if num > 1:# 检查是否有因子for i in range(2, int(num**0.5) + 1): # 优化:检查到其平方根即可if (num % i) == 0:break # 如果找到因子,则不是素数,跳出内层循环,不加入到用于存储的列表当中else:# 如果内层循环没有被 break,说明是素数prime_numbers.append(str(num))# 打印结果 if prime_numbers:print(", ".join(prime_numbers))
-
预期输出 (以 Sample 1 为例):
Input a: 2 Input b: 20 2, 3, 5, 7, 11, 13, 17, 19
练习 3 - 回文数
-
作业要求: 判断用户输入的一个正整数是否为回文数。回文数是指正序和倒序读都一样的数。
-
涉及知识点:
- 类型转换
str()
: 将整数转换为字符串以便操作。 - 字符串切片:
[::-1]
可以快速地将一个字符串反转。 if/else
条件判断。
- 类型转换
-
解决思路:
- 获取用户输入的整数
n
。 - 使用
str(n)
将其转换为字符串original_str
。 - 使用切片
original_str[::-1]
得到反转后的字符串reversed_str
。 - 比较
original_str
和reversed_str
是否相等。 - 根据比较结果,打印相应的判断信息。
- 获取用户输入的整数
-
示例代码:
# 练习 3: 回文数n_str = input("Input n: ")# 反转字符串 reversed_str = n_str[::-1]# 打印原始和反转后的形式 print(n_str)# 判断是否为回文 if n_str == reversed_str:print(f"{n_str} is a palindrome") else:print(f"{reversed_str} is not a palindrome")
-
预期输出 (以 Sample 2 为例):
Input n: 123454321 123454321 123454321 is a palindrome
课程作业三: Python_lab03.pdf (函数)
练习 1 - 频率与直方图
-
作业要求:
- a. 编写
frequency()
函数,统计列表中每个元素出现的次数,并返回一个字典。要求统计一般会用到字典,因为它从逻辑上是键值对应的。 - b. 编写
histogram()
函数,接收 a. 中生成的字典,并打印出由星号*
组成的文本直方图。
- a. 编写
-
涉及知识点:
- 函数定义
def
。 - 字典:创建、添加和访问键值对。
for
循环:遍历列表和字典。- 字典的
.get(key, default)
方法:安全地获取字典的值。 - 字符串乘法:
'*' * n
可以生成n个星号组成的字符串。
- 函数定义
-
解决思路:
frequency(items_list)
函数:- 初始化一个空字典
freq_dict = {}
。 - 遍历输入列表
items_list
中的每一个item
。 - 使用
freq_dict[item] = freq_dict.get(item, 0) + 1
来更新计数。如果item
不在字典中,.get()
返回默认值0,否则返回当前计数值。 - 返回
freq_dict
。
- 初始化一个空字典
histogram(freq_dict)
函数:- 使用
for key, value in freq_dict.items():
遍历字典的键值对。 - 在循环中,打印
key
,后面跟上value
个星号。
- 使用
-
示例代码:
# 练习 1: 频率与直方图def frequency(items_list):"""统计列表中每个元素出现的次数,并返回一个字典。"""freq_dict = {}for item in items_list:freq_dict[item] = freq_dict.get(item, 0) + 1return freq_dictdef histogram(freq_dict):"""根据频率字典打印星号直方图。"""for key, value in freq_dict.items():stars = '*' * valueprint(f"{key} {stars}")# --- 主程序测试 --- myList = ['abc', 'def', 'abc', 'pop', 'abc'] myDict = frequency(myList) print(myDict) # 为了匹配 pdf 上的例子,手动修改 myDict myDict_for_hist = {'abc': 3, 'pdq': 1, 'def': 1} histogram(myDict_for_hist)
-
预期输出:
{'abc': 3, 'def': 1, 'pop': 1} abc *** pdq * def *
练习 2 - 列表/字典推导式与函数
-
作业要求:
- a.
pos()
: 接受一个列表和一个函数f
,返回f(element)
为True
的所有元素在列表中的位置(索引)。 - b.
evenFilter()
: 接受一个字典,返回所有偶数键(key)对应的值(value)。 - c.
diff()
: 返回在第一个列表中但不在第二个列表中的元素。
- a.
-
涉及知识点:
- 列表推导式 (List Comprehension):一种简洁地创建列表的语法。
- 高阶函数:将函数作为参数传递给另一个函数。
enumerate()
: 在遍历列表时同时获取索引和值。- 集合 (Set):用于高效地计算差集。
-
解决思路:
pos(a_list, f)
: 使用列表推导式和enumerate
。[index for index, value in enumerate(a_list) if f(value)]
。evenFilter(a_dict)
: 使用列表推导式遍历字典的.items()
。[value for key, value in a_dict.items() if key % 2 == 0]
。diff(list1, list2)
: 最简洁高效的方法是利用集合的差集运算。set(list1) - set(list2)
会得到差集,再用list()
转换回列表。
-
示例代码:
# 练习 2a def pos(a_list, f):return [i for i, val in enumerate(a_list) if f(val)]# 练习 2b def evenFilter(a_dict):return [value for key, value in a_dict.items() if key % 2 == 0]# 练习 2c def diff(list1, list2):# 使用集合运算效率更高set2 = set(list2)return [item for item in list1 if item not in set2]# --- 测试 --- def even(x): return x % 2 == 0 myList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17] print(f"2a Output: {pos(myList, even)}")data = {1:"one", 2:"two", 5:"five", 6:"six"} print(f"2b Output: {evenFilter(data)}")list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17] list2 = [1, 3, 5, 7, 9, 11, 13, 15, 17] print(f"2c Output: {diff(list1, list2)}")
-
预期输出:
2a Output: [1, 3, 5, 7, 9, 11, 13, 15] 2b Output: ['two', 'six'] 2c Output: [2, 4, 6, 8, 10, 12, 14, 16]
练习 3 - 罗马数字转换器
-
作业要求: 编写一个函数
romanNumber()
,将1-99的整数转换为罗马数字字符串。对于超出范围的数字,打印错误信息。 -
涉及知识点:
- 函数定义、参数、返回值。
- 整数除法
//
和取模%
。 if/else
条件判断,用于范围检查。- 使用列表或元组作为查找表(mapping table)来简化转换逻辑。
-
解决思路:
- 在函数开头先检查输入数字
num
是否在 1 到 99 的范围内。如果不是,打印错误信息并返回。 - 创建两个查找表(列表):一个用于个位数(0-9),一个用于十位数(0-9,代表0, 10, 20…90)。
ones = ["", "I", "II", ..., "IX"]
tens = ["", "X", "XX", ..., "XC"]
- 使用
num // 10
作为索引在tens
列表中查找十位对应的罗马数字。 - 使用
num % 10
作为索引在ones
列表中查找个位对应的罗马数字。 - 将两个结果字符串连接起来并返回。
- 在函数开头先检查输入数字
-
示例代码:
# 练习 3: 罗马数字转换器def romanNumber(num):if not 1 <= num <= 99:print("The number is out of range")returnones = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]tens = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"]tens_digit = num // 10ones_digit = num % 10return tens[tens_digit] + ones[ones_digit]# --- 测试 --- print(f"romanNumber(9) -> {romanNumber(9)}") print(f"romanNumber(45) -> {romanNumber(45)}") print(f"romanNumber(99) -> {romanNumber(99)}") print(f"romanNumber(101) -> ", end="") romanNumber(101) # This will print the error message
-
预期输出:
romanNumber(9) -> IX romanNumber(45) -> XLV romanNumber(99) -> XCIX romanNumber(101) -> The number is out of range
课程作业四: In-class Exercise (文件读取与数据可视化)
-
作业要求:
- 创建一个包含股票ID、开盘价(Open)和收盘价(Close)的 Excel 文件。
- 将其另存为 CSV (逗号分隔值) 文件。
- 编写一个 Python 程序来读取这个 CSV 文件,并使用
matplotlib
绘制一个折线图,展示开盘价和收盘价随 ID 变化的趋势。
-
涉及知识点:
pandas
库:用于轻松读取和处理 CSV 文件。pd.read_csv()
是核心函数。matplotlib.pyplot
库:用于数据可视化。- DataFrame 操作:从 DataFrame 中选择特定的列(Series)进行绘图。
plt.plot()
: 绘制折线图。plt.title()
,plt.xlabel()
,plt.ylabel()
,plt.legend()
: 用于添加图表的标题、坐标轴标签和图例,使图表更具可读性。plt.show()
: 显示图表。
-
解决思路:
- 准备数据: 手动创建一个名为
stock_data.csv
的文件,内容如下:ID,Open,Close 1,100,105 2,110,115 3,100,115 4,130,135 5,140,160 6,125,150 7,160,165 8,170,175 9,160,190 10,190,195
- 编写代码:
- 导入
pandas
和matplotlib.pyplot
。 - 使用
pd.read_csv('stock_data.csv')
将数据加载到一个 DataFrame 中。 - 从 DataFrame 中提取 ‘ID’, ‘Open’, 和 ‘Close’ 这三列数据。
- 调用
plt.plot()
两次,一次用 ‘ID’ 和 ‘Open’ 数据,另一次用 ‘ID’ 和 ‘Close’ 数据。 - 设置图表标题为 “Stock 1314.HK”。
- 设置 x 轴和 y 轴的标签。
- 添加图例以区分两条线。
- 调用
plt.show()
显示图像。
- 导入
- 准备数据: 手动创建一个名为
-
示例代码:
import pandas as pd import matplotlib.pyplot as plt# 假设你已经在同目录下创建了名为 stock_data.csv 的文件# 1. 使用 pandas 读取 CSV 文件 try:df = pd.read_csv('stock_data.csv')# 2. 提取数据列ids = df['ID']open_prices = df['Open']close_prices = df['Close']# 3. 开始绘图plt.figure(figsize=(8, 5)) # 创建一个图形窗口# 绘制开盘价和收盘价的折线图plt.plot(ids, open_prices, marker='o', linestyle='-', label='Open')plt.plot(ids, close_prices, marker='o', linestyle='-', label='Close')# 4. 添加图表元素plt.title('Stock 1314.HK') # 设置标题plt.xlabel('ID') # 设置 x 轴标签plt.ylabel('Price') # 设置 y 轴标签plt.grid(True) # 添加网格线plt.legend() # 显示图例# 5. 显示图表plt.show()except FileNotFoundError:print("错误: stock_data.csv 文件未找到。请先创建该文件并填入数据。")
-
预期输出:
gend()`: 用于添加图表的标题、坐标轴标签和图例,使图表更具可读性。plt.show()
: 显示图表。
-
解决思路:
- 准备数据: 手动创建一个名为
stock_data.csv
的文件,内容如下:ID,Open,Close 1,100,105 2,110,115 3,100,115 4,130,135 5,140,160 6,125,150 7,160,165 8,170,175 9,160,190 10,190,195
- 编写代码:
- 导入
pandas
和matplotlib.pyplot
。 - 使用
pd.read_csv('stock_data.csv')
将数据加载到一个 DataFrame 中。 - 从 DataFrame 中提取 ‘ID’, ‘Open’, 和 ‘Close’ 这三列数据。
- 调用
plt.plot()
两次,一次用 ‘ID’ 和 ‘Open’ 数据,另一次用 ‘ID’ 和 ‘Close’ 数据。 - 设置图表标题为 “Stock 1314.HK”。
- 设置 x 轴和 y 轴的标签。
- 添加图例以区分两条线。
- 调用
plt.show()
显示图像。
- 导入
- 准备数据: 手动创建一个名为
-
示例代码:
import pandas as pd import matplotlib.pyplot as plt# 假设你已经在同目录下创建了名为 stock_data.csv 的文件# 1. 使用 pandas 读取 CSV 文件 try:df = pd.read_csv('stock_data.csv')# 2. 提取数据列ids = df['ID']open_prices = df['Open']close_prices = df['Close']# 3. 开始绘图plt.figure(figsize=(8, 5)) # 创建一个图形窗口# 绘制开盘价和收盘价的折线图plt.plot(ids, open_prices, marker='o', linestyle='-', label='Open')plt.plot(ids, close_prices, marker='o', linestyle='-', label='Close')# 4. 添加图表元素plt.title('Stock 1314.HK') # 设置标题plt.xlabel('ID') # 设置 x 轴标签plt.ylabel('Price') # 设置 y 轴标签plt.grid(True) # 添加网格线plt.legend() # 显示图例# 5. 显示图表plt.show()except FileNotFoundError:print("错误: stock_data.csv 文件未找到。请先创建该文件并填入数据。")
-
预期输出:
程序将弹出一个窗口,显示一个标题为 “Stock 1314.HK” 的折线图。图中有两条线,分别代表开盘价和收盘价,x轴为ID (从1到10),y轴为价格。