def sim(<EOL>self,<EOL>src,<EOL>tar,<EOL>qval=<NUM_LIT:1>,<EOL>mode='<STR_LIT>',<EOL>long_strings=False,<EOL>boost_threshold=<NUM_LIT>,<EOL>scaling_factor=<NUM_LIT:0.1>,<EOL>):
if mode == '<STR_LIT>':<EOL><INDENT>if boost_threshold > <NUM_LIT:1> or boost_threshold < <NUM_LIT:0>:<EOL><INDENT>raise ValueError(<EOL>'<STR_LIT>'<EOL>+ '<STR_LIT>'<EOL>)<EOL><DEDENT>if scaling_factor > <NUM_LIT> or scaling_factor < <NUM_LIT:0>:<EOL><INDENT>raise ValueError(<EOL>'<STR_LIT>'<EOL>+ '<STR_LIT>'<EOL>)<EOL><DEDENT><DEDENT>if src == tar:<EOL><INDENT>return <NUM_LIT:1.0><EOL><DEDENT>src = QGrams(src.strip(), qval)._ordered_list<EOL>tar = QGrams(tar.strip(), qval)._ordered_list<EOL>lens = len(src)<EOL>lent = len(tar)<EOL>if lens == <NUM_LIT:0> or lent == <NUM_LIT:0>:<EOL><INDENT>return <NUM_LIT:0.0><EOL><DEDENT>if lens > lent:<EOL><INDENT>search_range = lens<EOL>minv = lent<EOL><DEDENT>else:<EOL><INDENT>search_range = lent<EOL>minv = lens<EOL><DEDENT>src_flag = [<NUM_LIT:0>] * search_range<EOL>tar_flag = [<NUM_LIT:0>] * search_range<EOL>search_range = max(<NUM_LIT:0>, search_range // <NUM_LIT:2> - <NUM_LIT:1>)<EOL>num_com = <NUM_LIT:0><EOL>yl1 = lent - <NUM_LIT:1><EOL>for i in range(lens):<EOL><INDENT>low_lim = (i - search_range) if (i >= search_range) else <NUM_LIT:0><EOL>hi_lim = (i + search_range) if ((i + search_range) <= yl1) else yl1<EOL>for j in range(low_lim, hi_lim + <NUM_LIT:1>):<EOL><INDENT>if (tar_flag[j] == <NUM_LIT:0>) and (tar[j] == src[i]):<EOL><INDENT>tar_flag[j] = <NUM_LIT:1><EOL>src_flag[i] = <NUM_LIT:1><EOL>num_com += <NUM_LIT:1><EOL>break<EOL><DEDENT><DEDENT><DEDENT>if num_com == <NUM_LIT:0>:<EOL><INDENT>return <NUM_LIT:0.0><EOL><DEDENT>k = n_trans = <NUM_LIT:0><EOL>for i in range(lens):<EOL><INDENT>if src_flag[i] != <NUM_LIT:0>:<EOL><INDENT>j = <NUM_LIT:0><EOL>for j in range(k, lent):  <EOL><INDENT>if tar_flag[j] != <NUM_LIT:0>:<EOL><INDENT>k = j + <NUM_LIT:1><EOL>break<EOL><DEDENT><DEDENT>if src[i] != tar[j]:<EOL><INDENT>n_trans += <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT>n_trans //= <NUM_LIT:2><EOL>weight = (<EOL>num_com / lens + num_com / lent + (num_com - n_trans) / num_com<EOL>)<EOL>weight /= <NUM_LIT><EOL>if mode == '<STR_LIT>' and weight > boost_threshold:<EOL><INDENT>j = <NUM_LIT:4> if (minv >= <NUM_LIT:4>) else minv<EOL>i = <NUM_LIT:0><EOL>while (i < j) and (src[i] == tar[i]):<EOL><INDENT>i += <NUM_LIT:1><EOL><DEDENT>weight += i * scaling_factor * (<NUM_LIT:1.0> - weight)<EOL>if (<EOL>long_strings<EOL>and (minv > <NUM_LIT:4>)<EOL>and (num_com > i + <NUM_LIT:1>)<EOL>and (<NUM_LIT:2> * num_com >= minv + i)<EOL>):<EOL><INDENT>weight += (<NUM_LIT:1.0> - weight) * (<EOL>(num_com - i - <NUM_LIT:1>) / (lens + lent - i * <NUM_LIT:2> + <NUM_LIT:2>)<EOL>)<EOL><DEDENT><DEDENT>return weight<EOL>
Return the Jaro or Jaro-Winkler similarity of two strings.

        Parameters
        ----------
        src : str
            Source string for comparison
        tar : str
            Target string for comparison
        qval : int
            The length of each q-gram (defaults to 1: character-wise matching)
        mode : str
            Indicates which variant of this distance metric to compute:

                - ``winkler`` -- computes the Jaro-Winkler distance (default)
                  which increases the score for matches near the start of the
                  word
                - ``jaro`` -- computes the Jaro distance

        long_strings : bool
            Set to True to "Increase the probability of a match when the number
            of matched characters is large. This option allows for a little
            more tolerance when the strings are large. It is not an appropriate
            test when comparing fixed length fields such as phone and social
            security numbers." (Used in 'winkler' mode only.)
        boost_threshold : float
            A value between 0 and 1, below which the Winkler boost is not
            applied (defaults to 0.7). (Used in 'winkler' mode only.)
        scaling_factor : float
            A value between 0 and 0.25, indicating by how much to boost scores
            for matching prefixes (defaults to 0.1). (Used in 'winkler' mode
            only.)

        Returns
        -------
        float
            Jaro or Jaro-Winkler similarity

        Raises
        ------
        ValueError
            Unsupported boost_threshold assignment; boost_threshold must be
            between 0 and 1.
        ValueError
            Unsupported scaling_factor assignment; scaling_factor must be
            between 0 and 0.25.'

        Examples
        --------
        >>> round(sim_jaro_winkler('cat', 'hat'), 12)
        0.777777777778
        >>> round(sim_jaro_winkler('Niall', 'Neil'), 12)
        0.805
        >>> round(sim_jaro_winkler('aluminum', 'Catalan'), 12)
        0.60119047619
        >>> round(sim_jaro_winkler('ATCG', 'TAGC'), 12)
        0.833333333333

        >>> round(sim_jaro_winkler('cat', 'hat', mode='jaro'), 12)
        0.777777777778
        >>> round(sim_jaro_winkler('Niall', 'Neil', mode='jaro'), 12)
        0.783333333333
        >>> round(sim_jaro_winkler('aluminum', 'Catalan', mode='jaro'), 12)
        0.60119047619
        >>> round(sim_jaro_winkler('ATCG', 'TAGC', mode='jaro'), 12)
        0.833333333333