doc = self.get_doc()<EOL>table = doc('<STR_LIT>'.format(award_id))<EOL>return list(map(int, sportsref.utils.parse_awards_table(table)))<EOL>

Template for simple award functions that simply list years, such as
        pro bowls and first-team all pro.

        :award_id: The div ID that is appended to "leaderboard_" in selecting
        the table's div.
        :returns: List of years for the award.


return self._simple_year_award('<STR_LIT>')<EOL>

Returns a list of years in which the player made the Pro Bowl.


Returns a list of years in which the player made 1st-Tm All Pro.


if '<STR_LIT>' not in kwargs:<EOL><INDENT>kwargs['<STR_LIT>'] = <NUM_LIT:0><EOL><DEDENT>playerSeasons = []<EOL>while True:<EOL><INDENT>querystring = _kwargs_to_qs(**kwargs)<EOL>url = '<STR_LIT>'.format(PSF_URL, querystring)<EOL>if kwargs.get('<STR_LIT>', False):<EOL><INDENT>print(url)<EOL><DEDENT>html = utils.get_html(url)<EOL>doc = pq(html)<EOL>table = doc('<STR_LIT>')<EOL>df = utils.parse_table(table)<EOL>if df.empty:<EOL><INDENT>break<EOL><DEDENT>thisSeason = list(zip(df.player_id, df.year))<EOL>playerSeasons.extend(thisSeason)<EOL>if doc('<STR_LIT>'):<EOL><INDENT>kwargs['<STR_LIT>'] += <NUM_LIT:100><EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>return playerSeasons<EOL>

Docstring will be filled in by __init__.py


<EOL>inpOptDef = inputs_options_defaults()<EOL>opts = {<EOL>name: dct['<STR_LIT:value>']<EOL>for name, dct in inpOptDef.items()<EOL>}<EOL>for k, v in kwargs.items():<EOL><INDENT>del kwargs[k]<EOL>if isinstance(v, bool):<EOL><INDENT>kwargs[k] = '<STR_LIT:Y>' if v else '<STR_LIT:N>'<EOL><DEDENT>elif k.lower() in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>kwargs['<STR_LIT>'] = v<EOL><DEDENT>elif k.lower() in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>if isinstance(v, collections.Iterable):<EOL><INDENT>lst = list(v)<EOL>kwargs['<STR_LIT>'] = min(lst)<EOL>kwargs['<STR_LIT>'] = max(lst)<EOL><DEDENT>elif isinstance(v, basestring):<EOL><INDENT>v = list(map(int, v.split('<STR_LIT:U+002C>')))<EOL>kwargs['<STR_LIT>'] = min(v)<EOL>kwargs['<STR_LIT>'] = max(v)<EOL><DEDENT>else:<EOL><INDENT>kwargs['<STR_LIT>'] = v<EOL>kwargs['<STR_LIT>'] = v<EOL><DEDENT><DEDENT>elif k.lower() in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>if isinstance(v, basestring):<EOL><INDENT>v = v.split('<STR_LIT:U+002C>')<EOL><DEDENT>elif not isinstance(v, collections.Iterable):<EOL><INDENT>v = [v]<EOL><DEDENT>kwargs['<STR_LIT>'] = v<EOL><DEDENT>elif k.lower() in (<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>'<EOL>):<EOL><INDENT>if isinstance(v, basestring):<EOL><INDENT>v = v.split('<STR_LIT:U+002C>')<EOL><DEDENT>elif not isinstance(v, collections.Iterable):<EOL><INDENT>v = [v]<EOL><DEDENT>kwargs['<STR_LIT>'] = v<EOL><DEDENT>else:<EOL><INDENT>kwargs[k] = v<EOL><DEDENT><DEDENT>for k, v in kwargs.items():<EOL><INDENT>if k in opts or k in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>if isinstance(v, basestring):<EOL><INDENT>v = v.split('<STR_LIT:U+002C>')<EOL><DEDENT>elif not isinstance(v, collections.Iterable):<EOL><INDENT>v = [v]<EOL><DEDENT>opts[k] = v<EOL><DEDENT>if '<STR_LIT>' in k:<EOL><INDENT>opts['<STR_LIT>'] = [<NUM_LIT:1>]<EOL><DEDENT><DEDENT>opts['<STR_LIT>'] = [<NUM_LIT:1>]<EOL>opts['<STR_LIT>'] = [kwargs.get('<STR_LIT>', <NUM_LIT:0>)]<EOL>qs = '<STR_LIT:&>'.join(<EOL>'<STR_LIT>'.format(urllib.parse.quote_plus(name), val)<EOL>for name, vals in sorted(opts.items()) for val in vals<EOL>)<EOL>return qs<EOL>

Converts kwargs given to PSF to a querystring.

    :returns: the querystring.


<EOL>if os.path.isfile(PSF_CONSTANTS_FILENAME):<EOL><INDENT>modtime = int(os.path.getmtime(PSF_CONSTANTS_FILENAME))<EOL>curtime = int(time.time())<EOL><DEDENT>if (os.path.isfile(PSF_CONSTANTS_FILENAME)<EOL>and curtime - modtime <= <NUM_LIT:7> * <NUM_LIT> * <NUM_LIT> * <NUM_LIT>):<EOL><INDENT>with open(PSF_CONSTANTS_FILENAME, '<STR_LIT:r>') as const_f:<EOL><INDENT>def_dict = json.load(const_f)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>print('<STR_LIT>')<EOL>html = utils.get_html(PSF_URL)<EOL>doc = pq(html)<EOL>def_dict = {}<EOL>for inp in doc('<STR_LIT>'):<EOL><INDENT>name = inp.attrib['<STR_LIT:name>']<EOL>if name not in def_dict:<EOL><INDENT>def_dict[name] = {<EOL>'<STR_LIT:value>': set(),<EOL>'<STR_LIT>': set(),<EOL>'<STR_LIT:type>': inp.attrib['<STR_LIT:type>']<EOL>}<EOL><DEDENT>if inp.attrib['<STR_LIT:type>'] in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>if '<STR_LIT>' in inp.attrib:<EOL><INDENT>def_dict[name]['<STR_LIT:value>'].add(inp.attrib['<STR_LIT:value>'])<EOL><DEDENT>def_dict[name]['<STR_LIT>'].add(inp.attrib['<STR_LIT:value>'])<EOL><DEDENT>else:<EOL><INDENT>def_dict[name]['<STR_LIT:value>'].add(inp.attrib.get('<STR_LIT:value>', '<STR_LIT>'))<EOL><DEDENT><DEDENT>for sel in doc.items('<STR_LIT>'):<EOL><INDENT>name = sel.attr['<STR_LIT:name>']<EOL>if name not in def_dict:<EOL><INDENT>def_dict[name] = {<EOL>'<STR_LIT:value>': set(),<EOL>'<STR_LIT>': set(),<EOL>'<STR_LIT:type>': '<STR_LIT>'<EOL>}<EOL><DEDENT>defaultOpt = sel('<STR_LIT>')<EOL>if len(defaultOpt):<EOL><INDENT>defaultOpt = defaultOpt[<NUM_LIT:0>]<EOL>def_dict[name]['<STR_LIT:value>'].add(defaultOpt.attrib.get('<STR_LIT:value>', '<STR_LIT>'))<EOL><DEDENT>else:<EOL><INDENT>def_dict[name]['<STR_LIT:value>'].add(<EOL>sel('<STR_LIT>')[<NUM_LIT:0>].attrib.get('<STR_LIT:value>', '<STR_LIT>')<EOL>)<EOL><DEDENT>def_dict[name]['<STR_LIT>'] = {<EOL>opt.attrib['<STR_LIT:value>'] for opt in sel('<STR_LIT>')<EOL>if opt.attrib.get('<STR_LIT:value>')<EOL>}<EOL><DEDENT>def_dict.pop('<STR_LIT>', None)<EOL>def_dict.pop('<STR_LIT>', None)<EOL>with open(PSF_CONSTANTS_FILENAME, '<STR_LIT>') as f:<EOL><INDENT>for k in def_dict:<EOL><INDENT>try:<EOL><INDENT>def_dict[k]['<STR_LIT:value>'] = sorted(<EOL>list(def_dict[k]['<STR_LIT:value>']), key=int<EOL>)<EOL>def_dict[k]['<STR_LIT>'] = sorted(<EOL>list(def_dict[k]['<STR_LIT>']), key=int<EOL>)<EOL><DEDENT>except Exception:<EOL><INDENT>def_dict[k]['<STR_LIT:value>'] = sorted(list(def_dict[k]['<STR_LIT:value>']))<EOL>def_dict[k]['<STR_LIT>'] = sorted(<EOL>list(def_dict[k]['<STR_LIT>'])<EOL>)<EOL><DEDENT><DEDENT>json.dump(def_dict, f)<EOL><DEDENT><DEDENT>return def_dict<EOL>

Handles scraping options for player-season finder form.

    :returns: {'name1': {'value': val, 'options': [opt1, ...] }, ... }


querystring = _kwargs_to_qs(**kwargs)<EOL>url = '<STR_LIT>'.format(GPF_URL, querystring)<EOL>if kwargs.get('<STR_LIT>', False):<EOL><INDENT>print(url)<EOL><DEDENT>html = utils.get_html(url)<EOL>doc = pq(html)<EOL>table = doc('<STR_LIT>')<EOL>plays = utils.parse_table(table)<EOL>if '<STR_LIT>' in plays.columns:<EOL><INDENT>oScore, dScore = zip(*plays.score.apply(lambda s: s.split('<STR_LIT:->')))<EOL>plays['<STR_LIT>'] = oScore<EOL>plays['<STR_LIT>'] = dScore<EOL><DEDENT>if '<STR_LIT:description>' in plays.columns:<EOL><INDENT>plays = pbp.expand_details(plays, detailCol='<STR_LIT:description>')<EOL><DEDENT>return plays<EOL>


<EOL>inpOptDef = inputs_options_defaults()<EOL>opts = {<EOL>name: dct['<STR_LIT:value>']<EOL>for name, dct in inpOptDef.items()<EOL>}<EOL>for k, v in kwargs.items():<EOL><INDENT>if k.lower() in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>del kwargs[k]<EOL>kwargs['<STR_LIT>'] = v<EOL><DEDENT>if k == '<STR_LIT>':<EOL><INDENT>if v.startswith('<STR_LIT>'):<EOL><INDENT>kwargs[k] = utils.rel_url_to_id(v)<EOL><DEDENT><DEDENT>if isinstance(v, bool):<EOL><INDENT>kwargs[k] = '<STR_LIT:Y>' if v else '<STR_LIT:N>'<EOL><DEDENT>if k.lower() in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>del kwargs[k]<EOL>kwargs['<STR_LIT>'] = v<EOL><DEDENT>if k.lower() in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>del kwargs[k]<EOL>if k.lower() == '<STR_LIT>':<EOL><INDENT>kwargs['<STR_LIT>'] = int(v)<EOL><DEDENT>else:<EOL><INDENT>kwargs['<STR_LIT>'] = int(v)<EOL><DEDENT><DEDENT>if k.lower() in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>del kwargs[k]<EOL>if k.lower() == '<STR_LIT>':<EOL><INDENT>kwargs['<STR_LIT>'] = int(v)<EOL><DEDENT>else:<EOL><INDENT>kwargs['<STR_LIT>'] = int(v)<EOL><DEDENT><DEDENT>if k.lower() in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>del kwargs[k]<EOL>if isinstance(v, collections.Iterable):<EOL><INDENT>lst = list(v)<EOL>kwargs['<STR_LIT>'] = min(lst)<EOL>kwargs['<STR_LIT>'] = max(lst)<EOL><DEDENT>elif isinstance(v, basestring):<EOL><INDENT>v = list(map(int, v.split('<STR_LIT:U+002C>')))<EOL>kwargs['<STR_LIT>'] = min(v)<EOL>kwargs['<STR_LIT>'] = max(v)<EOL><DEDENT>else:<EOL><INDENT>kwargs['<STR_LIT>'] = v<EOL>kwargs['<STR_LIT>'] = v<EOL><DEDENT><DEDENT>if k.lower() in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>del kwargs[k]<EOL>if isinstance(v, collections.Iterable):<EOL><INDENT>lst = list(v)<EOL>kwargs['<STR_LIT>'] = min(lst)<EOL>kwargs['<STR_LIT>'] = max(lst)<EOL><DEDENT>elif isinstance(v, basestring):<EOL><INDENT>v = list(map(int, v.split('<STR_LIT:U+002C>')))<EOL>kwargs['<STR_LIT>'] = min(v)<EOL>kwargs['<STR_LIT>'] = max(v)<EOL><DEDENT>else:<EOL><INDENT>kwargs['<STR_LIT>'] = v<EOL>kwargs['<STR_LIT>'] = v<EOL><DEDENT><DEDENT>if k == '<STR_LIT>':<EOL><INDENT>kwargs['<STR_LIT>'] = '<STR_LIT:P>'<EOL><DEDENT>if isinstance(v, basestring):<EOL><INDENT>v = v.split('<STR_LIT:U+002C>')<EOL><DEDENT>if not isinstance(v, collections.Iterable):<EOL><INDENT>v = [v]<EOL><DEDENT><DEDENT>for k in kwargs:<EOL><INDENT>if k in opts:<EOL><INDENT>opts[k] = []<EOL><DEDENT><DEDENT>for k, v in kwargs.items():<EOL><INDENT>if k in opts:<EOL><INDENT>if isinstance(v, basestring):<EOL><INDENT>v = v.split('<STR_LIT:U+002C>')<EOL><DEDENT>elif not isinstance(v, collections.Iterable):<EOL><INDENT>v = [v]<EOL><DEDENT>for val in v:<EOL><INDENT>opts[k].append(val)<EOL><DEDENT><DEDENT><DEDENT>opts['<STR_LIT>'] = [<NUM_LIT:1>]<EOL>qs = '<STR_LIT:&>'.join('<STR_LIT>'.format(name, val)<EOL>for name, vals in sorted(opts.items()) for val in vals)<EOL>return qs<EOL>

Converts kwargs given to GPF to a querystring.

    :returns: the querystring.


<EOL>if os.path.isfile(GPF_CONSTANTS_FILENAME):<EOL><INDENT>modtime = int(os.path.getmtime(GPF_CONSTANTS_FILENAME))<EOL>curtime = int(time.time())<EOL><DEDENT>if (os.path.isfile(GPF_CONSTANTS_FILENAME)<EOL>and curtime - modtime <= <NUM_LIT:7> * <NUM_LIT> * <NUM_LIT> * <NUM_LIT>):<EOL><INDENT>with open(GPF_CONSTANTS_FILENAME, '<STR_LIT:r>') as const_f:<EOL><INDENT>def_dict = json.load(const_f)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>print('<STR_LIT>')<EOL>html = utils.get_html(GPF_URL)<EOL>doc = pq(html)<EOL>def_dict = {}<EOL>for inp in doc('<STR_LIT>'):<EOL><INDENT>name = inp.attrib['<STR_LIT:name>']<EOL>if name not in def_dict:<EOL><INDENT>def_dict[name] = {<EOL>'<STR_LIT:value>': set(),<EOL>'<STR_LIT>': set(),<EOL>'<STR_LIT:type>': inp.type<EOL>}<EOL><DEDENT>val = inp.attrib.get('<STR_LIT:value>', '<STR_LIT>')<EOL>if inp.type in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>if '<STR_LIT>' in inp.attrib:<EOL><INDENT>def_dict[name]['<STR_LIT:value>'].add(val)<EOL><DEDENT>def_dict[name]['<STR_LIT>'].add(val)<EOL><DEDENT>else:<EOL><INDENT>def_dict[name]['<STR_LIT:value>'].add(val)<EOL><DEDENT><DEDENT>for sel in doc.items('<STR_LIT>'):<EOL><INDENT>name = sel.attr['<STR_LIT:name>']<EOL>if name not in def_dict:<EOL><INDENT>def_dict[name] = {<EOL>'<STR_LIT:value>': set(),<EOL>'<STR_LIT>': set(),<EOL>'<STR_LIT:type>': '<STR_LIT>'<EOL>}<EOL><DEDENT>defaultOpt = sel('<STR_LIT>')<EOL>if len(defaultOpt):<EOL><INDENT>defaultOpt = defaultOpt[<NUM_LIT:0>]<EOL>def_dict[name]['<STR_LIT:value>'].add(defaultOpt.attrib.get('<STR_LIT:value>', '<STR_LIT>'))<EOL><DEDENT>else:<EOL><INDENT>def_dict[name]['<STR_LIT:value>'].add(<EOL>sel('<STR_LIT>')[<NUM_LIT:0>].attrib.get('<STR_LIT:value>', '<STR_LIT>')<EOL>)<EOL><DEDENT>def_dict[name]['<STR_LIT>'] = {<EOL>opt.attrib['<STR_LIT:value>'] for opt in sel('<STR_LIT>')<EOL>if opt.attrib.get('<STR_LIT:value>')<EOL>}<EOL><DEDENT>def_dict['<STR_LIT>']['<STR_LIT:value>'] = ['<STR_LIT:0>']<EOL>def_dict.pop('<STR_LIT>', None)<EOL>def_dict.pop('<STR_LIT>', None)<EOL>with open(GPF_CONSTANTS_FILENAME, '<STR_LIT>') as f:<EOL><INDENT>for k in def_dict:<EOL><INDENT>try:<EOL><INDENT>def_dict[k]['<STR_LIT:value>'] = sorted(<EOL>list(def_dict[k]['<STR_LIT:value>']), key=int<EOL>)<EOL>def_dict[k]['<STR_LIT>'] = sorted(<EOL>list(def_dict[k]['<STR_LIT>']), key=int<EOL>)<EOL><DEDENT>except:<EOL><INDENT>def_dict[k]['<STR_LIT:value>'] = sorted(list(def_dict[k]['<STR_LIT:value>']))<EOL>def_dict[k]['<STR_LIT>'] = sorted(<EOL>list(def_dict[k]['<STR_LIT>'])<EOL>)<EOL><DEDENT><DEDENT>json.dump(def_dict, f)<EOL><DEDENT><DEDENT>return def_dict<EOL>

Handles scraping options for play finder form.

    :returns: {'name1': {'value': val, 'options': [opt1, ...] }, ... }


line = float(line)<EOL>probWin = <NUM_LIT:1.> - norm.cdf(<NUM_LIT:0.5>, -line, <NUM_LIT>)<EOL>probTie = norm.cdf(<NUM_LIT:0.5>, -line, <NUM_LIT>) - norm.cdf(-<NUM_LIT:0.5>, -line, <NUM_LIT>)<EOL>return <NUM_LIT> * (probWin + <NUM_LIT:0.5> * probTie)<EOL>

Gets the initial win probability of a game given its Vegas line.

    :line: The Vegas line from the home team's perspective (negative means
    home team is favored).
    :returns: A float in [0., 100.] that represents the win probability.


