当前位置: 首页 > news >正文

副业收益追踪器,记录时间投入与收入,自行算时薪,判断副业是否值得坚持。

副业收益追踪器 - 时薪计算与价值评估系统

一、实际应用场景描述

场景:小王是一名前端开发工程师,利用晚上和周末接私活、写技术博客、做线上课程。一个月下来,他接了3个外包项目(共收入15000元),写了2篇技术文章(稿费800元),录制了1节课程(收入500元)。但他感觉很累,不确定这些副业是否值得。他打开"副业收益追踪器",输入各项副业的投入时间和收入,系统自动计算时薪,分析时间价值,并与他的本职工作时薪对比,给出"继续/调整/停止"的建议,同时生成可视化报表帮助他做决策。

二、引入痛点

1. 时间投入无记录:"感觉花了很多时间,但具体多少说不清"

2. 时薪计算混乱:"收入看起来不错,但不知道时薪到底多少"

3. 多项目难比较:"外包、写文、录课哪个更划算?没有数据支撑"

4. 机会成本忽视:"没考虑副业时间本可用于学习或休息的价值"

5. 收益趋势不明:"不知道副业收入是在增长还是下滑"

6. 精力分配失衡:"副业挤占太多时间,影响主业发展和健康"

三、核心逻辑讲解

┌─────────────────────────────────────────────────────────┐

│ 副业收益追踪决策流程 │

├─────────────────────────────────────────────────────────┤

│ 1. 数据录入层 │

│ └── 记录副业项目: 名称/类型/收入/开始时间/结束时间/技能标签 │

│ └── 记录主业数据: 月薪/工作时长(用于计算基准时薪) │

│ └── 数据验证: 时间逻辑/收入合理性/重复项目检测 │

│ │

│ 2. 时薪计算层 (核心算法) │

│ └── 单项目时薪 = 项目收入 ÷ 实际投入小时数 │

│ └── 总时薪 = 总收入 ÷ 总投入小时数 │

│ └── 有效时薪 = 总收入 ÷ (总投入 - 无效时间) │

│ └── 时薪趋势 = 滑动平均/环比/同比分析 │

│ │

│ 3. 价值评估层 │

│ └── 机会成本计算: 副业时薪 vs 主业时薪 vs 学习投资回报率 │

│ └── 价值系数 = 副业时薪 ÷ 基准时薪 │

│ └── 综合评分 = 时薪×0.4 + 成长性×0.3 + 技能提升×0.2 + 兴趣度×0.1 │

│ └── 可持续性评估: 时间可扩展性/收入稳定性/技能复用性 │

│ │

│ 4. 决策建议层 │

│ └── 价值系数>1.5: 强烈建议继续 │

│ └── 价值系数1.0-1.5: 建议优化 │

│ └── 价值系数0.5-1.0: 建议调整 │

│ └── 价值系数<0.5: 建议停止或转型 │

│ │

│ 5. 报表生成层 │

│ └── 时薪趋势图/项目对比图/时间分布饼图/收益构成图 │

│ └── 周报/月报/自定义周期报告 │

└─────────────────────────────────────────────────────────┘

关键算法:

- 时薪计算引擎: 支持多维度时薪计算(毛时薪/净时薪/有效时薪)

- 价值评估模型: 基于多因素加权的综合评分算法

- 趋势分析器: 使用移动平均和环比分析预测未来收益

- 机会成本计算器: 对比不同时间投入的价值回报

四、代码模块化实现

项目结构

side_hustle_tracker/

├── main.py # 主程序入口

├── config.py # 配置文件

├── data/

│ ├── models.py # 数据模型定义

│ ├── database.py # 数据库操作

│ └── sample_data.py # 示例数据

├── core/

│ ├── time_calculator.py # 时薪计算引擎

│ ├── value_evaluator.py # 价值评估器

│ ├── decision_maker.py # 决策建议器

│ └── report_generator.py # 报表生成器

├── utils/

│ ├── validators.py # 数据验证器

│ ├── formatters.py # 格式化工具

│ └── helpers.py # 辅助函数

└── README.md # 使用说明

1. config.py - 配置文件

"""

配置模块 - 定义系统参数、分类体系和计算规则

"""

from dataclasses import dataclass, field

