diff --git a/09/ex2/space_crew.py b/09/ex2/space_crew.py new file mode 100644 index 0000000..8351a8c --- /dev/null +++ b/09/ex2/space_crew.py @@ -0,0 +1,97 @@ +from enum import Enum +from typing_extensions import Self +from pydantic import BaseModel, Field, model_validator +from datetime import datetime +from json import load + + +class Rank(Enum): + CADET = "cadet" + OFFICER = "officer" + LIEUTENANT = "lieutenant" + CAPTAIN = "captain" + COMMANDER = "commander" + + +class CrewMember(BaseModel): + member_id: str = Field(min_length=3, max_length=10) + name: str = Field(min_length=2, max_length=50) + rank: Rank + age: int = Field(ge=18, le=80) + specialization: str = Field(min_length=3, max_length=30) + years_experience: int = Field(ge=0, le=50) + is_active: bool = Field(default=True) + + +class SpaceMission(BaseModel): + mission_id: str = Field(min_length=5, max_length=15) + mission_name: str = Field(min_length=3, max_length=100) + destination: str = Field(min_length=3, max_length=50) + launch_date: datetime + duration_days: int = Field(ge=1, le=3650) + crew: list[CrewMember] = Field(min_length=1, max_length=12) + mission_status: str = Field(default="planned") + budget_millions: float = Field(ge=1.0, le=10000.0) + + @model_validator(mode="after") + def validation(self) -> Self: + if not self.mission_id.startswith("M"): + raise ValueError('Mission ID must start with "M"') + try: + crew = {member.rank: member for member in self.crew} + crew[Rank.CAPTAIN] + crew[Rank.COMMANDER] + except KeyError: + raise ValueError("Must have at least one Commander or Captain") + if ( + self.duration_days > 365 + and len( + [ + member + for member in self.crew + if member.years_experience >= 5 + ] + ) + < len(self.crew) / 2 + ): + raise ValueError( + "Long missions (> 365 days) need 50% " + "experienced crew (5+ years)" + ) + for member in self.crew: + if member.is_active == False: + raise ValueError("All crew members must be active") + return self + + +def main() -> None: + try: + with open("../generated_data/space_missions.json") as file: + data = load(file) + for mission in data: + try: + print("=========================================") + sp = SpaceMission(**mission) + print( + "Valid mission created:\n" + f"Mission: {sp.mission_name}\n" + f"ID: {sp.mission_id}\n" + f"Destination: {sp.destination}\n" + f"Duration: {sp.duration_days} days\n" + f"Budget: ${sp.budget_millions}M\n" + f"Crew size: {len(sp.crew)}\n" + "Crew members:" + ) + for member in sp.crew: + print( + f"- {member.name} ({member.rank}) - " + f"{member.specialization}" + ) + except Exception as err: + print(err) + except Exception as err: + print(err) + + +if __name__ == "__main__": + main()