-
Notifications
You must be signed in to change notification settings - Fork 0
Dev jihyun - 통계 기능 구현 #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fe95400
bb7044c
726f32f
1e058ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,41 @@ | ||||||||||||||||||||||||||
| """Statistics and reporting module for ChillMCP server.""" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| import json | ||||||||||||||||||||||||||
| from pathlib import Path | ||||||||||||||||||||||||||
| from collections import Counter | ||||||||||||||||||||||||||
| from datetime import datetime | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # State file path (in project root) | ||||||||||||||||||||||||||
| STATE_FILE = Path(__file__).parent.parent / ".chillmcp_state.json" | ||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| def get_break_statistics() -> dict: | ||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||
| Analyze break history and generate statistics. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Returns: | ||||||||||||||||||||||||||
| dict: A dictionary containing break statistics. | ||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||
| if not STATE_FILE.exists(): | ||||||||||||||||||||||||||
| return {"error": "No break history found."} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| with open(STATE_FILE, 'r') as f: | ||||||||||||||||||||||||||
| data = json.load(f) | ||||||||||||||||||||||||||
| history = data.get("history", []) | ||||||||||||||||||||||||||
|
Comment on lines
+18
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 함수는 상태 파일을 직접 읽어 |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if not history: | ||||||||||||||||||||||||||
| return {"error": "Break history is empty."} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| total_breaks = len(history) | ||||||||||||||||||||||||||
| tool_counter = Counter(item['tool_name'] for item in history) | ||||||||||||||||||||||||||
| most_common_tool = tool_counter.most_common(1)[0][0] if tool_counter else "N/A" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Analyze break times by hour | ||||||||||||||||||||||||||
| hour_counter = Counter(datetime.fromtimestamp(item['timestamp']).hour for item in history) | ||||||||||||||||||||||||||
| most_common_hour = hour_counter.most_common(1)[0][0] if hour_counter else "N/A" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||
| "total_breaks": total_breaks, | ||||||||||||||||||||||||||
| "most_common_tool": most_common_tool, | ||||||||||||||||||||||||||
| "most_common_hour": f"{most_common_hour}:00 - {most_common_hour+1}:00", | ||||||||||||||||||||||||||
| "breaks_by_tool": dict(tool_counter), | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
+36
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -4,7 +4,7 @@ | |||||
| import random | ||||||
| from typing import List | ||||||
|
|
||||||
| from . import ascii_art | ||||||
| from . import ascii_art, statistics | ||||||
| from .response_formatter import format_response | ||||||
| from .state_manager import StateManager | ||||||
|
|
||||||
|
|
@@ -96,6 +96,10 @@ async def execute_break_tool( | |||||
|
|
||||||
| # Potentially increase boss alert | ||||||
| boss_increased, old_boss_level = await state_manager.increase_boss_alert() | ||||||
| boss_alert_change = 1 if boss_increased else 0 | ||||||
|
|
||||||
| # Save history | ||||||
| state_manager.add_history_event(tool_name, -stress_decrease, boss_alert_change) | ||||||
|
|
||||||
| # Get current state | ||||||
| state = await state_manager.get_state() | ||||||
|
|
@@ -284,6 +288,9 @@ async def chimaek(state_manager: StateManager) -> str: | |||||
| boss_increase = random.randint(2, 3) | ||||||
| await state_manager.change_boss_alert(boss_increase) | ||||||
|
|
||||||
| # Save history | ||||||
| state_manager.add_history_event("chimaek", -stress_relief, boss_increase) | ||||||
|
|
||||||
| # Get updated state | ||||||
| state = await state_manager.get_state() | ||||||
|
|
||||||
|
|
@@ -309,9 +316,17 @@ async def leave_work(state_manager: StateManager) -> str: | |||||
| Returns: | ||||||
| str: Formatted response. | ||||||
| """ | ||||||
| # Save current levels before reset for history | ||||||
| current_state = await state_manager.get_state() | ||||||
| stress_before = current_state["stress_level"] | ||||||
| boss_before = current_state["boss_alert_level"] | ||||||
|
|
||||||
| # 퇴근하면 모든 스트레스와 Boss Alert 리셋! | ||||||
| await state_manager.reset() | ||||||
|
|
||||||
| # Save history (negative values mean decrease) | ||||||
| state_manager.add_history_event("leave_work", -stress_before, -boss_before) | ||||||
|
|
||||||
| # Get state | ||||||
| state = await state_manager.get_state() | ||||||
|
|
||||||
|
|
@@ -359,13 +374,17 @@ async def company_dinner(state_manager: StateManager) -> str: | |||||
| await state_manager.increase_stress(amount=stress_change) | ||||||
|
|
||||||
| # Boss alert changes slightly | ||||||
| boss_alert_change = -1 if is_positive else 1 | ||||||
| if is_positive: | ||||||
| # Positive event: boss alert decreases a bit | ||||||
| await state_manager.change_boss_alert(-1) | ||||||
| else: | ||||||
| # Negative event: boss alert increases | ||||||
| await state_manager.change_boss_alert(1) | ||||||
|
|
||||||
| # Save history (use negative stress_change for decrease) | ||||||
| state_manager.add_history_event("company_dinner", -stress_change if stress_change < 0 else stress_change, boss_alert_change) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| # Get state | ||||||
| state = await state_manager.get_state() | ||||||
|
|
||||||
|
|
@@ -381,6 +400,45 @@ async def company_dinner(state_manager: StateManager) -> str: | |||||
| ) | ||||||
|
|
||||||
|
|
||||||
| async def generate_report(state_manager: StateManager) -> str: | ||||||
| """ | ||||||
| Generate a report of break statistics. | ||||||
|
|
||||||
| Args: | ||||||
| state_manager: The state manager instance. | ||||||
|
|
||||||
| Returns: | ||||||
| str: Formatted response with statistics. | ||||||
| """ | ||||||
| stats = statistics.get_break_statistics() | ||||||
|
|
||||||
| if "error" in stats: | ||||||
| return format_response( | ||||||
| break_summary=stats["error"], | ||||||
| stress_level=(await state_manager.get_state())["stress_level"], | ||||||
| boss_alert_level=(await state_manager.get_state())["boss_alert_level"], | ||||||
| tool_name="generate_report" | ||||||
| ) | ||||||
|
|
||||||
| report = f"""**Breakdown of Your Break Habits** | ||||||
|
|
||||||
| - **Total Breaks Taken:** {stats["total_breaks"]} | ||||||
| - **Favorite Break Tool:** {stats["most_common_tool"]} | ||||||
| - **Busiest Break Time:** {stats["most_common_hour"]} | ||||||
|
|
||||||
| **Breaks by Tool:** | ||||||
| """ | ||||||
| for tool, count in stats["breaks_by_tool"].items(): | ||||||
| report += f"- {tool}: {count}\n" | ||||||
|
|
||||||
| return format_response( | ||||||
| break_summary=report, | ||||||
| stress_level=(await state_manager.get_state())["stress_level"], | ||||||
| boss_alert_level=(await state_manager.get_state())["boss_alert_level"], | ||||||
| tool_name="generate_report" | ||||||
| ) | ||||||
|
Comment on lines
+413
to
+439
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
stats = statistics.get_break_statistics()
state = await state_manager.get_state()
if "error" in stats:
return format_response(
break_summary=stats["error"],
stress_level=state["stress_level"],
boss_alert_level=state["boss_alert_level"],
tool_name="generate_report"
)
report = f"""**Breakdown of Your Break Habits**
- **Total Breaks Taken:** {stats["total_breaks"]}
- **Favorite Break Tool:** {stats["most_common_tool"]}
- **Busiest Break Time:** {stats["most_common_hour"]}
**Breaks by Tool:**
"""
for tool, count in stats["breaks_by_tool"].items():
report += f"- {tool}: {count}\n"
return format_response(
break_summary=report,
stress_level=state["stress_level"],
boss_alert_level=state["boss_alert_level"],
tool_name="generate_report"
) |
||||||
|
|
||||||
|
|
||||||
| async def snack_time(state_manager: StateManager) -> str: | ||||||
| """ | ||||||
| Take a snack break at the convenience store! | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
history속성을_history로 변경하여 클래스의 다른 내부 상태 변수(__stress_level,_last_stress_update등)와의 명명 규칙 일관성을 유지하는 것이 좋습니다. 이는 이 변수가 클래스 내부용임을 나타냅니다. 이 변경을 적용하려면 이 파일의 236, 258, 273번째 줄에 있는self.history도self._history로 함께 수정해야 합니다.