from pydantic import BaseModel from typing import List import random class ModelOutput(BaseModel): @classmethod def classname(cls) -> str: """Return classname.""" return cls.__name__ @classmethod def list_fields(cls) -> List[str]: """List options that are stored as attributes.""" return list(cls.model_fields.keys()) @classmethod def from_random(cls): """Instantiate with random numbers.""" kwargs = {field: random.random() for field in cls.list_fields()} return cls(**kwargs) def __repr__(self) -> str: model_dict = self.model_dump() model_repr_str = f"{self.classname()}(" model_repr_str += ", ".join([f"{field}={value:.3f}" for field, value in model_dict.items()]) model_repr_str += ")" return model_repr_str def highest_score_field(self) -> str: """Return name of field with highest score.""" model_dict = self.model_dump() return max(model_dict, key=lambda k: model_dict[k]) def highest_score_value(self) -> float: """Return value of field with highest score.""" model_dict = self.model_dump() return max(model_dict.values()) class ExperientialModelOutput(ModelOutput): non_transactional_action: float non_transactional_reaction: float unidirectional_transactional_action: float unidirectional_transactional_reaction: float bidirectional_transactional_action: float bidirectional_transactional_reaction: float conversion: float speech_process: float classification_overt_taxonomy: float analytical_exhaustive: float analytical_disarranged: float analytical_temporal: float analytical_distributed: float analytical_topological: float analytical_exploded: float analytical_inclusive: float symbolic_suggestive: float symbolic_attributive: float if __name__ == '__main__': m = ExperientialModelOutput.from_random() print(m) print(repr(m)) print(m.highest_score_field()) print(m.highest_score_value())