# Buggy code
def _get_liblinear_solver_type(multi_class, penalty, loss, dual):
    """Find the liblinear magic number for the solver.

    This number depends on the values of the following attributes:
      - multi_class
      - penalty
      - loss
      - dual

    The same number is also internally used by LibLinear to determine
    which solver to use.
    """
    # nested dicts containing level 1: available loss functions,
    # level2: available penalties for the given loss functin,
    # level3: wether the dual solver is available for the specified
    # combination of loss function and penalty
    _solver_type_dict = {
        "logistic_regression": {"l1": {False: 6}, "l2": {False: 0, True: 7}},
        "hinge": {"l2": {True: 3}},
        "squared_hinge": {"l1": {False: 5}, "l2": {False: 2, True: 1}},
        "epsilon_insensitive": {"l2": {True: 13}},
        "squared_epsilon_insensitive": {"l2": {False: 11, True: 12}},
        "crammer_singer": 4,
    }

    if multi_class == "crammer_singer":
        return _solver_type_dict[multi_class]
    elif multi_class != "ovr":
        raise ValueError(
            "`multi_class` must be one of `ovr`, `crammer_singer`, got %r" % multi_class
        )

    # FIXME loss.lower() --> loss in 0.18
    _solver_pen = _solver_type_dict.get(loss.lower(), None)
    if _solver_pen is None:
        error_string = "loss='%s' is not supported" % loss
    else:
        # FIME penalty.lower() --> penalty in 0.18
        _solver_dual = _solver_pen.get(penalty.lower(), None)
        if _solver_dual is None:
            error_string = (
                "The combination of penalty='%s'"
                "and loss='%s' is not supported" % (penalty, loss)
            )
        else:
            solver_num = _solver_dual.get(dual, None)
            if solver_num is None:
                error_string = (
                    "loss='%s' and penalty='%s'"
                    "are not supported when dual=%s" % (penalty, loss, dual)
                )
            else:
                return solver_num

    raise ValueError(
        ("Unsupported set of arguments: %s, Parameters: penalty=%r, loss=%r, dual=%r")
        % (error_string, penalty, loss, dual)
    )


# Traceback (AssertionError)
======================================================================
FAIL: Tests that class_weight and sample_weight are multiplicative
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/buildd/scikit-learn-0.16.0~b1+git1-gab4d07d/debian/python-sklearn/usr/lib/python2.7/dist-packages/sklearn/linear_model/tests/test_sgd.py", line 633, in test_weights_multiplied
assert_array_equal(clf1.coef_, clf2.coef_)
File "/usr/lib/python2.7/dist-packages/numpy/testing/utils.py", line 718, in assert_array_equal
verbose=verbose, header='Arrays are not equal')
File "/usr/lib/python2.7/dist-packages/numpy/testing/utils.py", line 644, in assert_array_compare
raise AssertionError(msg)
AssertionError:
Arrays are not equal

(mismatch 16.6666666667%)
x: array([[-0.34681637, -0.32240913, -0.31335029,  0.34920789,  0.3658206 ,
0.38752489]])
y: array([[-0.34681637, -0.32240913, -0.31335029,  0.34920789,  0.3658206 ,
0.38752489]])

# Fixed code
def _get_liblinear_solver_type(multi_class, penalty, loss, dual):
    """Find the liblinear magic number for the solver.

    This number depends on the values of the following attributes:
      - multi_class
      - penalty
      - loss
      - dual

    The same number is also internally used by LibLinear to determine
    which solver to use.
    """
    # nested dicts containing level 1: available loss functions,
    # level2: available penalties for the given loss functin,
    # level3: wether the dual solver is available for the specified
    # combination of loss function and penalty
    _solver_type_dict = {
        "logistic_regression": {"l1": {False: 6}, "l2": {False: 0, True: 7}},
        "hinge": {"l2": {True: 3}},
        "squared_hinge": {"l1": {False: 5}, "l2": {False: 2, True: 1}},
        "epsilon_insensitive": {"l2": {True: 13}},
        "squared_epsilon_insensitive": {"l2": {False: 11, True: 12}},
        "crammer_singer": 4,
    }

    if multi_class == "crammer_singer":
        return _solver_type_dict[multi_class]
    elif multi_class != "ovr":
        raise ValueError(
            "`multi_class` must be one of `ovr`, `crammer_singer`, got %r" % multi_class
        )

    # FIXME loss.lower() --> loss in 0.18
    _solver_pen = _solver_type_dict.get(loss.lower(), None)
    if _solver_pen is None:
        error_string = "loss='%s' is not supported" % loss
    else:
        # FIME penalty.lower() --> penalty in 0.18
        _solver_dual = _solver_pen.get(penalty.lower(), None)
        if _solver_dual is None:
            error_string = (
                "The combination of penalty='%s'"
                "and loss='%s' is not supported" % (penalty, loss)
            )
        else:
            solver_num = _solver_dual.get(dual, None)
            if solver_num is None:
                error_string = (
                    "loss='%s' and penalty='%s'"
                    "are not supported when dual=%s" % (penalty, loss, dual)
                )
            else:
                return solver_num
    raise ValueError(
        "Unsupported set of arguments: %s, "
        "Parameters: penalty=%r, loss=%r, dual=%r" % (error_string, penalty, loss, dual)
    )