惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Vercel News
Vercel News
SecWiki News
SecWiki News
WordPress大学
WordPress大学
小众软件
小众软件
博客园 - 司徒正美
酷 壳 – CoolShell
酷 壳 – CoolShell
V
Visual Studio Blog
Y
Y Combinator Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
云风的 BLOG
云风的 BLOG
MyScale Blog
MyScale Blog
K
Kaspersky official blog
T
The Exploit Database - CXSecurity.com
腾讯CDC
Scott Helme
Scott Helme
I
InfoQ
Cyberwarzone
Cyberwarzone
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Security Latest
Security Latest
The Register - Security
The Register - Security
Project Zero
Project Zero
F
Fortinet All Blogs
C
CERT Recently Published Vulnerability Notes
A
Arctic Wolf
C
Cisco Blogs
L
LINUX DO - 热门话题
P
Privacy International News Feed
IT之家
IT之家
U
Unit 42
P
Privacy & Cybersecurity Law Blog
H
Help Net Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Palo Alto Networks Blog
F
Full Disclosure
宝玉的分享
宝玉的分享
Simon Willison's Weblog
Simon Willison's Weblog
L
Lohrmann on Cybersecurity
Google DeepMind News
Google DeepMind News
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
H
Hacker News: Front Page
Know Your Adversary
Know Your Adversary
PCI Perspectives
PCI Perspectives
Hugging Face - Blog
Hugging Face - Blog
AWS News Blog
AWS News Blog
MongoDB | Blog
MongoDB | Blog
S
Schneier on Security
Recent Announcements
Recent Announcements
Forbes - Security
Forbes - Security
Cisco Talos Blog
Cisco Talos Blog

少数派