from typing import Dict, List, Set, Tuple, Optional

from enum import Enum

from datetime import time

class IncomeType(Enum):

"""副业收入类型"""

OUTSOURCING = "外包项目" # 接私活、外包开发

CONTENT_CREATION = "内容创作" # 写文章、拍视频、做播客

ONLINE_COURSE = "在线课程" # 录制课程、知识付费

CONSULTING = "咨询服务" # 技术咨询、顾问服务

AFFILIATE = "联盟营销" # 推广分成、佣金

INVESTMENT = "投资收益" # 理财、投资回报

FREELANCE = "自由职业" # 设计、翻译、其他技能服务

OTHER = "其他" # 未分类收入

class SkillTag(Enum):

"""技能标签"""

FRONTEND = "前端开发"

BACKEND = "后端开发"

FULLSTACK = "全栈开发"

MOBILE = "移动开发"

DATA_SCIENCE = "数据科学"

AI_ML = "人工智能"

DEVOPS = "运维开发"

UI_UX = "UI/UX设计"

WRITING = "技术写作"

VIDEO = "视频制作"

TEACHING = "教学培训"

CONSULTING = "技术咨询"

PRODUCT = "产品管理"

MARKETING = "数字营销"

OTHER = "其他技能"

class DecisionCategory(Enum):

"""决策类别"""

STRONGLY_CONTINUE = "强烈建议继续" # 价值系数>1.5

OPTIMIZE_AND_CONTINUE = "建议优化后继续" # 价值系数1.0-1.5

ADJUST_AND_MONITOR = "建议调整并监控" # 价值系数0.5-1.0

STOP_OR_PIVOT = "建议停止或转型" # 价值系数<0.5

@dataclass

class SystemConfig:

"""系统全局配置"""

# 时薪计算规则

MIN_HOURLY_RATE: float = 0.0 # 最低时薪阈值(低于此值警告)

BENCHMARK_HOURLY_RATE: float = 100.0 # 基准时薪(用于对比)

EFFECTIVE_HOUR_THRESHOLD: float = 0.6 # 有效时间比例阈值(60%)

# 价值评估权重

VALUE_WEIGHTS: Dict[str, float] = field(default_factory=lambda: {

'hourly_rate': 0.40, # 时薪占比

'growth_potential': 0.25, # 成长潜力

'skill_development': 0.20, # 技能提升

'interest_alignment': 0.10, # 兴趣匹配度

'sustainability': 0.05 # 可持续性

})

# 决策阈值

DECISION_THRESHOLDS: Dict[str, float] = field(default_factory=lambda: {

'strong_continue': 1.5, # 强烈继续

'optimize_continue': 1.0, # 优化继续

'adjust_monitor': 0.5, # 调整监控

'stop_pivot': 0.0 # 停止转型

})

# 时间计算规则

WORKING_DAYS_PER_WEEK: int = 5

WORKING_HOURS_PER_DAY: int = 8

WEEKS_PER_MONTH: int = 4.33

# 收入类型默认时薪参考(元/小时)

DEFAULT_HOURLY_RATES: Dict[IncomeType, float] = field(default_factory=lambda: {

IncomeType.OUTSOURCING: 150.0,

IncomeType.CONTENT_CREATION: 80.0,

IncomeType.ONLINE_COURSE: 120.0,

IncomeType.CONSULTING: 300.0,

IncomeType.AFFILIATE: 50.0,

IncomeType.INVESTMENT: 0.0, # 被动收入特殊处理

IncomeType.FREELANCE: 100.0,

IncomeType.OTHER: 75.0

})

# 技能加成系数(相对于基准时薪)

SKILL_MULTIPLIERS: Dict[SkillTag, float] = field(default_factory=lambda: {

SkillTag.FRONTEND: 1.0,

SkillTag.BACKEND: 1.1,

SkillTag.FULLSTACK: 1.2,

SkillTag.MOBILE: 1.15,

SkillTag.DATA_SCIENCE: 1.3,

SkillTag.AI_ML: 1.4,

SkillTag.DEVOPS: 1.25,

SkillTag.UI_UX: 0.95,

SkillTag.WRITING: 0.8,

SkillTag.VIDEO: 0.75,

SkillTag.TEACHING: 0.9,

SkillTag.CONSULTING: 1.5,

SkillTag.PRODUCT: 1.35,

SkillTag.MARKETING: 0.85,

SkillTag.OTHER: 0.9

})