match = re.match(r'<STR_LIT>', self.boxscore_id)<EOL>year, month, day = map(int, match.groups())<EOL>return datetime.date(year=year, month=month, day=day)<EOL>

Returns the date of the game. See Python datetime.date documentation
        for more.
        :returns: A datetime.date object with year, month, and day attributes.


days = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>']<EOL>date = self.date()<EOL>wd = date.weekday()<EOL>return days[wd]<EOL>

Returns the day of the week on which the game occurred.
        :returns: String representation of the day of the week for the game.


doc = self.get_doc()<EOL>table = doc('<STR_LIT>')<EOL>relURL = table('<STR_LIT>').eq(<NUM_LIT:2>)('<STR_LIT:a>').eq(<NUM_LIT:2>).attr['<STR_LIT>']<EOL>home = sportsref.utils.rel_url_to_id(relURL)<EOL>return home<EOL>

Returns home team ID.
        :returns: 3-character string representing home team's ID.


doc = self.get_doc()<EOL>table = doc('<STR_LIT>')<EOL>relURL = table('<STR_LIT>').eq(<NUM_LIT:1>)('<STR_LIT:a>').eq(<NUM_LIT:2>).attr['<STR_LIT>']<EOL>away = sportsref.utils.rel_url_to_id(relURL)<EOL>return away<EOL>

Returns away team ID.
        :returns: 3-character string representing away team's ID.


doc = self.get_doc()<EOL>table = doc('<STR_LIT>')<EOL>home_score = table('<STR_LIT>').eq(<NUM_LIT:2>)('<STR_LIT>')[-<NUM_LIT:1>].text_content()<EOL>return int(home_score)<EOL>

Returns score of the home team.
        :returns: int of the home score.


doc = self.get_doc()<EOL>table = doc('<STR_LIT>')<EOL>away_score = table('<STR_LIT>').eq(<NUM_LIT:1>)('<STR_LIT>')[-<NUM_LIT:1>].text_content()<EOL>return int(away_score)<EOL>

Returns score of the away team.
        :returns: int of the away score.


hmScore = self.home_score()<EOL>awScore = self.away_score()<EOL>if hmScore > awScore:<EOL><INDENT>return self.home()<EOL><DEDENT>elif hmScore < awScore:<EOL><INDENT>return self.away()<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Returns the team ID of the winning team. Returns NaN if a tie.


doc = self.get_doc()<EOL>raw = doc('<STR_LIT>').attr['<STR_LIT>']<EOL>match = re.match(<EOL>r'<STR_LIT>'.format(self.season()), raw<EOL>)<EOL>if match:<EOL><INDENT>return int(match.group(<NUM_LIT:1>))<EOL><DEDENT>else:<EOL><INDENT>return <NUM_LIT><EOL><DEDENT>

Returns the week in which this game took place. 18 is WC round, 19
        is Div round, 20 is CC round, 21 is SB.
        :returns: Integer from 1 to 21.


date = self.date()<EOL>return date.year - <NUM_LIT:1> if date.month <= <NUM_LIT:3> else date.year<EOL>

Returns the year ID of the season in which this game took place.
Useful for week 17 January games.

:returns: An int representing the year of the season.


doc = self.get_doc()<EOL>a = doc('<STR_LIT>')<EOL>h = doc('<STR_LIT>')<EOL>data = []<EOL>for h, table in enumerate((a, h)):<EOL><INDENT>team = self.home() if h else self.away()<EOL>for i, row in enumerate(table('<STR_LIT>').items()):<EOL><INDENT>datum = {}<EOL>datum['<STR_LIT>'] = sportsref.utils.rel_url_to_id(<EOL>row('<STR_LIT:a>')[<NUM_LIT:0>].attrib['<STR_LIT>']<EOL>)<EOL>datum['<STR_LIT>'] = row('<STR_LIT>').text()<EOL>datum['<STR_LIT>'] = row('<STR_LIT>').text()<EOL>datum['<STR_LIT>'] = team<EOL>datum['<STR_LIT>'] = (h == <NUM_LIT:1>)<EOL>datum['<STR_LIT>'] = (i <= <NUM_LIT:10>)<EOL>data.append(datum)<EOL><DEDENT><DEDENT>return pd.DataFrame(data)<EOL>

Returns a DataFrame where each row is an entry in the starters table
        from PFR.

        The columns are:
        * player_id - the PFR player ID for the player (note that this column
        is not necessarily all unique; that is, one player can be a starter in
        multiple positions, in theory).
        * playerName - the listed name of the player; this too is not
        necessarily unique.
        * position - the position at which the player started for their team.
        * team - the team for which the player started.
        * home - True if the player's team was at home, False if they were away
        * offense - True if the player is starting on an offensive position,
        False if defense.

        :returns: A pandas DataFrame. See the description for details.


doc = self.get_doc()<EOL>table = doc('<STR_LIT>')<EOL>giTable = sportsref.utils.parse_info_table(table)<EOL>return giTable.get('<STR_LIT>', np.nan)<EOL>

The playing surface on which the game was played.

        :returns: string representing the type of surface. Returns np.nan if
        not avaiable.


doc = self.get_doc()<EOL>table = doc('<STR_LIT>')<EOL>giTable = sportsref.utils.parse_info_table(table)<EOL>if '<STR_LIT>' in giTable:<EOL><INDENT>ou = giTable['<STR_LIT>']<EOL>return float(ou.split()[<NUM_LIT:0>])<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Returns the over/under for the game as a float, or np.nan if not
available.


doc = self.get_doc()<EOL>table = doc('<STR_LIT>')<EOL>giTable = sportsref.utils.parse_info_table(table)<EOL>if '<STR_LIT>' in giTable:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Gets information relating to the opening coin toss.

        Keys are:
        * wonToss - contains the ID of the team that won the toss
        * deferred - bool whether the team that won the toss deferred it

        :returns: Dictionary of coin toss-related info.


doc = self.get_doc()<EOL>table = doc('<STR_LIT>')<EOL>giTable = sportsref.utils.parse_info_table(table)<EOL>if '<STR_LIT>' in giTable:<EOL><INDENT>regex = (<EOL>r'<STR_LIT>'<EOL>r'<STR_LIT>'<EOL>r'<STR_LIT>'<EOL>r'<STR_LIT>'<EOL>)<EOL>m = re.match(regex, giTable['<STR_LIT>'])<EOL>d = m.groupdict()<EOL>for k in d:<EOL><INDENT>try:<EOL><INDENT>d[k] = int(d[k])<EOL><DEDENT>except TypeError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>d['<STR_LIT>'] = (d['<STR_LIT>'] if pd.notnull(d['<STR_LIT>'])<EOL>else d['<STR_LIT>'])<EOL>d['<STR_LIT>'] = d['<STR_LIT>'] if pd.notnull(d['<STR_LIT>']) else <NUM_LIT:0><EOL>return d<EOL><DEDENT>else:<EOL><INDENT>return {<EOL>'<STR_LIT>': <NUM_LIT>, '<STR_LIT>': <NUM_LIT>, '<STR_LIT>': None, '<STR_LIT>': <NUM_LIT:0><EOL>}<EOL><DEDENT>

Returns a dictionary of weather-related info.

        Keys of the returned dict:
        * temp
        * windChill
        * relHumidity
        * windMPH

        :returns: Dict of weather data.


