Files
42-Piscine_Python/09/ex2/space_crew.py
2026-03-12 17:46:56 +01:00

98 lines
3.2 KiB
Python

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()