# 技能标签显示名称映射

SKILL_TAG_NAMES = {

SkillTag.FRONTEND: "前端开发",

SkillTag.BACKEND: "后端开发",

SkillTag.FULLSTACK: "全栈开发",

SkillTag.MOBILE: "移动开发",

SkillTag.DATA_SCIENCE: "数据科学",

SkillTag.AI_ML: "人工智能",

SkillTag.DEVOPS: "运维开发",

SkillTag.UI_UX: "UI/UX设计",

SkillTag.WRITING: "技术写作",

SkillTag.VIDEO: "视频制作",

SkillTag.TEACHING: "教学培训",

SkillTag.CONSULTING: "技术咨询",

SkillTag.PRODUCT: "产品管理",

SkillTag.MARKETING: "数字营销",

SkillTag.OTHER: "其他技能"

}

# 收入类型图标

INCOME_TYPE_ICONS = {

IncomeType.OUTSOURCING: "💻",

IncomeType.CONTENT_CREATION: "✍️",

IncomeType.ONLINE_COURSE: "🎓",

IncomeType.CONSULTING: "💼",

IncomeType.AFFILIATE: "🔗",

IncomeType.INVESTMENT: "📈",

IncomeType.FREELANCE: "🎨",

IncomeType.OTHER: "📦"

}

# 决策类别颜色和图标

DECISION_STYLES = {

DecisionCategory.STRONGLY_CONTINUE: {"color": "green", "icon": "✅", "emoji": "🚀"},

DecisionCategory.OPTIMIZE_AND_CONTINUE: {"color": "blue", "icon": "⚡", "emoji": "📈"},

DecisionCategory.ADJUST_AND_MONITOR: {"color": "yellow", "icon": "⚠️", "emoji": "🤔"},

DecisionCategory.STOP_OR_PIVOT: {"color": "red", "icon": "❌", "emoji": "🛑"}

}

2. data/models.py - 数据模型定义

"""

数据模型模块 - 定义核心数据结构

使用Python dataclass实现类型安全的模型

"""

from dataclasses import dataclass, field

from typing import List, Optional, Dict, Any, Union

from datetime import datetime, timedelta

from enum import Enum

import uuid

from config import IncomeType, SkillTag, SystemConfig

@dataclass

class TimeEntry:

"""时间记录条目"""

id: str = field(default_factory=lambda: str(uuid.uuid4()))

project_id: str = "" # 关联的项目ID

start_time: Optional[datetime] = None # 开始时间

end_time: Optional[datetime] = None # 结束时间

duration_minutes: float = 0.0 # 持续时间(分钟)

description: str = "" # 描述

tags: List[str] = field(default_factory=list) # 标签

created_at: datetime = field(default_factory=datetime.now)

@property

def duration_hours(self) -> float:

"""获取小时数"""

return self.duration_minutes / 60.0

def to_dict(self) -> Dict[str, Any]:

"""转换为字典"""

return {

"id": self.id,

"project_id": self.project_id,

"start_time": self.start_time.isoformat() if self.start_time else None,

"end_time": self.end_time.isoformat() if self.end_time else None,

"duration_minutes": self.duration_minutes,

"duration_hours": round(self.duration_hours, 2),

"description": self.description,

"tags": self.tags,

"created_at": self.created_at.isoformat()

}

@dataclass

class SideHustleProject:

"""副业项目"""

id: str = field(default_factory=lambda: str(uuid.uuid4()))

name: str = "" # 项目名称

income_type: IncomeType = IncomeType.OTHER # 收入类型

skill_tags: List[SkillTag] = field(default_factory=list) # 技能标签

total_income: float = 0.0 # 总收入(元)

currency: str = "CNY" # 货币单位

time_entries: List[TimeEntry] = field(default_factory=list) # 时间记录

start_date: Optional[datetime] = None # 开始日期

end_date: Optional[datetime] = None # 结束日期

status: str = "active" # 状态: active/completed/paused

notes: str = "" # 备注

created_at: datetime = field(default_factory=datetime.now)

updated_at: datetime = field(default_factory=datetime.now)

@property

