feat(python基础): 完成基础综合项目
This commit is contained in:
366
01_python基础/1_14_python基础综合项目/README.md
Normal file
366
01_python基础/1_14_python基础综合项目/README.md
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
# 第 1-14 课:Python 基础综合项目
|
||||||
|
|
||||||
|
## 一、项目名称
|
||||||
|
|
||||||
|
命令行 Agent 管理系统。
|
||||||
|
|
||||||
|
命令行程序是直接在终端中运行和操作的程序。本项目不会创建网页界面,而是通过数字菜单接收用户选择。
|
||||||
|
|
||||||
|
## 二、为什么要做综合项目
|
||||||
|
|
||||||
|
前面的课程分别学习了变量、条件判断、循环、数据结构和函数。单独完成一道小题,只需要使用其中一个知识点;真实程序通常需要把多个知识点组合起来。
|
||||||
|
|
||||||
|
本项目用于检验你能否:
|
||||||
|
|
||||||
|
1. 把一个较大的需求拆分成多个小功能;
|
||||||
|
2. 选择合适的数据结构保存信息;
|
||||||
|
3. 使用函数组织重复逻辑;
|
||||||
|
4. 使用循环让菜单持续运行;
|
||||||
|
5. 使用条件判断处理不同操作;
|
||||||
|
6. 对用户输入进行基本检查;
|
||||||
|
7. 独立完成一个可以反复操作的命令行程序。
|
||||||
|
|
||||||
|
## 三、前置知识
|
||||||
|
|
||||||
|
开始前应当掌握:
|
||||||
|
|
||||||
|
- `print()` 和 `input()`;
|
||||||
|
- 字符串、整数和布尔值;
|
||||||
|
- 比较运算与逻辑运算;
|
||||||
|
- `if...elif...else`;
|
||||||
|
- `for` 和 `while` 循环;
|
||||||
|
- 列表、字典和集合;
|
||||||
|
- 函数、参数和返回值;
|
||||||
|
- `*args` 和 `**kwargs` 的基本含义。
|
||||||
|
|
||||||
|
本项目主要使用普通参数,不会为了展示高级语法而强行使用 `*args` 或 `**kwargs`。
|
||||||
|
|
||||||
|
## 四、项目最终功能
|
||||||
|
|
||||||
|
程序启动后显示以下菜单:
|
||||||
|
|
||||||
|
```text
|
||||||
|
==============================
|
||||||
|
命令行 Agent 管理系统
|
||||||
|
1. 查看全部 Agent
|
||||||
|
2. 新增 Agent
|
||||||
|
3. 修改 Agent 状态
|
||||||
|
4. 删除 Agent
|
||||||
|
5. 查看 Agent 工具
|
||||||
|
0. 退出程序
|
||||||
|
==============================
|
||||||
|
```
|
||||||
|
|
||||||
|
用户输入菜单编号后,程序执行对应功能:
|
||||||
|
|
||||||
|
- 输入 `1`:查看全部 Agent;
|
||||||
|
- 输入 `2`:新增 Agent;
|
||||||
|
- 输入 `3`:启用或停用 Agent;
|
||||||
|
- 输入 `4`:删除 Agent;
|
||||||
|
- 输入 `5`:查看指定 Agent 的工具;
|
||||||
|
- 输入 `0`:结束程序;
|
||||||
|
- 输入其他内容:显示“无效选项,请重新输入。”。
|
||||||
|
|
||||||
|
## 五、数据结构设计
|
||||||
|
|
||||||
|
所有 Agent 使用列表保存:
|
||||||
|
|
||||||
|
```python
|
||||||
|
agents = [
|
||||||
|
{
|
||||||
|
"name": "代码助手",
|
||||||
|
"model": "gpt-5",
|
||||||
|
"enabled": True,
|
||||||
|
"tools": ["搜索", "终端"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "聊天助手",
|
||||||
|
"model": "o3",
|
||||||
|
"enabled": False,
|
||||||
|
"tools": ["搜索"],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
选择这种结构的原因:
|
||||||
|
|
||||||
|
- 列表适合保存数量可以增加或减少的多条 Agent 记录;
|
||||||
|
- 每个 Agent 有多个不同含义的字段,适合使用字典;
|
||||||
|
- `tools` 是一组可以按顺序展示的工具,适合使用列表。
|
||||||
|
|
||||||
|
## 六、程序功能拆分
|
||||||
|
|
||||||
|
不要把所有代码都写进一个 `while` 循环。项目应拆分为以下函数。
|
||||||
|
|
||||||
|
### 6.1 `print_menu()`
|
||||||
|
|
||||||
|
职责:输出操作菜单。
|
||||||
|
|
||||||
|
- 参数:无;
|
||||||
|
- 返回值:无;
|
||||||
|
- 主要操作:使用多条 `print()` 输出菜单。
|
||||||
|
|
||||||
|
### 6.2 `print_agents(agents)`
|
||||||
|
|
||||||
|
职责:输出全部 Agent。
|
||||||
|
|
||||||
|
- 参数:Agent 列表;
|
||||||
|
- 返回值:无;
|
||||||
|
- 空列表时输出“当前没有 Agent。”;
|
||||||
|
- 非空时输出每个 Agent 的编号、名称、模型和状态。
|
||||||
|
|
||||||
|
预期格式:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 代码助手|模型:gpt-5|状态:启用
|
||||||
|
2. 聊天助手|模型:o3|状态:停用
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.3 `find_agent_by_name(agents, name)`
|
||||||
|
|
||||||
|
职责:按名称查找 Agent。
|
||||||
|
|
||||||
|
- 参数:Agent 列表和需要查找的名称;
|
||||||
|
- 找到时:返回对应的 Agent 字典;
|
||||||
|
- 未找到时:返回 `None`;
|
||||||
|
- 本函数只负责查找,不负责输出提示。
|
||||||
|
|
||||||
|
### 6.4 `add_agent(agents)`
|
||||||
|
|
||||||
|
职责:接收输入并新增 Agent。
|
||||||
|
|
||||||
|
执行顺序:
|
||||||
|
|
||||||
|
1. 输入 Agent 名称,并使用 `strip()` 清理两侧空白;
|
||||||
|
2. 名称为空时输出“Agent 名称不能为空。”并结束本次操作;
|
||||||
|
3. 调用 `find_agent_by_name()` 检查名称是否重复;
|
||||||
|
4. 名称重复时输出“该 Agent 已存在。”并结束本次操作;
|
||||||
|
5. 输入模型名称;
|
||||||
|
6. 输入工具,多个工具使用英文逗号分隔;
|
||||||
|
7. 使用 `split(",")` 拆分工具;
|
||||||
|
8. 清理每个工具两侧空白,并去掉空字符串;
|
||||||
|
9. 创建 Agent 字典,新 Agent 默认启用;
|
||||||
|
10. 使用 `append()` 加入列表并输出成功提示。
|
||||||
|
|
||||||
|
例如输入:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Agent 名称:搜索助手
|
||||||
|
模型名称:gpt-5
|
||||||
|
工具:搜索,网页浏览
|
||||||
|
```
|
||||||
|
|
||||||
|
新增后的字典应为:
|
||||||
|
|
||||||
|
```python
|
||||||
|
{
|
||||||
|
"name": "搜索助手",
|
||||||
|
"model": "gpt-5",
|
||||||
|
"enabled": True,
|
||||||
|
"tools": ["搜索", "网页浏览"],
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.5 `change_agent_status(agents)`
|
||||||
|
|
||||||
|
职责:修改指定 Agent 的启用状态。
|
||||||
|
|
||||||
|
执行顺序:
|
||||||
|
|
||||||
|
1. 输入 Agent 名称;
|
||||||
|
2. 调用 `find_agent_by_name()` 查找;
|
||||||
|
3. 未找到时输出“未找到该 Agent。”;
|
||||||
|
4. 找到时使用 `not` 反转 `enabled`;
|
||||||
|
5. 输出修改后的中文状态。
|
||||||
|
|
||||||
|
### 6.6 `delete_agent(agents)`
|
||||||
|
|
||||||
|
职责:删除指定 Agent。
|
||||||
|
|
||||||
|
执行顺序:
|
||||||
|
|
||||||
|
1. 输入 Agent 名称;
|
||||||
|
2. 调用 `find_agent_by_name()` 查找;
|
||||||
|
3. 未找到时输出“未找到该 Agent。”;
|
||||||
|
4. 找到时使用 `remove()` 删除整个 Agent 字典;
|
||||||
|
5. 输出“Agent 已删除。”。
|
||||||
|
|
||||||
|
### 6.7 `print_agent_tools(agents)`
|
||||||
|
|
||||||
|
职责:输出指定 Agent 的工具。
|
||||||
|
|
||||||
|
- 未找到 Agent 时输出“未找到该 Agent。”;
|
||||||
|
- 工具列表为空时输出“该 Agent 暂无工具。”;
|
||||||
|
- 有工具时按编号逐行输出。
|
||||||
|
|
||||||
|
预期格式:
|
||||||
|
|
||||||
|
```text
|
||||||
|
代码助手的工具:
|
||||||
|
1. 搜索
|
||||||
|
2. 终端
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.8 `main()`
|
||||||
|
|
||||||
|
职责:组织程序主流程。
|
||||||
|
|
||||||
|
执行顺序:
|
||||||
|
|
||||||
|
1. 创建初始 Agent 列表;
|
||||||
|
2. 使用 `while True` 持续显示菜单;
|
||||||
|
3. 使用 `input()` 接收菜单选项;
|
||||||
|
4. 使用 `if...elif...else` 分发功能;
|
||||||
|
5. 用户输入 `0` 时输出结束提示并使用 `break` 退出循环。
|
||||||
|
|
||||||
|
## 七、完整示例
|
||||||
|
|
||||||
|
示例文件:
|
||||||
|
|
||||||
|
```text
|
||||||
|
01_python基础/1_14_python基础综合项目/agent_manager.py
|
||||||
|
```
|
||||||
|
|
||||||
|
示例是完整可运行版本。建议先阅读讲义,再运行示例了解程序行为,最后关闭示例文件,独立完成 `practice.py`。
|
||||||
|
|
||||||
|
## 八、运行方法
|
||||||
|
|
||||||
|
在项目根目录执行示例:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python .\01_python基础\1_14_python基础综合项目\agent_manager.py
|
||||||
|
```
|
||||||
|
|
||||||
|
运行自己的项目练习:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python .\01_python基础\1_14_python基础综合项目\practice.py
|
||||||
|
```
|
||||||
|
|
||||||
|
程序等待输入时,在终端输入菜单编号并按回车。
|
||||||
|
|
||||||
|
## 九、建议开发顺序
|
||||||
|
|
||||||
|
不要一次写完整个项目。按照以下顺序逐步完成并运行:
|
||||||
|
|
||||||
|
1. 定义初始 Agent 列表;
|
||||||
|
2. 完成并测试 `print_menu()`;
|
||||||
|
3. 完成并测试 `print_agents()`;
|
||||||
|
4. 完成并测试 `find_agent_by_name()`;
|
||||||
|
5. 完成新增功能;
|
||||||
|
6. 完成状态修改功能;
|
||||||
|
7. 完成删除功能;
|
||||||
|
8. 完成工具查看功能;
|
||||||
|
9. 最后编写 `main()` 菜单循环;
|
||||||
|
10. 按验收用例完整测试。
|
||||||
|
|
||||||
|
每完成一个函数就运行一次,可以更早发现问题。
|
||||||
|
|
||||||
|
## 十、验收测试
|
||||||
|
|
||||||
|
### 测试一:查看初始数据
|
||||||
|
|
||||||
|
操作:输入 `1`。
|
||||||
|
|
||||||
|
预期:显示代码助手和聊天助手,状态分别为启用和停用。
|
||||||
|
|
||||||
|
### 测试二:新增 Agent
|
||||||
|
|
||||||
|
操作:
|
||||||
|
|
||||||
|
```text
|
||||||
|
输入菜单:2
|
||||||
|
名称:搜索助手
|
||||||
|
模型:gpt-5
|
||||||
|
工具:搜索,网页浏览
|
||||||
|
```
|
||||||
|
|
||||||
|
再次输入 `1`,预期显示三条 Agent 数据。
|
||||||
|
|
||||||
|
### 测试三:拒绝重复名称
|
||||||
|
|
||||||
|
再次新增“搜索助手”,预期输出“该 Agent 已存在。”,列表数量不增加。
|
||||||
|
|
||||||
|
### 测试四:修改状态
|
||||||
|
|
||||||
|
输入 `3` 并选择“聊天助手”,预期状态由停用变为启用。
|
||||||
|
|
||||||
|
### 测试五:查看工具
|
||||||
|
|
||||||
|
输入 `5` 并选择“代码助手”,预期依次显示“搜索”和“终端”。
|
||||||
|
|
||||||
|
### 测试六:删除 Agent
|
||||||
|
|
||||||
|
输入 `4` 并删除“聊天助手”,再次查看列表时不再显示它。
|
||||||
|
|
||||||
|
### 测试七:无效名称
|
||||||
|
|
||||||
|
查询、修改或删除一个不存在的名称,程序应显示提示且不崩溃。
|
||||||
|
|
||||||
|
### 测试八:无效菜单
|
||||||
|
|
||||||
|
输入 `9` 或任意未知内容,预期输出“无效选项,请重新输入。”,随后继续显示菜单。
|
||||||
|
|
||||||
|
### 测试九:退出程序
|
||||||
|
|
||||||
|
输入 `0`,预期输出“程序已退出。”并正常结束。
|
||||||
|
|
||||||
|
## 十一、常见错误
|
||||||
|
|
||||||
|
### 11.1 在函数内部重新创建列表
|
||||||
|
|
||||||
|
功能函数应修改 `main()` 传入的同一个列表。不要在 `add_agent()` 中重新创建一个无关列表。
|
||||||
|
|
||||||
|
### 11.2 查找失败后仍继续操作
|
||||||
|
|
||||||
|
如果 Agent 不存在,应使用提前返回结束函数,否则继续读取字典可能产生错误。
|
||||||
|
|
||||||
|
### 11.3 把布尔值保存为字符串
|
||||||
|
|
||||||
|
启用状态应使用 `True` 或 `False`,不要使用字符串 `"True"` 或 `"False"`。
|
||||||
|
|
||||||
|
### 11.4 忘记清理用户输入
|
||||||
|
|
||||||
|
名称和工具建议使用 `strip()`,否则多余空格可能导致名称匹配失败。
|
||||||
|
|
||||||
|
### 11.5 菜单无法退出
|
||||||
|
|
||||||
|
处理选项 `0` 时必须执行 `break`,否则 `while True` 会继续运行。
|
||||||
|
|
||||||
|
### 11.6 在导入文件时自动启动程序
|
||||||
|
|
||||||
|
示例最后使用:
|
||||||
|
|
||||||
|
```python
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
```
|
||||||
|
|
||||||
|
这是程序入口判断。本课先理解为:“直接运行当前文件时才调用 `main()`”。模块与包课程会进一步解释。
|
||||||
|
|
||||||
|
## 十二、项目小结
|
||||||
|
|
||||||
|
完成本项目后,你已经把前 13 课的知识组合成了一个完整程序:
|
||||||
|
|
||||||
|
- 字符串保存名称和模型;
|
||||||
|
- 布尔值保存启用状态;
|
||||||
|
- 列表保存多条记录和工具;
|
||||||
|
- 字典表示单个 Agent;
|
||||||
|
- 集合思想用于理解工具去重;
|
||||||
|
- 条件判断分发菜单操作;
|
||||||
|
- 循环维持程序运行并遍历数据;
|
||||||
|
- 函数拆分不同业务功能;
|
||||||
|
- 返回值传递查找结果。
|
||||||
|
|
||||||
|
## 十三、完成标准
|
||||||
|
|
||||||
|
- 所有菜单选项均能正常执行;
|
||||||
|
- 可以新增、查看、修改和删除 Agent;
|
||||||
|
- 可以查看指定 Agent 的工具;
|
||||||
|
- 重复名称不会被新增;
|
||||||
|
- 无效输入不会导致程序崩溃;
|
||||||
|
- 输入 `0` 可以正常退出;
|
||||||
|
- 每个函数只承担一个清晰职责;
|
||||||
|
- 变量名和函数名使用规范英文蛇形命名;
|
||||||
|
- 代码包含必要的中文注释;
|
||||||
|
- 九组验收测试全部通过。
|
||||||
194
01_python基础/1_14_python基础综合项目/agent_manager.py
Normal file
194
01_python基础/1_14_python基础综合项目/agent_manager.py
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
# 第 1-14 课完整示例:命令行 Agent 管理系统
|
||||||
|
#
|
||||||
|
# 本项目综合使用变量、字符串、列表、字典、条件判断、循环和函数。
|
||||||
|
# 建议先运行程序体验功能,再按照讲义中的开发顺序阅读代码。
|
||||||
|
|
||||||
|
|
||||||
|
def print_separator():
|
||||||
|
"""输出分隔线,让菜单和结果更容易阅读。"""
|
||||||
|
print("=" * 30)
|
||||||
|
|
||||||
|
|
||||||
|
def print_menu():
|
||||||
|
"""输出主菜单;本函数只负责显示,不需要返回值。"""
|
||||||
|
print_separator()
|
||||||
|
print("命令行 Agent 管理系统")
|
||||||
|
print("1. 查看全部 Agent")
|
||||||
|
print("2. 新增 Agent")
|
||||||
|
print("3. 修改 Agent 状态")
|
||||||
|
print("4. 删除 Agent")
|
||||||
|
print("5. 查看 Agent 工具")
|
||||||
|
print("0. 退出程序")
|
||||||
|
print_separator()
|
||||||
|
|
||||||
|
|
||||||
|
def get_status_text(enabled):
|
||||||
|
"""把布尔状态转换成适合显示的中文文本。"""
|
||||||
|
if enabled:
|
||||||
|
return "启用"
|
||||||
|
|
||||||
|
return "停用"
|
||||||
|
|
||||||
|
|
||||||
|
def print_agents(agents):
|
||||||
|
"""按照统一格式输出列表中的全部 Agent。"""
|
||||||
|
if not agents:
|
||||||
|
print("当前没有 Agent。")
|
||||||
|
return
|
||||||
|
|
||||||
|
print("全部 Agent:")
|
||||||
|
|
||||||
|
for number, agent in enumerate(agents, start=1):
|
||||||
|
status_text = get_status_text(agent["enabled"])
|
||||||
|
print(
|
||||||
|
f"{number}. {agent['name']}|"
|
||||||
|
f"模型:{agent['model']}|"
|
||||||
|
f"状态:{status_text}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def find_agent_by_name(agents, name):
|
||||||
|
"""按名称查找 Agent;找到时返回字典,否则返回 None。"""
|
||||||
|
for agent in agents:
|
||||||
|
if agent["name"] == name:
|
||||||
|
return agent
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def parse_tools(tools_text):
|
||||||
|
"""把英文逗号分隔的文本转换成没有空字符串的工具列表。"""
|
||||||
|
tools = []
|
||||||
|
|
||||||
|
for tool in tools_text.split(","):
|
||||||
|
clean_tool = tool.strip()
|
||||||
|
|
||||||
|
# 只添加非空工具,同时避免同一个工具重复出现。
|
||||||
|
if clean_tool and clean_tool not in tools:
|
||||||
|
tools.append(clean_tool)
|
||||||
|
|
||||||
|
return tools
|
||||||
|
|
||||||
|
|
||||||
|
def add_agent(agents):
|
||||||
|
"""接收用户输入,检查名称后新增 Agent。"""
|
||||||
|
name = input("请输入 Agent 名称:").strip()
|
||||||
|
|
||||||
|
if not name:
|
||||||
|
print("Agent 名称不能为空。")
|
||||||
|
return
|
||||||
|
|
||||||
|
if find_agent_by_name(agents, name) is not None:
|
||||||
|
print("该 Agent 已存在。")
|
||||||
|
return
|
||||||
|
|
||||||
|
model = input("请输入模型名称:").strip()
|
||||||
|
tools_text = input("请输入工具,多个工具使用英文逗号分隔:")
|
||||||
|
tools = parse_tools(tools_text)
|
||||||
|
|
||||||
|
new_agent = {
|
||||||
|
"name": name,
|
||||||
|
"model": model,
|
||||||
|
"enabled": True,
|
||||||
|
"tools": tools,
|
||||||
|
}
|
||||||
|
|
||||||
|
agents.append(new_agent)
|
||||||
|
print("Agent 新增成功。")
|
||||||
|
|
||||||
|
|
||||||
|
def change_agent_status(agents):
|
||||||
|
"""查找指定 Agent,并反转它的启用状态。"""
|
||||||
|
name = input("请输入需要修改状态的 Agent 名称:").strip()
|
||||||
|
agent = find_agent_by_name(agents, name)
|
||||||
|
|
||||||
|
if agent is None:
|
||||||
|
print("未找到该 Agent。")
|
||||||
|
return
|
||||||
|
|
||||||
|
agent["enabled"] = not agent["enabled"]
|
||||||
|
status_text = get_status_text(agent["enabled"])
|
||||||
|
print(f"状态修改成功,当前状态:{status_text}。")
|
||||||
|
|
||||||
|
|
||||||
|
def delete_agent(agents):
|
||||||
|
"""查找并删除指定 Agent。"""
|
||||||
|
name = input("请输入需要删除的 Agent 名称:").strip()
|
||||||
|
agent = find_agent_by_name(agents, name)
|
||||||
|
|
||||||
|
if agent is None:
|
||||||
|
print("未找到该 Agent。")
|
||||||
|
return
|
||||||
|
|
||||||
|
agents.remove(agent)
|
||||||
|
print("Agent 已删除。")
|
||||||
|
|
||||||
|
|
||||||
|
def print_agent_tools(agents):
|
||||||
|
"""输出指定 Agent 的全部工具。"""
|
||||||
|
name = input("请输入需要查看工具的 Agent 名称:").strip()
|
||||||
|
agent = find_agent_by_name(agents, name)
|
||||||
|
|
||||||
|
if agent is None:
|
||||||
|
print("未找到该 Agent。")
|
||||||
|
return
|
||||||
|
|
||||||
|
tools = agent.get("tools", [])
|
||||||
|
|
||||||
|
if not tools:
|
||||||
|
print("该 Agent 暂无工具。")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"{agent['name']}的工具:")
|
||||||
|
|
||||||
|
for number, tool in enumerate(tools, start=1):
|
||||||
|
print(f"{number}. {tool}")
|
||||||
|
|
||||||
|
|
||||||
|
def create_initial_agents():
|
||||||
|
"""创建程序启动时使用的初始 Agent 数据。"""
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"name": "代码助手",
|
||||||
|
"model": "gpt-5",
|
||||||
|
"enabled": True,
|
||||||
|
"tools": ["搜索", "终端"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "聊天助手",
|
||||||
|
"model": "o3",
|
||||||
|
"enabled": False,
|
||||||
|
"tools": ["搜索"],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""创建数据并通过循环组织整个菜单流程。"""
|
||||||
|
agents = create_initial_agents()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
print_menu()
|
||||||
|
choice = input("请输入菜单编号:").strip()
|
||||||
|
|
||||||
|
if choice == "1":
|
||||||
|
print_agents(agents)
|
||||||
|
elif choice == "2":
|
||||||
|
add_agent(agents)
|
||||||
|
elif choice == "3":
|
||||||
|
change_agent_status(agents)
|
||||||
|
elif choice == "4":
|
||||||
|
delete_agent(agents)
|
||||||
|
elif choice == "5":
|
||||||
|
print_agent_tools(agents)
|
||||||
|
elif choice == "0":
|
||||||
|
print("程序已退出。")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print("无效选项,请重新输入。")
|
||||||
|
|
||||||
|
|
||||||
|
# 只有直接运行当前文件时才启动菜单。
|
||||||
|
# 后续“模块与包”课程会进一步解释 __name__ 的作用。
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
135
01_python基础/1_14_python基础综合项目/practice.py
Normal file
135
01_python基础/1_14_python基础综合项目/practice.py
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
# 第 1-14 课课堂练习:命令行 Agent 管理系统
|
||||||
|
#
|
||||||
|
# 这是 Python 基础阶段综合项目,请按照题目顺序逐步完成。
|
||||||
|
# 完成要求:
|
||||||
|
# 1. 每完成一个函数就单独调用并测试,不要等全部写完再运行。
|
||||||
|
# 2. 需要查找结果时使用 return,不要依赖全局变量传递结果。
|
||||||
|
# 3. 函数名和变量名使用有意义的英文蛇形命名。
|
||||||
|
# 4. 函数体使用四个空格缩进,并添加必要的中文注释。
|
||||||
|
# 5. 不要删除题目、测试数据、预期结果和自查注释。
|
||||||
|
# 6. 完成所有功能后,再执行末尾列出的九组验收测试。
|
||||||
|
|
||||||
|
|
||||||
|
# 第一部分:准备初始数据
|
||||||
|
# 创建列表 agents,其中包含以下两个字典:
|
||||||
|
# 1. name="代码助手"、model="gpt-5"、enabled=True、tools=["搜索", "终端"];
|
||||||
|
# 2. name="聊天助手"、model="o3"、enabled=False、tools=["搜索"]。
|
||||||
|
# 完成后临时使用 print(agents) 检查结构,确认每个 Agent 都是一个字典。
|
||||||
|
|
||||||
|
|
||||||
|
# 第二部分:定义 print_menu() 函数
|
||||||
|
# 1. 函数不接收参数,也不需要 return。
|
||||||
|
# 2. 使用 print() 输出以下菜单:
|
||||||
|
# 1. 查看全部 Agent
|
||||||
|
# 2. 新增 Agent
|
||||||
|
# 3. 修改 Agent 状态
|
||||||
|
# 4. 删除 Agent
|
||||||
|
# 5. 查看 Agent 工具
|
||||||
|
# 0. 退出程序
|
||||||
|
# 3. 单独调用一次 print_menu(),确认六个选项均正确显示。
|
||||||
|
|
||||||
|
|
||||||
|
# 第三部分:定义 get_status_text(enabled) 函数
|
||||||
|
# 1. 参数 enabled 接收布尔值。
|
||||||
|
# 2. enabled 为 True 时 return "启用",否则 return "停用"。
|
||||||
|
# 3. 分别传入 True 和 False,保存并输出返回值。
|
||||||
|
# 4. 两次预期输出分别为“启用”和“停用”。
|
||||||
|
|
||||||
|
|
||||||
|
# 第四部分:定义 print_agents(agents) 函数
|
||||||
|
# 1. 参数 agents 接收 Agent 列表,本函数只负责输出,不需要 return。
|
||||||
|
# 2. 如果列表为空,输出“当前没有 Agent。”并提前结束函数。
|
||||||
|
# 3. 如果列表非空,使用 enumerate(agents, start=1) 遍历。
|
||||||
|
# 4. 调用 get_status_text() 得到中文状态。
|
||||||
|
# 5. 每条记录按照以下格式输出:
|
||||||
|
# 1. 代码助手|模型:gpt-5|状态:启用
|
||||||
|
# 6. 分别传入初始 agents 和空列表 [] 测试两个分支。
|
||||||
|
|
||||||
|
# 第五部分:定义 find_agent_by_name(agents, name) 函数
|
||||||
|
# 1. 遍历 agents,比较 agent["name"] 和参数 name。
|
||||||
|
# 2. 找到同名 Agent 时,立即 return 对应的 Agent 字典。
|
||||||
|
# 3. 循环结束仍未找到时,return None。
|
||||||
|
# 4. 查找“代码助手”,预期返回对应字典。
|
||||||
|
# 5. 查找“不存在的助手”,预期返回 None。
|
||||||
|
# 注意:本函数只负责查找,不在函数内部输出“找到”或“未找到”。
|
||||||
|
|
||||||
|
# 第六部分:定义 parse_tools(tools_text) 函数
|
||||||
|
# 1. 参数接收英文逗号分隔的工具文本。
|
||||||
|
# 2. 使用 tools_text.split(",") 拆分字符串。
|
||||||
|
# 3. 遍历拆分结果,对每个工具调用 strip()。
|
||||||
|
# 4. 只把非空且尚未存在的工具加入结果列表。
|
||||||
|
# 5. 使用 "搜索, 终端,搜索, ,计算器" 测试。
|
||||||
|
# 6. 预期返回 ["搜索", "终端", "计算器"]。
|
||||||
|
|
||||||
|
# 第七部分:定义 add_agent(agents) 函数
|
||||||
|
# 1. 输入 Agent 名称并清理两侧空白。
|
||||||
|
# 2. 名称为空时输出“Agent 名称不能为空。”并提前 return。
|
||||||
|
# 3. 调用 find_agent_by_name() 检查名称;重复时输出“该 Agent 已存在。”并 return。
|
||||||
|
# 4. 输入模型名称。
|
||||||
|
# 5. 输入英文逗号分隔的工具文本,并调用 parse_tools() 得到工具列表。
|
||||||
|
# 6. 创建包含 name、model、enabled 和 tools 的字典,新 Agent 默认 enabled=True。
|
||||||
|
# 7. 使用 agents.append() 添加字典,并输出“Agent 新增成功。”。
|
||||||
|
# 8. 新增“搜索助手”后调用 print_agents(),预期列表共有三条记录。
|
||||||
|
|
||||||
|
|
||||||
|
# 第八部分:定义 change_agent_status(agents) 函数
|
||||||
|
# 1. 输入 Agent 名称并调用 find_agent_by_name()。
|
||||||
|
# 2. 未找到时输出“未找到该 Agent。”并提前 return。
|
||||||
|
# 3. 找到时执行 agent["enabled"] = not agent["enabled"]。
|
||||||
|
# 4. 调用 get_status_text() 得到修改后的中文状态并输出。
|
||||||
|
# 5. 修改“聊天助手”后,它的状态应由 False 变为 True。
|
||||||
|
|
||||||
|
|
||||||
|
# 第九部分:定义 delete_agent(agents) 函数
|
||||||
|
# 1. 输入 Agent 名称并调用 find_agent_by_name()。
|
||||||
|
# 2. 未找到时输出“未找到该 Agent。”并提前 return。
|
||||||
|
# 3. 找到时使用 agents.remove(agent) 删除整个字典。
|
||||||
|
# 4. 输出“Agent 已删除。”。
|
||||||
|
# 5. 删除“聊天助手”后调用 print_agents(),确认它不再出现。
|
||||||
|
|
||||||
|
|
||||||
|
# 第十部分:定义 print_agent_tools(agents) 函数
|
||||||
|
# 1. 输入 Agent 名称并调用 find_agent_by_name()。
|
||||||
|
# 2. 未找到时输出“未找到该 Agent。”并提前 return。
|
||||||
|
# 3. 使用 agent.get("tools", []) 安全读取工具列表。
|
||||||
|
# 4. 工具列表为空时输出“该 Agent 暂无工具。”并提前 return。
|
||||||
|
# 5. 有工具时使用 enumerate(tools, start=1) 遍历并按编号输出。
|
||||||
|
# 6. 查看“代码助手”时,预期依次显示“搜索”和“终端”。
|
||||||
|
|
||||||
|
|
||||||
|
# 第十一部分:定义 main() 函数
|
||||||
|
# 1. 在函数内部使用 while True 持续运行菜单。
|
||||||
|
# 2. 每轮先调用 print_menu(),再用 input() 接收菜单编号并调用 strip()。
|
||||||
|
# 3. 使用 if...elif...else 完成以下分发:
|
||||||
|
# "1" 调用 print_agents(agents);
|
||||||
|
# "2" 调用 add_agent(agents);
|
||||||
|
# "3" 调用 change_agent_status(agents);
|
||||||
|
# "4" 调用 delete_agent(agents);
|
||||||
|
# "5" 调用 print_agent_tools(agents);
|
||||||
|
# "0" 输出“程序已退出。”并使用 break 结束循环;
|
||||||
|
# 其他内容输出“无效选项,请重新输入。”。
|
||||||
|
# 4. 在文件最后调用 main(),启动完整程序。
|
||||||
|
|
||||||
|
# 最终验收测试:
|
||||||
|
# 1. 输入 1,确认显示两个初始 Agent;
|
||||||
|
# 2. 输入 2,新增“搜索助手”,再次查看时共有三条记录;
|
||||||
|
# 3. 再次新增“搜索助手”,确认重复名称被拒绝;
|
||||||
|
# 4. 输入 3,把“聊天助手”从停用修改为启用;
|
||||||
|
# 5. 输入 5,确认“代码助手”显示两个工具;
|
||||||
|
# 6. 输入 4,删除“聊天助手”,确认列表中不再显示它;
|
||||||
|
# 7. 使用不存在的名称进行查询、修改或删除,确认程序不崩溃;
|
||||||
|
# 8. 输入 9,确认显示无效选项后菜单继续运行;
|
||||||
|
# 9. 输入 0,确认程序正常退出。
|
||||||
|
|
||||||
|
|
||||||
|
# 完成后进行代码自查:
|
||||||
|
# 1. 是否使用列表保存多个 Agent;
|
||||||
|
# 2. 每个 Agent 是否使用字典表示;
|
||||||
|
# 3. enabled 是否使用真正的布尔值;
|
||||||
|
# 4. find_agent_by_name() 是否返回字典或 None;
|
||||||
|
# 5. 查找失败后是否提前 return;
|
||||||
|
# 6. 是否使用函数拆分不同功能;
|
||||||
|
# 7. 菜单循环是否能够正常退出;
|
||||||
|
# 8. 重复名称是否不会被添加;
|
||||||
|
# 9. 工具文本是否完成拆分、清理和去重;
|
||||||
|
# 10. 九组验收测试是否全部通过。
|
||||||
21
README.md
21
README.md
@@ -189,12 +189,12 @@ Python/
|
|||||||
## 当前学习进度
|
## 当前学习进度
|
||||||
|
|
||||||
- 当前阶段:第一阶段——Python 基础语法。
|
- 当前阶段:第一阶段——Python 基础语法。
|
||||||
- 当前课程:`1_13_函数进阶`。
|
- 当前课程:`1_14_python基础综合项目`。
|
||||||
- 当前状态:第 1~13 课全部完成。
|
- 当前状态:第一阶段 Python 基础课程已完成。
|
||||||
- 已完成课程:`1_1_hello_world` 至 `1_13_函数进阶`。
|
- 已完成课程:`1_1_hello_world` 至 `1_14_python基础综合项目`。
|
||||||
- 学习中的课程:暂无。
|
- 学习中的课程:暂无。
|
||||||
- 已创建课程目录:`01_python基础/1_1_hello_world/` 至 `01_python基础/1_13_函数进阶/`。
|
- 已创建课程目录:`01_python基础/1_1_hello_world/` 至 `01_python基础/1_14_python基础综合项目/`。
|
||||||
- 下一步:进行第一阶段知识复习,并准备 Python 基础综合项目。
|
- 下一步:进入第二阶段 Python 进阶,学习模块与包。
|
||||||
|
|
||||||
## 建议环境
|
## 建议环境
|
||||||
|
|
||||||
@@ -209,9 +209,10 @@ Python/
|
|||||||
|
|
||||||
## 下一步
|
## 下一步
|
||||||
|
|
||||||
第 1~13 课已经完成。接下来将进行:
|
第一阶段 Python 基础课程已经完成。下一课将学习:
|
||||||
|
|
||||||
1. 回顾变量、条件判断、循环和常用数据结构;
|
1. 模块是什么,以及为什么要拆分文件;
|
||||||
2. 回顾函数、参数和返回值;
|
2. 使用 `import` 导入模块;
|
||||||
3. 完成 Python 基础阶段测试;
|
3. 使用 `from...import...` 导入指定内容;
|
||||||
4. 开始 Python 基础综合项目。
|
4. 理解 `__name__ == "__main__"`;
|
||||||
|
5. 创建和使用自己的模块与包。
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
# 第八课“列表”教学设计
|
|
||||||
|
|
||||||
## 一、设计目标
|
|
||||||
|
|
||||||
第八课面向已经掌握字符串、条件判断和循环的零基础学习者,目标是让学习者理解“一个变量保存多个有序数据”的需求,并能够使用列表完成基础数据管理。
|
|
||||||
|
|
||||||
本课只讲列表,不讲元组。元组调整为独立的第九课。列表推导式保留到 Python 进阶阶段,避免本课知识密度过高。
|
|
||||||
|
|
||||||
## 二、课程目录
|
|
||||||
|
|
||||||
```text
|
|
||||||
01_python基础/1_8_列表/
|
|
||||||
├── README.md
|
|
||||||
├── lists.py
|
|
||||||
└── practice.py
|
|
||||||
```
|
|
||||||
|
|
||||||
- `README.md`:中文讲义、运行方法、常见错误、练习说明和验收标准。
|
|
||||||
- `lists.py`:带有详细中文注释的可运行示例。
|
|
||||||
- `practice.py`:只包含题目和提示,不预填答案。
|
|
||||||
|
|
||||||
## 三、知识范围
|
|
||||||
|
|
||||||
本课覆盖:
|
|
||||||
|
|
||||||
1. 创建列表和空列表;
|
|
||||||
2. 列表索引、负索引与切片;
|
|
||||||
3. 使用 `len()` 获取元素数量;
|
|
||||||
4. 修改指定位置的元素;
|
|
||||||
5. 使用 `append()`、`insert()` 添加元素;
|
|
||||||
6. 使用 `remove()`、`pop()` 和 `del` 删除元素;
|
|
||||||
7. 使用 `in` 判断成员;
|
|
||||||
8. 使用 `index()`、`count()` 查找和统计;
|
|
||||||
9. 使用 `sort()`、`reverse()` 排序和反转;
|
|
||||||
10. 使用 `for` 遍历列表;
|
|
||||||
11. 使用 `range(len(...))` 在确实需要索引时遍历;
|
|
||||||
12. 简单认识二维列表;
|
|
||||||
13. 理解列表可变性;
|
|
||||||
14. 区分直接赋值与浅复制列表的基础行为。
|
|
||||||
|
|
||||||
本课不覆盖:
|
|
||||||
|
|
||||||
- 元组;
|
|
||||||
- 列表推导式;
|
|
||||||
- 深复制;
|
|
||||||
- 复杂排序键;
|
|
||||||
- 列表内部实现与性能分析。
|
|
||||||
|
|
||||||
## 四、教学顺序
|
|
||||||
|
|
||||||
课程按照“读取 → 修改 → 增删 → 查询 → 排序 → 遍历 → 复制”的顺序推进。
|
|
||||||
|
|
||||||
先使用字符串索引和切片作为已有知识连接点,再说明字符串不可变而列表可变。随后通过 Agent 工具名称列表演示列表的常见操作,最后介绍直接赋值导致两个变量引用同一个列表的现象。
|
|
||||||
|
|
||||||
## 五、示例程序
|
|
||||||
|
|
||||||
`lists.py` 使用 Agent 开发工具清单作为统一业务背景,依次演示:
|
|
||||||
|
|
||||||
- 读取第一个和最后一个工具;
|
|
||||||
- 取得列表切片;
|
|
||||||
- 修改工具名称;
|
|
||||||
- 添加和删除工具;
|
|
||||||
- 查询某工具是否存在;
|
|
||||||
- 排序并遍历工具;
|
|
||||||
- 使用二维列表表示工具名称与用途;
|
|
||||||
- 对比直接赋值和 `copy()` 的结果。
|
|
||||||
|
|
||||||
示例不要求用户输入,确保可以直接运行并稳定复现结果。
|
|
||||||
|
|
||||||
## 六、课堂练习
|
|
||||||
|
|
||||||
`practice.py` 的项目名称为“Agent 工具清单管理器”。
|
|
||||||
|
|
||||||
练习要求学习者:
|
|
||||||
|
|
||||||
1. 创建初始工具列表;
|
|
||||||
2. 输出长度、首项和末项;
|
|
||||||
3. 添加两个工具;
|
|
||||||
4. 在指定位置插入工具;
|
|
||||||
5. 修改一个元素;
|
|
||||||
6. 判断并删除指定工具;
|
|
||||||
7. 使用 `pop()` 取得被删除的数据;
|
|
||||||
8. 对列表排序;
|
|
||||||
9. 遍历并输出编号;
|
|
||||||
10. 统计指定工具出现次数;
|
|
||||||
11. 创建列表副本并验证修改副本不影响原列表;
|
|
||||||
12. 输出最终管理报告。
|
|
||||||
|
|
||||||
练习文件只提供中文注释、测试数据和预期核心结果,不包含参考答案。
|
|
||||||
|
|
||||||
## 七、错误处理边界
|
|
||||||
|
|
||||||
本课在调用 `remove()` 和 `index()` 前先使用 `in` 判断,避免因元素不存在产生 `ValueError`。
|
|
||||||
|
|
||||||
访问首尾元素前应确认列表非空。复杂异常处理将在后续课程讲解,本课使用条件判断保护常见边界。
|
|
||||||
|
|
||||||
## 八、验证方式
|
|
||||||
|
|
||||||
创建课程后执行:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
python lists.py
|
|
||||||
python practice.py
|
|
||||||
```
|
|
||||||
|
|
||||||
验收要求:
|
|
||||||
|
|
||||||
- `lists.py` 正常退出且输出覆盖所有主要列表操作;
|
|
||||||
- 空白 `practice.py` 可以正常执行;
|
|
||||||
- `practice.py` 不包含非注释答案;
|
|
||||||
- 根目录 `README.md` 的当前课程更新为 `1_8_列表`;
|
|
||||||
- 不创建 `1_9_元组` 目录;
|
|
||||||
- 不修改第六、七课文件。
|
|
||||||
|
|
||||||
## 九、后续课程调整
|
|
||||||
|
|
||||||
第九课单独讲解元组,重点包括创建、单元素元组、索引切片、不可变性、解包和适用场景。字典、集合及后续课程编号依次顺延,实际目录仍按照学习进度逐课创建。
|
|
||||||
Reference in New Issue
Block a user