def dist_abs(<EOL>self,<EOL>src,<EOL>tar,<EOL>metric='<STR_LIT>',<EOL>cost=(<NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0.5>, <NUM_LIT:0.5>),<EOL>layout='<STR_LIT>',<EOL>):
ins_cost, del_cost, sub_cost, shift_cost = cost<EOL>if src == tar:<EOL><INDENT>return <NUM_LIT:0.0><EOL><DEDENT>if not src:<EOL><INDENT>return len(tar) * ins_cost<EOL><DEDENT>if not tar:<EOL><INDENT>return len(src) * del_cost<EOL><DEDENT>keyboard = self._keyboard[layout]<EOL>lowercase = {item for sublist in keyboard[<NUM_LIT:0>] for item in sublist}<EOL>uppercase = {item for sublist in keyboard[<NUM_LIT:1>] for item in sublist}<EOL>def _kb_array_for_char(char):<EOL><INDENT>"""<STR_LIT>"""<EOL>if char in lowercase:<EOL><INDENT>return keyboard[<NUM_LIT:0>]<EOL><DEDENT>elif char in uppercase:<EOL><INDENT>return keyboard[<NUM_LIT:1>]<EOL><DEDENT>raise ValueError(char + '<STR_LIT>')<EOL><DEDENT>def _substitution_cost(char1, char2):<EOL><INDENT>cost = sub_cost<EOL>cost *= metric_dict[metric](char1, char2) + shift_cost * (<EOL>_kb_array_for_char(char1) != _kb_array_for_char(char2)<EOL>)<EOL>return cost<EOL><DEDENT>def _get_char_coord(char, kb_array):<EOL><INDENT>"""<STR_LIT>"""<EOL>for row in kb_array:  <EOL><INDENT>if char in row:<EOL><INDENT>return kb_array.index(row), row.index(char)<EOL><DEDENT><DEDENT><DEDENT>def _euclidean_keyboard_distance(char1, char2):<EOL><INDENT>row1, col1 = _get_char_coord(char1, _kb_array_for_char(char1))<EOL>row2, col2 = _get_char_coord(char2, _kb_array_for_char(char2))<EOL>return ((row1 - row2) ** <NUM_LIT:2> + (col1 - col2) ** <NUM_LIT:2>) ** <NUM_LIT:0.5><EOL><DEDENT>def _manhattan_keyboard_distance(char1, char2):<EOL><INDENT>row1, col1 = _get_char_coord(char1, _kb_array_for_char(char1))<EOL>row2, col2 = _get_char_coord(char2, _kb_array_for_char(char2))<EOL>return abs(row1 - row2) + abs(col1 - col2)<EOL><DEDENT>def _log_euclidean_keyboard_distance(char1, char2):<EOL><INDENT>return log(<NUM_LIT:1> + _euclidean_keyboard_distance(char1, char2))<EOL><DEDENT>def _log_manhattan_keyboard_distance(char1, char2):<EOL><INDENT>return log(<NUM_LIT:1> + _manhattan_keyboard_distance(char1, char2))<EOL><DEDENT>metric_dict = {<EOL>'<STR_LIT>': _euclidean_keyboard_distance,<EOL>'<STR_LIT>': _manhattan_keyboard_distance,<EOL>'<STR_LIT>': _log_euclidean_keyboard_distance,<EOL>'<STR_LIT>': _log_manhattan_keyboard_distance,<EOL>}<EOL>d_mat = np_zeros((len(src) + <NUM_LIT:1>, len(tar) + <NUM_LIT:1>), dtype=np_float32)<EOL>for i in range(len(src) + <NUM_LIT:1>):<EOL><INDENT>d_mat[i, <NUM_LIT:0>] = i * del_cost<EOL><DEDENT>for j in range(len(tar) + <NUM_LIT:1>):<EOL><INDENT>d_mat[<NUM_LIT:0>, j] = j * ins_cost<EOL><DEDENT>for i in range(len(src)):<EOL><INDENT>for j in range(len(tar)):<EOL><INDENT>d_mat[i + <NUM_LIT:1>, j + <NUM_LIT:1>] = min(<EOL>d_mat[i + <NUM_LIT:1>, j] + ins_cost,  <EOL>d_mat[i, j + <NUM_LIT:1>] + del_cost,  <EOL>d_mat[i, j]<EOL>+ (<EOL>_substitution_cost(src[i], tar[j])<EOL>if src[i] != tar[j]<EOL>else <NUM_LIT:0><EOL>),  <EOL>)<EOL><DEDENT><DEDENT>return d_mat[len(src), len(tar)]<EOL>
Return the typo distance between two strings.

        Parameters
        ----------
        src : str
            Source string for comparison
        tar : str
            Target string for comparison
        metric : str
            Supported values include: ``euclidean``, ``manhattan``,
            ``log-euclidean``, and ``log-manhattan``
        cost : tuple
            A 4-tuple representing the cost of the four possible edits:
            inserts, deletes, substitutions, and shift, respectively (by
            default: (1, 1, 0.5, 0.5)) The substitution & shift costs should be
            significantly less than the cost of an insertion & deletion unless
            a log metric is used.
        layout : str
            Name of the keyboard layout to use (Currently supported:
            ``QWERTY``, ``Dvorak``, ``AZERTY``, ``QWERTZ``)

        Returns
        -------
        float
            Typo distance

        Raises
        ------
        ValueError
            char not found in any keyboard layouts

        Examples
        --------
        >>> cmp = Typo()
        >>> cmp.dist_abs('cat', 'hat')
        1.5811388
        >>> cmp.dist_abs('Niall', 'Neil')
        2.8251407
        >>> cmp.dist_abs('Colin', 'Cuilen')
        3.4142137
        >>> cmp.dist_abs('ATCG', 'TAGC')
        2.5

        >>> cmp.dist_abs('cat', 'hat', metric='manhattan')
        2.0
        >>> cmp.dist_abs('Niall', 'Neil', metric='manhattan')
        3.0
        >>> cmp.dist_abs('Colin', 'Cuilen', metric='manhattan')
        3.5
        >>> cmp.dist_abs('ATCG', 'TAGC', metric='manhattan')
        2.5

        >>> cmp.dist_abs('cat', 'hat', metric='log-manhattan')
        0.804719
        >>> cmp.dist_abs('Niall', 'Neil', metric='log-manhattan')
        2.2424533
        >>> cmp.dist_abs('Colin', 'Cuilen', metric='log-manhattan')
        2.2424533
        >>> cmp.dist_abs('ATCG', 'TAGC', metric='log-manhattan')
        2.3465736