def total_hours(self) -> float:

"""总投入小时数"""

return sum(entry.duration_hours for entry in self.time_entries)

@property

def hourly_rate(self) -> float:

"""计算时薪"""

if self.total_hours <= 0:

return 0.0

return self.total_income / self.total_hours

@property

def effective_hours(self) -> float:

"""有效工作时间(扣除低效时间)"""

total = self.total_hours

if total <= 0:

return 0.0

# 假设有效时间比例为70%(可根据实际情况调整)

effective_ratio = 0.7

return total * effective_ratio

@property

def effective_hourly_rate(self) -> float:

"""有效时薪"""

if self.effective_hours <= 0:

return 0.0

return self.total_income / self.effective_hours

def add_time_entry(self, entry: TimeEntry) -> None:

"""添加时间记录"""

entry.project_id = self.id

self.time_entries.append(entry)

self.updated_at = datetime.now()

def calculate_metrics(self, config: SystemConfig) -> Dict[str, float]:

"""计算项目关键指标"""

return {

"total_income": self.total_income,

"total_hours": round(self.total_hours, 2),

"hourly_rate": round(self.hourly_rate, 2),

"effective_hours": round(self.effective_hours, 2),

"effective_hourly_rate": round(self.effective_hourly_rate, 2),

"daily_average_income": round(

self.total_income / max(1, (self.end_date - self.start_date).days), 2

) if self.end_date and self.start_date else 0,

"weekly_average_income": round(

self.total_income / max(1, len(self.time_entries) / 5), 2

) if self.time_entries else 0

}

def to_dict(self) -> Dict[str, Any]:

"""转换为字典"""

return {

"id": self.id,

"name": self.name,

"income_type": self.income_type.value,

"skill_tags": [tag.value for tag in self.skill_tags],

"total_income": self.total_income,

"currency": self.currency,

"total_hours": round(self.total_hours, 2),

"hourly_rate": round(self.hourly_rate, 2),

"effective_hours": round(self.effective_hours, 2),

"effective_hourly_rate": round(self.effective_hourly_rate, 2),

"time_entries_count": len(self.time_entries),

"start_date": self.start_date.isoformat() if self.start_date else None,

"end_date": self.end_date.isoformat() if self.end_date else None,

"status": self.status,

"notes": self.notes,

"created_at": self.created_at.isoformat(),

"updated_at": self.updated_at.isoformat()

}

@dataclass

class MainJobInfo:

"""主业信息"""

monthly_salary: float = 0.0 # 月薪

currency: str = "CNY" # 货币单位

working_hours_per_week: int = 40 # 每周工作小时数

working_days_per_week: int = 5 # 每周工作天数

vacation_days_per_year: int = 10 # 年假天数

start_date: Optional[datetime] = None # 入职日期

position: str = "" # 职位

company: str = "" # 公司

created_at: datetime = field(default_factory=datetime.now)

@property

def weekly_income(self) -> float:

"""周收入"""

return self.monthly_salary * 12 / 52

@property

def hourly_rate(self) -> float:

"""主业时薪"""

return self.weekly_income / self.working_hours_per_week

@property

def daily_income(self) -> float:

"""日收入"""

return self.monthly_salary / 21.75 # 月计薪天数

def to_dict(self) -> Dict[str, Any]:

"""转换为字典"""

return {

"monthly_salary": self.monthly_salary,

"currency": self.currency,

"working_hours_per_week": self.working_hours_per_week,

"working_days_per_week": self.working_days_per_week,

"vacation_days_per_year": self.vacation_days_per_year,

"hourly_rate": round(self.hourly_rate, 2),

"weekly_income": round(self.weekly_income, 2),

"daily_income": round(self.daily_income, 2),

"position": self.position,

"company": self.company,

"created_at": self.created_at.isoformat()

}

@dataclass

class ValueEvaluation:

"""价值评估结果"""

project_id: str = ""

project_name: str = ""

hourly_rate: float = 0.0

effective_hourly_rate: float = 0.0

benchmark_hourly_rate: float = 0.0

value_coefficient: float = 0.0 # 价值系数 = 副业时薪 / 基准时薪

growth_potential: float = 0.0 # 成长潜力评分(0-10)

skill_development: float = 0.0 # 技能提升评分(0-10)

