"""This is the receiver for K-Means model."""

from enum import Enum
from typing import NamedTuple
from lexos.receivers.base_receiver import BaseReceiver


class KMeansVisualizationOption(Enum):
    """The typed tuple to hold K-Means Visualization method."""

    PCA = "PCA"
    Voronoi = "Voronoi"


class KMeansOption(NamedTuple):
    """The typed tuple to hold K-Means options."""

    viz: KMeansVisualizationOption  # method of visualization.
    n_init: int  # number of iterations with different centroids.
    k_value: int  # k value-for k-means analysis. (k groups)
    max_iter: int  # maximum number of iterations.
    tolerance: float  # relative tolerance, inertia to declare convergence.
    init_method: str  # method of initialization: "K++" or "random".


class KMeansReceiver(BaseReceiver):
    """Class to get K-Means front end option."""

    def options_from_front_end(self) -> KMeansOption:
        """Get the K-Means option from front end.

        :return: a KMeansOption object to hold all the options.
        """
        # Get all front end data.
        viz = KMeansVisualizationOption.PCA \
            if self._front_end_data['viz'] == "PCA" \
            else KMeansVisualizationOption.Voronoi
        n_init = int(self._front_end_data['n_init'])
        k_value = int(self._front_end_data['nclusters'])
        max_iter = int(self._front_end_data['max_iter'])
        tolerance = float(self._front_end_data['tolerance'])
        init_method = self._front_end_data['init']

        return KMeansOption(viz=viz,
                            n_init=n_init,
                            k_value=k_value,
                            max_iter=max_iter,
                            tolerance=tolerance,
                            init_method=init_method)

@@ -195,35 +195,35 @@
 %0A    %22%22%22The 
-typed tuple
+Enum object
  to hold K-M
@@ -261,42 +261,237 @@
     
-PCA = %22PCA%22%0A    Voronoi = %22Voronoi
+two_d_scatter = %222DScatter%22%0A    three_d_scatter = %223DScatter%22%0A    voronoi = %22Voronoi%22%0A%0A%0Aclass KMeansInitOption(Enum):%0A    %22%22%22The Enum object to hold K-Means initialization method.%22%22%22%0A    k_means = %22k-means++%22%0A    random = %22random
 %22%0A%0A%0A
@@ -912,11 +912,24 @@
 od: 
-str
+KMeansInitOption
   # 
@@ -956,27 +956,8 @@
 tion
-: %22K++%22 or %22random%22
 .%0A%0A%0A
@@ -1269,58 +1269,240 @@
     
-viz = KMeansVisualizationOption.PCA %5C%0A            
+if self._front_end_data%5B%22viz%22%5D == %222DScatter%22:%0A            viz = KMeansVisualizationOption.two_d_scatter%0A        elif self._front_end_data%5B%22viz%22%5D == %223DScatter%22:%0A            viz = KMeansVisualizationOption.three_d_scatter%0A        el
 if s
@@ -1525,25 +1525,28 @@
 ata%5B
-'viz'
+%22viz%22
 %5D == %22
-PCA%22 %5C
+Voronoi%22:
 %0A   
@@ -1558,12 +1558,13 @@
     
-else
+viz =
  KMe
@@ -1586,23 +1586,260 @@
 nOption.
-Voronoi
+voronoi%0A        else:%0A            raise ValueError(%22Invalid K-Means visualization method.%22)%0A%0A        init_method = KMeansInitOption.k_means %5C%0A            if self._front_end_data%5B%22init%22%5D == %22k-means++%22 %5C%0A            else KMeansInitOption.random%0A
 %0A       
@@ -1877,16 +1877,16 @@
 ata%5B
-'
+%22
 n_init
-'
+%22
 %5D)%0A 
@@ -1927,17 +1927,17 @@
 nd_data%5B
-'
+%22
 ncluster
@@ -1937,17 +1937,17 @@
 clusters
-'
+%22
 %5D)%0A     
@@ -1989,17 +1989,17 @@
 ata%5B
-'
+%22
 max_iter
 '%5D)%0A
@@ -1994,17 +1994,17 @@
 max_iter
-'
+%22
 %5D)%0A     
@@ -2045,17 +2045,17 @@
 nd_data%5B
-'
+%22
 toleranc
@@ -2059,62 +2059,11 @@
 ance
-'
+%22
 %5D)
-%0A        init_method = self._front_end_data%5B'init'%5D
 %0A%0A  

Update receiver