import streamlit as st
import pandas as pd
import random
import time # 用于模拟加载时间
# --- 页面配置(放在最前面)---
st.set_page_config(
page_title="趣闻发现器✨",
page_icon="💡",
layout="centered", # 可以是 "centered" 或 "wide"
initial_sidebar_state="expanded" # 侧边栏初始状态
)
# --- 侧边栏内容 ---
with st.sidebar:
st.title("关于这个应用")
st.info(
"欢迎来到**趣闻发现器**!\n\n"
"这个应用旨在通过随机展示有趣的小知识,\n"
"让你在忙碌之余也能轻松获取新知,\n"
"发现世界的奇妙之处。✨"
)
st.write("---")
st.markdown("Developed with ❤️ using [Streamlit](https://streamlit.io/)")
st.markdown("数据来源:人工整理")
st.write("---")
# 添加一个小的提示,增加趣味性
st.caption("小提示:每次点击 '再来一个!🚀' 都能带来惊喜哦!")
# --- 主页面标题和描述 ---
st.title("🌍 趣闻发现器")
st.markdown("### 💡 每次点击,发现一个新奇世界!")
st.write("点击下面的按钮,探索一条随机的趣味知识。")
st.write("---")
# --- 数据加载 ---
@st.cache_data
def load_data():
"""
加载趣闻数据。
使用 st.cache_data 缓存数据,避免每次运行都重新加载。
"""
try:
df = pd.read_csv("fun_facts.csv")
# 确保 'Category' 和 'Link' 列存在,如果不存在则添加并填充NaN
if 'Category' not in df.columns:
df['Category'] = pd.NA
if 'Link' not in df.columns:
df['Link'] = pd.NA
return df
except FileNotFoundError:
st.error("错误:找不到 'fun_facts.csv' 文件。请确保文件与 'fun_fact_app.py' 在同一目录下。")
st.stop()
except Exception as e:
st.error(f"加载数据时发生错误:{e}")
st.stop()
facts_df = load_data()
# --- 筛选器:如果数据不为空且包含类别列 ---
if not facts_df.empty and 'Category' in facts_df.columns:
all_categories = ['所有类别'] + sorted(facts_df['Category'].dropna().unique().tolist())
selected_category = st.selectbox(
"按类别筛选趣闻:",
options=all_categories,
index=0,
help="选择一个类别来获取特定类型的趣闻"
)
if selected_category == '所有类别':
filtered_df = facts_df
else:
filtered_df = facts_df[facts_df['Category'] == selected_category]
if filtered_df.empty:
st.warning(f"在 '{selected_category}' 类别下没有找到趣闻。请尝试其他类别或 '所有类别'。")
filtered_df = facts_df # 如果筛选结果为空,则回到所有数据,避免错误
else:
filtered_df = facts_df # 如果没有类别列或数据为空,则使用全部数据
# --- 核心功能:随机展示趣闻 ---
if not filtered_df.empty:
# 使用 Streamlit 的 session state 来保存当前显示的趣闻索引
if 'current_fact_index' not in st.session_state:
st.session_state.current_fact_index = random.randint(0, len(filtered_df) - 1)
# 如果筛选后的数据发生变化,重置索引
if 'last_filtered_category' not in st.session_state or \
st.session_state.last_filtered_category != selected_category:
st.session_state.current_fact_index = random.randint(0, len(filtered_df) - 1)
st.session_state.last_filtered_category = selected_category
def get_random_fact():
"""获取一条随机趣闻并更新 session state"""
st.session_state.current_fact_index = random.randint(0, len(filtered_df) - 1)
# 模拟加载,给用户更好的体验
with st.spinner("正在努力寻找新趣闻..."):
time.sleep(0.5) # 短暂暂停,模拟数据加载过程
# 使用列布局美化显示
col1, col2 = st.columns([3, 1]) # 趣闻占3份宽度,按钮占1份
with col1:
st.markdown("### 🤩 精彩趣闻:")
current_fact_data = filtered_df.iloc[st.session_state.current_fact_index]
# 使用 st.success 或 st.warning 来突出显示趣闻,增加视觉效果
st.success(current_fact_data['Fact'])
# 显示类别和链接
st.markdown(f"📚 **类别**: {current_fact_data['Category'] if pd.notna(current_fact_data['Category']) else '未分类'}", unsafe_allow_html=True)
if pd.notna(current_fact_data['Link']):
st.markdown(f"👉 [**了解更多**]({current_fact_data['Link']})", unsafe_allow_html=True)
with col2:
st.markdown("---") # 占位符,让按钮对齐
# 使用 Streamlit 的 `use_container_width=True` 让按钮自适应列宽
st.button("再来一个!🚀", on_click=get_random_fact, use_container_width=True)
else:
st.warning("根据当前筛选条件,没有找到任何趣闻。请调整筛选器或检查数据。")
# --- 页脚 ---
st.markdown("---")
st.markdown("感谢使用!希望你今天学到了一些有趣的东西。😊")
st.markdown("项目地址:[你的GitHub地址/Inscode地址] (可选,可删除)", unsafe_allow_html=True)