Exemplo n.º 1
0
def get_oprs(session, event, mod_since=None):
    """Retrieves OPR, DPR, and CCWM for each team at an event.

    Args:
        session (tbap.api.Session):
            An instance of tbap.api.Session that contains
            a valid username and authorization key.
        event (str):
            A key value specifying the competition year and event.
        mod_since (str):
            A string containing an HTTP formatted date and time.
            Optional.

    Returns:
        A pandas.Dataframe object or a Python dictionary object.

    """
    http_args = ["event", event, "oprs"]
    data = server.send_http_request(session, http_args, mod_since)
    if session.data_format != "dataframe" or data["code"] != 200:
        return data

    jdata = json.loads(data["text"])
    col_names = ["team"] + list(jdata.keys())
    cols = collections.OrderedDict([(col, []) for col in col_names])
    for team in jdata["oprs"].keys():
        cols["team"].append(team)
        for col in jdata.keys():
            cols[col].append(jdata[col][team])
    dframe = pandas.DataFrame(cols).set_index("team")
    return server.attach_attributes(dframe, data)
Exemplo n.º 2
0
def get_district_points(session, event, mod_since=None):
    """ Retrieves district points earned at an FRC competition.

    Args:
        session (tbap.api.Session):
            An instance of tbap.api.Session that contains
            a valid username and authorization key.
        event (str):
            A key value specifying the competition year and event.
        mod_since (str):
            A string containing an HTTP formatted date and time.
            Optional.

    Returns:
        A dictionary of pandas.Dataframe objects or a Python dictionary
        object. The keys ofthe dictionary are *points* and
        *high_scores*.
    """
    http_args = ["event", event, "district_points"]
    data = server.send_http_request(session, http_args, mod_since)
    if session.data_format != "dataframe" or data["code"] != 200:
        return data

    jdata = json.loads(data["text"])

    # District Points
    df_points = pandas.read_json(json.dumps(jdata["points"]), orient="index")

    # High Scores
    rows = []
    for team, tdata in jdata["tiebreakers"].items():
        idx = 1
        for score in tdata["highest_qual_scores"]:
            row = {
                "team": team,
                "highest_qual_score": score,
                "score_rank": idx
            }
            idx += 1
            row["qual_wins"] = tdata["qual_wins"]
            rows.append(row)
    df_high_scores = pandas.DataFrame(rows).set_index(["team"])

    results = {"points": df_points, "high_scores": df_high_scores}
    return {
        key: server.attach_attributes(value, data)
        for key, value in results.items()
    }
Exemplo n.º 3
0
def get_event_rankings(session, event, mod_since=None):
    """Retrieves team rankings for a specific event.

    Args:
        session (tbap.api.Session):
            An instance of tbap.api.Session that contains
            a valid username and authorization key.
        event (str):
            A key value specifying the competition year and event.
        mod_since (str):
            A string containing an HTTP formatted date and time.
            Optional.

    Returns:
        A pandas.Dataframe object or a Python dictionary object.
    """
    http_args = ["event", event, "rankings"]
    data = server.send_http_request(session, http_args, mod_since)
    if session.data_format != "dataframe" or data["code"] != 200:
        return data

    jdata = json.loads(data["text"])
    sort_order = list(map(lambda x: x["name"], jdata["sort_order_info"]))
    extra_stats = list(map(lambda x: x["name"], jdata["extra_stats_info"]))
    rec_stat = ["wins", "losses", "ties"]
    rankings = jdata["rankings"]
    rows = []
    for rank in rankings:
        row = {}
        for key, val in rank.items():
            if not isinstance(val, dict) and not isinstance(val, list):
                row[key] = val
        for stat in rec_stat:
            row[stat] = rank["record"][stat]
        for idx in range(len(sort_order)):
            row[sort_order[idx]] = rank["sort_orders"][idx]
        for idx in range(len(extra_stats)):
            row[extra_stats[idx]] = rank["extra_stats"][idx]
        rows.append(row)

    df = pandas.DataFrame(rows).set_index(["rank"])
    df.columns = map(lambda x: re.sub("team_key", "team", x), df.columns)

    # Put columns in a logical order
    sorted_cols = ["team", "matches_played"
                   ] + extra_stats + sort_order + rec_stat
    other_cols = [col for col in df.columns if col not in sorted_cols]
    return server.attach_attributes(df[sorted_cols + other_cols], data)
