def make_negative(self) -> 'Polynomial':
        """ Returns a Negative version of this instance """
        result = list([0] * self.length)

        for i in range(self.length):
            result[i] = Modulus.negate(self.coefficients[i])
            
        return Polynomial(0, 0, result)
def test_codewords(codewords: list, error_correction_length: int) -> tuple:
    """ Decode the received codewords """
    poly_codewords = Polynomial(0, 0, codewords)

    # create syndrom coefficients array
    syndrome = list([0] * error_correction_length)

    # assume new errors
    error = False

    # test for errors
    # if the syndrom array is all zeros, there is no error
    for i in range(error_correction_length, 0, -1):
        # TODO: This may have been translated incorrectly! Confirm it's not broken.
        # Original Code: if((Syndrome[ErrorCorrectionLength - Index] = PolyCodewords.EvaluateAt(Modulus.ExpTable[Index])) != 0) Error = true;
        mod_exp_table_result = Modulus.exp_table[i]
        evaluate_result = poly_codewords.evaluate_at(mod_exp_table_result)
        syndrome_index = error_correction_length - i
        syndrome[syndrome_index] = evaluate_result
        if (syndrome[syndrome_index] != 0):
            error = True

    if (not error):
        return (0, codewords)

    # convert syndrom array to polynomial
    poly_syndrome = Polynomial(0, 0, syndrome)

    # Greatest Common Divisor (return -1 if error cannot be corrected)
    result = euclidean_algorithm(error_correction_length, poly_syndrome)

    if (not result[0]):
        return (-1, codewords)

    error_locator = result[1]
    error_evaluator = result[2]

    error_locations = find_error_locations(error_locator)

    if (error_locations is None):
        return (-1, codewords)

    formal_derivative = find_formal_derivatives(error_locator)

    errors = len(error_locations)

    # This is directly applying Forney's Formula
    for i in range(errors):
        error_location = error_locations[i]
        error_position = len(codewords) - 1 - Modulus.log_table[Modulus.invert(
            error_location)]

        if (error_position < 0):
            return (-1, codewords)

        error_magnitude = Modulus.divide(
            Modulus.negate(error_evaluator.evaluate_at(error_location)),
            formal_derivative.evaluate_at(error_location))
        corrected_codeword = Modulus.subtract(codewords[error_position],
                                              error_magnitude)
        codewords[error_position] = corrected_codeword
        error_locations[i] = error_position

    return (errors, codewords)