【python 100行左右代码】基于Streamlit的简单食谱推荐系统实现
源代码下载:https://pan.quark.cn/s/1b691d70d0af下载方式2: https://pan.baidu.com/s/1M5evnzw1O6EdycVuwkP4kA?pwd=buue 提取码: buue。
源代码下载:https://pan.quark.cn/s/1b691d70d0af
下载方式2: https://pan.baidu.com/s/1M5evnzw1O6EdycVuwkP4kA?pwd=buue 提取码: buue
一、引言
本系统借助Python语言以及Streamlit框架的便捷可视化特性,实现了基于关键词的食谱推荐功能,并对推荐结果进行了直观的统计展示。
二、关键函数解析
2.1 食材数据解析函数parse_ingredients
def parse_ingredients(ingredients_json):
"""解析JSON格式的食材数据,兼容字典列表和字符串列表两种格式"""
try:
ingredients = json.loads(ingredients_json)
ingredient_names = []
formatted_text = ""
for item in ingredients:
if isinstance(item, dict):
# 处理字典格式(原逻辑)
name = item.get("name", "未知食材")
amount = item.get("amount", "适量")
else:
# 处理字符串格式(新增逻辑)
name = str(item).strip() # 转换为字符串并去除首尾空格
amount = "适量" # 默认为"适量"
ingredient_names.append(name.lower())
formatted_text += f"- {name}: {amount}\n"
return formatted_text.strip(), ingredient_names
except (json.JSONDecodeError, TypeError):
# 保持原错误处理逻辑
return str(ingredients_json), []
该函数旨在解析食材数据,支持两种格式:字典列表和字符串列表。通过json.loads尝试将输入解析为JSON数据,若解析成功,遍历其中元素。对于字典格式,提取食材名称和用量;对于字符串格式,将字符串作为食材名称并默认用量为“适量”。最后返回格式化后的食材文本及食材名称列表,若解析失败则返回原数据及空列表。
2.2 食谱推荐函数recommend_recipes
def recommend_recipes(keywords):
df = pd.read_csv('E:\\pycharm_workspace\\食谱数据\\1_Recipe_csv.csv')
matching_indices = []
for index, row in df.iterrows():
title_text = str(row['recipe_title']).lower()
description_text = str(row['description']).lower()
ingredients_json = str(row['ingredients'])
_, ingredient_names = parse_ingredients(ingredients_json) # 获取食材名称列表
ingredients_text = " ".join(ingredient_names) # 转换为空格分隔的文本用于匹配
# 检查关键词是否出现在标题、描述或解析后的食材名称中
if all(keyword in title_text or keyword in description_text or keyword in ingredients_text
for keyword in keywords):
matching_indices.append(index)
matching_recipes = df.loc[matching_indices]
return matching_recipes
此函数根据用户输入的关键词推荐食谱。它读取包含食谱信息的CSV文件,遍历每一行数据,将食谱标题、描述以及解析后的食材名称转换为小写并拼接成文本。检查每个关键词是否出现在这些文本中,若都出现则记录该行索引。最后返回匹配关键词的食谱数据。
2.3 类别统计绘图函数plot_category_counts
def plot_category_counts(matching_recipes):
# 统计不同类别中推荐食谱的数量
category_counts = matching_recipes['category'].value_counts()
# 设置图片清晰度
plt.rcParams['figure.dpi'] = 300
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['WenQuanYi Zen Hei']
# 绘制柱状图
plt.figure(figsize=(10, 6))
category_counts.plot(kind='bar', color='skyblue')
plt.title('不同类别中推荐食谱的数量')
plt.xlabel('类别')
plt.ylabel('食谱数量')
plt.xticks(rotation=45)
plt.tight_layout()
return plt
该函数统计推荐食谱在不同类别中的数量,并绘制柱状图进行可视化展示。设置图片清晰度和中文字体,利用value_counts统计每个类别中食谱的数量,然后绘制柱状图,标注图表标题、坐标轴标签,并调整刻度旋转角度以确保图表可读性。
三、Streamlit交互界面实现
st.title('食谱推荐系统')
keyword_input = st.text_input('请输入关键词(用空格分隔)')
keywords = keyword_input.lower().split() if keyword_input else []
if st.button('推荐食谱'):
if keywords:
recommended_recipes = recommend_recipes(keywords)
if not recommended_recipes.empty:
st.write("以下是根据关键词推荐的食谱:")
sorted_recipes = recommended_recipes.sort_values('recipe_title')
cols_per_row = 3
rows = (len(sorted_recipes) + cols_per_row - 1) // cols_per_row
fig = plot_category_counts(recommended_recipes)
st.pyplot(fig)
for row_idx in range(rows):
cols = st.columns(cols_per_row)
for col_idx in range(cols_per_row):
recipe_idx = row_idx * cols_per_row + col_idx
if recipe_idx < len(sorted_recipes):
recipe = sorted_recipes.iloc[recipe_idx]
with cols[col_idx]:
st.markdown(f"### {recipe['recipe_title']}")
st.caption(f"**类别:** {recipe['category']}")
description = recipe['description']
if description and len(description) > 100:
st.write(f"**描述:** {description[:100]}...")
else:
st.write(f"**描述:** {description or '无描述信息'}")
# {{ edit_4: 展示格式化后的食材列表 }}
with st.expander("查看食材"):
ingredients_json = str(recipe['ingredients'])
formatted_ingredients, _ = parse_ingredients(ingredients_json)
st.text(formatted_ingredients) # 显示解析后的结构化食材
st.divider()
else:
st.write("没有找到匹配关键词的食谱。")
else:
st.write("请输入关键词。")
通过Streamlit构建用户交互界面。设置页面标题为“食谱推荐系统”,提供文本输入框让用户输入关键词,并将输入转换为小写并按空格分割成关键词列表。当用户点击“推荐食谱”按钮时,若有关键词输入,则调用recommend_recipes函数获取推荐食谱。若有推荐结果,对食谱按标题排序,绘制推荐食谱类别统计柱状图并展示。同时,以每行3列的布局展示每个推荐食谱的标题、类别、简短描述及食材信息。若未找到匹配食谱或未输入关键词,则给出相应提示。
更多推荐


所有评论(0)