Exemplo n.º 4
0
def send_request(session, http_args, normalize, index=None, mod_since=None):
    """Routes data request to correct internal functions.

    Args:
        session:
            An instance of tbap.classes.Session that contains
            a valid username and authorization key.
        http_args:
            A Python list of parameters that will be added to the http
            request.
        normalize (str):
            Specifies which alorithm will be used to convert and
            normalize the JSON data into a pandas dataframe.
        mod_since:
            A string containing an HTTP formatted date and time.
            Causes function to return None if no changes have been
            made to the requested data since the date and time provided.
            Optional.

    Returns:
        Either a pandas.Dataframe object (if session.data_format =
        "dataframe") or a Python dictionary.

    """
    http_response = server.send_http_request(session, http_args, mod_since)
    if session.data_format != "dataframe" or http_response["code"] != 200:
        return http_response
    else:
        if normalize == "table":
            frame = dframe.build_table(http_response)
        elif normalize == "single_column":
            frame = dframe.build_single_column(http_response["text"])
    if index is not None:
        try:
            frame.set_index(index, inplace=True)
        except KeyError:
            pass  # Skip setting the index if index columns not in dataframe.
    return server.attach_attributes(frame, http_response)
Exemplo n.º 5
0
def get_event_team_status(session, event, team, series=False, mod_since=None):
    """Retrieves team rankings for a specific event.

    Args:
        session (tbap.api.Session):
            An instance of tbap.api.Session that contains
            a valid username and authorization key.
        event (str):
            A key value specifying the competition year and event.
        team (str):
            The four digit FRC team number as an integer.
        series (boolean):
            If True, returns a pandas series instead of a dataframe.
            Optional. Default is False.
        mod_since (str):
            A string containing an HTTP formatted date and time.
            Optional.

    Returns:
        A pandas.Dataframe object or a Python dictionary object.
    """
    http_args = ["team", team, "event", event, "status"]
    data = server.send_http_request(session, http_args, mod_since)
    if session.data_format != "dataframe" or data["code"] != 200:
        return data
    jdata = json.loads(data["text"])
    if team is not None:
        sort_order = list(
            map(lambda x: re.sub(" ", "_", x["name"]),
                jdata["qual"]["sort_order_info"]))
        sort_data = jdata["qual"]["ranking"]["sort_orders"]
        for idx, field in enumerate(sort_order):
            jdata["qual"]["ranking"][field] = sort_data[idx]
        del (jdata["qual"]["sort_order_info"])
        del (jdata["qual"]["ranking"]["sort_orders"])
        df = dframe.build_single_column(jdata, series)
        return server.attach_attributes(df, data)
Exemplo n.º 6
0
def get_insights(session, event, mod_since=None):
    """

    Args:
        session (tbap.api.Session):
            An instance of tbap.api.Session that contains
            a valid username and authorization key.
        event (str):
            A key value specifying the competition year and event.
        mod_since (str):
            A string containing an HTTP formatted date and time.
            Optional.

    Returns:
        A pandas.Dataframe object or a Python dictionary object.

    """
    http_args = ["event", event, "insights"]

    data = server.send_http_request(session, http_args, mod_since)
    if session.data_format != "dataframe" or data["code"] != 200:
        return data

    jdata = json.loads(data["text"])
    rows = []
    for lvl in jdata.keys():
        for key, val in jdata[lvl].items():
            if isinstance(val, list):
                row = {"level": lvl, "statistic": key}
                for idx in range(len(val)):
                    row["value_" + str(idx)] = val[idx]
                rows.append(row)
            else:
                rows.append({"level": lvl, "statistic": key, "value_0": val})

    dframe = pandas.DataFrame(rows).set_index(["level", "statistic"])
    return server.attach_attributes(dframe, data)
