def score_pairwise(aseq, bseq):
    """Compute pairwise distances between two sequences (raw strings)."""
    assert len(aseq) == len(bseq)

    # Affine gap penalties -- default values from EMBOSS needle/water
    GAP_OPEN = -10.0
    GAP_EXTEND = -0.5
    GAP_CHARS = frozenset('-.')

    score = 0.0
    in_gap = True   # Don't apply the opening penalty to the N-terminal gap

    for ares, bres in zip(aseq.upper(), bseq.upper()):
        if ares in GAP_CHARS and bres in GAP_CHARS:
            # Both are gaps -- this happens in multiple sequence alignments
            continue
        match = blosum62.get((ares, bres), None)
        if match is None:
            assert GAP_CHARS.intersection((ares, bres)), \
                    "Expected one gap in: " + str((ares, bres))
            # Gap
            if not in_gap:
                score += GAP_OPEN
                in_gap = True
            score += GAP_EXTEND
        else:
            in_gap = False
            score += match

    if in_gap:
        # Correct for a penalty on the C-terminal gap
        score -= GAP_OPEN

    return score
Compute pairwise distances between two sequences (raw strings).