派早报:Google 发布 Fitbit Air 等 - 少数派 「新人报到」確認需求,再開始 - 少数派 从 SOLO 独立开发者社区,我看到了越来越多开发者开始做自己的产品 - 少数派 我怎么管理那些"不常做,但总会忘"的生活事项 - 少数派 人形机器人量产元年,数据才是具身智能的“生死线” - 少数派 BuhoLaunchpad 高度还原 Mac 启动台:开发历程与思考 - 少数派 五年陪伴依然不舍,DIY 换壳后让罗技 MX Master 3 继续服役 - 少数派 新玩意 240|少数派的编辑们最近买了啥? - 少数派 一日一技|为什么你应该关闭 iOS 的键盘声音 - 少数派 我做了个插件和 Skills,一键提取任何网站的设计规范 Design.md - 少数派 住在三四线城市的你,该开始录播客了 - 少数派 甘南秘境,大白高国 - 少数派 AI的审美:谁让把我变成川内倫子 - 少数派 返工怎能不烦恼,打工人片单总有一部是你的「嘴替」 - 少数派 为了让「上厕所」更健康,我做了一个小工具 - 少数派 AI + Skill,能够让生成的文章去除 AI 味吗? - 少数派 新玩意|韶音OpenDots ONE 耳夹式耳机 - 少数派 《美满》| 在每一个春天的晚上相爱(362) - 少数派 新玩意|优篮子 PS01 MagSnap 磁吸支架 - 少数派 自我整合手记 | 我开始早睡了:用稳定规则,为自由托底 - 少数派 用龙虾(OpenClaw)两个多月,我最深的12个体会 - 少数派 听歌时间到,12 张你可能错过的 2025 华语乐坛好专辑 - 少数派 承诺能追吗 - 少数派 macOS 26启动台没了? 我做了个不一样的App启动器 - Keboard - 少数派 《四海为家的人》| INTJ对话INTJ(361) - 少数派 你发过的那些黑历史,是时候一次清干净了 - 少数派 新玩意:安安静静玩,越玩越专注:计客密码机 - 少数派 iPad 用户首次体验 Android 平板:vivo Pad6 Pro - 少数派 数据逻辑强 - 少数派 极北行+ | 一路向北,探访日本至北之地 | 001 - 少数派 万字剖析:千问App深度体验报告(2026) - 少数派 在2026年,如何真正防止别人抄袭你的作品 - 少数派 怎么用 50 块搭个 AI 语音助手?我踩了 3 天坑 - 少数派 YeeroAI:让 AI 对话真正成为知识管理的一部分 - 少数派 爬泰山 - 少数派 「旅图显影」 App 更新:这次,我们补上了一点「手感」 - 少数派 假期出门太折磨?我的 23 条经验帮你规划惬意旅行 - 少数派 工作流会变吗 - 少数派 Claude Opus 4.6 怎么用最省钱?我测了 5 种方案 - 少数派 GPT Image 2 让图文并茂不再稀罕 - 少数派 用户侧出发——什么是AI,我要不要学习? - 少数派 找片、转存、整理、播放一条龙!让你的付费网盘值回票价 - 少数派 欢迎试用!日课一问2.0插件 - 少数派 自己做的MDeditor,原本想购买 Typora 试了两次支付不成功,干脆自己做一个 - 少数派 vibe coding了一个 3MB 的小工具,让 ~/Downloads 彻底告别混乱 - 少数派 因为受不了 Mac 的风扇策略,我做了一个风扇控制工具 - 少数派 别只怪模型 - 少数派 Warp 终端的 AI 功能怎么用?我测了一周的体验 - 少数派 AI 写代码老是出 bug?这 5 个配置我后悔没早知道 - 少数派 「新玩意」苹果出相机可能就这样:Sigma BF + 45mm F2.8 DG Contemporary - 少数派 一个面向2030年的AI操作系统是什么样子的:浅谈cola这款有灵魂的Agent - 少数派 别只看写代码 - 少数派 每天解决10个问题,还是一口气攻坚解决400个? - 少数派 AI 交易机器人怎么搭?我用 Claude 跑了一周实盘 - 少数派 Maptoposter Online:把你爱的城市画成艺术海报 - 少数派 Function Calling 怎么用?我测了 3 个模型发现差距真大 - 少数派 Legend Talk:我做了个 AI 圆桌,让 160 位思想家围着你的问题转 - 少数派 如何找到自己的蓝方?在小县城寻找压力测试 - 少数派 语音输入与软件接口|2026年聊AI时,我们都聊些什么(上) - 少数派 混动已经卖爆,纯电又来补刀——钛7闪充版简直“不讲武德” - 少数派 本月玩什么|朋友收藏、识质存在、沙罗周期 - 少数派 为什么要每天坚持输出? - 少数派 Claude API 挂了好几个小时,你的项目有备用方案吗? - 少数派 Function Calling 没你想的复杂——我用它做了个有点用的工具 - 少数派 登录系统立即播放视频或者图片音乐的软件 - 少数派 我为什么创建 FlipHTML5 下载工具 - 少数派 残局没电?多品牌外设电量统一管理软件EasyBluetooth已支持RTSS游戏内显示以及AIDA64 - 少数派 前往通义路的路 - 少数派 太好看了,媲美Sun的个人导航页,NAS部署星云门户 - 少数派 乌黑嘴唇“一键检测”上线了 - 少数派 派早报:Claude AI 接入多个创意软件生态、FILCO 生产方接手品牌等 - 少数派 【更新】BearCLI、Claude 连接器与 MCP 服务器 - 少数派 记了上千条流水,还是看不懂财务?我做了一个让 AI 读懂账本的工作台 - 少数派 MINI R56 升级原厂 Sport 模式 - 少数派 新玩意 | 一棵柠檬树(仿真版) - 少数派 Momenta的“物理AI”野望,需迈过“含摩量”这道关 - 少数派 网页直接投屏控制手机!NAS一键部署PandaScrcpy,流畅丝滑可远程。 - 少数派 众测|邀你一同探索随身 AI 硬件入口 YoooClaw C·ONE - 少数派 2050大会:分享时间是真诚 参会记 - 少数派 iPad 赋能电影创作:国内首部宣纸手绘长片《燃比娃》的幕后故事 - 少数派 AI的审美:我用 8 个大模型给 100 张旅行照片打分 - 少数派 普通人如何破圈?去参加一个本地协会 - 少数派 把极空间的图标全换了,主题DIY全攻略打造你的专属NAS桌面 - 少数派 电子便签墙,帮你实现便签自由 - 少数派 我如何用三个 CLI 工具取代文档创建需求 - 少数派 原来真的有人可以玩一辈子 - 少数派 社区速递 139 | 派友热议三月买了啥、复古单反尼康 Df 体验 - 少数派 06 作品的赏析与评价 - 少数派 TDS REVIEW|索尼 WF-1000XM6 降噪真无线耳机体验 - 少数派 35.98万起售的第二代腾势D9,我看重的不是堆料,而是不凑合 - 少数派 鼠须管 Squirrel 皮肤配置指北 - 少数派 从watch ultra2换到redmi watch6 - 少数派 派早报:阿里巴巴发布视频生成模型 HappyHorse 1.0 等 - 少数派 别迷信1M - 少数派 家人们天塌了!网盘“大封杀”,多个渠道多条路,NAS部署PanHub - 少数派 AI与人勾心斗角!NAS一键部署AI狼人杀,假日休闲必备。 - 少数派 电商必备!Comfyui工作流批量生图插件,一次生成12张!支持Nano banana pro模型 - 少数派 Comfyui工作流配置Gpt-image-2模型教程,0.03/张 - 少数派 OpenClaw第三方APi怎么配置?可使用Gpt-image-2模型 - 少数派 会员社区话题精选 Ep. 103 - 少数派
使用 streamlit 编写一个退休计算器 - 少数派
2024-09-28 · via 少数派