Exemplo n.º 7
0
def get_predictions(session, event, mod_since=None):
    """ Retrieves predictions regarding team performance.

    Args:
        session (tbap.api.Session):
            An instance of tbap.api.Session that contains
            a valid username and authorization key.
        event (str):
            A key value specifying the competition year and event.
        mod_since (str):
            A string containing an HTTP formatted date and time.
            Optional.

    Returns:
        A dictionary of pandas.Dataframe objects or a Python dictionary
        object. The keys ofthe dictionary are *event_stats*,
        *team_stats*, *predictions*, and *team_rankings*.
    """
    http_args = ["event", event, "predictions"]
    data = server.send_http_request(session, http_args, mod_since)
    if session.data_format != "dataframe" or data["code"] != 200:
        return data

    jdata = json.loads(data["text"])
    frames = {key: None for key in ["stats", "matches", "teams"]}

    # Match Prediction Stats
    rows = []
    for lvl in jdata["match_prediction_stats"].keys():
        for key, val in jdata["match_prediction_stats"][lvl].items():
            if isinstance(val, dict):
                for sub_key, sub_val in val.items():
                    rows.append({
                        "level": lvl,
                        "statistic": key + "_" + sub_key,
                        "value": sub_val
                    })
            else:
                rows.append({"level": lvl, "statistic": key, "value": val})
    stats_frame = pandas.DataFrame(rows).set_index(["level", "statistic"])

    # Match Predictions
    rows = []
    jdata_predictions = jdata["match_predictions"]
    for lvl in jdata_predictions.keys():
        for match_key, match_data in jdata_predictions[lvl].items():
            for alliance in ["red", "blue"]:
                for stat_lbl, stat_val in match_data[alliance].items():
                    rows.append({
                        "level": lvl,
                        "match": match_key,
                        "alliance": alliance,
                        "statistic": stat_lbl,
                        "value": stat_val
                    })
            rows.append({
                "level": lvl,
                "match": match_key,
                "statistic": "prob",
                "value": match_data["prob"]
            })
            rows.append({
                "level": lvl,
                "match": match_key,
                "statistic": "winning_alliance",
                "value": match_data["winning_alliance"]
            })

    prediction_frame = pandas.DataFrame(rows).set_index(
        ["level", "match", "alliance", "statistic"])

    # Ranking Predictions
    jdata_ranks = jdata["ranking_predictions"]
    rows = []
    for team in jdata_ranks:
        rows.append({
            "team": team[0],
            "rank": team[1][0],
            "points": team[1][4]
        })
    rank_frame = pandas.DataFrame(rows).set_index("team")

    # Team Predictions
    jdata_teams = jdata["stat_mean_vars"]
    levels = list(jdata_teams.keys())
    stats = list(jdata_teams[levels[0]].keys())
    points = list(jdata_teams[levels[0]][stats[0]].keys())
    teams = list(jdata_teams[levels[0]][stats[0]][points[0]].keys())
    rows = []
    for team in teams:
        for lvl, lvl_data in jdata_teams.items():
            for stat, stat_data in lvl_data.items():
                for point, point_data in stat_data.items():
                    rows.append({
                        "team": team,
                        "level": lvl,
                        "statistic": stat,
                        "point": point,
                        "value": point_data[team]
                    })
    teams_frame = pandas.DataFrame(rows).set_index(
        ["team", "statistic", "point", "level"])

    results = {
        "event_stats": stats_frame,
        "predictions": prediction_frame,
        "team_rankings": rank_frame,
        "team_stats": teams_frame
    }
    return {
        key: server.attach_attributes(value, data)
        for key, value in results.items()
    }
Exemplo n.º 8
0
def get_alliances(session, event, mod_since=None):
    """Retrieves data for each playoff alliance.

    Args:
        session (tbap.api.Session):
            An instance of tbap.api.Session that contains
            a valid username and authorization key.
        event (str):
            A key value specifying the competition year and event.
        mod_since (str):
            A string containing an HTTP formatted date and time.
            Optional.
    Returns:
        A pandas.Dataframe object or a Python dictionary object.
    """
    http_args = ["event", event, "alliances"]

    data = server.send_http_request(session, http_args, mod_since)
    if session.data_format != "dataframe" or data["code"] != 200:
        return data

    jdata = json.loads(data["text"])
    alli_dct = collections.OrderedDict()
    alli_dct["name"] = []
    alli_dct["team"] = []
    alli_dct["backup"] = []
    alli_dct["status"] = []
    alli_dct["declines"] = []
    alli_dct["level"] = []
    alli_dct["playoff_average"] = []
    alli_dct["current_level_wins"] = []
    alli_dct["current_level_losses"] = []
    alli_dct["current_level_ties"] = []
    alli_dct["overall_wins"] = []
    alli_dct["overall_losses"] = []
    alli_dct["overall_ties"] = []

    def append_rank_data(alliance, team):
        alli_dct["name"].append(alliance["name"])
        alli_dct["team"].append(team)
        if alliance["backup"] is not None:
            if alliance["backup"]["out"] == team:
                alli_dct["backup"].append("out")
            elif alliance["backup"]["in"] == team:
                alli_dct["backup"].append("in")
            else:
                alli_dct["backup"].append(False)
        else:
            alli_dct["backup"].append(False)
        alli_dct["status"].append(alliance["status"]["status"])
        alli_dct["declines"].append(str(alliance["declines"]))
        alli_dct["level"].append(alliance["status"]["level"])
        alli_dct["playoff_average"].append(
            alliance["status"]["playoff_average"])
        for stat in ["wins", "losses", "ties"]:
            alli_dct["current_level_" + stat].append(
                alliance["status"]["current_level_record"][stat])
            alli_dct["overall_" + stat].append(
                alliance["status"]["record"][stat])

    for curr_alliance in jdata:
        for curr_team in curr_alliance["picks"]:
            append_rank_data(curr_alliance, curr_team)
        if curr_alliance["backup"] is not None:
            append_rank_data(curr_alliance, curr_alliance["backup"]["in"])

    df = pandas.DataFrame(alli_dct).set_index(["name", "team"])
    return server.attach_attributes(df, data)
