first commit

This commit is contained in:
wjy
2026-05-08 17:32:18 +08:00
commit 64836b0eff
6 changed files with 779 additions and 0 deletions
+38
View File
@@ -0,0 +1,38 @@
import json
import os
# 定义数据文件路径
DATA_FILE = "./data/houses.json"
def init_db():
"""
初始化数据文件:如果houses.json不存在,创建并写入空列表
空间复杂度:O(1)(仅创建空文件)
"""
# 确保data文件夹存在
os.makedirs("./data", exist_ok=True)
# 如果文件不存在,创建并写入空列表
if not os.path.exists(DATA_FILE):
with open(DATA_FILE, 'w', encoding='utf-8') as f:
json.dump([], f, ensure_ascii=False, indent=4)
def read_houses():
"""
读取所有房源数据
时间复杂度:O(n)(n为房源数,JSON解析耗时与数据量正相关)
空间复杂度:O(n)(存储所有房源数据)
return: 房源列表(每个元素是字典)
"""
init_db() # 先确保文件存在
with open(DATA_FILE, 'r', encoding='utf-8') as f:
return json.load(f)
def write_houses(houses):
"""
写入房源数据到JSON文件
时间复杂度:O(n)(n为房源数,JSON序列化耗时与数据量正相关)
空间复杂度:O(1)(仅写入操作,无额外存储)
param houses: 要写入的房源列表
"""
with open(DATA_FILE, 'w', encoding='utf-8') as f:
json.dump(houses, f, ensure_ascii=False, indent=4)
+83
View File
@@ -0,0 +1,83 @@
import json
import os
# 以下为 V1.0 原有代码,完全未修改
# 定义数据文件路径
HOUSE_FILE = "./data/houses.json"
def init_db():
"""
初始化数据文件:如果houses.json不存在,创建并写入空列表
空间复杂度:O(1)(仅创建空文件)
"""
# 确保data文件夹存在
os.makedirs("./data", exist_ok=True)
# 如果文件不存在,创建并写入空列表
if not os.path.exists(HOUSE_FILE):
with open(HOUSE_FILE, 'w', encoding='utf-8') as f:
json.dump([], f, ensure_ascii=False, indent=4)
def read_houses():
"""
读取所有房源数据
时间复杂度:O(n)(n为房源数,JSON解析耗时与数据量正相关)
空间复杂度:O(n)(存储所有房源数据)
return: 房源列表(每个元素是字典)
"""
init_db() # 先确保文件存在
with open(HOUSE_FILE, 'r', encoding='utf-8') as f:
return json.load(f)
def write_houses(houses):
"""
写入房源数据到JSON文件
时间复杂度:O(n)(n为房源数,JSON序列化耗时与数据量正相关)
空间复杂度:O(1)(仅写入操作,无额外存储)
param houses: 要写入的房源列表
"""
with open(HOUSE_FILE, 'w', encoding='utf-8') as f:
json.dump(houses, f, ensure_ascii=False, indent=4)
# V2.0 新增代码:栈数据读写
# V2.0 新增:栈数据文件配置
STACK_FILE = "./data/stack_data.json"
# V2.0 新增:栈数据初始化与读写
def init_stack_db():
"""
初始化栈数据文件:若不存在则创建,区分操作记录栈/浏览历史栈
"""
os.makedirs("./data", exist_ok=True)
if not os.path.exists(STACK_FILE):
init_data = {
"operation_stack": [],
"browse_stack": []
}
with open(STACK_FILE, 'w', encoding='utf-8') as f:
json.dump(init_data, f, ensure_ascii=False, indent=4)
def read_stack(stack_type):
"""
读取指定类型的栈数据
:param stack_type: operation(操作记录)/ browse(浏览历史)
"""
init_stack_db()
with open(STACK_FILE, 'r', encoding='utf-8') as f:
data = json.load(f)
stack_key = f"{stack_type}_stack"
return data.get(stack_key, [])
def write_stack(stack_type, new_stack):
"""
写入指定类型的栈数据到文件
"""
init_stack_db()
# 读取原有数据,避免覆盖另一个栈
with open(STACK_FILE, 'r', encoding='utf-8') as f:
data = json.load(f)
stack_key = f"{stack_type}_stack"
data[stack_key] = new_stack
with open(STACK_FILE, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
+140
View File
@@ -0,0 +1,140 @@
from house.db_operation import read_houses, write_houses
def get_next_house_id():
"""
生成下一个房源ID(保证ID唯一)
时间复杂度:O(n)(遍历所有房源找最大ID)
return: 下一个可用的ID(整数)
"""
houses = read_houses()
if not houses:
return 1 # 无房源时,第一个ID为1
# 找到最大ID,加1作为新ID
max_id = max(house["id"] for house in houses)
return max_id + 1
def add_house(address, price, area, house_type):
"""
新增房源(线性表的尾部插入操作)
时间复杂度:O(n)read/write各O(n),整体O(n)
空间复杂度:O(n)(存储所有房源数据)
param address: 房源地址(字符串)
param price: 租金(整数/浮点数)
param area: 面积(整数/浮点数)
param house_type: 户型(字符串,如"一居室"
return: 新增成功返回True,失败返回False
"""
# 基础数据校验(非空+数值合法性)
if not address or not house_type:
print("错误:地址和户型不能为空!")
return False
if not isinstance(price, (int, float)) or price <= 0:
print("错误:租金必须是正数!")
return False
if not isinstance(area, (int, float)) or area <= 0:
print("错误:面积必须是正数!")
return False
# 构建新房源字典(线性表的元素)
new_house = {
"id": get_next_house_id(),
"address": address,
"price": price,
"area": area,
"house_type": house_type
}
# 读取现有房源(线性表),新增元素(尾部插入)
houses = read_houses()
houses.append(new_house) # 线性表append操作,时间复杂度O(1)
# 写入文件
write_houses(houses)
print(f"房源新增成功!房源ID{new_house['id']}")
return True
def delete_house(house_id):
"""
删除房源(线性表的指定位置删除操作)
时间复杂度:O(n)(遍历找ID+写入文件,整体O(n))
空间复杂度:O(n)(存储所有房源数据)
param house_id: 要删除的房源ID(整数)
return: 删除成功返回True,失败返回False
"""
houses = read_houses()
# 遍历线性表,找到对应ID的房源
for index, house in enumerate(houses):
if house["id"] == house_id:
del houses[index] # 线性表删除操作,时间复杂度O(n)(后续元素前移)
write_houses(houses)
print(f"房源ID {house_id} 删除成功!")
return True
print(f"错误:未找到房源ID {house_id}")
return False
def update_house(house_id, new_info):
"""
修改房源信息(线性表的指定元素更新操作)
时间复杂度:O(n)(遍历找ID+写入文件,整体O(n))
空间复杂度:O(n)(存储所有房源数据)
param house_id: 要修改的房源ID(整数)
param new_info: 要修改的字段字典(如{"price": 5500, "area": 85}
return: 修改成功返回True,失败返回False
"""
houses = read_houses()
# 遍历线性表,找到对应ID的房源
for house in houses:
if house["id"] == house_id:
# 仅更新传入的有效字段
for key, value in new_info.items():
if key in ["address", "price", "area", "house_type"]:
# 校验数值字段合法性
if key in ["price", "area"]:
if not isinstance(value, (int, float)) or value <= 0:
print(f"错误:{key}必须是正数!")
return False
house[key] = value
write_houses(houses)
print(f"房源ID {house_id} 修改成功!")
return True
print(f"错误:未找到房源ID {house_id}")
return False
def query_house(condition_type, condition_value):
"""
查询房源(线性表的遍历筛选操作)
时间复杂度:O(n)(遍历所有房源,n为房源数)
空间复杂度:O(k)(k为符合条件的房源数,最坏O(n))
param condition_type: 查询条件类型("id"/"address"/"price"/"house_type"
param condition_value: 查询条件值
return: 符合条件的房源列表
"""
houses = read_houses()
result = []
# 按条件遍历筛选
for house in houses:
# 处理ID查询(整数匹配)
if condition_type == "id":
if house["id"] == int(condition_value):
result.append(house)
# 处理地址查询(模糊匹配)
elif condition_type == "address":
if condition_value in house["address"]:
result.append(house)
# 处理户型查询(精确匹配)
elif condition_type == "house_type":
if house["house_type"] == condition_value:
result.append(house)
# 处理租金查询(数值匹配,示例:查询等于该价格的房源)
elif condition_type == "price":
if house["price"] == float(condition_value):
result.append(house)
else:
print("错误:不支持的查询条件类型!")
return []
return result
+219
View File
@@ -0,0 +1,219 @@
from house.house_operation import read_houses, write_houses
# V2.0新增:导入新增的栈数据函数
from house.house_operation import read_stack, write_stack
from datetime import datetime
# V1.0
def get_next_house_id():
"""
生成下一个房源ID(保证ID唯一)
时间复杂度:O(n)(遍历所有房源找最大ID)
return: 下一个可用的ID(整数)
"""
houses = read_houses()
if not houses:
return 1 # 无房源时,第一个ID为1
# 找到最大ID,加1作为新ID
max_id = max(house["id"] for house in houses)
return max_id + 1
def add_house(address, price, area, house_type):
"""
新增房源(线性表的尾部插入操作)
时间复杂度:O(n)read/write各O(n),整体O(n)
空间复杂度:O(n)(存储所有房源数据)
param address: 房源地址(字符串)
param price: 租金(整数/浮点数)
param area: 面积(整数/浮点数)
param house_type: 户型(字符串,如"一居室"
return: 新增成功返回True,失败返回False
"""
# 基础数据校验(非空+数值合法性)
if not address or not house_type:
print("错误:地址和户型不能为空!")
return False
if not isinstance(price, (int, float)) or price <= 0:
print("错误:租金必须是正数!")
return False
if not isinstance(area, (int, float)) or area <= 0:
print("错误:面积必须是正数!")
return False
# 构建新房源字典(线性表的元素)
new_house = {
"id": get_next_house_id(),
"address": address,
"price": price,
"area": area,
"house_type": house_type
}
# 读取现有房源(线性表),新增元素(尾部插入)
houses = read_houses()
houses.append(new_house) # 线性表append操作,时间复杂度O(1)
# 写入文件
write_houses(houses)
print(f"房源新增成功!房源ID{new_house['id']}")
return True
def delete_house(house_id):
"""
删除房源(线性表的指定位置删除操作)
时间复杂度:O(n)(遍历找ID+写入文件,整体O(n))
空间复杂度:O(n)(存储所有房源数据)
param house_id: 要删除的房源ID(整数)
return: 删除成功返回True,失败返回False
"""
houses = read_houses()
# 遍历线性表,找到对应ID的房源
for index, house in enumerate(houses):
if house["id"] == house_id:
del houses[index] # 线性表删除操作,时间复杂度O(n)(后续元素前移)
write_houses(houses)
print(f"房源ID {house_id} 删除成功!")
return True
print(f"错误:未找到房源ID {house_id}")
return False
def update_house(house_id, new_info):
"""
修改房源信息(线性表的指定元素更新操作)
时间复杂度:O(n)(遍历找ID+写入文件,整体O(n))
空间复杂度:O(n)(存储所有房源数据)
param house_id: 要修改的房源ID(整数)
param new_info: 要修改的字段字典(如{"price": 5500, "area": 85}
return: 修改成功返回True,失败返回False
"""
houses = read_houses()
# 遍历线性表,找到对应ID的房源
for house in houses:
if house["id"] == house_id:
# 仅更新传入的有效字段
for key, value in new_info.items():
if key in ["address", "price", "area", "house_type"]:
# 校验数值字段合法性
if key in ["price", "area"]:
if not isinstance(value, (int, float)) or value <= 0:
print(f"错误:{key}必须是正数!")
return False
house[key] = value
write_houses(houses)
print(f"房源ID {house_id} 修改成功!")
return True
print(f"错误:未找到房源ID {house_id}")
return False
def query_house(condition_type, condition_value):
"""
查询房源(线性表的遍历筛选操作)
时间复杂度:O(n)(遍历所有房源,n为房源数)
空间复杂度:O(k)(k为符合条件的房源数,最坏O(n))
param condition_type: 查询条件类型("id"/"address"/"price"/"house_type"
param condition_value: 查询条件值
return: 符合条件的房源列表
"""
houses = read_houses()
result = []
# 按条件遍历筛选
for house in houses:
# 处理ID查询(整数匹配)
if condition_type == "id":
if house["id"] == int(condition_value):
result.append(house)
# 处理地址查询(模糊匹配)
elif condition_type == "address":
if condition_value in house["address"]:
result.append(house)
# 处理户型查询(精确匹配)
elif condition_type == "house_type":
if house["house_type"] == condition_value:
result.append(house)
# 处理租金查询(数值匹配,示例:查询等于该价格的房源)
elif condition_type == "price":
if house["price"] == float(condition_value):
result.append(house)
else:
print("错误:不支持的查询条件类型!")
return []
return result
# V2.0 新增代码:栈业务逻辑
# V2.0 新增:栈配置
MAX_STACK_LENGTH = 100 # 栈最大存储长度
# V2.0 新增:栈核心操作
def push_operation_stack(operation_info):
"""
栈顶添加,先进后出
"""
time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
full_info = f"[{time_str}] {operation_info}"
stack = read_stack("operation")
stack.append(full_info)
# 超出长度则删除最早的栈底元素
if len(stack) > MAX_STACK_LENGTH:
stack.pop(0)
write_stack("operation", stack)
def push_browse_stack(house_id):
"""
V2.0房源浏览历史入栈
"""
stack = read_stack("browse")
# 去重:避免同一房源重复入栈顶
if stack and stack[-1] == house_id:
return
stack.append(house_id)
if len(stack) > MAX_STACK_LENGTH:
stack.pop(0)
write_stack("browse", stack)
def pop_operation_stack():
"""
V2.0新增操作记录出栈(获取并删除最新的栈顶记录)
"""
stack = read_stack("operation")
if not stack:
return None
latest_op = stack.pop()
write_stack("operation", stack)
return latest_op
def pop_browse_stack():
"""
V2.0新】浏览历史出栈(获取并删除最新浏览的房源)
"""
stack = read_stack("browse")
if not stack:
return None
latest_hid = stack.pop()
write_stack("browse", stack)
return latest_hid
def get_recent_records(stack_type, limit=10):
"""
V2.0新增获取栈内最新的N条记录(从新到旧)
"""
stack = read_stack(stack_type)
return stack[-limit:][::-1]
def clear_stack(stack_type):
"""
V2.0新增清空指定栈
"""
write_stack(stack_type, [])
print(f"{stack_type}记录已清空!")
+101
View File
@@ -0,0 +1,101 @@
from house_service import add_house, delete_house, update_house, query_house
def print_menu():
"""打印控制台菜单"""
print("\n===== 房屋出租系统 V1.0 =====")
print("1. 新增房源")
print("2. 删除房源")
print("3. 修改房源")
print("4. 查询房源")
print("5. 退出系统")
print("============================")
def main():
"""主程序入口"""
while True:
print_menu()
choice = input("请输入操作编号(1-5):")
# 1. 新增房源
if choice == "1":
print("\n----- 新增房源 -----")
address = input("请输入房源地址:")
try:
price = float(input("请输入租金(元/月):"))
area = float(input("请输入面积(㎡):"))
except ValueError:
print("错误:租金/面积必须是数字!")
continue
house_type = input("请输入户型(如:一居室、两居室):")
add_house(address, price, area, house_type)
# 2. 删除房源
elif choice == "2":
print("\n----- 删除房源 -----")
try:
house_id = int(input("请输入要删除的房源ID"))
delete_house(house_id)
except ValueError:
print("错误:房源ID必须是整数!")
# 3. 修改房源
elif choice == "3":
print("\n----- 修改房源 -----")
try:
house_id = int(input("请输入要修改的房源ID"))
# 收集要修改的字段
new_info = {}
address = input("请输入新地址(不修改按回车):")
if address:
new_info["address"] = address
price_input = input("请输入新租金(不修改按回车):")
if price_input:
try:
new_info["price"] = float(price_input)
except ValueError:
print("错误:租金必须是数字!")
continue
area_input = input("请输入新面积(不修改按回车):")
if area_input:
try:
new_info["area"] = float(area_input)
except ValueError:
print("错误:面积必须是数字!")
continue
house_type = input("请输入新户型(不修改按回车):")
if house_type:
new_info["house_type"] = house_type
# 调用修改函数
if new_info:
update_house(house_id, new_info)
else:
print("未输入任何修改内容!")
except ValueError:
print("错误:房源ID必须是整数!")
# 4. 查询房源
elif choice == "4":
print("\n----- 查询房源 -----")
print("查询条件类型:1-ID 2-地址 3-租金 4-户型")
cond_choice = input("请输入条件类型编号(1-4):")
cond_type_map = {"1": "id", "2": "address", "3": "price", "4": "house_type"}
if cond_choice not in cond_type_map:
print("错误:无效的条件类型!")
continue
condition_type = cond_type_map[cond_choice]
condition_value = input(f"请输入{condition_type}查询值:")
# 执行查询
result = query_house(condition_type, condition_value)
# 展示结果
if result:
print("\n查询结果:")
for house in result:
print(f"ID{house['id']} | 地址:{house['address']} | 租金:{house['price']}元/月 | 面积:{house['area']}㎡ | 户型:{house['house_type']}")
else:
print("未找到符合条件的房源!")
# 5. 退出系统
elif choice == "5":
print("感谢使用房屋出租系统,再见!")
break
# 无效输入
else:
print("错误:请输入1-5之间的有效编号!")
if __name__ == "__main__":
main()
+198
View File
@@ -0,0 +1,198 @@
# 导入原有业务函数,完全保留
from house_service import add_house, delete_house, update_house, query_house
# V2.0新增:导入新增的栈业务函数
from house_service import push_operation_stack, push_browse_stack
from house_service import pop_operation_stack, pop_browse_stack
from house_service import get_recent_records, clear_stack
from house_service import get_next_house_id
# V1.0
def print_menu():
print("\n===== 房屋出租系统 V2.0 =====")
print("1. 新增房源")
print("2. 删除房源")
print("3. 修改房源")
print("4. 查询房源")
# V2.0新增:2个新菜单选项
print("5. 查看/管理操作记录")
print("6. 查看/管理浏览历史")
print("7. 退出系统")
print("============================")
def main():
while True:
print_menu()
choice = input("请输入操作编号(1-7):")
# 1. 新增房源
if choice == "1":
print("\n----- 新增房源 -----")
address = input("请输入房源地址:")
try:
price = float(input("请输入租金(元/月):"))
area = float(input("请输入面积(㎡):"))
except ValueError:
print("错误:租金/面积必须是数字!")
continue
house_type = input("请输入户型(如:一居室、两居室):")
if add_house(address, price, area, house_type):
# V2.0 新增:操作记录埋点
new_id = get_next_house_id() - 1
push_operation_stack(f"新增房源ID:{new_id},地址:{address}")
# 2. 删除房源
elif choice == "2":
print("\n----- 删除房源 -----")
try:
house_id = int(input("请输入要删除的房源ID"))
# 原有删除前的查询,用于埋点
house = query_house("id", house_id)
house_addr = house[0]["address"] if house else "未知地址"
# 原有删除逻辑,完全未改
if delete_house(house_id):
# V2.0 新增:操作记录埋点
push_operation_stack(f"删除房源ID:{house_id},地址:{house_addr}")
except ValueError:
print("错误:房源ID必须是整数!")
# 3. 修改房源)
elif choice == "3":
print("\n----- 修改房源 -----")
try:
house_id = int(input("请输入要修改的房源ID"))
# 原有收集修改字段逻辑,完全未改
new_info = {}
address = input("请输入新地址(不修改按回车):")
if address:
new_info["address"] = address
price_input = input("请输入新租金(不修改按回车):")
if price_input:
try:
new_info["price"] = float(price_input)
except ValueError:
print("错误:租金必须是数字!")
continue
area_input = input("请输入新面积(不修改按回车):")
if area_input:
try:
new_info["area"] = float(area_input)
except ValueError:
print("错误:面积必须是数字!")
continue
house_type = input("请输入新户型(不修改按回车):")
if house_type:
new_info["house_type"] = house_type
# 原有修改逻辑,完全未改
if new_info:
if update_house(house_id, new_info):
# V2.0 新增:操作记录埋点
push_operation_stack(f"修改房源ID:{house_id},修改内容:{new_info}")
else:
print("未输入任何修改内容!")
except ValueError:
print("错误:房源ID必须是整数!")
# 4. 查询房源
elif choice == "4":
print("\n----- 查询房源 -----")
print("查询条件类型:1-ID 2-地址 3-租金 4-户型")
cond_choice = input("请输入条件类型编号(1-4):")
cond_type_map = {"1": "id", "2": "address", "3": "price", "4": "house_type"}
if cond_choice not in cond_type_map:
print("错误:无效的条件类型!")
continue
condition_type = cond_type_map[cond_choice]
condition_value = input(f"请输入{condition_type}查询值:")
# 原有查询逻辑,完全未改
result = query_house(condition_type, condition_value)
# 原有结果展示逻辑,完全未改
if result:
print("\n查询结果:")
for house in result:
print(
f"ID{house['id']} | 地址:{house['address']} | 租金:{house['price']}元/月 | 面积:{house['area']}㎡ | 户型:{house['house_type']}")
# V2.0 新增:浏览历史埋点
if condition_type == "id":
push_browse_stack(house["id"])
else:
print("未找到符合条件的房源!")
# V2.0 新增代码:栈功能交互
# 5. 操作记录管理
elif choice == "5":
while True:
print("\n----- 操作记录管理 -----")
print("1. 查看最新10条操作记录")
print("2. 获取最新1条操作记录(并删除)")
print("3. 清空所有操作记录")
print("4. 返回主菜单")
c = input("请输入操作编号:")
if c == "1":
records = get_recent_records("operation", 10)
if records:
print("\n最新10条操作记录(从新到旧):")
for i, r in enumerate(records, 1):
print(f"{i}. {r}")
else:
print("暂无操作记录!")
elif c == "2":
latest = pop_operation_stack()
print(latest if latest else "暂无操作记录!")
elif c == "3":
clear_stack("operation")
elif c == "4":
break
else:
print("无效编号!")
# 6. 浏览历史管理
elif choice == "6":
while True:
print("\n----- 浏览历史管理 -----")
print("1. 查看最新10条浏览历史")
print("2. 获取最新1条浏览房源(并删除)")
print("3. 清空所有浏览历史")
print("4. 返回主菜单")
c = input("请输入操作编号:")
if c == "1":
ids = get_recent_records("browse", 10)
if ids:
print("\n最新10条浏览历史(从新到旧):")
for i, hid in enumerate(ids, 1):
h = query_house("id", hid)
if h:
h = h[0]
print(f"{i}. ID:{hid} | 地址:{h['address']} | 租金:{h['price']}")
else:
print(f"{i}. ID:{hid}(房源已删除)")
else:
print("暂无浏览历史!")
elif c == "2":
hid = pop_browse_stack()
if hid:
h = query_house("id", hid)
if h:
h = h[0]
print(f"最新浏览:ID:{hid} | 地址:{h['address']}")
else:
print(f"最新浏览ID:{hid}(已删除)")
else:
print("暂无浏览历史!")
elif c == "3":
clear_stack("browse")
elif c == "4":
break
else:
print("无效编号!")
# 7. 退出系统(原有逻辑完全保留)
elif choice == "7":
print("感谢使用房屋出租系统,再见!")
break
# 无效输入(原有逻辑完全保留)
else:
print("错误:请输入1-7之间的有效编号!")
if __name__ == "__main__":
main()