From 3054eb8c0de880655a3a01bf4c2da154e6c3ab42 Mon Sep 17 00:00:00 2001 From: matin Date: Tue, 30 Sep 2025 15:13:08 +0200 Subject: save + load includes the launch date and duration. also, increased readability of the json output --- prediction_state.py | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 prediction_state.py (limited to 'prediction_state.py') diff --git a/prediction_state.py b/prediction_state.py new file mode 100644 index 0000000..966b3c0 --- /dev/null +++ b/prediction_state.py @@ -0,0 +1,77 @@ +# prediction_state.py +from datetime import datetime +from dateutil.relativedelta import relativedelta +from typing import List, Optional, Dict, Any, TYPE_CHECKING +if TYPE_CHECKING: + from calendar_entry import CalendarEntry +import uuid + +class PredictionState: + """Represents the complete state of a prediction including all metadata""" + + def __init__(self, launch_date: Optional[datetime] = None, + duration_years: Optional[int] = None, + prediction_date: Optional[datetime] = None, + entries: Optional[List["CalendarEntry"]] = None): + self.launch_date = launch_date + self.duration_years = duration_years + self.prediction_date = prediction_date + self.entries = entries or [] + self.created_at = datetime.now() + self.version = "1.0" + + def to_dict(self) -> Dict[str, Any]: + """Convert state to dictionary for serialization""" + return { + 'version': self.version, + 'created_at': self.created_at.isoformat(), + 'launch_date': self.launch_date.strftime('%Y-%m-%d') if self.launch_date else None, + 'duration_years': self.duration_years, + 'prediction_date': self.prediction_date.strftime('%Y-%m-%d') if self.prediction_date else None, + 'entries': [self._entry_to_dict_without_id(entry) for entry in self.entries] + } + + def _entry_to_dict_without_id(self, entry: "CalendarEntry") -> Dict[str, Any]: + """Convert entry to dictionary without ID for better readability""" + return { + 'start_date': entry.start_date.strftime('%Y-%m-%d'), + 'end_date': entry.end_date.strftime('%Y-%m-%d'), + 'keyword': entry.keyword, + 'commentary': entry.commentary, + 'corrected_start_date': entry.corrected_start_date.strftime('%Y-%m-%d') if entry.corrected_start_date else None, + 'corrected_end_date': entry.corrected_end_date.strftime('%Y-%m-%d') if entry.corrected_end_date else None, + 'time_period': entry.time_period if hasattr(entry, 'time_period') else None + } + + @classmethod + def from_dict(cls, data: Dict[str, Any]) -> 'PredictionState': + """Create state from dictionary, generating new IDs for entries""" + from calendar_entry import CalendarEntry + + state = cls() + state.version = data.get('version', '1.0') + # created_at can include time; others are date-only strings + state.created_at = datetime.fromisoformat(data['created_at']) if data.get('created_at') else datetime.now() + state.launch_date = datetime.fromisoformat(data['launch_date']) if data.get('launch_date') else None + state.duration_years = data.get('duration_years') + state.prediction_date = datetime.fromisoformat(data['prediction_date']) if data.get('prediction_date') else None + + # Create entries with new IDs + state.entries = [] + for entry_data in data.get('entries', []): + entry = CalendarEntry( + start_date=entry_data['start_date'], + end_date=entry_data['end_date'], + keyword=entry_data['keyword'], + entry_id=str(uuid.uuid4()), # Generate new ID + corrected_start_date=datetime.fromisoformat(entry_data['corrected_start_date']) if entry_data.get('corrected_start_date') else None, + corrected_end_date=datetime.fromisoformat(entry_data['corrected_end_date']) if entry_data.get('corrected_end_date') else None, + commentary=entry_data.get('commentary', '') + ) + # Set time_period if available + if entry_data.get('time_period'): + entry.time_period = entry_data['time_period'] + + state.entries.append(entry) + + return state \ No newline at end of file -- cgit v1.1