Exemplo n.º 9
0
def get_matches(session,
                event=None,
                team=None,
                year=None,
                match=None,
                response="full",
                mod_since=None):
    """Returns detailed information on competition matches.

    The allowed combinations of optional arguments are *event*,
    *team* and *event*, *team* and *year*, and *match*. This function
    will raise an error if any other combinations of arguments are
    provided.

    Args:
        session (tbap.api.Session):
            An instance of tbap.api.Session that contains
            a valid username and authorization key.
        event (str):
            A key value specifying the competition year and event.
        team (str):
            The four digit FRC team number as an integer.
        year (int or str):
            Specifies for which year to return team http_data. Optional.
        match (str):
            The key value for the desired match. The key value has the
            format "YYYY{EventCode}_{CompetitionLevel}NNN" where YYYY
            is the four digit year and NN is the match number with no
            leading zeros. For example, *2017wasno_qm79* is the 79th
            qualification match at the 2017 district competition at
            Glacier Peak High School in Snohomish, WA.
        response (str):
            Either "full" (default), "simple", or "keys". Optional.
        mod_since (str):
            A string containing an HTTP formatted date and time.
            Optional.

    Returns:
        A pandas.Dataframe object or a Python dictionary object. All
        columnes with time data contain pandas.Timestamp objects. All
        times are in universal coordinated time (UTC).

    Raises:
        tbap.Classes.ArgumentError: If any unallowed combinations of
        arguments are provided to the function.
    """
    if event is not None and team is None and year is None and match is None:
        http_args = ["event", event, "matches"]
    elif (team is not None and event is not None and year is None
          and match is None):
        http_args = ["team", team, "event", event, "matches"]
    elif (team is not None and year is not None and event is None
          and match is None):
        http_args = ["team", team, "matches", year]
    elif (match is not None and event is None and team is None and year is None
          and response in ["full", "simple"]):
        http_args = ["match", match]
    else:
        raise server.ArgumentError("Incorrect Arguments")
    if response.lower() in ["simple", "keys"]:
        http_args.append(response.lower())
    http_data = server.send_http_request(session, http_args, mod_since)
    if session.data_format != "dataframe" or http_data["code"] != 200:
        return http_data

    if response.lower() == "keys":
        df = dframe.build_table(http_data)
        df.columns = ["key"]
        return server.attach_attributes(df, http_data)

    # Convert nested JSON text into a flat dataframe
    jdata = json.loads(http_data["text"])
    if not isinstance(jdata, list):
        jdata = [jdata]  # TBA returns single match when match arg used

    def extract_match(mtch, team_key, alliance, surrogate):
        output = collections.OrderedDict([
            ("team_key", team_key), ("alliance", alliance),
            ("surrogate", surrogate),
            ("score", mtch["alliances"][alliance]["score"])
        ])
        if team_key in mtch["alliances"][alliance]["dq_team_keys"]:
            output["disqualified"] = True
        else:
            output["disqualified"] = False
        for key, val in mtch.items():
            if not isinstance(val, list) and not isinstance(val, dict):
                output[key] = val
        if "score_breakdown" in mtch and mtch["score_breakdown"] is not None:
            for key, val in mtch["score_breakdown"][alliance].items():
                output[key] = val
        return output

    matches = []
    for indv_match in jdata:
        for team in indv_match["alliances"]["blue"]["team_keys"]:
            matches.append(extract_match(indv_match, team, "blue", False))
        for team in indv_match["alliances"]["blue"]["surrogate_team_keys"]:
            matches.append(extract_match(indv_match, team, "blue", True))
        for team in indv_match["alliances"]["red"]["team_keys"]:
            matches.append(extract_match(indv_match, team, "red", False))
        for team in indv_match["alliances"]["red"]["surrogate_team_keys"]:
            matches.append(extract_match(indv_match, team, "red", True))

    df = pandas.DataFrame(matches)
    if "score_breakdown" in df.columns:
        df.drop("score_breakdown", 1, inplace=True)

    for col in [x for x in df.columns if re.search("time$", x) is not None]:
        ts = pandas.to_datetime(df[col], unit="s")
        df[col] = ts.dt.tz_localize("UTC").dt.tz_convert(session.time_zone)

    df.set_index(["key", "team_key"], inplace=True)

    return server.attach_attributes(df, http_data,
                                    {"timezone": str(session.time_zone)})