doc = self.get_doc()<EOL>table = doc('<STR_LIT>')<EOL>df = sportsref.utils.parse_table(table)<EOL>df['<STR_LIT>'] = self.boxscore_id<EOL>df['<STR_LIT>'] = self.home()<EOL>df['<STR_LIT>'] = self.away()<EOL>df['<STR_LIT>'] = self.season()<EOL>df['<STR_LIT>'] = self.week()<EOL>feats = sportsref.nfl.pbp.expand_details(df)<EOL>df = sportsref.nfl.pbp._add_team_columns(feats)<EOL>df['<STR_LIT>'] = df.home_wp.diff()<EOL>for col in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>if col in df.columns:<EOL><INDENT>df[col] = df[col].shift(<NUM_LIT:1>)<EOL><DEDENT><DEDENT>df.loc[<NUM_LIT:0>, ['<STR_LIT>', '<STR_LIT>']] = <NUM_LIT:0><EOL>df.home_wp.fillna(method='<STR_LIT>', inplace=True)<EOL>firstPlaysOfGame = df[df.secsElapsed == <NUM_LIT:0>].index<EOL>line = self.line()<EOL>for i in firstPlaysOfGame:<EOL><INDENT>initwp = sportsref.nfl.winProb.initialWinProb(line)<EOL>df.loc[i, '<STR_LIT>'] = initwp<EOL>df.loc[i, '<STR_LIT>'] = df.loc[i + <NUM_LIT:1>, '<STR_LIT>'] - initwp<EOL><DEDENT>lastPlayIdx = df.index[-<NUM_LIT:1>]<EOL>lastPlayWP = df.loc[lastPlayIdx, '<STR_LIT>']<EOL>winner = self.winner()<EOL>finalWP = <NUM_LIT> if pd.isnull(winner) else (winner == self.home()) * <NUM_LIT><EOL>df.loc[lastPlayIdx, '<STR_LIT>'] = finalWP - lastPlayWP<EOL>timeouts = df[df.isTimeout].index<EOL>for to in timeouts:<EOL><INDENT>df.loc[to, '<STR_LIT>'] = <NUM_LIT:0.><EOL>if to + <NUM_LIT:2> in df.index:<EOL><INDENT>wpa = df.loc[to + <NUM_LIT:2>, '<STR_LIT>'] - df.loc[to + <NUM_LIT:1>, '<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>wpa = finalWP - df.loc[to + <NUM_LIT:1>, '<STR_LIT>']<EOL><DEDENT>df.loc[to + <NUM_LIT:1>, '<STR_LIT>'] = wpa<EOL><DEDENT>df = sportsref.nfl.pbp._add_team_features(df)<EOL>df['<STR_LIT>'] = np.where(df.isKickoff, <NUM_LIT>, df.distToGoal)<EOL>df.distToGoal.fillna(method='<STR_LIT>', inplace=True)<EOL>df.distToGoal.fillna(method='<STR_LIT>', inplace=True)  <EOL>return df<EOL>

Returns a dataframe of the play-by-play data from the game.

        Order of function calls:
            1. parse_table on the play-by-play table
            2. expand_details
                - calls parse_play_details & _clean_features
            3. _add_team_columns
            4. various fixes to clean data
            5. _add_team_features

        :returns: pandas DataFrame of play-by-play. Similar to GPF.


doc = self.get_doc()<EOL>table = doc('<STR_LIT>')<EOL>return sportsref.utils.parse_info_table(table)<EOL>

Gets a dictionary of ref positions and the ref IDs of the refs for
        that game.

        :returns: A dictionary of ref positions and IDs.


doc = self.get_doc()<EOL>tableIDs = ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>')<EOL>dfs = []<EOL>for tID in tableIDs:<EOL><INDENT>table = doc('<STR_LIT>'.format(tID))<EOL>dfs.append(sportsref.utils.parse_table(table))<EOL><DEDENT>dfs = [df for df in dfs if not df.empty]<EOL>df = reduce(<EOL>lambda x, y: pd.merge(<EOL>x, y, how='<STR_LIT>', on=list(set(x.columns) & set(y.columns))<EOL>), dfs<EOL>).reset_index(drop=True)<EOL>return df<EOL>

Gets the stats for offense, defense, returning, and kicking of
        individual players in the game.
        :returns: A DataFrame containing individual player stats.


<EOL>doc = self.get_doc()<EOL>table_ids = ('<STR_LIT>', '<STR_LIT>')<EOL>tms = (self.away(), self.home())<EOL>df = pd.concat([<EOL>sportsref.utils.parse_table(doc('<STR_LIT>'.format(table_id)))<EOL>.assign(is_home=bool(i), team=tms[i], opp=tms[i*-<NUM_LIT:1>+<NUM_LIT:1>])<EOL>for i, table_id in enumerate(table_ids)<EOL>])<EOL>if df.empty:<EOL><INDENT>return df<EOL><DEDENT>return df.set_index('<STR_LIT>')<EOL>

Gets the snap counts for both teams' players and returns them in a
        DataFrame. Note: only goes back to 2012.

        :returns: DataFrame of snap count data


doc = pq(sportsref.utils.get_html(sportsref.nfl.BASE_URL + '<STR_LIT>'))<EOL>active_table = doc('<STR_LIT>')<EOL>active_df = sportsref.utils.parse_table(active_table)<EOL>inactive_table = doc('<STR_LIT>')<EOL>inactive_df = sportsref.utils.parse_table(inactive_table)<EOL>df = pd.concat((active_df, inactive_df))<EOL>df = df.loc[~df['<STR_LIT>']]<EOL>ids = df.team_id.str[:<NUM_LIT:3>].values<EOL>names = [tr('<STR_LIT>') for tr in active_table('<STR_LIT>').items()]<EOL>names.extend(tr('<STR_LIT>') for tr in inactive_table('<STR_LIT>').items())<EOL>names = [_f for _f in names if _f]<EOL>names = [lst[<NUM_LIT:0>].text_content() for lst in names]<EOL>series = pd.Series(names, index=ids)<EOL>mask = ((df.year_min <= year) & (year <= df.year_max)).values<EOL>return series[mask].to_dict()<EOL>

Returns a mapping from team ID to full team name for a given season.
    Example of a full team name: "New England Patriots"

    :year: The year of the season in question (as an int).
    :returns: A dictionary with teamID keys and full team name values.


names = team_names(year)<EOL>return {v: k for k, v in names.items()}<EOL>

Returns a mapping from team name to team ID for a given season. Inverse
    mapping of team_names. Example of a full team name: "New England Patriots"

    :year: The year of the season in question (as an int).
    :returns: A dictionary with full team name keys and teamID values.


return list(team_names(year).keys())<EOL>

Returns a list of team IDs for a given season.

    :year: The year of the season in question (as an int).
    :returns: A list of team IDs.


doc = self.get_main_doc()<EOL>headerwords = doc('<STR_LIT>')[<NUM_LIT:0>].text_content().split()<EOL>lastIdx = headerwords.index('<STR_LIT>')<EOL>teamwords = headerwords[:lastIdx]<EOL>return '<STR_LIT:U+0020>'.join(teamwords)<EOL>

Returns the real name of the franchise given the team ID.

        Examples:
        'nwe' -> 'New England Patriots'
        'sea' -> 'Seattle Seahawks'

        :returns: A string corresponding to the team's full name.


doc = self.get_year_doc('<STR_LIT>'.format(year))<EOL>roster_table = doc('<STR_LIT>')<EOL>df = sportsref.utils.parse_table(roster_table)<EOL>starter_table = doc('<STR_LIT>')<EOL>if not starter_table.empty:<EOL><INDENT>start_df = sportsref.utils.parse_table(starter_table)<EOL>start_df = start_df.dropna(axis=<NUM_LIT:0>, subset=['<STR_LIT>'])<EOL>starters = start_df.set_index('<STR_LIT>').player_id<EOL>df['<STR_LIT>'] = df.player_id.isin(starters)<EOL>df['<STR_LIT>'] = df.player_id.map(<EOL>lambda pid: (starters[starters == pid].index[<NUM_LIT:0>]<EOL>if pid in starters.values else None)<EOL>)<EOL><DEDENT>return df<EOL>

Returns the roster table for the given year.

        :year: The year for which we want the roster; defaults to current year.
        :returns: A DataFrame containing roster information for that year.


doc = self.get_year_doc(year)<EOL>table = doc('<STR_LIT>')<EOL>df = sportsref.utils.parse_table(table)<EOL>if df.empty:<EOL><INDENT>return np.array([])<EOL><DEDENT>return df.boxscore_id.values<EOL>

Gets list of BoxScore objects corresponding to the box scores from
        that year.

        :year: The year for which we want the boxscores; defaults to current
        year.
        :returns: np.array of strings representing boxscore IDs.


@sportsref.decorators.memoize<EOL><INDENT>def _year_info_pq(self, year, keyword):<DEDENT>

doc = self.get_year_doc(year)<EOL>p_tags = doc('<STR_LIT>')<EOL>texts = [p_tag.text_content().strip() for p_tag in p_tags]<EOL>try:<EOL><INDENT>return next(<EOL>pq(p_tag) for p_tag, text in zip(p_tags, texts)<EOL>if keyword.lower() in text.lower()<EOL>)<EOL><DEDENT>except StopIteration:<EOL><INDENT>if len(texts):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT><DEDENT>

Returns a PyQuery object containing the info from the meta div at
        the top of the team year page with the given keyword.

        :year: Int representing the season.
        :keyword: A keyword to filter to a single p tag in the meta div.
        :returns: A PyQuery object for the selected p element.


coach_str = self._year_info_pq(year, '<STR_LIT>').text()<EOL>regex = r'<STR_LIT>'<EOL>coachAndTenure = []<EOL>m = True<EOL>while m:<EOL><INDENT>m = re.search(regex, coach_str)<EOL>coachID, wins, losses, ties = m.groups()<EOL>nextIndex = m.end(<NUM_LIT:4>) + <NUM_LIT:1><EOL>coachStr = coachStr[nextIndex:]<EOL>tenure = int(wins) + int(losses) + int(ties)<EOL>coachAndTenure.append((coachID, tenure))<EOL><DEDENT>coachIDs = [<EOL>cID for cID, games in coachAndTenure for _ in range(games)<EOL>]<EOL>return np.array(coachIDs[::-<NUM_LIT:1>])<EOL>

Returns head coach data by game.

        :year: An int representing the season in question.
        :returns: An array with an entry per game of the season that the team
        played (including playoffs). Each entry is the head coach's ID for that
        game in the season.


schedule = self.schedule(year)<EOL>if schedule.empty:<EOL><INDENT>return np.nan<EOL><DEDENT>return schedule.query('<STR_LIT>').is_win.sum()<EOL>

Returns the # of regular season wins a team in a year.

        :year: The year for the season in question.
        :returns: The number of regular season wins.


doc = self.get_year_doc(year)<EOL>table = doc('<STR_LIT>')<EOL>df = sportsref.utils.parse_table(table)<EOL>if df.empty:<EOL><INDENT>return pd.DataFrame()<EOL><DEDENT>df = df.loc[df['<STR_LIT>'].notnull()]<EOL>df['<STR_LIT>'] = np.arange(len(df)) + <NUM_LIT:1><EOL>df['<STR_LIT>'] = df['<STR_LIT>'] == '<STR_LIT>'<EOL>df['<STR_LIT>'] = df['<STR_LIT>'] == '<STR_LIT:L>'<EOL>df['<STR_LIT>'] = df['<STR_LIT>'] == '<STR_LIT:T>'<EOL>df['<STR_LIT>'] = df['<STR_LIT>'].isnull()<EOL>df['<STR_LIT>'] = df['<STR_LIT>'].notnull()<EOL>return df<EOL>

Returns a DataFrame with schedule information for the given year.

        :year: The year for the season in question.
        :returns: Pandas DataFrame with schedule information.


try:<EOL><INDENT>srs_text = self._year_info_pq(year, '<STR_LIT>').text()<EOL><DEDENT>except ValueError:<EOL><INDENT>return None<EOL><DEDENT>m = re.match(r'<STR_LIT>', srs_text)<EOL>if m:<EOL><INDENT>return float(m.group(<NUM_LIT:1>))<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Returns the SRS (Simple Rating System) for a team in a year.

        :year: The year for the season in question.
        :returns: A float of SRS.


try:<EOL><INDENT>sos_text = self._year_info_pq(year, '<STR_LIT>').text()<EOL><DEDENT>except ValueError:<EOL><INDENT>return None<EOL><DEDENT>m = re.search(r'<STR_LIT>', sos_text)<EOL>if m:<EOL><INDENT>return float(m.group(<NUM_LIT:1>))<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Returns the SOS (Strength of Schedule) for a team in a year, based
        on SRS.

        :year: The year for the season in question.
        :returns: A float of SOS.


try:<EOL><INDENT>oc_anchor = self._year_info_pq(year, '<STR_LIT>')('<STR_LIT:a>')<EOL>if oc_anchor:<EOL><INDENT>return oc_anchor.attr['<STR_LIT>']<EOL><DEDENT><DEDENT>except ValueError:<EOL><INDENT>return None<EOL><DEDENT>

Returns the coach ID for the team's OC in a given year.

        :year: An int representing the year.
        :returns: A string containing the coach ID of the OC.


try:<EOL><INDENT>dc_anchor = self._year_info_pq(year, '<STR_LIT>')('<STR_LIT:a>')<EOL>if dc_anchor:<EOL><INDENT>return dc_anchor.attr['<STR_LIT>']<EOL><DEDENT><DEDENT>except ValueError:<EOL><INDENT>return None<EOL><DEDENT>

Returns the coach ID for the team's DC in a given year.

        :year: An int representing the year.
        :returns: A string containing the coach ID of the DC.


anchor = self._year_info_pq(year, '<STR_LIT>')('<STR_LIT:a>')<EOL>return sportsref.utils.rel_url_to_id(anchor.attr['<STR_LIT>'])<EOL>

Returns the ID for the stadium in which the team played in a given
        year.

        :year: The year in question.
        :returns: A string representing the stadium ID.


scheme_text = self._year_info_pq(year, '<STR_LIT>').text()<EOL>m = re.search(r'<STR_LIT>', scheme_text, re.I)<EOL>if m:<EOL><INDENT>return m.group(<NUM_LIT:1>)<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Returns the name of the offensive scheme the team ran in the given
        year.

        :year: Int representing the season year.
        :returns: A string representing the offensive scheme.


Returns the name of the defensive alignment the team ran in the
        given year.

        :year: Int representing the season year.
        :returns: A string representing the defensive alignment.


doc = self.get_year_doc(year)<EOL>table = doc('<STR_LIT>')<EOL>df = sportsref.utils.parse_table(table)<EOL>if df.empty:<EOL><INDENT>return pd.Series()<EOL><DEDENT>return df.loc[df.player_id == '<STR_LIT>'].iloc[<NUM_LIT:0>]<EOL>

Returns a Series (dict-like) of team stats from the team-season
        page.

        :year: Int representing the season.
        :returns: A Series of team stats.


doc = self.get_year_doc(year)<EOL>table = doc('<STR_LIT>')<EOL>df = sportsref.utils.parse_table(table)<EOL>return df.loc[df.player_id == '<STR_LIT>'].iloc[<NUM_LIT:0>]<EOL>

Returns a Series (dict-like) of the team's opponent's stats from the
        team-season page.

        :year: Int representing the season.
        :returns: A Series of team stats.


doc = self.get_year_doc('<STR_LIT>'.format(year))<EOL>tables = doc('<STR_LIT>')<EOL>dfs = [sportsref.utils.parse_table(table) for table in tables.items()]<EOL>dfs = [<EOL>df.assign(split=df.columns[<NUM_LIT:0>])<EOL>.rename(columns={df.columns[<NUM_LIT:0>]: '<STR_LIT>'})<EOL>for df in dfs<EOL>]<EOL>if not dfs:<EOL><INDENT>return pd.DataFrame()<EOL><DEDENT>return pd.concat(dfs).reset_index(drop=True)<EOL>

Returns a DataFrame of offensive team splits for a season.

        :year: int representing the season.
        :returns: Pandas DataFrame of split data.


Returns a DataFrame of defensive team splits (i.e. opponent splits)
        for a season.

        :year: int representing the season.
        :returns: Pandas DataFrame of split data.


df = copy.deepcopy(df)<EOL>df['<STR_LIT>'] = df[detailCol]<EOL>dicts = [sportsref.nfl.pbp.parse_play_details(detail) for detail in df['<STR_LIT>'].values]<EOL>cols = {c for d in dicts if d for c in d.keys()}<EOL>blankEntry = {c: np.nan for c in cols}<EOL>newDicts = [d if d else blankEntry for d in dicts]<EOL>details = pd.DataFrame(newDicts)<EOL>df = pd.merge(df, details, left_index=True, right_index=True)<EOL>errors = [i for i, d in enumerate(dicts) if d is None]<EOL>df['<STR_LIT>'] = False<EOL>df.loc[errors, '<STR_LIT>'] = True<EOL>df.loc[<NUM_LIT:0>, '<STR_LIT>'] = '<STR_LIT>'<EOL>df.qtr_time_remain.fillna(method='<STR_LIT>', inplace=True)<EOL>df.qtr_time_remain.fillna(<EOL>pd.Series(np.where(df.quarter == <NUM_LIT:4>, '<STR_LIT>', '<STR_LIT>')), inplace=True<EOL>)<EOL>new_df = df.apply(_clean_features, axis=<NUM_LIT:1>)<EOL>return new_df<EOL>

Expands the details column of the given dataframe and returns the
    resulting DataFrame.

    :df: The input DataFrame.
    :detailCol: The detail column name.
    :returns: Returns DataFrame with new columns from pbp parsing.


<EOL>if not isinstance(details, basestring):<EOL><INDENT>return None<EOL><DEDENT>rushOptRE = r'<STR_LIT>'.format(<EOL>r'<STR_LIT:|>'.join(RUSH_OPTS.keys())<EOL>)<EOL>passOptRE = r'<STR_LIT>'.format(<EOL>r'<STR_LIT:|>'.join(PASS_OPTS.keys())<EOL>)<EOL>playerRE = r"<STR_LIT>"<EOL>struct = {}<EOL>challengeRE = re.compile(<EOL>r'<STR_LIT>'<EOL>'<STR_LIT>',<EOL>re.IGNORECASE<EOL>)<EOL>match = challengeRE.search(details)<EOL>if match:<EOL><INDENT>struct['<STR_LIT>'] = True<EOL>struct.update(match.groupdict())<EOL>if '<STR_LIT>' in details:<EOL><INDENT>overturnedIdx = details.index('<STR_LIT>')<EOL>newStart = overturnedIdx + len('<STR_LIT>')<EOL>details = details[newStart:].strip()<EOL><DEDENT><DEDENT>else:<EOL><INDENT>struct['<STR_LIT>'] = False<EOL><DEDENT>struct['<STR_LIT>'] = details.find('<STR_LIT>') != -<NUM_LIT:1><EOL>rusherRE = r"<STR_LIT>".format(playerRE)<EOL>rushOptRE = r"<STR_LIT>".format(rushOptRE)<EOL>rushYardsRE = r"<STR_LIT>"<EOL>tackleRE = (r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>.format(playerRE))<EOL>fumbleRE = (<EOL>r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>.format(playerRE))<EOL>tdSafetyRE = r"<STR_LIT>"<EOL>penaltyRE = (r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>.format(playerRE))<EOL>rushREstr = (<EOL>r"<STR_LIT>"<EOL>).format(rusherRE, rushOptRE, rushYardsRE, tackleRE, fumbleRE, tdSafetyRE,<EOL>penaltyRE)<EOL>rushRE = re.compile(rushREstr, re.IGNORECASE)<EOL>passerRE = r"<STR_LIT>".format(playerRE)<EOL>sackRE = (r"<STR_LIT>"<EOL>r"<STR_LIT>"<EOL>.format(playerRE))<EOL>completeRE = r"<STR_LIT>"<EOL>passOptRE = r"<STR_LIT>".format(passOptRE)<EOL>targetedRE = r"<STR_LIT>".format(<EOL>playerRE)<EOL>passYardsRE = r"<STR_LIT>"<EOL>intRE = (r'<STR_LIT>'.format(playerRE)<EOL>+ r'<STR_LIT>'<EOL>+ r'<STR_LIT>')<EOL>throwRE = r'<STR_LIT>'.format(<EOL>completeRE, passOptRE, targetedRE, passYardsRE, intRE, tackleRE<EOL>)<EOL>passREstr = (<EOL>r"<STR_LIT>"<EOL>).format(passerRE, sackRE, throwRE, fumbleRE, tdSafetyRE, penaltyRE)<EOL>passRE = re.compile(passREstr, re.IGNORECASE)<EOL>koKickerRE = r'<STR_LIT>'.format(playerRE)<EOL>koYardsRE = (r'<STR_LIT>'<EOL>r'<STR_LIT>')<EOL>nextREs = []<EOL>nextREs.append(<EOL>(r'<STR_LIT>'<EOL>r'<STR_LIT>').format(playerRE)<EOL>)<EOL>nextREs.append(<EOL>(r'<STR_LIT>'<EOL>r'<STR_LIT>').format(playerRE) +<EOL>r'<STR_LIT>'<EOL>)<EOL>nextREs.append(<EOL>r'<STR_LIT>'.format(playerRE)<EOL>)<EOL>nextREs.append(r'<STR_LIT>')<EOL>nextREs.append(r'<STR_LIT>')<EOL>nextRE = '<STR_LIT>'.join(r'<STR_LIT>'.format(nre) for nre in nextREs)<EOL>kickoffREstr = r'<STR_LIT>'.format(<EOL>koKickerRE, koYardsRE, nextRE,<EOL>tackleRE, fumbleRE, tdSafetyRE, penaltyRE<EOL>)<EOL>kickoffRE = re.compile(kickoffREstr, re.IGNORECASE)<EOL>timeoutREstr = r'<STR_LIT>'<EOL>timeoutRE = re.compile(timeoutREstr, re.IGNORECASE)<EOL>fgKickerRE = r'<STR_LIT>'.format(playerRE)<EOL>fgBaseRE = (r'<STR_LIT>'<EOL>r'<STR_LIT>')<EOL>fgBlockRE = (<EOL>r'<STR_LIT>'<EOL>r'<STR_LIT>'.format(playerRE) +<EOL>r'<STR_LIT>'.format(playerRE) +<EOL>r'<STR_LIT>'<EOL>)<EOL>fgREstr = r'<STR_LIT>'.format(fgKickerRE, fgBaseRE,<EOL>fgBlockRE, tdSafetyRE, penaltyRE)<EOL>fgRE = re.compile(fgREstr, re.IGNORECASE)<EOL>punterRE = r'<STR_LIT>'.format(playerRE)<EOL>puntBlockRE = (<EOL>(r'<STR_LIT>'<EOL>r'<STR_LIT>').format(playerRE) +<EOL>r'<STR_LIT>'<EOL>)<EOL>puntYdsRE = r'<STR_LIT>'<EOL>nextREs = []<EOL>nextREs.append(r'<STR_LIT>'<EOL>.format(playerRE))<EOL>nextREs.append(r'<STR_LIT>')<EOL>nextREs.append(<EOL>(r'<STR_LIT>'<EOL>r'<STR_LIT>').format(playerRE) +<EOL>r'<STR_LIT>' +<EOL>r'<STR_LIT>'<EOL>)<EOL>nextREs.append(<EOL>r'<STR_LIT>'.format(playerRE) +<EOL>r'<STR_LIT>'<EOL>)<EOL>nextRE = r'<STR_LIT>'.format('<STR_LIT:|>'.join(nextREs))<EOL>puntREstr = r'<STR_LIT>'.format(<EOL>punterRE, puntBlockRE, puntYdsRE, nextRE,<EOL>tackleRE, fumbleRE, tdSafetyRE, penaltyRE<EOL>)<EOL>puntRE = re.compile(puntREstr, re.IGNORECASE)<EOL>kneelREstr = (r'<STR_LIT>'.format(playerRE) +<EOL>r'<STR_LIT>')<EOL>kneelRE = re.compile(kneelREstr, re.IGNORECASE)<EOL>spikeREstr = r'<STR_LIT>'.format(playerRE)<EOL>spikeRE = re.compile(spikeREstr, re.IGNORECASE)<EOL>extraPointREstr = (r'<STR_LIT>'<EOL>r'<STR_LIT>').format(playerRE)<EOL>extraPointRE = re.compile(extraPointREstr, re.IGNORECASE)<EOL>twoPointREstr = (<EOL>r'<STR_LIT>'<EOL>r'<STR_LIT>'<EOL>)<EOL>twoPointRE = re.compile(twoPointREstr, re.IGNORECASE)<EOL>psPenaltyREstr = (<EOL>r'<STR_LIT>'.format(playerRE) + r'<STR_LIT>' +<EOL>r'<STR_LIT>' +<EOL>r'<STR_LIT>' +<EOL>r'<STR_LIT>')<EOL>psPenaltyRE = re.compile(psPenaltyREstr, re.IGNORECASE)<EOL>match = kickoffRE.search(details)<EOL>if match:<EOL><INDENT>struct['<STR_LIT>'] = True<EOL>struct.update(match.groupdict())<EOL>return struct<EOL><DEDENT>match = timeoutRE.search(details)<EOL>if match:<EOL><INDENT>struct['<STR_LIT>'] = True<EOL>struct.update(match.groupdict())<EOL>return struct<EOL><DEDENT>match = fgRE.search(details)<EOL>if match:<EOL><INDENT>struct['<STR_LIT>'] = True<EOL>struct.update(match.groupdict())<EOL>return struct<EOL><DEDENT>match = puntRE.search(details)<EOL>if match:<EOL><INDENT>struct['<STR_LIT>'] = True<EOL>struct.update(match.groupdict())<EOL>return struct<EOL><DEDENT>match = kneelRE.search(details)<EOL>if match:<EOL><INDENT>struct['<STR_LIT>'] = True<EOL>struct.update(match.groupdict())<EOL>return struct<EOL><DEDENT>match = spikeRE.search(details)<EOL>if match:<EOL><INDENT>struct['<STR_LIT>'] = True<EOL>struct.update(match.groupdict())<EOL>return struct<EOL><DEDENT>match = extraPointRE.search(details)<EOL>if match:<EOL><INDENT>struct['<STR_LIT>'] = True<EOL>struct.update(match.groupdict())<EOL>return struct<EOL><DEDENT>match = twoPointRE.search(details)<EOL>if match:<EOL><INDENT>struct['<STR_LIT>'] = True<EOL>struct['<STR_LIT>'] = match.group('<STR_LIT>')<EOL>realPlay = sportsref.nfl.pbp.parse_play_details(<EOL>match.group('<STR_LIT>'))<EOL>if realPlay:<EOL><INDENT>struct.update(realPlay)<EOL><DEDENT>return struct<EOL><DEDENT>match = passRE.search(details)<EOL>if match:<EOL><INDENT>struct['<STR_LIT>'] = True<EOL>struct.update(match.groupdict())<EOL>return struct<EOL><DEDENT>match = psPenaltyRE.search(details)<EOL>if match:<EOL><INDENT>struct['<STR_LIT>'] = True<EOL>struct.update(match.groupdict())<EOL>return struct<EOL><DEDENT>match = rushRE.search(details)<EOL>if match:<EOL><INDENT>struct['<STR_LIT>'] = True<EOL>struct.update(match.groupdict())<EOL>return struct<EOL><DEDENT>return None<EOL>

Parses play details from play-by-play string and returns structured
    data.

    :details: detail string for play
    :returns: dictionary of play attributes


struct = dict(struct)<EOL>ptypes = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>']<EOL>for pt in ptypes:<EOL><INDENT>struct[pt] = struct[pt] if pd.notnull(struct.get(pt)) else False<EOL><DEDENT>struct['<STR_LIT>'] = struct.get('<STR_LIT>') == '<STR_LIT>'<EOL>struct['<STR_LIT>'] = struct.get('<STR_LIT>') == '<STR_LIT>'<EOL>struct['<STR_LIT>'] = struct.get('<STR_LIT>') == '<STR_LIT>'<EOL>struct['<STR_LIT>'] = struct.get('<STR_LIT>') == '<STR_LIT>'<EOL>struct['<STR_LIT>'] = struct.get('<STR_LIT>') == '<STR_LIT>'<EOL>struct['<STR_LIT>'] = pd.notnull(struct.get('<STR_LIT>'))<EOL>struct['<STR_LIT>'] = (<EOL>'<STR_LIT>' in struct['<STR_LIT>'] and<EOL>'<STR_LIT>' not in struct['<STR_LIT>']<EOL>if struct.get('<STR_LIT>') else False)<EOL>struct['<STR_LIT>'] = struct.get('<STR_LIT>') == '<STR_LIT>'<EOL>struct['<STR_LIT>'] = pd.notnull(struct.get('<STR_LIT>'))<EOL>struct['<STR_LIT>'] = (struct.get('<STR_LIT>') == '<STR_LIT>' or<EOL>(struct.get('<STR_LIT>') and<EOL>'<STR_LIT>' in struct['<STR_LIT>']))<EOL>struct['<STR_LIT>'] = struct.get('<STR_LIT>') == '<STR_LIT>'<EOL>struct['<STR_LIT>'] = struct.get('<STR_LIT>') == '<STR_LIT>'<EOL>struct['<STR_LIT>'] = pd.notnull(struct.get('<STR_LIT>'))<EOL>struct['<STR_LIT>'] = PASS_OPTS.get(struct.get('<STR_LIT>'), np.nan)<EOL>if struct['<STR_LIT>']:<EOL><INDENT>pyds = struct['<STR_LIT>']<EOL>struct['<STR_LIT>'] = pyds if pd.notnull(pyds) else <NUM_LIT:0><EOL><DEDENT>if pd.notnull(struct['<STR_LIT>']):<EOL><INDENT>struct['<STR_LIT>'] = struct['<STR_LIT>'].strip()<EOL><DEDENT>struct['<STR_LIT>'] = struct.get('<STR_LIT>') == '<STR_LIT>'<EOL>if struct['<STR_LIT>'] == '<STR_LIT>':<EOL><INDENT>struct['<STR_LIT>'] = <NUM_LIT:5><EOL><DEDENT>struct['<STR_LIT>'] = RUSH_OPTS.get(struct.get('<STR_LIT>'), np.nan)<EOL>if struct['<STR_LIT>']:<EOL><INDENT>ryds = struct['<STR_LIT>']<EOL>struct['<STR_LIT>'] = ryds if pd.notnull(ryds) else <NUM_LIT:0><EOL><DEDENT>year = struct.get('<STR_LIT>', np.nan)<EOL>struct['<STR_LIT>'] = sportsref.nfl.teams.team_ids(year).get(<EOL>struct.get('<STR_LIT>'), np.nan<EOL>)<EOL>struct['<STR_LIT>'] = struct.get('<STR_LIT>') == '<STR_LIT>'<EOL>struct['<STR_LIT>'] = struct.get('<STR_LIT>') == '<STR_LIT>'<EOL>bool_vars = [<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'<EOL>]<EOL>int_vars = [<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>'<EOL>]<EOL>float_vars = [<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>'<EOL>]<EOL>string_vars = [<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT:target>', '<STR_LIT>',<EOL>'<STR_LIT>'<EOL>]<EOL>for var in bool_vars:<EOL><INDENT>struct[var] = struct.get(var) is True<EOL><DEDENT>for var in int_vars:<EOL><INDENT>try:<EOL><INDENT>struct[var] = int(struct.get(var))<EOL><DEDENT>except (ValueError, TypeError):<EOL><INDENT>struct[var] = np.nan<EOL><DEDENT><DEDENT>for var in float_vars:<EOL><INDENT>try:<EOL><INDENT>struct[var] = float(struct.get(var))<EOL><DEDENT>except (ValueError, TypeError):<EOL><INDENT>struct[var] = np.nan<EOL><DEDENT><DEDENT>for var in string_vars:<EOL><INDENT>if var not in struct or pd.isnull(struct[var]) or var == '<STR_LIT>':<EOL><INDENT>struct[var] = np.nan<EOL><DEDENT><DEDENT>if struct['<STR_LIT>']:<EOL><INDENT>struct['<STR_LIT>'] = struct['<STR_LIT>'] = np.nan<EOL><DEDENT>else:<EOL><INDENT>fieldSide, ydline = _loc_to_features(struct.get('<STR_LIT:location>'))<EOL>struct['<STR_LIT>'] = fieldSide<EOL>struct['<STR_LIT>'] = ydline<EOL><DEDENT>if pd.notnull(struct.get('<STR_LIT>')):<EOL><INDENT>qtr = struct['<STR_LIT>']<EOL>mins, secs = map(int, struct['<STR_LIT>'].split('<STR_LIT::>'))<EOL>struct['<STR_LIT>'] = qtr * <NUM_LIT> - mins * <NUM_LIT> - secs<EOL><DEDENT>struct['<STR_LIT>'] = pd.notnull(struct.get('<STR_LIT>'))<EOL>struct['<STR_LIT>'] = pd.notnull(struct.get('<STR_LIT>'))<EOL>struct['<STR_LIT>'] = pd.notnull(struct.get('<STR_LIT>'))<EOL>struct['<STR_LIT>'] = struct['<STR_LIT>'] - struct['<STR_LIT>']<EOL>struct['<STR_LIT>'] = struct['<STR_LIT>'] - struct['<STR_LIT>']<EOL>return pd.Series(struct)<EOL>

Cleans up the features collected in parse_play_details.

    :struct: Pandas Series of features parsed from details string.
    :returns: the same dict, but with cleaner features (e.g., convert bools,
    ints, etc.)


if loc:<EOL><INDENT>if isinstance(loc, basestring):<EOL><INDENT>loc = loc.strip()<EOL>if '<STR_LIT:U+0020>' in loc:<EOL><INDENT>r = loc.split()<EOL>r[<NUM_LIT:0>] = r[<NUM_LIT:0>].lower()<EOL>r[<NUM_LIT:1>] = int(r[<NUM_LIT:1>])<EOL><DEDENT>else:<EOL><INDENT>r = (np.nan, int(loc))<EOL><DEDENT><DEDENT>elif isinstance(loc, float):<EOL><INDENT>return (np.nan, <NUM_LIT:50>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>r = (np.nan, np.nan)<EOL><DEDENT>return r<EOL>

Converts a location string "{Half}, {YardLine}" into a tuple of those
    values, the second being an int.

    :l: The string from the play by play table representing location.
    :returns: A tuple that separates out the values, making them missing
    (np.nan) when necessary.


features = features.to_dict('<STR_LIT>')<EOL>curTm = curOpp = None<EOL>playAfterKickoff = False<EOL>for row in features:<EOL><INDENT>if row['<STR_LIT>'] or playAfterKickoff:<EOL><INDENT>curTm, curOpp = _team_and_opp(row)<EOL><DEDENT>else:<EOL><INDENT>curTm, curOpp = _team_and_opp(row, curTm, curOpp)<EOL><DEDENT>row['<STR_LIT>'], row['<STR_LIT>'] = curTm, curOpp<EOL>playAfterKickoff = row['<STR_LIT>']<EOL><DEDENT>features = pd.DataFrame(features)<EOL>features.team.fillna(method='<STR_LIT>', inplace=True)<EOL>features.opp.fillna(method='<STR_LIT>', inplace=True)<EOL>features.team.fillna(method='<STR_LIT>', inplace=True)<EOL>features.opp.fillna(method='<STR_LIT>', inplace=True)<EOL>return features<EOL>

Function that adds 'team' and 'opp' columns to the features by iterating
    through the rows in order. A precondition is that the features dicts are in
    order in a continuous game sense and that all rows are from the same game.

    :features: A DataFrame with each row representing each play (in order).
    :returns: A similar DataFrame but with 'team' and 'opp' columns added.


def _team_and_opp(struct, curTm=None, curOpp=None):

<EOL>if pd.isnull(curTm):<EOL><INDENT>if struct['<STR_LIT>']:<EOL><INDENT>pID = struct['<STR_LIT>']<EOL><DEDENT>elif struct['<STR_LIT>']:<EOL><INDENT>pID = struct['<STR_LIT>']<EOL><DEDENT>elif struct['<STR_LIT>']:<EOL><INDENT>pID = struct['<STR_LIT>']<EOL><DEDENT>elif struct['<STR_LIT>']:<EOL><INDENT>pID = struct['<STR_LIT>']<EOL><DEDENT>elif struct['<STR_LIT>']:<EOL><INDENT>pID = struct['<STR_LIT>']<EOL><DEDENT>elif struct['<STR_LIT>']:<EOL><INDENT>pID = struct['<STR_LIT>']<EOL><DEDENT>elif struct['<STR_LIT>']:<EOL><INDENT>pID = struct['<STR_LIT>']<EOL><DEDENT>elif struct['<STR_LIT>']:<EOL><INDENT>pID = struct['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>pID = None<EOL><DEDENT>curTm = curOpp = np.nan<EOL>bs = sportsref.nfl.boxscores.BoxScore(struct['<STR_LIT>'])<EOL>if pID and len(pID) == <NUM_LIT:3>:<EOL><INDENT>curTm = pID<EOL>curOpp = bs.away() if bs.home() == curTm else bs.home()<EOL><DEDENT>elif pID:<EOL><INDENT>player = sportsref.nfl.Player(pID)<EOL>gamelog = player.gamelog(kind='<STR_LIT:B>')<EOL>curTm = gamelog.loc[<EOL>gamelog.boxscore_id == struct['<STR_LIT>'], '<STR_LIT>'<EOL>].item()<EOL>curOpp = bs.home() if bs.home() != curTm else bs.away()<EOL><DEDENT>return curTm, curOpp<EOL><DEDENT>if struct['<STR_LIT>']:<EOL><INDENT>return curOpp, curTm<EOL><DEDENT>else:<EOL><INDENT>return curTm, curOpp<EOL><DEDENT>

Given a dict representing a play and the current team with the ball,
    returns (team, opp) where team is the team with the ball and opp is the
    team without the ball at the end of the play.

    :struct: A Series/dict representing the play.
    :curTm: The current team with the ball; None means it's the first play of
    the game or the offensive team on the previous play's offensive team was
    somehow undetermined.
    :curOpp: The current team on defense; None means same as curTm.
    :returns: (team, opp) tuple where team and opp are the 3-character team IDs
    or the offensive and defensive teams respectively.


assert df.team.notnull().all()<EOL>homeOnOff = df['<STR_LIT>'] == df['<STR_LIT>']<EOL>df['<STR_LIT>'] = np.where(df['<STR_LIT>'] != df['<STR_LIT>'],<EOL>df['<STR_LIT>'], <NUM_LIT:100> - df['<STR_LIT>'])<EOL>df['<STR_LIT>'] = np.where(df['<STR_LIT>'] | df['<STR_LIT>'],<EOL><NUM_LIT:2>, df['<STR_LIT>'])<EOL>df['<STR_LIT>'] = np.where(homeOnOff, df['<STR_LIT>'], <NUM_LIT> - df['<STR_LIT>'])<EOL>df['<STR_LIT>'] = <NUM_LIT> - df['<STR_LIT>']<EOL>df['<STR_LIT>'] = np.where(homeOnOff, df['<STR_LIT>'], -df['<STR_LIT>'])<EOL>df['<STR_LIT>'] = -df['<STR_LIT>']<EOL>assert df['<STR_LIT>'].nunique() == <NUM_LIT:1><EOL>bs_id = df['<STR_LIT>'].values[<NUM_LIT:0>]<EOL>bs = sportsref.nfl.boxscores.BoxScore(bs_id)<EOL>df['<STR_LIT>'] = np.where(df['<STR_LIT>'] == bs.home(),<EOL>df['<STR_LIT>'], df['<STR_LIT>'])<EOL>df['<STR_LIT>'] = np.where(df['<STR_LIT>'] == bs.home(),<EOL>df['<STR_LIT>'], df['<STR_LIT>'])<EOL>return df<EOL>

Adds extra convenience features based on teams with and without
    possession, with the precondition that the there are 'team' and 'opp'
    specified in row.

    :df: A DataFrame representing a game's play-by-play data after
        _clean_features has been called and 'team' and 'opp' have been added by
        _add_team_columns.
    :returns: A dict with new features in addition to previous features.


global last_request_time<EOL>with throttle_process_lock:<EOL><INDENT>with throttle_thread_lock:<EOL><INDENT>wait_left = THROTTLE_DELAY - (time.time() - last_request_time.value)<EOL>if wait_left > <NUM_LIT:0>:<EOL><INDENT>time.sleep(wait_left)<EOL><DEDENT>response = requests.get(url)<EOL>last_request_time.value = time.time()<EOL><DEDENT><DEDENT>if <NUM_LIT> <= response.status_code < <NUM_LIT>:<EOL><INDENT>raise ValueError(<EOL>'<STR_LIT>'<EOL>.format(response.status_code, url)<EOL>)<EOL><DEDENT>html = response.text<EOL>html = html.replace('<STR_LIT>', '<STR_LIT>').replace('<STR_LIT>', '<STR_LIT>')<EOL>return html<EOL>

Gets the HTML for the given URL using a GET request.

    :url: the absolute URL of the desired page.
    :returns: a string of HTML.


def parse_table(table, flatten=True, footer=False):

if not len(table):<EOL><INDENT>return pd.DataFrame()<EOL><DEDENT>columns = [c.attrib['<STR_LIT>']<EOL>for c in table('<STR_LIT>')]<EOL>rows = list(table('<STR_LIT>' if not footer else '<STR_LIT>')<EOL>.not_('<STR_LIT>').items())<EOL>data = [<EOL>[flatten_links(td) if flatten else td.text()<EOL>for td in row.items('<STR_LIT>')]<EOL>for row in rows<EOL>]<EOL>df = pd.DataFrame(data, columns=columns, dtype='<STR_LIT:float>')<EOL>allClasses = set(<EOL>cls<EOL>for row in rows<EOL>if row.attr['<STR_LIT:class>']<EOL>for cls in row.attr['<STR_LIT:class>'].split()<EOL>)<EOL>for cls in allClasses:<EOL><INDENT>df['<STR_LIT>' + cls] = [<EOL>bool(row.attr['<STR_LIT:class>'] and<EOL>cls in row.attr['<STR_LIT:class>'].split())<EOL>for row in rows<EOL>]<EOL><DEDENT>df.drop(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'],<EOL>axis=<NUM_LIT:1>, inplace=True, errors='<STR_LIT:ignore>')<EOL>if '<STR_LIT>' in df.columns:<EOL><INDENT>df.rename(columns={'<STR_LIT>': '<STR_LIT>'}, inplace=True)<EOL>if flatten:<EOL><INDENT>df.year = df.year.fillna(method='<STR_LIT>')<EOL>df['<STR_LIT>'] = df.year.map(lambda s: str(s)[:<NUM_LIT:4>]).astype(int)<EOL><DEDENT><DEDENT>if '<STR_LIT>' in df.columns:<EOL><INDENT>df.rename(columns={'<STR_LIT>': '<STR_LIT>'}, inplace=True)<EOL><DEDENT>for bs_id_col in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>if bs_id_col in df.columns:<EOL><INDENT>df.rename(columns={bs_id_col: '<STR_LIT>'}, inplace=True)<EOL>break<EOL><DEDENT><DEDENT>df.replace(re.compile(r'<STR_LIT>', re.U), '<STR_LIT>', inplace=True)<EOL>for col in df.columns:<EOL><INDENT>if hasattr(df[col], '<STR_LIT:str>'):<EOL><INDENT>df[col] = df[col].str.strip()<EOL><DEDENT><DEDENT>if '<STR_LIT>' in df.columns:<EOL><INDENT>if flatten:<EOL><INDENT>df.rename(columns={'<STR_LIT>': '<STR_LIT>'}, inplace=True)<EOL>player_names = parse_table(table, flatten=False)['<STR_LIT>']<EOL>df['<STR_LIT>'] = player_names<EOL><DEDENT>else:<EOL><INDENT>df.rename(columns={'<STR_LIT>': '<STR_LIT>'}, inplace=True)<EOL><DEDENT><DEDENT>for team_col in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>if team_col in df.columns:<EOL><INDENT>df = df.loc[~df[team_col].isin(['<STR_LIT>'])]<EOL>if flatten:<EOL><INDENT>df.rename(columns={team_col: '<STR_LIT>'}, inplace=True)<EOL><DEDENT><DEDENT><DEDENT>if '<STR_LIT>' in df.columns and flatten:<EOL><INDENT>df['<STR_LIT>'] = df['<STR_LIT>'].astype(int)<EOL><DEDENT>if '<STR_LIT>' in df.columns and flatten:<EOL><INDENT>date_re = r'<STR_LIT>'<EOL>date_df = df['<STR_LIT>'].str.extract(date_re, expand=True)<EOL>if date_df.notnull().all(axis=<NUM_LIT:1>).any():<EOL><INDENT>df = pd.concat((df, date_df), axis=<NUM_LIT:1>)<EOL><DEDENT>else:<EOL><INDENT>df.rename(columns={'<STR_LIT>': '<STR_LIT>'}, inplace=True)<EOL><DEDENT><DEDENT>if '<STR_LIT>' in df.columns and flatten:<EOL><INDENT>df['<STR_LIT>'] = df['<STR_LIT>'].isnull()<EOL>df.rename(columns={'<STR_LIT>': '<STR_LIT>'}, inplace=True)<EOL><DEDENT>if '<STR_LIT>' in df.columns and df.dtypes['<STR_LIT>'] == object and flatten:<EOL><INDENT>mp_df = df['<STR_LIT>'].str.extract(<EOL>r'<STR_LIT>', expand=True).astype(float)<EOL>no_match = mp_df.isnull().all(axis=<NUM_LIT:1>)<EOL>if no_match.any():<EOL><INDENT>df.loc[no_match, '<STR_LIT>'] = df.loc[no_match, '<STR_LIT>']<EOL><DEDENT>df['<STR_LIT>'] = mp_df['<STR_LIT:m>'] + mp_df['<STR_LIT:s>'] / <NUM_LIT><EOL><DEDENT>def convert_to_float(val):<EOL><INDENT>m = re.search(r'<STR_LIT>',<EOL>val if isinstance(val, basestring) else str(val), re.U)<EOL>try:<EOL><INDENT>if m:<EOL><INDENT>return float(m.group(<NUM_LIT:1>)) / <NUM_LIT:100> if m else val<EOL><DEDENT>if m:<EOL><INDENT>return int(m.group(<NUM_LIT:1>)) + int(m.group(<NUM_LIT:2>)) / <NUM_LIT><EOL><DEDENT><DEDENT>except ValueError:<EOL><INDENT>return val<EOL><DEDENT>m = re.search(r'<STR_LIT>',<EOL>val if isinstance(val, basestring) else str(val), re.U)<EOL>try:<EOL><INDENT>if m:<EOL><INDENT>return float(re.sub(r'<STR_LIT>', '<STR_LIT>', val))<EOL><DEDENT><DEDENT>except Exception:<EOL><INDENT>return val<EOL><DEDENT>try:<EOL><INDENT>if isinstance(val, (int, bool)):<EOL><INDENT>return val<EOL><DEDENT>else:<EOL><INDENT>return float(val)<EOL><DEDENT><DEDENT>except Exception:<EOL><INDENT>return val<EOL><DEDENT><DEDENT>if flatten:<EOL><INDENT>df = df.applymap(convert_to_float)<EOL><DEDENT>df = df.loc[df.astype(bool).any(axis=<NUM_LIT:1>)]<EOL>return df<EOL>

Parses a table from sports-reference sites into a pandas dataframe.

    :param table: the PyQuery object representing the HTML table
    :param flatten: if True, flattens relative URLs to IDs. otherwise, leaves
        all fields as text without cleaning.
    :param footer: If True, returns the summary/footer of the page. Recommended
        to use this with flatten=False. Defaults to False.
    :returns: pd.DataFrame


ret = {}<EOL>for tr in list(table('<STR_LIT>').not_('<STR_LIT>').items()):<EOL><INDENT>th, td = list(tr('<STR_LIT>').items())<EOL>key = th.text().lower()<EOL>key = re.sub(r'<STR_LIT>', '<STR_LIT:_>', key)<EOL>val = sportsref.utils.flatten_links(td)<EOL>ret[key] = val<EOL><DEDENT>return ret<EOL>

Parses an info table, like the "Game Info" table or the "Officials"
    table on the PFR Boxscore page. Keys are lower case and have spaces/special
    characters converted to underscores.

    :table: PyQuery object representing the HTML table.
    :returns: A dictionary representing the information.


return [flatten_links(tr) for tr in list(table('<STR_LIT>').items())]<EOL>

Parses an awards table, like the "Pro Bowls" table on a PFR player page.

    :table: PyQuery object representing the HTML table.
    :returns: A list of the entries in the table, with flattened links.


<EOL>def _flatten_node(c):<EOL><INDENT>if isinstance(c, basestring):<EOL><INDENT>return c.strip()<EOL><DEDENT>elif '<STR_LIT>' in c.attrib:<EOL><INDENT>c_id = rel_url_to_id(c.attrib['<STR_LIT>'])<EOL>return c_id if c_id else c.text_content().strip()<EOL><DEDENT>else:<EOL><INDENT>return flatten_links(pq(c), _recurse=True)<EOL><DEDENT><DEDENT>if td is None or not td.text():<EOL><INDENT>return '<STR_LIT>' if _recurse else None<EOL><DEDENT>td.remove('<STR_LIT>')<EOL>return '<STR_LIT>'.join(_flatten_node(c) for c in td.contents())<EOL>

Flattens relative URLs within text of a table cell to IDs and returns
    the result.

    :td: the PyQuery object for the HTML to convert
    :returns: the string with the links flattened to IDs


yearRegex = r'<STR_LIT>'<EOL>playerRegex = r'<STR_LIT>'<EOL>boxscoresRegex = r'<STR_LIT>'<EOL>teamRegex = r'<STR_LIT>'<EOL>coachRegex = r'<STR_LIT>'<EOL>stadiumRegex = r'<STR_LIT>'<EOL>refRegex = r'<STR_LIT>'<EOL>collegeRegex = r'<STR_LIT>'<EOL>hsRegex = r'<STR_LIT>'<EOL>bsDateRegex = r'<STR_LIT>'<EOL>leagueRegex = r'<STR_LIT>'<EOL>awardRegex = r'<STR_LIT>'<EOL>regexes = [<EOL>yearRegex,<EOL>playerRegex,<EOL>boxscoresRegex,<EOL>teamRegex,<EOL>coachRegex,<EOL>stadiumRegex,<EOL>refRegex,<EOL>collegeRegex,<EOL>hsRegex,<EOL>bsDateRegex,<EOL>leagueRegex,<EOL>awardRegex,<EOL>]<EOL>for regex in regexes:<EOL><INDENT>match = re.match(regex, url, re.I)<EOL>if match:<EOL><INDENT>return [_f for _f in match.groups() if _f][<NUM_LIT:0>]<EOL><DEDENT><DEDENT>if any(<EOL>url.startswith(s) for s in<EOL>(<EOL>'<STR_LIT>',<EOL>)<EOL>):<EOL><INDENT>return url<EOL><DEDENT>print('<STR_LIT>'.format(url))<EOL>return url<EOL>

Converts a relative URL to a unique ID.

    Here, 'ID' refers generally to the unique ID for a given 'type' that a
    given datum has. For example, 'BradTo00' is Tom Brady's player ID - this
    corresponds to his relative URL, '/players/B/BradTo00.htm'. Similarly,
    '201409070dal' refers to the boxscore of the SF @ DAL game on 09/07/14.

    Supported types:
    * player/...
    * boxscores/...
    * teams/...
    * years/...
    * leagues/...
    * awards/...
    * coaches/...
    * officials/...
    * schools/...
    * schools/high_schools.cgi?id=...

    :returns: ID associated with the given relative URL.


def decorator(func):<EOL><INDENT>@funcutils.wraps(func)<EOL>def wrapper(*args, **kwargs):<EOL><INDENT>orig_cwd = os.getcwd()<EOL>os.chdir(dirPath)<EOL>ret = func(*args, **kwargs)<EOL>os.chdir(orig_cwd)<EOL>return ret<EOL><DEDENT>return wrapper<EOL><DEDENT>return decorator<EOL>

Decorator that switches to given directory before executing function, and
then returning to orignal directory.


CACHE_DIR = appdirs.user_cache_dir('<STR_LIT>', getpass.getuser())<EOL>if not os.path.isdir(CACHE_DIR):<EOL><INDENT>os.makedirs(CACHE_DIR)<EOL><DEDENT>@funcutils.wraps(func)<EOL>def wrapper(url):<EOL><INDENT>file_hash = hashlib.md5()<EOL>encoded_url = url.encode(errors='<STR_LIT:replace>')<EOL>file_hash.update(encoded_url)<EOL>file_hash = file_hash.hexdigest()<EOL>filename = '<STR_LIT>'.format(CACHE_DIR, file_hash)<EOL>sport_id = None<EOL>for a_base_url, a_sport_id in sportsref.SITE_ABBREV.items():<EOL><INDENT>if url.startswith(a_base_url):<EOL><INDENT>sport_id = a_sport_id<EOL>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>print('<STR_LIT>'.format(url))<EOL><DEDENT>file_exists = os.path.isfile(filename)<EOL>if sport_id and file_exists:<EOL><INDENT>cur_time = int(time.time())<EOL>mod_time = int(os.path.getmtime(filename))<EOL>days_since_mod = datetime.timedelta(seconds=(cur_time - mod_time)).days<EOL>days_cache_valid = globals()['<STR_LIT>'.format(sport_id)](url)<EOL>cache_is_valid = days_since_mod < days_cache_valid<EOL><DEDENT>else:<EOL><INDENT>cache_is_valid = False<EOL><DEDENT>allow_caching = sportsref.get_option('<STR_LIT>')<EOL>if file_exists and cache_is_valid and allow_caching:<EOL><INDENT>with codecs.open(filename, '<STR_LIT:r>', encoding='<STR_LIT:utf-8>', errors='<STR_LIT:replace>') as f:<EOL><INDENT>text = f.read()<EOL><DEDENT><DEDENT>else:<EOL><INDENT>text = func(url)<EOL>with codecs.open(filename, '<STR_LIT>', encoding='<STR_LIT:utf-8>') as f:<EOL><INDENT>f.write(text)<EOL><DEDENT><DEDENT>return text<EOL><DEDENT>return wrapper<EOL>

Caches the HTML returned by the specified function `func`. Caches it in
    the user cache determined by the appdirs package.


def get_class_instance_key(cls, args, kwargs):

l = [id(cls)]<EOL>for arg in args:<EOL><INDENT>l.append(id(arg))<EOL><DEDENT>l.extend((k, id(v)) for k, v in kwargs.items())<EOL>return tuple(sorted(l))<EOL>

Returns a unique identifier for a class instantiation.


@funcutils.wraps(fun)<EOL>def wrapper(*args, **kwargs):<EOL><INDENT>do_memoization = sportsref.get_option('<STR_LIT>')<EOL>if not do_memoization:<EOL><INDENT>return fun(*args, **kwargs)<EOL><DEDENT>hash_args = tuple(args)<EOL>hash_kwargs = frozenset(sorted(kwargs.items()))<EOL>key = (hash_args, hash_kwargs)<EOL>def _copy(v):<EOL><INDENT>if isinstance(v, pq):<EOL><INDENT>return v.clone()<EOL><DEDENT>else:<EOL><INDENT>return copy.deepcopy(v)<EOL><DEDENT><DEDENT>try:<EOL><INDENT>ret = _copy(cache[key])<EOL>return ret<EOL><DEDENT>except KeyError:<EOL><INDENT>cache[key] = fun(*args, **kwargs)<EOL>ret = _copy(cache[key])<EOL>return ret<EOL><DEDENT>except TypeError:<EOL><INDENT>print('<STR_LIT>'<EOL>.format(fun.__name__, key))<EOL>raise<EOL><DEDENT><DEDENT>cache = {}<EOL>return wrapper<EOL>

A decorator for memoizing functions.

    Only works on functions that take simple arguments - arguments that take
    list-like or dict-like arguments will not be memoized, and this function
    will raise a TypeError.


def _assert_file_event(self, event, name, flags=aionotify.Flags.CREATE, alias=None):

if alias is None:<EOL><INDENT>alias = self.testdir<EOL><DEDENT>self.assertEqual(name, event.name)<EOL>self.assertEqual(flags, event.flags)<EOL>self.assertEqual(alias, event.alias)<EOL>

Check for an expected file event.

        Allows for more readable tests.


task = self.watcher.get_event()<EOL>try:<EOL><INDENT>result = yield from asyncio.wait_for(task, timeout, loop=self.loop)<EOL><DEDENT>except asyncio.TimeoutError:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>raise AssertionError("<STR_LIT>" % (result, timeout))<EOL><DEDENT>

Ensure that no events are left in the queue.


def watch(self, path, flags, *, alias=None):

if alias is None:<EOL><INDENT>alias = path<EOL><DEDENT>if alias in self.requests:<EOL><INDENT>raise ValueError("<STR_LIT>" % alias)<EOL><DEDENT>self.requests[alias] = (path, flags)<EOL>if self._fd is not None:<EOL><INDENT>self._setup_watch(alias, path, flags)<EOL><DEDENT>


if alias not in self.descriptors:<EOL><INDENT>raise ValueError("<STR_LIT>" % (alias, list(self.descriptors.keys())))<EOL><DEDENT>wd = self.descriptors[alias]<EOL>errno = LibC.inotify_rm_watch(self._fd, wd)<EOL>if errno != <NUM_LIT:0>:<EOL><INDENT>raise IOError("<STR_LIT>" % (wd, errno))<EOL><DEDENT>del self.descriptors[alias]<EOL>del self.requests[alias]<EOL>del self.aliases[wd]<EOL>


def _setup_watch(self, alias, path, flags):

assert alias not in self.descriptors, "<STR_LIT>" % alias<EOL>wd = LibC.inotify_add_watch(self._fd, path, flags)<EOL>if wd < <NUM_LIT:0>:<EOL><INDENT>raise IOError("<STR_LIT>" % (<EOL>path, flags, wd))<EOL><DEDENT>self.descriptors[alias] = wd<EOL>self.aliases[wd] = alias<EOL>


self._loop = loop<EOL>self._fd = LibC.inotify_init()<EOL>for alias, (path, flags) in self.requests.items():<EOL><INDENT>self._setup_watch(alias, path, flags)<EOL><DEDENT>self._stream, self._transport = yield from aioutils.stream_from_fd(self._fd, loop)<EOL>

Start the watcher, registering new watches if any.


self._transport.close()<EOL>self._reset()<EOL>

Schedule closure.

        This will close the transport and all related resources.


return self._transport is None<EOL>


while True:<EOL><INDENT>prefix = yield from self._stream.readexactly(PREFIX.size)<EOL>if prefix == b'<STR_LIT>':<EOL><INDENT>return<EOL><DEDENT>wd, flags, cookie, length = PREFIX.unpack(prefix)<EOL>path = yield from self._stream.readexactly(length)<EOL>if wd not in self.aliases:<EOL><INDENT>continue<EOL><DEDENT>decoded_path = struct.unpack('<STR_LIT>' % length, path)[<NUM_LIT:0>].rstrip(b'<STR_LIT:\x00>').decode('<STR_LIT:utf-8>')<EOL>return Event(<EOL>flags=flags,<EOL>cookie=cookie,<EOL>name=decoded_path,<EOL>alias=self.aliases[wd],<EOL>)<EOL><DEDENT>

Fetch an event.

        This coroutine will swallow events for removed watches.


reader = asyncio.StreamReader(loop=loop)<EOL>protocol = asyncio.StreamReaderProtocol(reader, loop=loop)<EOL>waiter = asyncio.futures.Future(loop=loop)<EOL>transport = UnixFileDescriptorTransport(<EOL>loop=loop,<EOL>fileno=fd,<EOL>protocol=protocol,<EOL>waiter=waiter,<EOL>)<EOL>try:<EOL><INDENT>yield from waiter<EOL><DEDENT>except Exception:<EOL><INDENT>transport.close()<EOL><DEDENT>if loop.get_debug():<EOL><INDENT>logger.debug("<STR_LIT>", fd, transport, protocol)<EOL><DEDENT>return reader, transport<EOL>

Recieve a streamer for a given file descriptor.


try:<EOL><INDENT>data = os.read(self._fileno, self.max_size)<EOL><DEDENT>except InterruptedError:<EOL><INDENT>pass<EOL><DEDENT>except OSError as exc:<EOL><INDENT>self._fatal_error(exc, "<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>if data:<EOL><INDENT>self._protocol.data_received(data)<EOL><DEDENT>else:<EOL><INDENT>if self._loop.get_debug():<EOL><INDENT>logger.info("<STR_LIT>", self)<EOL><DEDENT>self._closing = False<EOL>self.pause_reading()<EOL>self._loop.call_soon(self._protocol.eof_received)<EOL>self._loop.call_soon(self._call_connection_lost, None)<EOL><DEDENT><DEDENT>

Called by the event loop whenever the fd is ready for reading.


self._loop.remove_reader(self._fileno)<EOL>self._active = False<EOL>

Public API: pause reading the transport.


self._loop.add_reader(self._fileno, self._read_ready)<EOL>self._active = True<EOL>


if not self._closing:<EOL><INDENT>self._close()<EOL><DEDENT>


self._closing = True<EOL>self.pause_reading()<EOL>self._loop.call_soon(self._call_connection_lost, error)<EOL>

Actual closing code, both from manual close and errors.


try:<EOL><INDENT>self._protocol.connection_lost(error)<EOL><DEDENT>finally:<EOL><INDENT>os.close(self._fileno)<EOL>self._fileno = None<EOL>self._protocol = None<EOL>self._loop = None<EOL><DEDENT>


PyFunceble.load_config(True)<EOL>PyFunceble.INTERN["<STR_LIT>"] = "<STR_LIT>"<EOL>self.file = (<EOL>PyFunceble.CURRENT_DIRECTORY<EOL>+ PyFunceble.OUTPUTS["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>self.expected_content = {<EOL>PyFunceble.INTERN["<STR_LIT>"]: {<EOL>"<STR_LIT>": ["<STR_LIT>", "<STR_LIT>"],<EOL>"<STR_LIT>": ["<STR_LIT>"],<EOL>}<EOL>}<EOL>self.time_past = str(int(PyFunceble.time()) - (<NUM_LIT> * <NUM_LIT> * <NUM_LIT>))<EOL>self.time_future = str(int(PyFunceble.time()) + (<NUM_LIT> * <NUM_LIT> * <NUM_LIT>))<EOL>


PyFunceble.INTERN["<STR_LIT>"] = "<STR_LIT>"<EOL>self.file = (<EOL>PyFunceble.CURRENT_DIRECTORY<EOL>+ PyFunceble.OUTPUTS["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>self.expected_content = {<EOL>PyFunceble.INTERN["<STR_LIT>"]: {<EOL>"<STR_LIT>": {<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT:state>": "<STR_LIT>",<EOL>},<EOL>"<STR_LIT>": {<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT:state>": "<STR_LIT>",<EOL>},<EOL>}<EOL>}<EOL>


Load(PyFunceble.CURRENT_DIRECTORY)<EOL>BaseStdout.setUp(self)<EOL>PyFunceble.CONFIGURATION["<STR_LIT>"] = True<EOL>PyFunceble.INTERN["<STR_LIT:start>"] = int(PyFunceble.time())<EOL>PyFunceble.INTERN["<STR_LIT:end>"] = int(PyFunceble.time()) + <NUM_LIT:15><EOL>


PyFunceble.load_config(True)<EOL>PyFunceble.CONFIGURATION["<STR_LIT>"] = True<EOL>PyFunceble.INTERN["<STR_LIT>"] = "<STR_LIT>"<EOL>self.file = (<EOL>PyFunceble.CURRENT_DIRECTORY + PyFunceble.OUTPUTS["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>self.excepted_content = {<EOL>PyFunceble.INTERN["<STR_LIT>"]: {<EOL>"<STR_LIT>": ["<STR_LIT>", "<STR_LIT>"]<EOL>}<EOL>}<EOL>


PyFunceble.CONFIGURATION["<STR_LIT>"] = False<EOL>

Setup every we do not need after the test.


Load(PyFunceble.CURRENT_DIRECTORY)<EOL>self.file_to_work_with = (<EOL>PyFunceble.OUTPUT_DIRECTORY<EOL>+ PyFunceble.OUTPUTS["<STR_LIT>"]<EOL>+ PyFunceble.OUTPUTS["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>PyFunceble.INTERN["<STR_LIT>"] = "<STR_LIT>"<EOL>self.types = ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>"]<EOL>


for string in self.types:<EOL><INDENT>PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"].update({string: to_set})<EOL><DEDENT>

Set the counter at a given number.

Argument:
    - to_set: int
        The number to set to every counter.


Load(PyFunceble.CURRENT_DIRECTORY)<EOL>self.file = (<EOL>PyFunceble.OUTPUT_DIRECTORY<EOL>+ PyFunceble.OUTPUTS["<STR_LIT>"]<EOL>+ "<STR_LIT>"<EOL>)<EOL>self.types = ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>"]<EOL>


Set the counters to the desired number.

Argument:
    - to_set: int
        The number to set to each counter


sys.stdout = StringIO()<EOL>


PyFunceble.load_config(True)<EOL>PyFunceble.INTERN["<STR_LIT>"] = "<STR_LIT>"<EOL>PyFunceble.INTERN["<STR_LIT>"] = "<STR_LIT>"<EOL>


self.file = "<STR_LIT>"<EOL>self.data_to_write = ["<STR_LIT>", "<STR_LIT>"]<EOL>self.expected_hashed = {<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": "<STR_LIT>",  <EOL>"<STR_LIT>": "<STR_LIT>",  <EOL>}<EOL>


self.main_list = ["<STR_LIT:hello>", "<STR_LIT>", <NUM_LIT:5>, {"<STR_LIT:hello>": "<STR_LIT>"}, [<NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:3>]]<EOL>


self.to_test = {<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": {"<STR_LIT>", "<STR_LIT:hello>"},<EOL>"<STR_LIT>": ["<STR_LIT>", "<STR_LIT>"],<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": ["<STR_LIT>"],<EOL>}<EOL>


self.data_list = [<EOL>"<STR_LIT:hello>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>]<EOL>self.data = "<STR_LIT>"<EOL>


PyFunceble.load_config(True)<EOL>self.types = ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>"]<EOL>

Setup everything that is needed for the test.


for string in self.types:<EOL><INDENT>PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"].update({string: <NUM_LIT:15>})<EOL><DEDENT>


PyFunceble.initiate(True)<EOL>PyFunceble.load_config(True)<EOL>BaseStdout.setUp(self)<EOL>logo =


PyFunceble.load_config(True)<EOL>self.domains = [<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>]<EOL>

Setup everything that is needed for the tests.


PyFunceble.load_config(True)<EOL>self.exception_message = "<STR_LIT>"<EOL>


PyFunceble.load_config(True)<EOL>self.file = "<STR_LIT>"<EOL>self.to_print = {<EOL>"<STR_LIT>": {"<STR_LIT:hello>": <NUM_LIT:5>, "<STR_LIT>": <NUM_LIT:6>, "<STR_LIT>": <NUM_LIT:7>, "<STR_LIT>": <NUM_LIT:8>, "<STR_LIT>": <NUM_LIT:10>},<EOL>"<STR_LIT>": [<NUM_LIT:5>, <NUM_LIT:6>, <NUM_LIT:7>, <NUM_LIT:8>, <NUM_LIT:9>, <NUM_LIT:10>],<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": {"<STR_LIT>": <NUM_LIT:7>, "<STR_LIT>": <NUM_LIT:11>},<EOL>}<EOL>


if "<STR_LIT>" not in PyFunceble.INTERN or not PyFunceble.INTERN["<STR_LIT>"]:<EOL><INDENT>PyFunceble.INTERN["<STR_LIT>"] = self.iana_db<EOL><DEDENT>

Initiate the IANA database if it is not the case.


<EOL>iana_record = self.lookup.whois(<EOL>PyFunceble.CONFIGURATION["<STR_LIT>"], "<STR_LIT>" % extension<EOL>)<EOL>if iana_record and "<STR_LIT>" in iana_record:<EOL><INDENT>regex_referer = r"<STR_LIT>"<EOL>matched = Regex(<EOL>iana_record, regex_referer, return_data=True, group=<NUM_LIT:1><EOL>).match()<EOL>if matched:<EOL><INDENT>return matched<EOL><DEDENT><DEDENT>if extension in self.manual_server:<EOL><INDENT>return self.manual_server[extension]<EOL><DEDENT>return None<EOL>

Return the referer for the given extension.

:param extension: A valid domain extension.
:type extension: str

:return: The whois server to use to get the WHOIS record.
:rtype: str


upstream_lines = (<EOL>Download(self.iana_url, return_data=True)<EOL>.text()<EOL>.split('<STR_LIT>')<EOL>)<EOL>regex_valid_extension = r"<STR_LIT>"<EOL>for block in upstream_lines:<EOL><INDENT>if "<STR_LIT>" in block:<EOL><INDENT>matched = Regex(<EOL>block, regex_valid_extension, return_data=True, rematch=True<EOL>).match()[<NUM_LIT:1>]<EOL>if matched:<EOL><INDENT>referer = self._referer(matched)<EOL>yield (matched, referer)<EOL><DEDENT><DEDENT><DEDENT>

Extract the extention from the given block.
Plus get its referer.


if not PyFunceble.CONFIGURATION["<STR_LIT>"]:<EOL><INDENT>print("<STR_LIT>", end="<STR_LIT:U+0020>")<EOL><DEDENT>for extension, referer in self._extensions():<EOL><INDENT>if extension not in self.iana_db or self.iana_db[extension] != referer:<EOL><INDENT>self.iana_db[extension] = referer<EOL>Dict(self.iana_db).to_json(self.destination)<EOL><DEDENT><DEDENT>if not PyFunceble.CONFIGURATION["<STR_LIT>"]:<EOL><INDENT>print(PyFunceble.INTERN["<STR_LIT>"])<EOL><DEDENT>

Update the content of the `iana-domains-db` file.


Get the HTTP code status.

:return: The matched HTTP status code.
:rtype: int|None


if PyFunceble.HTTP_CODE["<STR_LIT>"]:<EOL><INDENT>http_code = self._access()<EOL>list_of_valid_http_code = []<EOL>for codes in [<EOL>PyFunceble.HTTP_CODE["<STR_LIT:list>"]["<STR_LIT>"],<EOL>PyFunceble.HTTP_CODE["<STR_LIT:list>"]["<STR_LIT>"],<EOL>PyFunceble.HTTP_CODE["<STR_LIT:list>"]["<STR_LIT>"],<EOL>]:<EOL><INDENT>list_of_valid_http_code.extend(codes)<EOL><DEDENT>if http_code not in list_of_valid_http_code or http_code is None:<EOL><INDENT>return "<STR_LIT:*>" * <NUM_LIT:3><EOL><DEDENT>return http_code<EOL><DEDENT>return None<EOL>

Return the HTTP code status.

:return: The matched and formatted status code.
:rtype: str|int|None


if not path_to_config.endswith(PyFunceble.directory_separator):<EOL><INDENT>default = parsed = path_to_config + PyFunceble.directory_separator<EOL><DEDENT>else:<EOL><INDENT>default = parsed = path_to_config<EOL><DEDENT>parsed += PyFunceble.CONFIGURATION_FILENAME<EOL>default += PyFunceble.DEFAULT_CONFIGURATION_FILENAME<EOL>return (parsed, default)<EOL>

Set the paths to the configuration files.

:param path_to_config: The possible path to the config to load.
:type path_to_config: str

:return:
    The path to the config to read (0), the path to the default
    configuration to read as fallback.(1)
:rtype: tuple


<EOL>production_config_link = "<STR_LIT>"  <EOL>production_config_link = Version(True).right_url_from_version(<EOL>production_config_link<EOL>)<EOL>if not Version(True).is_cloned():<EOL><INDENT>Download(production_config_link, self.path_to_default_config).text()<EOL><DEDENT>return Download(production_config_link, self.path_to_config).text()<EOL>

Download the production configuration and install it in the
current directory.


<EOL>iana_link = PyFunceble.CONFIGURATION["<STR_LIT>"]["<STR_LIT>"]<EOL>iana_link = Version(True).right_url_from_version(iana_link)<EOL>destination = PyFunceble.CURRENT_DIRECTORY + "<STR_LIT>"<EOL>if not Version(True).is_cloned() or not PyFunceble.path.isfile(destination):<EOL><INDENT>return Download(iana_link, destination).text()<EOL><DEDENT>return None<EOL>

Download `iana-domains-db.json` if not present.


<EOL>psl_link = PyFunceble.CONFIGURATION["<STR_LIT>"]["<STR_LIT>"]<EOL>psl_link = Version(True).right_url_from_version(psl_link)<EOL>destination = (<EOL>PyFunceble.CURRENT_DIRECTORY<EOL>+ PyFunceble.CONFIGURATION["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>if not Version(True).is_cloned() or not PyFunceble.path.isfile(destination):<EOL><INDENT>return Download(psl_link, destination).text()<EOL><DEDENT>return None<EOL>

Download `public-suffix.json` if not present.


<EOL>dir_structure_link = PyFunceble.CONFIGURATION["<STR_LIT>"]["<STR_LIT>"]<EOL>dir_structure_link = Version(True).right_url_from_version(dir_structure_link)<EOL>destination = (<EOL>PyFunceble.CURRENT_DIRECTORY<EOL>+ PyFunceble.CONFIGURATION["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>if not Version(True).is_cloned() or not PyFunceble.path.isfile(destination):<EOL><INDENT>data = Download(dir_structure_link, destination, return_data=True).text()<EOL>File(destination).write(data, overwrite=True)<EOL>return True<EOL><DEDENT>return None<EOL>

Download the latest version of `dir_structure_production.json`.


to_remove = []<EOL>self.new_config = Dict(<EOL>Dict(self.upstream_config).merge(PyFunceble.CONFIGURATION)<EOL>).remove_key(to_remove)<EOL>

Simply merge the older into the new one.


Dict(self.new_config).to_yaml(self.path_to_config)<EOL>

Save the new configuration inside the configuration file.


if "<STR_LIT>" not in PyFunceble.environ:<EOL><INDENT>while True:<EOL><INDENT>response = input(<EOL>PyFunceble.Style.BRIGHT<EOL>+ PyFunceble.Fore.RED<EOL>+ "<STR_LIT>"<EOL>+ PyFunceble.Fore.RESET<EOL>+ "<STR_LIT>"<EOL>% (<EOL>PyFunceble.Style.BRIGHT<EOL>+ self.path_to_config<EOL>+ PyFunceble.Style.RESET_ALL<EOL>)<EOL>)<EOL>if isinstance(response, str):<EOL><INDENT>if response.lower() == "<STR_LIT:y>":<EOL><INDENT>self._merge_values()<EOL>self._save()<EOL>print(<EOL>PyFunceble.Style.BRIGHT + PyFunceble.Fore.GREEN + "<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>)<EOL>break<EOL><DEDENT>elif response.lower() == "<STR_LIT:n>":<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>self._merge_values()<EOL>self._save()<EOL><DEDENT>


@classmethod<EOL><INDENT>def split_versions(cls, version, return_non_digits=False):<DEDENT>

<EOL>splited_version = version.split("<STR_LIT:.>")<EOL>digits = [x for x in splited_version if x.isdigit()]<EOL>if not return_non_digits:<EOL><INDENT>return digits<EOL><DEDENT>non_digits = [x for x in splited_version if not x.isdigit()]<EOL>return (digits, non_digits[<NUM_LIT:0>])<EOL>

Convert the versions to a shorter one.

:param version: The version to split.
:type version: str

:param return_non_digits:
    Activate the return of the non-digits parts of the splitted
    version.
:type return_non_digits: bool

:return: The splitted version name/numbers.
:rtype: list


@classmethod<EOL><INDENT>def check_versions_literally(cls, local, upstream):<DEDENT>

return local == upstream<EOL>

Compare the given versions literally.

:param local: The local version converted by split_versions().
:type local: str

:param upstream: The upstream version converted by split_versions().
:type upstream: str

:return:
    - True: local == upstream
    - False: local != upstream
:rtype: bool


@classmethod<EOL><INDENT>def check_versions(cls, local, upstream):<DEDENT>

<EOL>status = [None, None, None]<EOL>for index, version_number in enumerate(local):<EOL><INDENT>if int(version_number) < int(upstream[index]):<EOL><INDENT>status[index] = True<EOL><DEDENT>elif int(version_number) > int(upstream[index]):<EOL><INDENT>status[index] = False<EOL><DEDENT><DEDENT>if False in status:<EOL><INDENT>return False<EOL><DEDENT>if True in status:<EOL><INDENT>return True<EOL><DEDENT>return None<EOL>

Compare the given versions.

:param local: The local version converted by split_versions().
:type local: list

:param upstream: The upstream version converted by split_versions().
:type upstream: list

:return:
    - True: local < upstream
    - None: local == upstream
    - False: local > upstream
:rtype: bool|None


if self.upstream_data["<STR_LIT>"]["<STR_LIT:status>"]:<EOL><INDENT>for minimal in self.upstream_data["<STR_LIT>"]["<STR_LIT>"]:<EOL><INDENT>checked = self.check_versions(<EOL>self.local_splited, self.split_versions(minimal)<EOL>)<EOL>if not PyFunceble.CONFIGURATION["<STR_LIT>"]:<EOL><INDENT>if checked or checked is not False and not checked:<EOL><INDENT>message = (<EOL>PyFunceble.Style.BRIGHT<EOL>+ PyFunceble.Fore.RED<EOL>+ "<STR_LIT>"<EOL>+ PyFunceble.Style.RESET_ALL<EOL>)  <EOL>message += (<EOL>PyFunceble.Style.BRIGHT<EOL>+ PyFunceble.Fore.GREEN<EOL>+ "<STR_LIT>"<EOL>+ PyFunceble.Style.RESET_ALL<EOL>)  <EOL>print(message)<EOL>exit(<NUM_LIT:1>)<EOL><DEDENT><DEDENT>elif checked or checked is not False and not checked:<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>"  <EOL>)<EOL><DEDENT><DEDENT><DEDENT>for version in self.upstream_data["<STR_LIT>"]:<EOL><INDENT>checked = self.check_versions(<EOL>self.local_splited, self.split_versions(version)<EOL>)<EOL>if (<EOL>not PyFunceble.CONFIGURATION["<STR_LIT>"]<EOL>and checked<EOL>or checked is not False<EOL>and not checked<EOL>):<EOL><INDENT>message = (<EOL>PyFunceble.Style.BRIGHT<EOL>+ PyFunceble.Fore.RED<EOL>+ "<STR_LIT>"<EOL>+ PyFunceble.Style.RESET_ALL<EOL>)  <EOL>message += (<EOL>PyFunceble.Style.BRIGHT<EOL>+ PyFunceble.Fore.GREEN<EOL>+ "<STR_LIT>"<EOL>+ PyFunceble.Style.RESET_ALL<EOL>)  <EOL>print(message)<EOL>return<EOL><DEDENT>if checked or checked is not False and not checked:<EOL><INDENT>print("<STR_LIT>")<EOL>return<EOL><DEDENT><DEDENT>status = self.check_versions(<EOL>self.local_splited,<EOL>self.split_versions(self.upstream_data["<STR_LIT>"]),<EOL>)<EOL>if status is not None and not status and not PyFunceble.CONFIGURATION["<STR_LIT>"]:<EOL><INDENT>message = (<EOL>PyFunceble.Style.BRIGHT<EOL>+ PyFunceble.Fore.CYAN<EOL>+ "<STR_LIT>"  <EOL>+ PyFunceble.Style.RESET_ALL<EOL>)<EOL>message += (<EOL>PyFunceble.Style.BRIGHT<EOL>+ "<STR_LIT>"<EOL>+ PyFunceble.Style.RESET_ALL<EOL>+ PyFunceble.VERSION<EOL>+ "<STR_LIT:\n>"<EOL>)<EOL>message += (<EOL>PyFunceble.Style.BRIGHT<EOL>+ "<STR_LIT>"<EOL>+ PyFunceble.Style.RESET_ALL<EOL>+ self.upstream_data["<STR_LIT>"]<EOL>+ "<STR_LIT:\n>"<EOL>)<EOL>print(message)<EOL><DEDENT>elif status:<EOL><INDENT>if not PyFunceble.CONFIGURATION["<STR_LIT>"]:<EOL><INDENT>message = (<EOL>PyFunceble.Style.BRIGHT<EOL>+ PyFunceble.Fore.YELLOW<EOL>+ "<STR_LIT>"<EOL>+ PyFunceble.Style.RESET_ALL<EOL>)  <EOL>message += (<EOL>PyFunceble.Style.BRIGHT<EOL>+ "<STR_LIT>"<EOL>+ PyFunceble.Style.RESET_ALL<EOL>+ PyFunceble.VERSION<EOL>+ "<STR_LIT:\n>"<EOL>)  <EOL>message += (<EOL>PyFunceble.Style.BRIGHT<EOL>+ "<STR_LIT>"<EOL>+ PyFunceble.Style.RESET_ALL<EOL>+ self.upstream_data[  <EOL>"<STR_LIT>"<EOL>]<EOL>+ "<STR_LIT:\n>"<EOL>)<EOL>print(message)<EOL><DEDENT>else:<EOL><INDENT>print("<STR_LIT>")<EOL><DEDENT><DEDENT>return<EOL>

Compare the current version with the upstream saved version.


if not PyFunceble.path.isdir("<STR_LIT>"):<EOL><INDENT>return False<EOL><DEDENT>list_of_file = [<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>]<EOL>list_of_dir = ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>"]<EOL>for file in list_of_file:<EOL><INDENT>if not PyFunceble.path.isfile(file):<EOL><INDENT>return False<EOL><DEDENT><DEDENT>for directory in list_of_dir:<EOL><INDENT>if not PyFunceble.path.isdir(directory):<EOL><INDENT>return False<EOL><DEDENT><DEDENT>return True<EOL>

Let us know if we are currently in the cloned version of
PyFunceble which implicitly mean that we are in developement mode.


if "<STR_LIT>" in PyFunceble.VERSION:<EOL><INDENT>return url.replace("<STR_LIT>", "<STR_LIT>")<EOL><DEDENT>return url.replace("<STR_LIT>", "<STR_LIT>")<EOL>

Convert the GitHub URL to the right one depending of the
branch or version we are working with.

:param url: The URL to convert.
:type url: str

:return: The converted URL.
:rtype: str


if (<EOL>not PyFunceble.CONFIGURATION["<STR_LIT>"]<EOL>and self.output<EOL>and not PyFunceble.path.isfile(self.output)<EOL>):<EOL><INDENT>link = "<STR_LIT>" % PyFunceble.LINKS["<STR_LIT>"]<EOL>date_of_generation = (<EOL>"<STR_LIT>" % PyFunceble.CURRENT_TIME<EOL>)<EOL>authorized_templates = [<EOL>"<STR_LIT>",<EOL>PyFunceble.STATUS["<STR_LIT>"]["<STR_LIT>"],<EOL>PyFunceble.STATUS["<STR_LIT>"]["<STR_LIT>"],<EOL>PyFunceble.STATUS["<STR_LIT>"]["<STR_LIT>"],<EOL>PyFunceble.STATUS["<STR_LIT>"]["<STR_LIT>"],<EOL>"<STR_LIT>",<EOL>]<EOL>if self.template in authorized_templates:<EOL><INDENT>header = (<EOL>self._header_constructor(self.currently_used_header, None)[<NUM_LIT:0>] + "<STR_LIT:\n>"<EOL>)<EOL><DEDENT>try:<EOL><INDENT>File(self.output).write(link + date_of_generation + header)<EOL><DEDENT>except UnboundLocalError:<EOL><INDENT>File(self.output).write(link + date_of_generation)<EOL><DEDENT><DEDENT>

Print informations about PyFunceble and the date of generation of a file
into a given path, if doesn't exist.


@classmethod<EOL><INDENT>def _header_constructor(<EOL>cls, data_to_print, header_separator="<STR_LIT:->", column_separator="<STR_LIT:U+0020>"<EOL>):<DEDENT>

<EOL>header_data = []<EOL>header_size = "<STR_LIT>"<EOL>before_size = "<STR_LIT>"<EOL>after_size = "<STR_LIT:s>"<EOL>if header_separator:<EOL><INDENT>header_separator_data = []<EOL><DEDENT>length_data_to_print = len(data_to_print) - <NUM_LIT:1><EOL>i = <NUM_LIT:0><EOL>for data in data_to_print:<EOL><INDENT>size = data_to_print[data]<EOL>header_data.append(data)<EOL>header_size += before_size + str(size) + after_size<EOL>if i < length_data_to_print:<EOL><INDENT>header_size += column_separator<EOL><DEDENT>if header_separator:<EOL><INDENT>header_separator_data.append(header_separator * size)<EOL><DEDENT>i += <NUM_LIT:1><EOL><DEDENT>if header_separator:<EOL><INDENT>return [<EOL>header_size % tuple(header_data),<EOL>header_size % tuple(header_separator_data),<EOL>]<EOL><DEDENT>return [header_size % tuple(header_data)]<EOL>

Construct header of the table according to template.

:param data_to_print:
    The list of data to print into the header of the table.
:type data_to_print: list

:param header_separator:
    The separator to use between the table header and our data.
:type header_separator: str

:param colomn_separator: The separator to use between each colomns.
:type colomn_separator: str

:return: The data to print in a list format.
:rtype: list


if (<EOL>not PyFunceble.CONFIGURATION["<STR_LIT>"]<EOL>or self.template == "<STR_LIT>"<EOL>or do_not_print<EOL>):<EOL><INDENT>if (<EOL>self.template.lower() in PyFunceble.STATUS["<STR_LIT:list>"]["<STR_LIT>"]<EOL>or self.template == "<STR_LIT>"<EOL>):<EOL><INDENT>to_print = self.headers["<STR_LIT>"]<EOL>if (<EOL>self.template.lower() in PyFunceble.STATUS["<STR_LIT:list>"]["<STR_LIT>"]<EOL>and PyFunceble.HTTP_CODE["<STR_LIT>"]<EOL>):<EOL><INDENT>to_print = Dict(to_print).remove_key("<STR_LIT>")<EOL><DEDENT><DEDENT>elif self.template.lower() in PyFunceble.STATUS["<STR_LIT:list>"]["<STR_LIT>"]:<EOL><INDENT>to_print = self.headers[PyFunceble.STATUS["<STR_LIT>"]["<STR_LIT>"]]<EOL><DEDENT>elif self.template.lower() in PyFunceble.STATUS["<STR_LIT:list>"]["<STR_LIT>"]:<EOL><INDENT>to_print = self.headers[PyFunceble.STATUS["<STR_LIT>"]["<STR_LIT>"]]<EOL><DEDENT>elif self.template.lower() in PyFunceble.STATUS["<STR_LIT:list>"]["<STR_LIT>"]:<EOL><INDENT>to_print = self.headers[PyFunceble.STATUS["<STR_LIT>"]["<STR_LIT>"]]<EOL><DEDENT>elif self.template.lower() in PyFunceble.STATUS["<STR_LIT:list>"]["<STR_LIT>"]:<EOL><INDENT>to_print = self.headers[PyFunceble.STATUS["<STR_LIT>"]["<STR_LIT>"]]<EOL><DEDENT>elif (<EOL>self.template == "<STR_LIT>"<EOL>or self.template == "<STR_LIT>"<EOL>or self.template == "<STR_LIT>"<EOL>):  <EOL><INDENT>to_print = self.headers[self.template]<EOL>if self.template == "<STR_LIT>" and not PyFunceble.HTTP_CODE["<STR_LIT>"]:<EOL><INDENT>to_print["<STR_LIT>"] = <NUM_LIT:10><EOL><DEDENT><DEDENT>if not PyFunceble.HTTP_CODE["<STR_LIT>"]:<EOL><INDENT>to_print = Dict(to_print).remove_key("<STR_LIT>")<EOL><DEDENT>self.currently_used_header = to_print<EOL>if not do_not_print:<EOL><INDENT>self._before_header()<EOL>for formatted_template in self._header_constructor(to_print):<EOL><INDENT>if not self.only_on_file:<EOL><INDENT>print(formatted_template)<EOL><DEDENT>if not PyFunceble.CONFIGURATION["<STR_LIT>"] and self.output:<EOL><INDENT>File(self.output).write(formatted_template + "<STR_LIT:\n>")<EOL><DEDENT><DEDENT><DEDENT><DEDENT>

Management and creation of templates of header.
Please consider as "header" the title of each columns.

:param do_not_print:
    Tell us if we have to print the header or not.
:type do_not_print: bool


<EOL>result = PyFunceble.OrderedDict()<EOL>if len(self.data_to_print) == len(size):<EOL><INDENT>for i in range(len(self.data_to_print)):<EOL><INDENT>result[self.data_to_print[i]] = size[i]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>" + str(len(self.data_to_print)) + "<STR_LIT>" + str(len(size))<EOL>)<EOL><DEDENT>return result<EOL>

Construct the table of data according to given size.

:param size: The maximal length of each string in the table.
:type size: list

:return:
    A dict with all information about the data and how to which what
    maximal size to print it.
:rtype: OrderedDict

:raises:
    :code:`Exception`
        If the data and the size does not have the same length.


<EOL>result = []<EOL>for data in header:<EOL><INDENT>result.append(header[data])<EOL><DEDENT>return result<EOL>

Get the size of each columns from the header.

:param header:
    The header template we have to get the size from.
:type header: dict

:return: The maximal size of the each data to print.
:rtype: list


if self.template in ["<STR_LIT>", "<STR_LIT>"]:<EOL><INDENT>if (<EOL>self.data_to_print[<NUM_LIT:1>].lower() in PyFunceble.STATUS["<STR_LIT:list>"]["<STR_LIT>"]<EOL>or self.data_to_print[<NUM_LIT:1>].lower() in PyFunceble.STATUS["<STR_LIT:list>"]["<STR_LIT>"]<EOL>):<EOL><INDENT>data = PyFunceble.Fore.BLACK + PyFunceble.Back.GREEN + data<EOL><DEDENT>elif self.data_to_print[<NUM_LIT:1>].lower() in PyFunceble.STATUS["<STR_LIT:list>"]["<STR_LIT>"]:<EOL><INDENT>data = PyFunceble.Fore.BLACK + PyFunceble.Back.RED + data<EOL><DEDENT>else:<EOL><INDENT>data = PyFunceble.Fore.BLACK + PyFunceble.Back.CYAN + data<EOL><DEDENT><DEDENT>return data<EOL>

Retun colored string.

:param data: The string to colorify.
:type data: str

:return: A colored string.
:rtype: str


if self.output:<EOL><INDENT>if PyFunceble.path.isfile(self.output):<EOL><INDENT>content = Dict().from_json(File(self.output).read())<EOL>if isinstance(content, list):<EOL><INDENT>content.extend(self.data_to_print)<EOL>content = List(content).custom_format(Sort.standard)<EOL>if PyFunceble.CONFIGURATION["<STR_LIT>"]:<EOL><INDENT>content = List(content).custom_format(Sort.hierarchical)<EOL><DEDENT>Dict(content).to_json(self.output)<EOL><DEDENT>else:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT><DEDENT>else:<EOL><INDENT>Dict(self.data_to_print).to_json(self.output)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>


if isinstance(self.data_to_print, list):<EOL><INDENT>to_print = {}<EOL>to_print_size = []<EOL>alone_cases = ["<STR_LIT>", "<STR_LIT>"]<EOL>without_header = ["<STR_LIT>", "<STR_LIT>"]<EOL>if self.template.lower() == "<STR_LIT>":<EOL><INDENT>if not PyFunceble.CONFIGURATION["<STR_LIT>"] and self.output:<EOL><INDENT>return self._json_print()<EOL><DEDENT>return None<EOL><DEDENT>if self.template not in alone_cases and self.template not in without_header:<EOL><INDENT>self.header(True)<EOL>to_print_size = self._size_from_header(self.currently_used_header)<EOL><DEDENT>elif self.template in without_header:<EOL><INDENT>for data in self.data_to_print:<EOL><INDENT>to_print_size.append(str(len(data)))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>to_print_size = self._size_from_header(self.headers[self.template])<EOL><DEDENT>to_print = self._data_constructor(to_print_size)<EOL>self._before_header()<EOL>for data in self._header_constructor(to_print, False):<EOL><INDENT>if self.template.lower() in PyFunceble.STATUS["<STR_LIT:list>"][<EOL>"<STR_LIT>"<EOL>] or self.template in ["<STR_LIT>", "<STR_LIT>"]:<EOL><INDENT>if not self.only_on_file:<EOL><INDENT>colorified_data = self._colorify(data)<EOL>print(colorified_data)<EOL><DEDENT><DEDENT>if not PyFunceble.CONFIGURATION["<STR_LIT>"] and self.output:<EOL><INDENT>File(self.output).write(data + "<STR_LIT:\n>")<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>

Management and input of data to the table.

:raises:
    :code:`Exception`
        When self.data_to_print is not a list.


<EOL>directory = PyFunceble.OUTPUT_DIRECTORY + PyFunceble.OUTPUTS["<STR_LIT>"]<EOL>if not directory.endswith(PyFunceble.directory_separator):  <EOL><INDENT>directory += PyFunceble.directory_separator<EOL><DEDENT>result = []<EOL>for root, _, files in PyFunceble.walk(directory):<EOL><INDENT>for file in files:<EOL><INDENT>if file not in ["<STR_LIT>", "<STR_LIT>"]:<EOL><INDENT>if root.endswith(PyFunceble.directory_separator):<EOL><INDENT>result.append(root + file)<EOL><DEDENT>else:<EOL><INDENT>result.append(<EOL>root + PyFunceble.directory_separator + file<EOL>)  <EOL><DEDENT><DEDENT><DEDENT><DEDENT>return result<EOL>


@classmethod<EOL><INDENT>def databases_to_delete(cls):  <DEDENT>

<EOL>directory = PyFunceble.CURRENT_DIRECTORY<EOL>result = []<EOL>result.append(<EOL>directory<EOL>+ PyFunceble.CONFIGURATION["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>result.append(<EOL>directory + PyFunceble.CONFIGURATION["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>result.append(<EOL>directory<EOL>+ PyFunceble.CONFIGURATION["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>result.append(<EOL>directory<EOL>+ PyFunceble.CONFIGURATION["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>result.append(<EOL>directory + PyFunceble.CONFIGURATION["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>result.append(<EOL>directory + PyFunceble.CONFIGURATION["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>return result<EOL>


<EOL>to_delete = self.file_to_delete()<EOL>if clean_all:  <EOL><INDENT>to_delete.extend(self.databases_to_delete())<EOL><DEDENT>for file in to_delete:<EOL><INDENT>File(file).delete()<EOL><DEDENT>if clean_all:  <EOL><INDENT>Load(PyFunceble.CURRENT_DIRECTORY)<EOL><DEDENT>

Delete almost all discovered files.

:param clean_all:
    Tell the subsystem if we have to clean everything instesd
    of almost everything.
:type clean_all: bool


if self.status:<EOL><INDENT>PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"] += <NUM_LIT:1><EOL>if (<EOL>self.status.lower() in PyFunceble.STATUS["<STR_LIT:list>"]["<STR_LIT>"]<EOL>or self.status.lower() in PyFunceble.STATUS["<STR_LIT:list>"]["<STR_LIT>"]<EOL>):<EOL><INDENT>PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"] += <NUM_LIT:1><EOL><DEDENT>elif self.status.lower() in PyFunceble.STATUS["<STR_LIT:list>"]["<STR_LIT>"]:<EOL><INDENT>PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"] += <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"] += <NUM_LIT:1><EOL><DEDENT><DEDENT>

Count the number of domain for each status.


<EOL>percentages = {<EOL>"<STR_LIT>": PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"],<EOL>"<STR_LIT>": PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"],<EOL>"<STR_LIT>": PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"],<EOL>}<EOL>for percentage in percentages:<EOL><INDENT>calculation = (<EOL>percentages[percentage]<EOL>* <NUM_LIT:100><EOL>// PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"].update({percentage: calculation})<EOL><DEDENT>

Calculate the percentage of each status.


if (<EOL>PyFunceble.CONFIGURATION["<STR_LIT>"]<EOL>and PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"] > <NUM_LIT:0><EOL>):<EOL><INDENT>output = (<EOL>PyFunceble.OUTPUT_DIRECTORY<EOL>+ PyFunceble.OUTPUTS["<STR_LIT>"]<EOL>+ PyFunceble.OUTPUTS["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>+ PyFunceble.OUTPUTS["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>+ PyFunceble.OUTPUTS["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]<EOL>)<EOL>File(output).delete()<EOL>self._calculate()<EOL>if not PyFunceble.CONFIGURATION["<STR_LIT>"]:<EOL><INDENT>print("<STR_LIT:\n>")<EOL>Prints(None, "<STR_LIT>", output).header()<EOL>lines_to_print = [<EOL>[<EOL>PyFunceble.STATUS["<STR_LIT>"]["<STR_LIT>"],<EOL>str(PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]) + "<STR_LIT:%>",<EOL>PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"],<EOL>],<EOL>[<EOL>PyFunceble.STATUS["<STR_LIT>"]["<STR_LIT>"],<EOL>str(PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"]) + "<STR_LIT:%>",<EOL>PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"],<EOL>],<EOL>[<EOL>PyFunceble.STATUS["<STR_LIT>"]["<STR_LIT>"],<EOL>str(PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"])<EOL>+ "<STR_LIT:%>",<EOL>PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"],<EOL>],<EOL>]<EOL>if PyFunceble.CONFIGURATION["<STR_LIT>"]:<EOL><INDENT>lines_to_print[<NUM_LIT:0>][<NUM_LIT:0>] = PyFunceble.STATUS["<STR_LIT>"]["<STR_LIT>"]<EOL>del lines_to_print[<NUM_LIT:1>]<EOL><DEDENT>for to_print in lines_to_print:<EOL><INDENT>Prints(to_print, "<STR_LIT>", output).data()<EOL><DEDENT><DEDENT><DEDENT>elif PyFunceble.INTERN["<STR_LIT>"]["<STR_LIT>"]["<STR_LIT>"] > <NUM_LIT:0>:<EOL><INDENT>self._calculate()<EOL><DEDENT>

Print on screen and on file the percentages for each status.


if PyFunceble.CONFIGURATION["<STR_LIT>"]:<EOL><INDENT>try:<EOL><INDENT>build_dir = PyFunceble.environ["<STR_LIT>"]<EOL>commands = [<EOL>"<STR_LIT>" % (build_dir),<EOL>"<STR_LIT>" % (build_dir),<EOL>"<STR_LIT>" % (build_dir),<EOL>"<STR_LIT>"<EOL>% (build_dir + PyFunceble.directory_separator),<EOL>r"<STR_LIT>" % (build_dir),<EOL>]<EOL>for command in commands:<EOL><INDENT>Command(command).execute()<EOL><DEDENT>if Command("<STR_LIT>").execute() == "<STR_LIT>":<EOL><INDENT>Command("<STR_LIT>").execute()<EOL><DEDENT><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>

Set permissions in order to avoid issues before commiting.