# coding: utf-8

"""
    Mixpeek API

    This is the Mixpeek API, providing access to various endpoints for data processing and retrieval.

    The version of the OpenAPI document: 1.3.0
    Contact: info@mixpeek.com
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field
from typing import Any, ClassVar, Dict, List, Optional, Union
from typing_extensions import Annotated
from typing import Optional, Set
from typing_extensions import Self

class ClusterExecutionMetrics(BaseModel):
    """
    Quality metrics for evaluating clustering execution performance.  Provides statistical measures to assess the quality of the clustering results. Higher quality clusters have better cohesion (documents within clusters are similar) and separation (clusters are distinct from each other).  Use Cases:     - Compare quality across multiple clustering executions     - Determine optimal number of clusters for a dataset     - Validate clustering algorithm performance     - Track clustering quality over time     - Debug clustering issues (poor metrics indicate problems)  Interpretation:     - Use silhouette_score as primary quality indicator (0.5+ = good, 0.7+ = excellent)     - Lower davies_bouldin_index indicates better-separated clusters     - Higher calinski_harabasz_score indicates denser, better-separated clusters  Note:     All metrics are OPTIONAL and only present if clustering completed successfully.     Failed executions return null for all metrics.
    """ # noqa: E501
    silhouette_score: Optional[Union[Annotated[float, Field(le=1.0, strict=True, ge=-1.0)], Annotated[int, Field(le=1, strict=True, ge=-1)]]] = Field(default=None, description="OPTIONAL. Silhouette score measuring cluster cohesion and separation. Range: -1 to +1. Interpretation:   +1.0 = Perfect clustering (documents far from other clusters, close to own cluster).   0.0 = Overlapping clusters (documents on cluster boundaries).   -1.0 = Poor clustering (documents assigned to wrong clusters). Practical thresholds:   0.7 to 1.0 = Excellent clustering.   0.5 to 0.7 = Good clustering.   0.25 to 0.5 = Weak clustering, consider different parameters.   Below 0.25 = Poor clustering, reconfigure or more data needed. null = metric not calculated (too few points or clustering failed).")
    davies_bouldin_index: Optional[Union[Annotated[float, Field(strict=True, ge=0.0)], Annotated[int, Field(strict=True, ge=0)]]] = Field(default=None, description="OPTIONAL. Davies-Bouldin index measuring cluster separation. Range: 0 to +∞ (lower is better, no upper bound). Interpretation:   0.0 = Perfect separation (impossible in practice).   0.0 to 1.0 = Excellent separation.   1.0 to 2.0 = Good separation.   Above 2.0 = Poor separation, clusters overlap. Formula: Average ratio of intra-cluster to inter-cluster distances. Use when: Validating that clusters are distinct and well-separated. null = metric not calculated (too few points or clustering failed).")
    calinski_harabasz_score: Optional[Union[Annotated[float, Field(strict=True, ge=0.0)], Annotated[int, Field(strict=True, ge=0)]]] = Field(default=None, description="OPTIONAL. Calinski-Harabasz score (also called Variance Ratio Criterion). Range: 0 to +∞ (higher is better, no strict upper bound). Interpretation:   Higher values indicate denser, more compact clusters.   No universal threshold - compare relative values across runs.   Typical good values: 100-1000+ (dataset dependent). Formula: Ratio of between-cluster to within-cluster dispersion. Use when: Comparing different numbers of clusters for the same dataset. Note: Biased toward algorithms that produce spherical, equally-sized clusters. null = metric not calculated (too few points or clustering failed).")
    __properties: ClassVar[List[str]] = ["silhouette_score", "davies_bouldin_index", "calinski_harabasz_score"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of ClusterExecutionMetrics from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of ClusterExecutionMetrics from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "silhouette_score": obj.get("silhouette_score"),
            "davies_bouldin_index": obj.get("davies_bouldin_index"),
            "calinski_harabasz_score": obj.get("calinski_harabasz_score")
        })
        return _obj


