# Path: unicycler/misc.py
# def weighted_average(num_1, num_2, weight_1, weight_2):
#     """
#     A simple weighted mean of two numbers.
#     """
#     weight_sum = weight_1 + weight_2
#     if weight_sum == 0:
#         return (num_1 + num_2) / 2.0
#     return num_1 * (weight_1 / weight_sum) + num_2 * (weight_2 / weight_sum)
# 
# def reverse_complement(seq):
#     """
#     Given a DNA sequences, this function returns the reverse complement sequence.
#     """
#     return ''.join([complement_base(x) for x in seq][::-1])
# 
# def get_num_agreement(num_1, num_2):
#     """
#     Returns a value between 0.0 and 1.0 describing how well the numbers agree.
#     1.0 is perfect agreement and 0.0 is the worst.
#     """
#     if num_1 == 0.0 and num_2 == 0.0:
#         return 1.0
#     if num_1 < 0.0 and num_2 < 0.0:
#         num_1 *= -1
#         num_2 *= -1
#     if num_1 * num_2 < 0.0:
#         return 0.0
#     return min(num_1, num_2) / max(num_1, num_2)


import sys
from collections import defaultdict
from .misc import weighted_average, reverse_complement, get_num_agreement
from . import settings
    from .cpp_wrappers import fully_global_alignment, path_alignment
    # the best path.
    except TooManyPaths:
        progressive_path_search = True
        paths = progressive_path_find(graph, start_seg, end_seg, min_length, max_length,
                                      sequence, scoring_scheme, expected_scaled_score)

    # Sort by length discrepancy from the target so the closest length matches come first.
    paths = sorted(paths, key=lambda x: abs(target_length - graph.get_bridge_path_length(x)))

    # We now align the consensus to each of the possible paths.
    paths_and_scores = []
    for path in paths:
        path_len = graph.get_bridge_path_length(path)
        length_discrepancy = abs(path_len - target_length)

        # If there is a consensus sequence, then we actually do an alignment against the path.
        if sequence:
            path_seq = graph.get_path_sequence(path)
            alignment_result = fully_global_alignment(sequence, path_seq, scoring_scheme,
                                                      True, 1000)
            if not alignment_result:
                continue

            seqan_parts = alignment_result.split(',', 9)
            raw_score = int(seqan_parts[6])
            scaled_score = float(seqan_parts[7])

        # If there isn't a consensus sequence (i.e. the start and end overlap), then each
        # path is only scored on how well its length agrees with the target length.
        else:

# Path: unicycler/misc.py
# def weighted_average(num_1, num_2, weight_1, weight_2):
#     """
#     A simple weighted mean of two numbers.
#     """
#     weight_sum = weight_1 + weight_2
#     if weight_sum == 0:
#         return (num_1 + num_2) / 2.0
#     return num_1 * (weight_1 / weight_sum) + num_2 * (weight_2 / weight_sum)
# 
# def reverse_complement(seq):
#     """
#     Given a DNA sequences, this function returns the reverse complement sequence.
#     """
#     return ''.join([complement_base(x) for x in seq][::-1])
# 
# def get_num_agreement(num_1, num_2):
#     """
#     Returns a value between 0.0 and 1.0 describing how well the numbers agree.
#     1.0 is perfect agreement and 0.0 is the worst.
#     """
#     if num_1 == 0.0 and num_2 == 0.0:
#         return 1.0
#     if num_1 < 0.0 and num_2 < 0.0:
#         num_1 *= -1
#         num_2 *= -1
#     if num_1 * num_2 < 0.0:
#         return 0.0
#     return min(num_1, num_2) / max(num_1, num_2)


# Path: unicycler/path_finding.py
import sys
from collections import defaultdict
from .misc import weighted_average, reverse_complement, get_num_agreement
from . import settings
    from .cpp_wrappers import fully_global_alignment, path_alignment

    # the best path.
    except TooManyPaths:
        progressive_path_search = True
        paths = progressive_path_find(graph, start_seg, end_seg, min_length, max_length,
                                      sequence, scoring_scheme, expected_scaled_score)

    # Sort by length discrepancy from the target so the closest length matches come first.
    paths = sorted(paths, key=lambda x: abs(target_length - graph.get_bridge_path_length(x)))

    # We now align the consensus to each of the possible paths.
    paths_and_scores = []
    for path in paths:
        path_len = graph.get_bridge_path_length(path)
        length_discrepancy = abs(path_len - target_length)

        # If there is a consensus sequence, then we actually do an alignment against the path.
        if sequence:
            path_seq = graph.get_path_sequence(path)
            alignment_result = fully_global_alignment(sequence, path_seq, scoring_scheme,
                                                      True, 1000)
            if not alignment_result:
                continue

            seqan_parts = alignment_result.split(',', 9)
            raw_score = int(seqan_parts[6])
            scaled_score = float(seqan_parts[7])

        # If there isn't a consensus sequence (i.e. the start and end overlap), then each
        # path is only scored on how well its length agrees with the target length.
        else:

            raw_score = get_num_agreement(path_len, target_length) * 100.0