1.综合代码
"""
题目描述
设计一个简单的图书借阅管理系统。系统初始包含若干本图书,每本图书的信息包括:
书号(字符串)
书名(字符串)
作者(字符串)
库存数量(整数)
另外,系统需记录借阅记录(列表,存储每笔借阅的字典)。程序通过菜单实现以下功能:
查看所有图书:以表格形式显示所有图书的书号、书名、作者、库存。
借书:输入书号和借阅数量,如果库存足够则减少库存,并添加一条借阅记录(包含书号、书名、借阅数量、借阅日期(可简化为当天日期字符串))。如果库存不足,提示失败。
还书:输入书号和归还数量,增加对应图书的库存,并从借阅记录中删除相应的借阅(按先进先出原则,或简单按书号匹配)。若归还数量大于该书的借出总量,则提示错误。
查询某本书的借阅情况:输入书号,显示该书当前被借出的总数量和所有借阅记录的详情(借阅数量、借阅日期)。
退出系统:结束程序。
要求:
数据初始化:至少预置 3 本图书和若干条借阅记录(可手动在代码中定义)。
菜单循环,用户输入 1~5 选择功能。
--------------
1.查看所有图书
2.借书
3.还书
4.查询某本书的借阅情况
5.退出系统
--------------
对用户输入做简单的有效性检查(如书号不存在、数量非法等)。
参考代码
python
# 初始化图书库存
books = {
"B001": {"name": "Python编程", "author": "张三", "stock": 5},
"B002": {"name": "数据结构", "author": "李四", "stock": 3},
"B003": {"name": "算法导论", "author": "王五", "stock": 0}
}
# 初始化借阅记录
borrow_records = [
{"book_id": "B001", "book_name": "Python编程", "quantity": 1, "date": "2026-03-25"},
{"book_id": "B002", "book_name": "数据结构", "quantity": 2, "date": "2026-03-26"}
]
"""
# 初始化图书库存
books = {
"B001": {"name": "Python编程", "author": "张三", "stock": 5},
"B002": {"name": "数据结构", "author": "李四", "stock": 8},
"B003": {"name": "算法导论", "author": "王五", "stock": 0}
}
# 初始化借阅记录
borrow_records = [
{"book_id": "B001", "book_name": "Python编程", "quantity": 3, "date": "2026-03-25"},
{"book_id": "B002", "book_name": "数据结构", "quantity": 3, "date": "2026-03-26"}
]
menu="""
--------------
1.查看所有图书
2.借书
3.还书
4.查询某本书的借阅情况
5.退出系统
--------------
"""
while True:
print(menu)
fun_choose=input("请输入你选择的功能:")
if fun_choose=="1":
# 遍历
for key,val in books.items():
print(f"书号:{key},书名:{val["name"]},作者:{val["author"]},库存:{val["stock"]}")
elif fun_choose=="2":
# 借书:输入书号和借阅数量,如果库存足够则减少库存,并添加一条借阅记录(包含书号、书名、借阅数量、借阅日期(可简化为当天日期字符串))。如果库存不足,提示失败。
borrow_book_id=input("请输入你要借的书号:")
# 有效判断,有没有这个书
if borrow_book_id in books:
# 有书,再看库存
kucun_number=books[borrow_book_id]["stock"]
if kucun_number>0:
# 有库存>0
borrow_book_number=int(input("请输入借阅数量:"))
# 借阅数量有效验证
if borrow_book_number >0:
if borrow_book_number<=kucun_number:
# 库存足够,借阅成功,减少该书数量
books[borrow_book_id]["stock"]-=borrow_book_number
# 并添加一条借阅记录(包含书号、书名、借阅数量、借阅日期(可简化为当天日期字符串))
# 获取系统日期
import datetime
borrow_book_date = datetime.date.today().strftime("%Y-%m-%d")
borrow_book_name=books[borrow_book_id]["name"]
borrow_record= dict(book_id=borrow_book_id, book_name=borrow_book_name, quantity=borrow_book_number, date=borrow_book_date)
borrow_records.append(borrow_record)
print(f"借阅成功!你借了{borrow_book_number}本{borrow_book_name},借阅日期是{borrow_book_date}")
else:
# 借阅数量过多,没有足够的书本
print(f"没有足够的书本,书本库存数{kucun_number},你借阅的数量{borrow_book_number}")
else:
print(f"{borrow_book_number},借阅数量非法")
else:
print("该书本无库存,无法借阅")
else:
print("书号不存在")
elif fun_choose=="3":
#还书:输入书号和归还数量,增加对应图书的库存,并从借阅记录中删除相应的借阅(按先进先出原则,或简单按书号匹配)。 若归还数量大于该书的借出总量,则提示错误。
# 这里逻辑要理清楚,很容易错
# 先不考虑多了,直接按书号匹配,考虑数量易出现问题
# 1. 简单按书号匹配,按先进先出原则,删除第一条匹配到的记录
return_book_id=input("请输入你需要归还的书号:")
# 查询是否书号在归还列表里
is_book_id=False
for i,borrow_record in enumerate(borrow_records):
if borrow_record["book_id"]==return_book_id:
is_book_id=True
# 增加库存
books[return_book_id]["stock"]+=borrow_record["quantity"]
# 删除借阅记录
borrow_records.remove(borrow_record) # 这里简单按书号匹配,删除第一条匹配到的记录
print(f"归还成功!你归还了{borrow_record["quantity"]}本{borrow_record["book_name"]}")
break
if not is_book_id:
print("该书号不在归还列表里,返回菜单...")
break
elif fun_choose=="4":
# 看一下所有借书记录borrow_records
# for i in borrow_records:
# print(i)
# 查询某本书的借阅情况:输入书号,显示该书当前被借出的总数量和所有借阅记录的详情(借阅数量、借阅日期)。
query_book_id=input("请输入你要查询的书号:")
borrow_total_number=0
for borrow_record in borrow_records:
if borrow_record["book_id"]==query_book_id:
# 累加数量
borrow_total_number+=borrow_record["quantity"]
# 借阅记录的详情(借阅数量、借阅日期)
print(f"借阅数量:{borrow_record["quantity"]},借阅日期:{borrow_record["date"]}")
#通过借阅的总数量,判断该书的借阅情况,无需额外开个标记来判断
if borrow_total_number!=0:
#总数量统计完成
print(f"该书当前被借出的总数量:{borrow_total_number}")
else:
print("没有该书的借阅情况")
elif fun_choose=="5":
print("退出系统")
break
else:
print("没有这个功能,请重新选择!")
# 我额外添加方便我看
if fun_choose=="6":
# 看一下所有借书记录borrow_records
# borrow_records.pop(0) # 这里简单按书号匹配,删除第一条匹配到的记录
for i,j in enumerate(borrow_records):
print(f"索引: {i}, 记录: {j}")
2.笔记
Python 基础学习笔记
第1天:Python基础入门
1. 注释符号
# 单行注释:从#开始到这一行结束,中间写的内容不会被python解释器识别
'''
多行注释
使用三个单引号
'''
"""
这个同样是多行注释
使用三个双引号
"""
要点:
- 单行注释用
# - 多行注释用
'''或""" - 如果多行注释没有赋值给变量,就是注释;赋值给变量,就是字符串
2. 输入与输出
# 输出函数 print()
print("hello world")
print(1, 2, 3, "这厮") # 可同时输出多个参数,用逗号隔开
# print默认会换行,可用 help(print) 查看帮助
# 输入函数 input("提示词")
name = input("请输入你的姓名:")
# 程序会卡顿在这个位置,直到用户按下Enter回车键
要点:
-
print()默认换行 -
input()返回的永远是字符串类型 - Python靠缩进决定代码层级,不要随便缩进(会报
IndentationError)
3. 变量
# 变量:存储数据的容器
# 变量名 = 数据 (= 是赋值,不是数学里的等于)
# 动态数据类型(同一个变量名可以存储不同类型的数据,当前存什么类型数据就是什么类型)
num1 = "字符串"
num1 = 11 # 现在变成整数了
# 链式赋值
num2, num3 = 1, 2
# 变量名命名规则:
# 1. 必须是有效字符:大小写字母、数字、下划线
# 2. 不能以数字开头
# 3. 不能有空格
# 4. 不使用关键字和保留字(help("keywords") 查看关键字)
# 5. 严格区分大小写
# 6. 长变量名采用蛇形命名:select_username_from_students(推荐)
# 7. 见名知义
4. 基本数据类型
# 基本数据类型:int(整数) float(浮点数) complex(复数) str(字符串) bool(布尔)
# type() 获取数据类型
print(type(-22)) # <class 'int'>
print(type(-1.11111)) # <class 'float'>
# 字符串
str1 = "zhangsan"
str2 = 'i\'am zhangsan' # \ 转义字符,去除后面字符的特殊含义
# 三引号字符串可以换行
str3 = """
a
v
f
g
"""
# 布尔类型:True(1) False(0)
print(type(True)) # <class 'bool'>
5. 字符串格式化输出
username = input("username:")
age = input("age:")
# 方法1:% 占位符
# %s:字符串 %d:整数 %f:浮点数
print("用户的math值是:%.2f,用户的年龄是:%d" % (math, age))
# 方法2:str.format()
print("用户的math值是:{},用户的年龄是:{}".format(math, age))
# 方法3:f-string(最推荐)
print(f"用户的math值是:{math:.2f},用户的年龄是:{age}")
第2天:运算符与数据类型转换
1. 数据类型转换
# 隐式转换:自动进行
print(1 + 1.11) # 2.1100000000000003
# 显式转换(强制转换)
a = int(input("num1")) # 转为整数,可指定进制:int("111000", 16)
print(float(10)) # 转为浮点数
print(str(12)) # 转为字符串
print(bool(0)) # 转为布尔值,非0数字都是True,""和0是False
# isinstance() 判断数据类型
print(isinstance(a, str)) # True/False
注意: input() 输入的永远是字符串,需要计算时必须转换!
2. 算术运算符
+ # 加
- # 减
* # 乘
/ # 除(结果默认是浮点数)
// # 整除(向下取整)
% # 取余数(判断奇偶:num % 2 == 0)
** # 幂运算(3**3 = 27)
3. 比较运算符
== # 等于(判断值是否相等)
!= # 不等于
< # 小于
> # 大于
<= # 小于等于
>= # 大于等于
# 返回结果是布尔值
注意: = 是赋值,== 才是判断是否相等
4. 逻辑运算符
and # 两边都为真,结果才为真
or # 一边为真,结果为真
not # 取反
# 重要:and/or/not 返回的是操作数本身,不是True/False
# and 短路求值:
# 左边为假,返回左边(右边不计算)
# 左边为真,返回右边
# or 短路求值:
# 左边为真,返回左边
# 左边为假,返回右边
# 实际实例,设置默认值
passwd = input("password:")
user_passwd = passwd or "openlab123" # 用户没输入就用默认值"openlab123"
5. 赋值运算符
= # 赋值
+= # a += 13 等价于 a = a + 13
-= # a -= 1 等价于 a = a - 1
*= # a *= 2 等价于 a = a * 2
/= # a /= 3 等价于 a = a / 3
%= # 取余赋值
**= # 幂赋值
6. 位运算符(了解)
& # 按位与:两位都为1,结果才为1
| # 按位或:一个1则为1
^ # 按位异或:相同为0,不同为1
~ # 按位取反
<< # 左移:右侧补0(左移n位 = 乘以2的n次方)
>> # 右移:左侧补符号位(右移n位 = 除以2的n次方)
#处理都是转换成二进制
print(11 & 10) # 10
print(11 | 10) # 11
print(11 ^ 10) # 1
print(8 << 2) # 32
print(8 >> 2) # 2
负数运算基于补码
7. 成员运算符
in # 在...里面
not in # 不在...里面
print("a" in "abcdcdc") # True
第3天:程序控制流程
1. 三大结构
| 结构 | 说明 |
|---|---|
| 顺序结构 | 代码默认从上到下,从左到右执行 |
| 选择结构 | 根据不同条件,执行不同代码块 |
| 循环结构 | 当条件成立时,重复执行一段代码 |
2. 选择结构
单分支 if
if 条件:
# 条件为True时执行的代码块(缩进!)
# 示例:判断偶数
num1 = int(input("num1:"))
if num1 % 2 == 0:
print(f"{num1}是偶数")
双分支 if-else
if 条件:
# 条件为真时执行
else:
# 条件为假时执行
# 示例:判断闰年
year = int(input("year:"))
if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
print(f"{year}是闰年")
else:
print(f"{year}不是闰年")
多分支 if-elif-else
if 条件1:
# 条件1成立
elif 条件2:
# 条件2成立
elif 条件3:
# 条件3成立
else:
# 以上都不满足
# 示例:判断季节
month = 6
if isinstance(month, int) and 0 < month <= 12:
if 1 <= month <= 3:
print("春天")
elif 4 <= month <= 6:
print("夏天")
elif 7 <= month <= 9:
print("秋天")
else:
print("冬天")
else:
print("请输入正常的月份")
三元运算符(双分支简写)
# 值1 if 条件 else 值2
# 条件成立执行值1,不成立执行值2
# 示例:小于10的数字前面补0
num1 = int(input("num1:"))
num1 = "0" + str(num1) if num1 < 10 else num1
3. 循环结构
for 循环(用于遍历序列)
for 临时变量 in 序列|容器:
循环体
# range() 生成数字序列
range(end) # [0, end)
range(start, end) # [start, end)
range(start, end, step) # 带步长
# 示例:打印5次hello
for i in range(5):
print("hello, python")
# 示例:100-200偶数之和
sum = 0
for i in range(100, 201):
if i % 2 == 0:
sum += i
print(sum)
循环控制
break # 直接退出整个循环
continue # 退出本次循环,立刻开始下一次
循环嵌套
# 外层控制行,内层控制列
# 打印三角形
for i in range(1, 6):
for j in range(i):
print("*", end="")
print() # 换行
# 九九乘法表
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j}*{i}={j*i}", end="\t")
print()
4. 综合练习:素数判断
num1 = int(input("num1:"))
if num1 <= 1:
print(f"{num1}不是素数")
else:
is_sushu = True
for i in range(2, num1 // 2 + 1): # 或 int(num1**0.5) + 1
if num1 % i == 0:
is_sushu = False
break
if is_sushu:
print(f"{num1}是素数")
else:
print(f"{num1}不是素数")
第4天:while循环与综合案例
1. while 循环
# 用于循环次数不确定的场景
while 条件:
循环体
# 三要素:
# 1. 条件的参考变量初始值
# 2. while 条件:
# 3. 初始值的更新
# 示例:打印10次hello
num1 = 0
while num1 <= 9:
print("hello, python")
num1 += 1
# 死循环 + break
while True:
result = input("你还爱我吗???:")
if result == "爱":
break
for/while 的 else 子句
for i in range(1, 6):
if i == 3:
break
print(i)
else:
print("循环正常结束") # 被break打断不会执行
# while 同理
2. 综合案例:猜数字游戏
import random
random1 = random.randint(1, 100) # 1-100随机整数
num1 = 0
while True:
if num1 == 3:
choose = input("是否继续游戏(y/n):")
if choose == "y":
num1 = 0
else:
print("退出游戏")
break
guess = int(input("请猜数字1-100:"))
if guess == random1:
print(f"猜对了!数字是{guess}")
break
elif guess > random1:
print("猜大了")
else:
print("猜小了")
num1 += 1
3. 综合案例:ATM系统
# 功能:查询、存款、取款、转账、改密、退出
# 要点:循环嵌套、密码验证(3次机会)、菜单选择
# 详见课堂代码 04-demo2.py
第5天:字符串与列表等容器的方法
查看方法:print(dir(容器)) ,看该容器可以有哪些操作,比如增删改查
1. 字符串详解
str1 = "hello python" # 有序序列,不可变数据类型
# 索引下标
# 正向:从左往右,从0开始
# 反向:从右往左,从-1开始
print(str1[2]) # l
print(str1[-2]) # o
# 切片 [start:end:step]
print(str1[1:4]) # ell(1到3)
print(str1[:2]) # he(0到1)
print(str1[::]) # 全部
print(str1[::-1]) # 反转
print(str1[6:1:-1]) # nohty(反向切片)
# 回文判断
str2 = input("请输入:")
print("是回文") if str2 == str2[::-1] else print("不是回文")
字符串常用方法
str1 = "hello pYthon"
#查看有哪些方法:print(dir(str1))
# 大小写转换
str1.upper() # 转大写
str1.lower() # 转小写
str1.title() # 每个单词首字母大写
str1.capitalize() # 只有第一个单词首字母大写
str1.swapcase() # 大小写互换
# 查找
str1.find("pYthon") # 找到返回索引,找不到返回-1
str1.rfind("h") # 从右往左找
str1.index("B") # 找不到报错ValueError
str1.rindex("h")
# 替换
str1.replace("h", "李四") # 全局替换
str1.replace("h", "李四", 1) # 只替换1个
# 判断
str1.startswith("he") # 是否以...开头
str1.endswith("py") # 是否以...结尾
# 去除空白
" zhangsan ".strip() # 去除左右空格
# 分割与拼接
str2.split(",") # 按逗号分割,返回列表
",".join(["a", "b", "c"]) # 用逗号拼接,返回"a,b,c"
# 其他
len(str1) # 长度(全局函数)
str1.count("h") # 统计出现次数
"hi".center(10, "=") # 居中填充
重要:字符串是不可变类型,所有方法都返回新字符串
2. 列表(List)
# 特点:1. 有序(有索引) 2. 可变 3. 可存任何数据类型
# 创建
list1 = [1, 2, 3, "zhangsan", True, None]
list2 = list("abcd") # 强制转换
list3 = list(range(1, 11, 2)) # [1, 3, 5, 7, 9]
# 索引和切片(同字符串)
print(list1[2])
print(list1[::-1]) # 反转
# 遍历
for i in list1:
print(i)
# while遍历
index = 0
while index <= len(list1) - 1:
print(list1[index])
index += 1
# enumerate 同时获取索引和元素
for index, value in enumerate(list1):
print(f"下标{index},元素是{value}")
列表方法
list1 = [1, 2, 3, 4, 5]
# 添加元素
list1.append("zhangsan") # 末尾添加
list1.insert(1, "lisi") # 指定下标位置插入
list1.extend(["wang", "wu"]) # 合并列表
# 删除元素
list1.pop() # 删除最后一个(或指定索引)
list1.remove(1) # 按值删除(第一个匹配的)
del list1[1:4] # 按索引或切片删除
list1.clear() # 清空
# 查找
list1.index("zhangsan") # 返回索引,找不到报错
list1.index("zhangsan", 2) # 从索引2开始找
"zhangsan" in list1 # 是否存在
list1.count("zhangsan") # 统计次数
# 排序
list1.sort() # 升序
list1.sort(reverse=True) # 降序
list1.reverse() # 反转
# 其他
list1.copy() # 浅拷贝
import copy
copy.deepcopy(list1) # 深拷贝
# 全局函数
len(list1), min(list1), max(list1), sum(list1)
浅拷贝 vs 深拷贝:
- 浅拷贝:只拷贝外层,内层嵌套对象共享引用
- 深拷贝:完全独立,递归拷贝所有层级
3. 元组(Tuple)
# 特点:有序、不可变(创建后不能改)
tuple1 = (1, 2, 3, "张三")
tuple2 = tuple() # 空元组
tuple3 = ("zhangsan",) # 单元素必须加逗号!
# 索引、切片、遍历(同列表)
print(tuple1[1])
print(tuple1[::-1])
# 方法(很少)
tuple1.count(2) # 计数
tuple1.index("张三") # 查找索引
# 注意:元组中的可变元素可以改
tuple5 = (1, 2, 3, [4, 5, 6])
tuple5[-1][1] = "zhangsan" # 可以!
4. 字典(Dictionary)
# 特点:键值对存储,无序(Python3.7+有序),可变
# 键:必须是不可变类型(字符串、数字、元组)
# 值:可以是任何类型
# 创建
dict1 = {
"uname": "zhangsan",
"age": 21,
"hobby": ["吃饭", "睡觉"]
}
dict2 = dict(name="zhangsan", age=21)
dict3 = dict([("name", "zhangsan"), ("age", 33)])
dict4 = dict.fromkeys(["uname", "age"], 0) # 批量设置默认值
# 空字典
dict5 = {}
dict6 = dict()
字典操作
dict1 = {"uname": "zhangsan", "age": 21}
# 查找
dict1["uname"] # 键不存在报错KeyError
dict1.get("uname") # 安全,不存在返回None
dict1.get("xxx", "默认值") # 自定义默认值
"uname" in dict1 # 判断键是否存在
# 添加/修改
dict1["uname"] = "lisi" # 存在则修改
dict1["hobby"] = ["吃饭"] # 不存在则添加
# 批量更新
dict1.update({"uname": "wangwu", "age": 444})
# 设置默认值(键不存在才生效)
dict1.setdefault("new_key", "666")
# 删除
dict1.pop("uname") # 删除并返回值
dict1.pop("xxx", "不存在") # 设置不存在时的返回值
dict1.popitem() # 删除最后插入的键值对
# 获取所有键、值、键值对
dict1.keys()
dict1.values()
dict1.items() # 用于遍历:for k, v in dict1.items()
5. 集合(Set)
# 特点:无序、可变、元素不重复、元素必须是不可变类型
set1 = {1, 2, 3, 3, 3} # 自动去重,结果为 {1, 2, 3}
set2 = set() # 空集合(不能用{},那是字典)
set3 = set([1,1,2,2,3]) # 转集合去重
# 方法
set1.add("zhangsan") # 添加
set1.update(["a", "b"]) # 批量添加
set1.remove("zhangsan") # 删除,不存在报错
set1.discard("xxx") # 删除,不存在不报错
set1.pop() # 随机删除并返回
set1.clear() # 清空
# 遍历(无序,不能索引)
for i in set1:
print(i)
集合运算
set1 = {1, 2, 3, "zhangsan"}
set2 = {1, 3, "lisi"}
# 交集
set1 & set2
set1.intersection(set2)
# 并集
set1 | set2
set1.union(set2)
# 差集(在set1但不在set2)
set1 - set2
set1.difference(set2)
# 对称差集(在A或在B,但不同时在AB)
set1 ^ set2
set1.symmetric_difference(set2)
6. 推导式(快速生成容器)
# 列表推导式
[i*i for i in range(1, 11)] # 1-10的平方的列表
[i for i in range(1, 11) if i % 2 == 0] # 带条件(偶数)
[str(i)+"zhangsan" for i in range(1, 11) if i % 2 == 0]
# 嵌套循环
[[i, j] for i in range(1, 3) for j in range(5, 8)]
# [[1,5], [1,6], [1,7], [2,5], [2,6], [2,7]]
# 字典推导式,键值对
{i: i*i for i in range(7)} # {0:0, 1:1, 2:4...}
{ i:i for i in range(1,11) if i%2==0} #{'2': 4, '4': 16, '6': 36, '8': 64, '10': 100}
{i: j for i in ["name", "age"] for j in range(1)} # 注意逻辑
# 集合推导式
{i for i in range(10)}
第6天:综合练习与进阶
1. 员工管理系统(综合应用)
# 涉及:列表、字典、循环、条件判断、增删改查
# 详见课堂代码 01-练习.py 和 16-练习.py
# 核心数据结构
employees = [
{"name": "张三", "id": "1001", "age": 28},
{"name": "李四", "id": "1002", "age": 45}
]
# 功能:添加、查看、查找、统计、退出
附录:重要概念速查
| 概念 | 说明 |
|---|---|
| 缩进 | Python用缩进表示代码块,通常为4个空格 |
| 动态类型 | 变量类型随赋值改变 |
| 可变类型 | list、dict、set(创建后可修改) |
| 不可变类型 | int、float、str、tuple元组(创建后不可修改) |
| 索引 | 从0开始,反向从-1开始 |
| 切片 |
[start:end:step],包头不包尾 |
| 浅拷贝 | 只拷贝外层,内层共享 |
| 深拷贝 | 完全独立拷贝 |
| 短路求值 |
and/or 根据左边决定是否计算右边 |
学习建议:
- 多动手敲代码,不要只看
- 注意缩进和冒号
- 理解可变与不可变的区别
- 掌握列表和字典的使用(最常用)
- 多做综合练习,融会贯通