依赖:

  1. streamlit 
  2. 智谱 glm-4-flash
  3. 延迟退休政策

效果:

效果图

项目结构:

retirement-planner
    ├── .env
    ├── .gitignore
    ├── app.py
    ├── calc_retirement.py
    ├── image.png
    ├── README.md
    ├── requirements.txt
    └── zhipuai.py

智谱 zhipuai.py

# zhipuai.py 
from openai import OpenAI
from dotenv import load_dotenv
import os

load_dotenv()

api_key = os.getenv("ZHIPUAI_API_KEY")
if not api_key:
    raise ValueError("API 密钥未找到,请检查环境变量")


def generate_text(messages: list):
    client = OpenAI(api_key=api_key, base_url="https://open.bigmodel.cn/api/paas/v4/")

    try:
        stream = client.chat.completions.create(
            model="glm-4-flash",
            messages=messages,
            top_p=0.7,
            temperature=0.9,
            stream=True,
        )
        for chunk in stream:
            if chunk.choices[0].delta.content is not None:
                yield chunk.choices[0].delta.content
    except Exception as e:
        raise RuntimeError(f"生成文本时出错: {e}")


if __name__ == "__main__":
    messages = [
        {"role": "system", "content": "你是一个聪明且富有创造力的小说作家"},
        {
            "role": "user",
            "content": "请你作为童话故事大王,写一篇短篇童话故事,故事的主题是要永远保持一颗善良的心,要能够激发儿童的学习兴趣和想象力,同时也能够帮助儿童更好地理解和接受故事中所蕴含的道理和价值观。",
        },
    ]

    try:
        for text in generate_text(messages):
            print(text, end="")
    except Exception as e:
        print(e)

计算退休信息 calc_retirement.py

# calc_retirement.py
from datetime import datetime
from dateutil.relativedelta import relativedelta
from math import ceil


