def search_gen(self, query, audio_basename=None, case_sensitive=False,<EOL>subsequence=False, supersequence=False, timing_error=<NUM_LIT:0.0>,<EOL>anagram=False, missing_word_tolerance=<NUM_LIT:0>):
def case_sensitivity_handler(case_sensitive=case_sensitive):<EOL><INDENT>def get_query_words(query, case_sensitive=case_sensitive):<EOL><INDENT>query_words = list(<EOL>filter(None, '<STR_LIT>'.join(<EOL>filter(lambda char: char in (ascii_letters + "<STR_LIT:U+0020>"),<EOL>list(query))).split("<STR_LIT:U+0020>")))<EOL>if case_sensitive:<EOL><INDENT>return query_words<EOL><DEDENT>return [q.lower() for q in query_words]<EOL><DEDENT>def get_timestamps(case_sensitive=case_sensitive):<EOL><INDENT>timestamps = self.get_timestamps().copy()<EOL>if not case_sensitive:<EOL><INDENT>return {<EOL>audio_basename: [<EOL>_WordBlock(word=word_block.word.lower(),<EOL>start=word_block.start,<EOL>end=word_block.end)<EOL>for word_block in timestamps[audio_basename]]<EOL>for audio_basename in timestamps}<EOL><DEDENT>return timestamps<EOL><DEDENT>return locals()<EOL><DEDENT>query_words = case_sensitivity_handler()["<STR_LIT>"](query)<EOL>timestamps = case_sensitivity_handler()["<STR_LIT>"]()<EOL>assert abs(missing_word_tolerance -<EOL>(len(query_words) - <NUM_LIT:2>)) >= <NUM_LIT:0>, (<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>)<EOL>for audio_filename in (<EOL>(lambda: (timestamps.keys() if audio_basename is None else<EOL>[audio_basename]))()):<EOL><INDENT>result = list()<EOL>missed_words_so_far = <NUM_LIT:0><EOL>query_cursor = <NUM_LIT:0><EOL>try:<EOL><INDENT>for word_block in timestamps[audio_filename]:<EOL><INDENT>if (<EOL>(word_block.word == query_words[query_cursor]) or<EOL>(subsequence and<EOL>self._is_subsequence_of(query_words[query_cursor],<EOL>word_block.word)) or<EOL>(supersequence and self._is_supersequence_of(<EOL>query_words[query_cursor], word_block.word)) or<EOL>(anagram and self._is_anagram_of(<EOL>query_words[query_cursor], word_block.word))<EOL>):<EOL><INDENT>result.append(word_block)<EOL>if timing_error is not None:<EOL><INDENT>try:<EOL><INDENT>if round(result[-<NUM_LIT:1>].start -<EOL>result[-<NUM_LIT:2>].end, <NUM_LIT:4>) > timing_error:<EOL><INDENT>result = list()<EOL>query_cursor = <NUM_LIT:0><EOL><DEDENT><DEDENT>except IndexError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>if self._partial_search_validator(<EOL>query_words, [x.word for x in result],<EOL>anagram=anagram,<EOL>subsequence=subsequence,<EOL>supersequence=supersequence):<EOL><INDENT>yield {<EOL>"<STR_LIT>": audio_filename,<EOL>"<STR_LIT>": query,<EOL>"<STR_LIT>": tuple([result[<NUM_LIT:0>].start,<EOL>result[-<NUM_LIT:1>].end])}<EOL>result = list()<EOL>query_cursor = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>query_cursor += <NUM_LIT:1><EOL><DEDENT><DEDENT>elif missed_words_so_far > missing_word_tolerance:<EOL><INDENT>result = list()<EOL>query_cursor = <NUM_LIT:0><EOL><DEDENT>elif (missing_word_tolerance > <NUM_LIT:0>) and (len(result) > <NUM_LIT:0>):<EOL><INDENT>result.append(word_block)<EOL>missed_words_so_far += <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT>except IndexError:<EOL><INDENT>continue<EOL><DEDENT><DEDENT>
A generator that searches for the `query` within the audiofiles of the
src_dir.

Parameters
----------
query : str
    A string that'll be searched. It'll be splitted on spaces and then
    each word gets sequentially searched.
audio_basename : str, optional
    Search only within the given audio_basename.

    Default is `None`
case_sensitive : bool, optional
    Default is `False`
subsequence : bool, optional
    `True` if it's not needed for the exact word be detected and larger
    strings that contain the given one are fine.

    If the query is a sentences with multiple words, it'll be
    considered for each word, not the whole sentence.

    Default is `False`.
supersequence : bool, optional
    `True` if it's not needed for the exact word be detected and
    smaller strings that are contained within the given one are fine.

    If the query is a sentences with multiple words, it'll be
    considered for each word, not the whole sentence.

    Default is `False`.
anagram : bool, optional
    `True` if it's acceptable for a complete permutation of the word to
    be found. e.g. "abcde" would be acceptable for "edbac".

    If the query is a sentences with multiple words, it'll be
    considered for each word, not the whole sentence.

    Default is `False`.
timing_error : None or float, optional
    Sometimes other words (almost always very small) would be detected
    between the words of the `query`. This parameter defines the
    timing difference/tolerance of the search.

    Default is 0.0 i.e. No timing error is tolerated.
missing_word_tolerance : int, optional
    The number of words that can be missed within the result.
    For example, if the query is "Some random text" and the tolerance
    value is `1`, then "Some text" would be a valid response.
    Note that the first and last words cannot be missed. Also,
    there'll be an error if the value is more than the number of
    available words. For the example above, any value more than 1
    would have given an error (since there's only one word i.e.
    "random" that can be missed)

    Default is 0.

Yields
------
{"File Name": str, "Query": `query`, "Result": (float, float)}
    The result of the search is returned as a tuple which is the value
    of the "Result" key. The first element of the tuple is the
    starting second of `query` and the last element is the ending
    second of `query`

Raises
------
AssertionError
    If `missing_word_tolerance` value is more than the total number of
    words in the query minus 2 (since the first and the last word
    cannot be removed)