# - Generated by tools/entrypoint_compiler.py: do not edit by hand
"""
Trainers.StochasticDualCoordinateAscentClassifier
"""

import numbers

from ..utils.entrypoints import EntryPoint
from ..utils.utils import try_set, unlist


def trainers_stochasticdualcoordinateascentclassifier(
        training_data,
        predictor_model=None,
        l2_const=None,
        l1_threshold=None,
        feature_column='Features',
        label_column='Label',
        normalize_features='Auto',
        caching='Auto',
        loss_function=None,
        num_threads=None,
        convergence_tolerance=0.1,
        max_iterations=None,
        shuffle=True,
        check_frequency=None,
        bias_learning_rate=0.0,
        **params):
    """
    **Description**
        The SDCA linear multi-class classification trainer.

    :param l2_const: L2 regularizer constant. By default the l2
        constant is automatically inferred based on data set.
        (inputs).
    :param training_data: The data to be used for training (inputs).
    :param l1_threshold: L1 soft threshold (L1/L2). Note that it is
        easier to control and sweep using the threshold parameter
        than the raw L1-regularizer constant. By default the l1
        threshold is automatically inferred based on data set.
        (inputs).
    :param feature_column: Column to use for features (inputs).
    :param label_column: Column to use for labels (inputs).
    :param normalize_features: Normalize option for the feature
        column (inputs).
    :param caching: Whether learner should cache input training data
        (inputs).
    :param loss_function: Loss Function (inputs).
    :param num_threads: Degree of lock-free parallelism. Defaults to
        automatic. Determinism not guaranteed. (inputs).
    :param convergence_tolerance: The tolerance for the ratio between
        duality gap and primal loss for convergence checking.
        (inputs).
    :param max_iterations: Maximum number of iterations; set to 1 to
        simulate online learning. Defaults to automatic. (inputs).
    :param shuffle: Shuffle data every epoch? (inputs).
    :param check_frequency: Convergence check frequency (in terms of
        number of iterations). Set as negative or zero for not
        checking at all. If left blank, it defaults to check after
        every 'numThreads' iterations. (inputs).
    :param bias_learning_rate: The learning rate for adjusting bias
        from being regularized. (inputs).
    :param predictor_model: The trained model (outputs).
    """

    entrypoint_name = 'Trainers.StochasticDualCoordinateAscentClassifier'
    inputs = {}
    outputs = {}

    if l2_const is not None:
        inputs['L2Const'] = try_set(
            obj=l2_const,
            none_acceptable=True,
            is_of_type=numbers.Real)
    if training_data is not None:
        inputs['TrainingData'] = try_set(
            obj=training_data,
            none_acceptable=False,
            is_of_type=str)
    if l1_threshold is not None:
        inputs['L1Threshold'] = try_set(
            obj=l1_threshold,
            none_acceptable=True,
            is_of_type=numbers.Real)
    if feature_column is not None:
        inputs['FeatureColumn'] = try_set(
            obj=feature_column,
            none_acceptable=True,
            is_of_type=str,
            is_column=True)
    if label_column is not None:
        inputs['LabelColumn'] = try_set(
            obj=label_column,
            none_acceptable=True,
            is_of_type=str,
            is_column=True)
    if normalize_features is not None:
        inputs['NormalizeFeatures'] = try_set(
            obj=normalize_features,
            none_acceptable=True,
            is_of_type=str,
            values=[
                'No',
                'Warn',
                'Auto',
                'Yes'])
    if caching is not None:
        inputs['Caching'] = try_set(
            obj=caching,
            none_acceptable=True,
            is_of_type=str,
            values=[
                'Auto',
                'Memory',
                'Disk',
                'None'])
    if loss_function is not None:
        inputs['LossFunction'] = try_set(
            obj=loss_function,
            none_acceptable=True,
            is_of_type=dict)
    if num_threads is not None:
        inputs['NumThreads'] = try_set(
            obj=num_threads,
            none_acceptable=True,
            is_of_type=numbers.Real)
    if convergence_tolerance is not None:
        inputs['ConvergenceTolerance'] = try_set(
            obj=convergence_tolerance,
            none_acceptable=True,
            is_of_type=numbers.Real)
    if max_iterations is not None:
        inputs['MaxIterations'] = try_set(
            obj=max_iterations,
            none_acceptable=True,
            is_of_type=numbers.Real)
    if shuffle is not None:
        inputs['Shuffle'] = try_set(
            obj=shuffle,
            none_acceptable=True,
            is_of_type=bool)
    if check_frequency is not None:
        inputs['CheckFrequency'] = try_set(
            obj=check_frequency,
            none_acceptable=True,
            is_of_type=numbers.Real)
    if bias_learning_rate is not None:
        inputs['BiasLearningRate'] = try_set(
            obj=bias_learning_rate,
            none_acceptable=True,
            is_of_type=numbers.Real)
    if predictor_model is not None:
        outputs['PredictorModel'] = try_set(
            obj=predictor_model, none_acceptable=False, is_of_type=str)

    input_variables = {
        x for x in unlist(inputs.values())
        if isinstance(x, str) and x.startswith("$")}
    output_variables = {
        x for x in unlist(outputs.values())
        if isinstance(x, str) and x.startswith("$")}

    entrypoint = EntryPoint(
        name=entrypoint_name, inputs=inputs, outputs=outputs,
        input_variables=input_variables,
        output_variables=output_variables)
    return entrypoint