interest_alignment: float = 0.0 # 兴趣匹配度(0-10)

sustainability: float = 0.0 # 可持续性评分(0-10)

overall_score: float = 0.0 # 综合评分(0-10)

decision_category: DecisionCategory = DecisionCategory.ADJUST_AND_MONITOR

recommendations: List[str] = field(default_factory=list)

risks: List[str] = field(default_factory=list)

opportunities: List[str] = field(default_factory=list)

created_at: datetime = field(default_factory=datetime.now)

def to_dict(self) -> Dict[str, Any]:

"""转换为字典"""

return {

"project_id": self.project_id,

"project_name": self.project_name,

"hourly_rate": round(self.hourly_rate, 2),

"effective_hourly_rate": round(self.effective_hourly_rate, 2),

"benchmark_hourly_rate": round(self.benchmark_hourly_rate, 2),

"value_coefficient": round(self.value_coefficient, 2),

"growth_potential": round(self.growth_potential, 1),

"skill_development": round(self.skill_development, 1),

"interest_alignment": round(self.interest_alignment, 1),

"sustainability": round(self.sustainability, 1),

"overall_score": round(self.overall_score, 1),

"decision_category": self.decision_category.value,

"recommendations": self.recommendations,

"risks": self.risks,

"opportunities": self.opportunities,

"created_at": self.created_at.isoformat()

}

@dataclass

class ReportData:

"""报表数据"""

report_period: str = "" # 报表周期

generated_at: datetime = field(default_factory=datetime.now)

summary: Dict[str, Any] = field(default_factory=dict)

projects_summary: List[Dict[str, Any]] = field(default_factory=list)

hourly_rate_trend: List[Dict[str, Any]] = field(default_factory=list)

time_distribution: Dict[str, float] = field(default_factory=dict)

income_breakdown: Dict[str, float] = field(default_factory=dict)

value_evaluations: List[ValueEvaluation] = field(default_factory=list)

charts_config: Dict[str, Any] = field(default_factory=dict)

def to_dict(self) -> Dict[str, Any]:

"""转换为字典"""

return {

"report_period": self.report_period,

"generated_at": self.generated_at.isoformat(),

"summary": self.summary,

"projects_summary": self.projects_summary,

"hourly_rate_trend": self.hourly_rate_trend,

"time_distribution": self.time_distribution,

"income_breakdown": self.income_breakdown,

"value_evaluations": [eval.to_dict() for eval in self.value_evaluations],

"charts_config": self.charts_config

}

3. data/database.py - 数据库操作

"""

数据库操作模块 - 使用SQLite存储和管理数据

"""

import sqlite3

import json

from datetime import datetime

from typing import List, Optional, Dict, Any

from contextlib import contextmanager

from data.models import (

TimeEntry, SideHustleProject, MainJobInfo,

ValueEvaluation, IncomeType, SkillTag

)

from config import SystemConfig

class DatabaseManager:

"""数据库管理器"""

def __init__(self, db_path: str = "side_hustle_tracker.db"):

self.db_path = db_path

self.init_database()

@contextmanager

def get_connection(self):

"""获取数据库连接的上下文管理器"""

conn = sqlite3.connect(self.db_path)

conn.row_factory = sqlite3.Row

try:

yield conn

conn.commit()

except Exception as e:

conn.rollback()

raise e

finally:

conn.close()

def init_database(self) -> None:

"""初始化数据库表结构"""

with self.get_connection() as conn:

cursor = conn.cursor()

# 主业信息表

cursor.execute('''

CREATE TABLE IF NOT EXISTS main_job (

id TEXT PRIMARY KEY,

monthly_salary REAL NOT NULL,

currency TEXT DEFAULT 'CNY',

working_hours_per_week INTEGER DEFAULT 40,

working_days_per_week INTEGER DEFAULT 5,

vacation_days_per_year INTEGER DEFAULT 10,

start_date TEXT,

position TEXT,

company TEXT,

created_at TEXT NOT NULL

)

''')

# 副业项目表

