def _synoname_word_approximation(<EOL>self, src_ln, tar_ln, src_fn='<STR_LIT>', tar_fn='<STR_LIT>', features=None<EOL>):
if features is None:<EOL><INDENT>features = {}<EOL><DEDENT>if '<STR_LIT>' not in features:<EOL><INDENT>features['<STR_LIT>'] = []<EOL><DEDENT>if '<STR_LIT>' not in features:<EOL><INDENT>features['<STR_LIT>'] = []<EOL><DEDENT>src_len_specials = len(features['<STR_LIT>'])<EOL>tar_len_specials = len(features['<STR_LIT>'])<EOL>if ('<STR_LIT>' in features and features['<STR_LIT>']) or (<EOL>'<STR_LIT>' in features and features['<STR_LIT>']<EOL>):<EOL><INDENT>return <NUM_LIT:0><EOL><DEDENT>full_tar1 = '<STR_LIT:U+0020>'.join((tar_ln, tar_fn)).replace('<STR_LIT:->', '<STR_LIT:U+0020>').strip()<EOL>for s_pos, s_type in features['<STR_LIT>']:<EOL><INDENT>if s_type == '<STR_LIT:a>':<EOL><INDENT>full_tar1 = full_tar1[<EOL>: -(<EOL><NUM_LIT:1><EOL>+ len(<EOL>self._stc._synoname_special_table[  <EOL>s_pos<EOL>][<NUM_LIT:1>]<EOL>)<EOL>)<EOL>]<EOL><DEDENT>elif s_type == '<STR_LIT:b>':<EOL><INDENT>loc = (<EOL>full_tar1.find(<EOL>'<STR_LIT:U+0020>'<EOL>+ self._stc._synoname_special_table[  <EOL>s_pos<EOL>][<NUM_LIT:1>]<EOL>+ '<STR_LIT:U+0020>'<EOL>)<EOL>+ <NUM_LIT:1><EOL>)<EOL>full_tar1 = (<EOL>full_tar1[:loc]<EOL>+ full_tar1[<EOL>loc<EOL>+ len(<EOL>self._stc._synoname_special_table[  <EOL>s_pos<EOL>][<NUM_LIT:1>]<EOL>) :<EOL>]<EOL>)<EOL><DEDENT>elif s_type == '<STR_LIT:c>':<EOL><INDENT>full_tar1 = full_tar1[<EOL><NUM_LIT:1><EOL>+ len(<EOL>self._stc._synoname_special_table[s_pos][  <EOL><NUM_LIT:1><EOL>]<EOL>) :<EOL>]<EOL><DEDENT><DEDENT>full_src1 = '<STR_LIT:U+0020>'.join((src_ln, src_fn)).replace('<STR_LIT:->', '<STR_LIT:U+0020>').strip()<EOL>for s_pos, s_type in features['<STR_LIT>']:<EOL><INDENT>if s_type == '<STR_LIT:a>':<EOL><INDENT>full_src1 = full_src1[<EOL>: -(<EOL><NUM_LIT:1><EOL>+ len(<EOL>self._stc._synoname_special_table[  <EOL>s_pos<EOL>][<NUM_LIT:1>]<EOL>)<EOL>)<EOL>]<EOL><DEDENT>elif s_type == '<STR_LIT:b>':<EOL><INDENT>loc = (<EOL>full_src1.find(<EOL>'<STR_LIT:U+0020>'<EOL>+ self._stc._synoname_special_table[  <EOL>s_pos<EOL>][<NUM_LIT:1>]<EOL>+ '<STR_LIT:U+0020>'<EOL>)<EOL>+ <NUM_LIT:1><EOL>)<EOL>full_src1 = (<EOL>full_src1[:loc]<EOL>+ full_src1[<EOL>loc<EOL>+ len(<EOL>self._stc._synoname_special_table[  <EOL>s_pos<EOL>][<NUM_LIT:1>]<EOL>) :<EOL>]<EOL>)<EOL><DEDENT>elif s_type == '<STR_LIT:c>':<EOL><INDENT>full_src1 = full_src1[<EOL><NUM_LIT:1><EOL>+ len(<EOL>self._stc._synoname_special_table[s_pos][  <EOL><NUM_LIT:1><EOL>]<EOL>) :<EOL>]<EOL><DEDENT><DEDENT>full_tar2 = full_tar1<EOL>for s_pos, s_type in features['<STR_LIT>']:<EOL><INDENT>if s_type == '<STR_LIT:d>':<EOL><INDENT>full_tar2 = full_tar2[<EOL>len(<EOL>self._stc._synoname_special_table[s_pos][  <EOL><NUM_LIT:1><EOL>]<EOL>) :<EOL>]<EOL><DEDENT>elif (<EOL>s_type == '<STR_LIT:X>'<EOL>and self._stc._synoname_special_table[s_pos][<NUM_LIT:1>]  <EOL>in full_tar2<EOL>):<EOL><INDENT>loc = full_tar2.find(<EOL>'<STR_LIT:U+0020>'<EOL>+ self._stc._synoname_special_table[s_pos][<NUM_LIT:1>]  <EOL>)<EOL>full_tar2 = (<EOL>full_tar2[:loc]<EOL>+ full_tar2[<EOL>loc<EOL>+ len(<EOL>self._stc._synoname_special_table[  <EOL>s_pos<EOL>][<NUM_LIT:1>]<EOL>) :<EOL>]<EOL>)<EOL><DEDENT><DEDENT>full_src2 = full_src1<EOL>for s_pos, s_type in features['<STR_LIT>']:<EOL><INDENT>if s_type == '<STR_LIT:d>':<EOL><INDENT>full_src2 = full_src2[<EOL>len(<EOL>self._stc._synoname_special_table[s_pos][  <EOL><NUM_LIT:1><EOL>]<EOL>) :<EOL>]<EOL><DEDENT>elif (<EOL>s_type == '<STR_LIT:X>'<EOL>and self._stc._synoname_special_table[s_pos][<NUM_LIT:1>]  <EOL>in full_src2<EOL>):<EOL><INDENT>loc = full_src2.find(<EOL>'<STR_LIT:U+0020>'<EOL>+ self._stc._synoname_special_table[s_pos][<NUM_LIT:1>]  <EOL>)<EOL>full_src2 = (<EOL>full_src2[:loc]<EOL>+ full_src2[<EOL>loc<EOL>+ len(<EOL>self._stc._synoname_special_table[  <EOL>s_pos<EOL>][<NUM_LIT:1>]<EOL>) :<EOL>]<EOL>)<EOL><DEDENT><DEDENT>full_tar1 = self._synoname_strip_punct(full_tar1)<EOL>tar1_words = full_tar1.split()<EOL>tar1_num_words = len(tar1_words)<EOL>full_src1 = self._synoname_strip_punct(full_src1)<EOL>src1_words = full_src1.split()<EOL>src1_num_words = len(src1_words)<EOL>full_tar2 = self._synoname_strip_punct(full_tar2)<EOL>tar2_words = full_tar2.split()<EOL>tar2_num_words = len(tar2_words)<EOL>full_src2 = self._synoname_strip_punct(full_src2)<EOL>src2_words = full_src2.split()<EOL>src2_num_words = len(src2_words)<EOL>if (<EOL>src1_num_words < <NUM_LIT:2><EOL>and src_len_specials == <NUM_LIT:0><EOL>and src2_num_words < <NUM_LIT:2><EOL>and tar_len_specials == <NUM_LIT:0><EOL>):<EOL><INDENT>return <NUM_LIT:0><EOL><DEDENT>if (<EOL>tar1_num_words == <NUM_LIT:1><EOL>and src1_num_words == <NUM_LIT:1><EOL>and tar1_words[<NUM_LIT:0>] == src1_words[<NUM_LIT:0>]<EOL>):<EOL><INDENT>return <NUM_LIT:1><EOL><DEDENT>if tar1_num_words < <NUM_LIT:2> and tar_len_specials == <NUM_LIT:0>:<EOL><INDENT>return <NUM_LIT:0><EOL><DEDENT>last_found = False<EOL>for word in tar1_words:<EOL><INDENT>if src_ln.endswith(word) or word + '<STR_LIT:U+0020>' in src_ln:<EOL><INDENT>last_found = True<EOL><DEDENT><DEDENT>if not last_found:<EOL><INDENT>for word in src1_words:<EOL><INDENT>if tar_ln.endswith(word) or word + '<STR_LIT:U+0020>' in tar_ln:<EOL><INDENT>last_found = True<EOL><DEDENT><DEDENT><DEDENT>matches = <NUM_LIT:0><EOL>if last_found:<EOL><INDENT>for i, s_word in enumerate(src1_words):<EOL><INDENT>for j, t_word in enumerate(tar1_words):<EOL><INDENT>if s_word == t_word:<EOL><INDENT>src1_words[i] = '<STR_LIT:@>'<EOL>tar1_words[j] = '<STR_LIT:@>'<EOL>matches += <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT><DEDENT>w_ratio = matches / max(tar1_num_words, src1_num_words)<EOL>if matches > <NUM_LIT:1> or (<EOL>matches == <NUM_LIT:1><EOL>and src1_num_words == <NUM_LIT:1><EOL>and tar1_num_words == <NUM_LIT:1><EOL>and (tar_len_specials > <NUM_LIT:0> or src_len_specials > <NUM_LIT:0>)<EOL>):<EOL><INDENT>return w_ratio<EOL><DEDENT>if (<EOL>tar2_num_words == <NUM_LIT:1><EOL>and src2_num_words == <NUM_LIT:1><EOL>and tar2_words[<NUM_LIT:0>] == src2_words[<NUM_LIT:0>]<EOL>):<EOL><INDENT>return <NUM_LIT:1><EOL><DEDENT>if tar2_num_words < <NUM_LIT:2> and tar_len_specials == <NUM_LIT:0>:  <EOL><INDENT>return <NUM_LIT:0><EOL><DEDENT>last_found = False<EOL>for word in tar2_words:<EOL><INDENT>if src_ln.endswith(word) or word + '<STR_LIT:U+0020>' in src_ln:<EOL><INDENT>last_found = True<EOL><DEDENT><DEDENT>if not last_found:<EOL><INDENT>for word in src2_words:<EOL><INDENT>if tar_ln.endswith(word) or word + '<STR_LIT:U+0020>' in tar_ln:<EOL><INDENT>last_found = True<EOL><DEDENT><DEDENT><DEDENT>if not last_found:<EOL><INDENT>return <NUM_LIT:0><EOL><DEDENT>matches = <NUM_LIT:0><EOL>if last_found:<EOL><INDENT>for i, s_word in enumerate(src2_words):<EOL><INDENT>for j, t_word in enumerate(tar2_words):<EOL><INDENT>if s_word == t_word:<EOL><INDENT>src2_words[i] = '<STR_LIT:@>'<EOL>tar2_words[j] = '<STR_LIT:@>'<EOL>matches += <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT><DEDENT>w_ratio = matches / max(tar2_num_words, src2_num_words)<EOL>if matches > <NUM_LIT:1> or (<EOL>matches == <NUM_LIT:1><EOL>and src2_num_words == <NUM_LIT:1><EOL>and tar2_num_words == <NUM_LIT:1><EOL>and (tar_len_specials > <NUM_LIT:0> or src_len_specials > <NUM_LIT:0>)<EOL>):<EOL><INDENT>return w_ratio<EOL><DEDENT>return <NUM_LIT:0><EOL>
Return the Synoname word approximation score for two names.

        Parameters
        ----------
        src_ln : str
            Last name of the source
        tar_ln : str
            Last name of the target
        src_fn : str
            First name of the source (optional)
        tar_fn : str
            First name of the target (optional)
        features : dict
            A dict containing special features calculated using
            :py:class:`fingerprint.SynonameToolcode` (optional)

        Returns
        -------
        float
            The word approximation score

        Examples
        --------
        >>> pe = Synoname()
        >>> pe._synoname_word_approximation('Smith Waterman', 'Waterman',
        ... 'Tom Joe Bob', 'Tom Joe')
        0.6