def calc_retirement(yob: int, mob: int, type: str) -> dict:
    """计算退休日期

    Args:
        yob (int): 出生年
        mob (int): 出生月
        type (str): 性别和人员类型
            'male' - 男职工,60岁退休
            'female50' - 女职工,50岁退休
            'female55' - 女职工,55岁退休

    Returns:
        dict: 返回详细的退休信息,包括
                出生年月、性别和人员类型、
                原退休年龄、原退休时间、现在距离原退休时间的天数、
                改革后新的退休年龄、改革后新的退休时间、现在距离改革后新的退休时间的天数、
                以及延迟月数
    """
    # 解析出生年月
    birth_date = datetime(yob, mob, 1).date()

    # 定义原退休年龄
    orig_ret_age_map = {"male": 60, "female50": 50, "female55": 55}
    orig_ret_age = orig_ret_age_map.get(type)
    if orig_ret_age is None:
        raise ValueError(
            "无效的性别及人员类型。预期值为'male'、'female50'或'female55'。"
        )

    # 政策开始日期
    policy_start_date = datetime(2025, 1, 1).date()

    # 计算原退休日期
    orig_ret_time = birth_date + relativedelta(years=orig_ret_age)

    # 获取当前日期
    current_date = datetime.now().date()

    # 计算当前日期与原退休日期之间的天数差
    orig_ret_days_between = (orig_ret_time - current_date).days

    # 如果天数差小于0,表示已经到了退休年龄,直接返回当前信息
    if orig_ret_days_between < 0:
        return {
            "yob": yob,
            "mob": mob,
            "type": type,
            "orig_ret_age": orig_ret_age,
            "orig_ret_time": orig_ret_time,
            "orig_ret_days_between": orig_ret_days_between,
            "ret_age": orig_ret_age,
            "ret_time": orig_ret_time,
            "ret_days_between": orig_ret_days_between,
            "delay": 0,
        }

    # 计算从政策开始日期到原退休日期的月数差
    months_between = (
        (orig_ret_time.year - policy_start_date.year) * 12
        + orig_ret_time.month
        - policy_start_date.month
    ) + 1  # 增加1个月以确保计算的准确性

    # 定义延迟月数的计算逻辑
    delay_map = {
        60: lambda months: min(
            36, ceil(months / 4)
        ),  # 60岁退休,最多延迟36个月,每4个月延迟1个月
        55: lambda months: min(
            36, ceil(months / 4)
        ),  # 55岁退休,最多延迟36个月,每4个月延迟1个月
        50: lambda months: min(
            60, ceil(months / 2)
        ),  # 50岁退休,最多延迟60个月,每2个月延迟1个月
    }
    delay = delay_map[orig_ret_age](months_between)

    # 计算最终的退休日期
    ret_time = orig_ret_time + relativedelta(months=delay)
    ret_days_between = (ret_time - current_date).days

    # 计算新的退休年龄(精确到月)
    new_ret_age = orig_ret_age + (delay / 12)

    return {
        "yob": yob,  # 出生年
        "mob": mob,  # 出生月
        "type": type,  # 性别和人员类型,可能值为 'male'、'female50' 或 'female55'
        "orig_ret_age": orig_ret_age,  # 原退休年龄
        "orig_ret_time": orig_ret_time,  # 原退休日期
        "orig_ret_days_between": orig_ret_days_between,  # 当前日期到原退休日期之间的天数差
        "ret_age": round(new_ret_age, 2),  # 改革后新的退休年龄,保留两位小数
        "ret_time": ret_time,  # 改革后新的退休日期
        "ret_days_between": ret_days_between,  # 当前日期到改革后新的退休日期之间的天数差
        "delay": delay,  # 延迟的月数
    }


if __name__ == "__main__":
    # 示例测试
    print(calc_retirement(1970, 1, "female55"))

入口文件 app.py

# app.py
import streamlit as st
from zhipuai import generate_text
from calc_retirement import calc_retirement
from datetime import datetime

# 设置页面配置
st.set_page_config(page_title="悠享退休", layout="centered")

st.title("悠享退休")
policy_url = "https://www.mohrss.gov.cn/SYrlzyhshbzb/ztzl/zt202409/qwfb/202409/t20240913_525781.html"

st.caption(
    f"说明:按照[《关于实施渐进式延迟法定退休年龄的决定》附表对照关系]({policy_url}),"
    f"您通过法定退休年龄计算器,选择出生年月、性别及人员类型,即可计算出对应的改革后法定退休年龄、改革后退休时间、延迟月数"
)

col1, col2, col3 = st.columns([1, 1, 2])

with col1:
    yob = st.number_input(
        "出生年份", min_value=1900, max_value=datetime.now().year, value=1987
    )

with col2:
    mob = st.number_input("出生月份", min_value=1, max_value=12, value=5)


# 计算当前岁数
def calculate_age(yob: int, mob: int) -> float:
    birth_date = datetime(yob, mob, 1)
    current_date = datetime.now()
    age_years = current_date.year - birth_date.year
    age_months = current_date.month - birth_date.month

    # 如果当前月份小于出生月份,岁数减一
    if age_months < 0:
        age_years -= 1
        age_months += 12

    age = age_years + (age_months / 12.0)
    return round(age)