cursor.execute('''

CREATE TABLE IF NOT EXISTS side_hustle_projects (

id TEXT PRIMARY KEY,

name TEXT NOT NULL,

income_type TEXT NOT NULL,

skill_tags TEXT,

total_income REAL DEFAULT 0,

currency TEXT DEFAULT 'CNY',

start_date TEXT,

end_date TEXT,

status TEXT DEFAULT 'active',

notes TEXT,

created_at TEXT NOT NULL,

updated_at TEXT NOT NULL

)

''')

# 时间记录表

cursor.execute('''

CREATE TABLE IF NOT EXISTS time_entries (

id TEXT PRIMARY KEY,

project_id TEXT NOT NULL,

start_time TEXT,

end_time TEXT,

duration_minutes REAL DEFAULT 0,

description TEXT,

tags TEXT,

created_at TEXT NOT NULL,

FOREIGN KEY (project_id) REFERENCES side_hustle_projects(id)

)

''')

# 价值评估表

cursor.execute('''

CREATE TABLE IF NOT EXISTS value_evaluations (

id TEXT PRIMARY KEY,

project_id TEXT NOT NULL,

利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!

http://www.jsqmd.com/news/480672/

相关文章:

  • 北京绩效薪酬政策解读哪家强,创锟咨询靠谱不? - 工业推荐榜
  • 2026找口碑好的亚克力透光板直销厂家,联系方式在这,目前透光板品牌三松发展迅速,实力雄厚 - 品牌推荐师
  • 2026年评价好的亮化照明工程公司推荐:城市夜景照明工程/户外亮化照明工程推荐供应链 - 行业平台推荐
  • ERP+PDA库存管理省时省力的庖丁解牛
  • 信息化整体架构设计与技术选型
  • 六大城市高端腕表维修避坑:百达翡丽/江诗丹顿/欧米茄养护与维修实战指南 - 时光修表匠
  • 拟上市公司股权激励性价比高的推荐,费用怎么算 - 工业品网
  • 六大城市高端腕表养护指南:百达翡丽/江诗丹顿等36品牌维修与保值技巧 - 时光修表匠
  • 2026年口碑好的四川礼盒印刷品牌推荐:月饼礼盒印刷/成都礼盒印刷源头工厂推荐 - 行业平台推荐
  • 什么是“计算图”?
  • 信息化建设-实施路径规划与投资预算
  • 信息化建设-核心系统实施方法论
  • 2026年靠谱的四川书刊印刷厂家推荐:台历书刊印刷/包装书刊印刷/折页书刊印刷厂家综合实力对比 - 行业平台推荐
  • YOLO26改进89:全网首发--c3k2模块添加LEGM模块
  • YOLOv11涨点改进| TGRS 2026 |全网创新首发、Conv卷积改进篇 | 引入SFEM空间-频率特征增强模块,同时建模空间域和频域信息,助力YOLOv11遥感小目标检测,小目标分割高效涨点
  • 【SQL Server】超详细SQLServer日期转换、字符串、数学、聚合等常用函数大全(最新版)
  • YOLOv11涨点改进| TGRS 2026 |独家创新首发、特征融合改进篇| 引入CIFusion 通道交互融合模块,通过跨特征交互机制强化目标区域响应,适合多模态融合目标检测,小目标检测高效涨点
  • YOLO26改进88:全网首发--c3k2模块添加C3k2_EfficientVIM_CGLU组合创新模块
  • 自检的邮件服务器发送的邮件可能被拒收-----伪造邮件地址
  • 探讨2026年钢结构设计专业机构哪家好,各品牌优势对比 - 工业品网
  • 【信息科学与工程学】【财务管理】 第十八篇 企业利润设计
  • 探讨多层钢结构厂家选购要点,苏东钢结构在全国口碑如何? - 工业品网
  • 止痒去屑洗发水怎么选?2026年这几款值得一试,有名的止痒去屑洗发水精选国内优质品牌榜单 - 品牌推荐师
  • 2026年红色教育馆策划设计品牌企业选购指南,怎么选 - 工业设备
  • 读书笔记.
  • 天猫超市卡回收教程,简单又高效 - 团团收购物卡回收
  • 2026年有名的货架制造企业排名,陕西靠谱的货架加工企业推荐 - 工业推荐榜
  • 读书笔记 .
  • 分析绩效薪酬咨询,哪家性价比高且服务覆盖北京上海 - myqiye
  • 为什么中国高考考外语,美英法不考汉语?全民强制学英语合理吗?