current_age = calculate_age(yob, mob)


with col3:
    gender = st.selectbox(
        "类型",
        options=["male", "female50", "female55"],
        format_func=lambda x: {
            "male": "男职工",
            "female50": "原法定退休年龄50周岁女职工",
            "female55": "原法定退休年龄55周岁女职工",
        }[x],
    )

result = calc_retirement(yob, mob, gender)
print(result)

st.markdown("---")

col1, col2 = st.columns(2)


def format_age(age: float) -> str:
    years = int(age)
    months = int(round((age - years) * 12))
    return f"{years}岁" if months == 0 else f"{years}岁{months}个月"


def format_date(date: datetime) -> str:
    return date.strftime("%Y年%m月")


with col1:
    st.header("原始退休信息")
    st.write(f"**原退休年龄:** {format_age(result['orig_ret_age'])}")
    st.write(f"**原退休时间:** {format_date(result['orig_ret_time'])}")

with col2:
    st.header("改革后退休信息")
    st.write(f"**退休年龄:** {format_age(result['ret_age'])}")
    st.write(f"**退休时间:** {format_date(result['ret_time'])}")
    st.write(f"**延迟月数:** {result['delay']}个月")
    if result["ret_days_between"] > 0:
        st.write(f"**距离退休还有:** {result['ret_days_between']} 天")
    else:
        st.write(f"**已退休:** {abs(result['ret_days_between'])} 天")

st.markdown("---")

# 显示调侃
st.header("调侃一下")

current_time = datetime.now().strftime("%Y年%m月")

messages = [
    {
        "role": "system",
        "content": (
            f"现在是{current_time},你是一位善于使用辛辣嘲讽的年轻人。"
            "请根据退休年龄计算器得出的退休信息,以尖酸刻薄的语气,"
            "生成一段挑剔、难听、尖酸、符合逻辑的吐槽或调侃,直接回复不要解释:"
        ),
    }
]

gender_str = "男士" if result["type"] == "male" else "女士"

if result["delay"] > 0:
    user_content = (
        f"幸灾乐祸地调侃:这位延迟退休的{current_age}岁{gender_str},"
        f"和所有同龄人一样受到国家新出台的延迟退休政策影响,需要调整原退休时间,"
        f"比原计划{format_date(result['orig_ret_time'])}退休,多上{result['delay']}个月班,"
        f"原退休年龄{format_age(result['orig_ret_age'])},现在要等到{format_age(result['ret_age'])}才能退休,"
        f"距离退休还有 {result['ret_days_between']} 天。"
    )
elif result["delay"] == 0 and result["ret_days_between"] == 0:
    user_content = (
        f"阴阳怪气地谈论:国家新出台的延迟退休政策对这位{gender_str}没有影响,不需要调整原退休时间,"
        f"今天就是这位{current_age}岁{gender_str}退休的日子,庆祝一下吧!"
    )
elif result["delay"] == 0 and result["ret_days_between"] > 0:
    user_content = (
        f"阴阳怪气地谈论:国家新出台的延迟退休政策对这位{current_age}岁{gender_str}没有影响,不需要调整原退休时间,"
        f"距离退休还有 {result['ret_days_between']} 天,庆祝一下吧!"
    )
else:
    user_content = (
        f"直接吐槽:这位已经退休的{current_age}岁{gender_str},"
        f"国家新出台的延迟退休政策与这位{gender_str}毫无关系,"
        f"早已经退休还来计算退休时间。吐槽内容中包含“已经退休 {abs(result['ret_days_between'])} 天”。"
    )

messages.append({"role": "user", "content": user_content})

output_area = st.empty()

try:
    generated_text = ""

    for chunk in generate_text(messages):
        generated_text += chunk
        output_area.write(generated_text)

except TypeError as e:
    output_area.write(f"生成文本时出现错误,请稍后再试。错误信息:{e}")

requirements.txt  和 .env

# requirements.txt 
streamlit
openai
python-dotenv
# .env
ZHIPUAI_API_KEY=xxx.xxx

使用:

安装依赖pip install -r requirements.txt.env 添加 api key,执行streamlit run app.py