import%20marimo%0A%0A__generated_with%20%3D%20%220.18.4%22%0Aapp%20%3D%20marimo.App(width%3D%22full%22)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20%23%20marimo%20notebook%0A%0A%20%20%20%20%23%20object%20handling%0A%20%20%20%20import%20attrs%0A%0A%20%20%20%20%23%20data%20handling%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20polars%20as%20pl%0A%0A%20%20%20%20%23%20plotting%0A%20%20%20%20from%20matplotlib%20import%20pyplot%20as%20plt%0A%20%20%20%20import%20seaborn%20as%20sns%0A%20%20%20%20from%20great_tables%20import%20GT%0A%0A%20%20%20%20%23%20pinsdb%20module%0A%20%20%20%20from%20pinsdb.models%20import%20Game%0A%20%20%20%20from%20pinsdb.namespace.expressions%20import%20Bowling%20%20%23%20noqa%3A%20F401%0A%20%20%20%20return%20GT%2C%20Game%2C%20attrs%2C%20pd%2C%20pl%2C%20plt%2C%20sns%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(Game%2C%20attrs%2C%20pl)%3A%0A%20%20%20%20%23%20define%20bowlers%20to%20include%20in%20%60bowler_frame%60%0A%20%20%20%20BOWLERS%3A%20tuple%5Bstr%5D%20%3D%20(%0A%20%20%20%20%20%20%20%20%22Cam%22%2C%0A%20%20%20%20%20%20%20%20%22Ryley%22%2C%0A%20%20%20%20%20%20%20%20%22Spencer%22%2C%0A%20%20%20%20%20%20%20%20%22Lucas%22%2C%0A%20%20%20%20%20%20%20%20%23%20%22Alek%22%2C%0A%20%20%20%20%20%20%20%20%23%20%22Jake%22%2C%0A%20%20%20%20%20%20%20%20%23%20%22Munson%22%2C%0A%20%20%20%20%20%20%20%20%23%20%22Tristan%22%2C%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20games%20stored%20as%20a%20Python%20object%0A%20%20%20%20all_games%20%3D%20sorted(%0A%20%20%20%20%20%20%20%20Game.load_games()%2C%20key%3Dlambda%20g%3A%20(g.date%2C%20g.game_id%2C%20g.bowler.bowler_id)%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20games%20stored%20as%20a%20Polars%20DataFrame%0A%20%20%20%20bowler_frame%20%3D%20(%0A%20%20%20%20%20%20%20%20pl.DataFrame(%5Battrs.asdict(game)%20for%20game%20in%20all_games%5D)%0A%20%20%20%20%20%20%20%20.with_columns(pl.col(%22bowler%22).struct.field(%22bowler_id%22))%0A%20%20%20%20%20%20%20%20.sort(%22date%22%2C%20%22game_id%22)%0A%20%20%20%20%20%20%20%20.drop(%22bowler%22)%0A%20%20%20%20%20%20%20%20.filter(pl.col(%22bowler_id%22).is_in(BOWLERS))%0A%20%20%20%20)%0A%20%20%20%20return%20(bowler_frame%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(bowler_frame%2C%20pl)%3A%0A%20%20%20%20ranks%20%3D%20(%0A%20%20%20%20%20%20%20%20bowler_frame.with_columns(pl.col(%22throws%22).bowling.compute_score())%0A%20%20%20%20%20%20%20%20.group_by(%22date%22%2C%20%22game_id%22)%0A%20%20%20%20%20%20%20%20.agg(%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22bowler_id%22).bowling.get_highest_bowler().alias(%22winner%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22bowler_id%22).bowling.get_lowest_bowler().alias(%22loser%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22score%22).rank(method%3D%22ordinal%22%2C%20descending%3DTrue).alias(%22rank%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22score%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22bowler_id%22)%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.explode(%22rank%22%2C%20%22score%22%2C%20%22bowler_id%22)%0A%20%20%20%20%20%20%20%20.group_by(%22bowler_id%22)%0A%20%20%20%20%20%20%20%20.agg(%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.len().alias(%22Games%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(pl.col(%22rank%22)%20%3D%3D%201).sum().alias(%22First%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(pl.col(%22rank%22)%20%3D%3D%202).sum().alias(%22Second%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(pl.col(%22rank%22)%20%3D%3D%203).sum().alias(%22Third%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(pl.col(%22loser%22)%20%3D%3D%20pl.col(%22bowler_id%22)).sum().alias(%22Losses%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22date%22).filter(pl.col(%22rank%22)%20%3D%3D%201).max().alias(%22Last%20Win%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22date%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20.filter(pl.col(%22loser%22)%20%3D%3D%20pl.col(%22bowler_id%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20.max()%0A%20%20%20%20%20%20%20%20%20%20%20%20.alias(%22Last%20Loss%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22score%22).filter(pl.col(%22rank%22)%20%3D%3D%201).max().alias(%22Highest%20Win%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22score%22).filter(pl.col(%22rank%22)%20%3D%3D%202).max().alias(%22Highest%20Second%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22score%22).filter(pl.col(%22rank%22)%20%3D%3D%203).max().alias(%22Highest%20Third%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22score%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20.filter(pl.col(%22loser%22)%20%3D%3D%20pl.col(%22bowler_id%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20.max()%0A%20%20%20%20%20%20%20%20%20%20%20%20.alias(%22Highest%20Loss%22)%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.with_columns(%0A%20%20%20%20%20%20%20%20%20%20%20%20(pl.col(%22First%22)%20%2F%20pl.col(%22Games%22)).alias(%22Win%20Rate%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(pl.col(%22First%22)%20%2B%20pl.col(%22Second%22)%20%2B%20pl.col(%22Third%22))%20%2F%20pl.col(%22Games%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20).alias(%22Podium%20Rate%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(pl.col(%22Losses%22)%20%2F%20pl.col(%22Games%22)).alias(%22Loss%20Rate%22)%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.sort(%22First%22%2C%20%22Second%22%2C%20%22Third%22%2C%20descending%3DTrue)%0A%20%20%20%20)%0A%20%20%20%20return%20(ranks%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(GT%2C%20ranks%2C%20results)%3A%0A%20%20%20%20%23%20Define%20column%20groups%0A%20%20%20%20podium_columns%20%3D%20%5B%22First%22%2C%20%22Second%22%2C%20%22Third%22%2C%20%22Losses%22%5D%0A%20%20%20%20scoring_columns%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%22Highest%20Win%22%2C%0A%20%20%20%20%20%20%20%20%22Highest%20Second%22%2C%0A%20%20%20%20%20%20%20%20%22Highest%20Third%22%2C%0A%20%20%20%20%20%20%20%20%22Highest%20Loss%22%2C%0A%20%20%20%20%5D%0A%20%20%20%20rates_columns%20%3D%20%5B%22Win%20Rate%22%2C%20%22Podium%20Rate%22%2C%20%22Loss%20Rate%22%5D%0A%20%20%20%20date_columns%20%3D%20%5B%22Last%20Win%22%2C%20%22Last%20Loss%22%5D%0A%0A%20%20%20%20%23%20Color%20palettes%0A%20%20%20%20scoring_palette%20%3D%20%22GnBu%22%0A%20%20%20%20rates_palette%20%3D%20%22Purples%22%0A%0A%20%20%20%20%23%20Build%20GT%20table%0A%20%20%20%20gt_table%20%3D%20(%0A%20%20%20%20%20%20%20%20GT(ranks)%0A%20%20%20%20%20%20%20%20.tab_header(%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Bowling%20Results%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20subtitle%3Df%22From%20%7Bresults%5B'date'%5D.min().strftime('%25B%20%25d%2C%20%25Y')%7D%20to%20%7Bresults%5B'date'%5D.max().strftime('%25B%20%25d%2C%20%25Y')%7D%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.tab_stub(rowname_col%3D%22bowler_id%22)%0A%20%20%20%20%20%20%20%20.tab_spanner(label%3D%22Podium%22%2C%20columns%3Dpodium_columns)%0A%20%20%20%20%20%20%20%20.tab_spanner(label%3D%22Scoring%22%2C%20columns%3Dscoring_columns)%0A%20%20%20%20%20%20%20%20.tab_spanner(label%3D%22Rates%22%2C%20columns%3Drates_columns)%0A%20%20%20%20%20%20%20%20.tab_spanner(label%3D%22Dates%22%2C%20columns%3Ddate_columns)%0A%20%20%20%20%20%20%20%20.data_color(columns%3Dscoring_columns%2C%20palette%3Dscoring_palette)%0A%20%20%20%20%20%20%20%20.data_color(columns%3D%22First%22%2C%20palette%3D%22PuBu%22)%0A%20%20%20%20%20%20%20%20.data_color(columns%3D%22Second%22%2C%20palette%3D%22Blues%22)%0A%20%20%20%20%20%20%20%20.data_color(columns%3D%22Third%22%2C%20palette%3D%22BuGn%22)%0A%20%20%20%20%20%20%20%20.data_color(columns%3D%22Losses%22%2C%20palette%3D%22OrRd%22)%0A%20%20%20%20%20%20%20%20.data_color(columns%3Drates_columns%2C%20palette%3Drates_palette)%0A%20%20%20%20%20%20%20%20.fmt_number(columns%3Dscoring_columns%2C%20decimals%3D0)%0A%20%20%20%20%20%20%20%20.fmt_percent(columns%3Drates_columns%2C%20decimals%3D1)%0A%20%20%20%20)%0A%0A%20%20%20%20gt_table%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(bowler_frame%2C%20pl)%3A%0A%20%20%20%20results%20%3D%20(%0A%20%20%20%20%20%20%20%20bowler_frame.with_columns(pl.col(%22throws%22).bowling.compute_score())%0A%20%20%20%20%20%20%20%20.group_by(%22date%22%2C%20%22game_id%22)%0A%20%20%20%20%20%20%20%20.agg(%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22bowler_id%22).bowling.get_highest_bowler().alias(%22winner%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20pl.col(%22bowler_id%22).bowling.get_lowest_bowler().alias(%22loser%22)%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.unpivot(%0A%20%20%20%20%20%20%20%20%20%20%20%20index%3D(%22date%22%2C%20%22game_id%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20on%3D(%22winner%22%2C%20%22loser%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20variable_name%3D%22outcome%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20value_name%3D%22bowler_id%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.sort(by%3D(%22date%22%2C%20%22game_id%22))%0A%20%20%20%20%20%20%20%20.join(bowler_frame%2C%20on%3D(%22date%22%2C%20%22game_id%22%2C%20%22bowler_id%22)%2C%20how%3D%22right%22)%0A%20%20%20%20%20%20%20%20.with_columns(pl.col(%22throws%22).bowling.compute_score())%0A%20%20%20%20)%0A%20%20%20%20return%20(results%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(pd%2C%20pl%2C%20plt%2C%20results%2C%20sns)%3A%0A%20%20%20%20from%20statsmodels.nonparametric.smoothers_lowess%20import%20lowess%0A%0A%20%20%20%20winning_scores%20%3D%20(%0A%20%20%20%20%20%20%20%20results.filter(pl.col(%22outcome%22)%20%3D%3D%20%22winner%22)%0A%20%20%20%20%20%20%20%20.select(%5B%22date%22%2C%20%22bowler_id%22%2C%20%22throws%22%5D)%0A%20%20%20%20%20%20%20%20.with_columns(pl.col(%22throws%22).bowling.compute_score().alias(%22score%22))%0A%20%20%20%20%20%20%20%20.sort(%22date%22)%0A%20%20%20%20%20%20%20%20.to_pandas()%0A%20%20%20%20)%0A%0A%20%20%20%20winning_scores%5B%22date_num%22%5D%20%3D%20(%0A%20%20%20%20%20%20%20%20winning_scores%5B%22date%22%5D%20-%20winning_scores%5B%22date%22%5D.min()%0A%20%20%20%20).dt.days%0A%0A%20%20%20%20%23%20Build%20a%20color%20map%20keyed%20to%20bowler%20so%20scatter%20%2B%20lines%20share%20colors%0A%20%20%20%20bowlers%20%3D%20winning_scores%5B%22bowler_id%22%5D.unique()%0A%20%20%20%20palette%20%3D%20dict(zip(bowlers%2C%20sns.color_palette(%22tab10%22%2C%20len(bowlers))))%0A%0A%20%20%20%20fig%2C%20ax%20%3D%20plt.subplots(figsize%3D(14%2C%206))%0A%0A%20%20%20%20%23%20Scatter%20(same%20as%20before)%0A%20%20%20%20sns.scatterplot(%0A%20%20%20%20%20%20%20%20data%3Dwinning_scores%2C%0A%20%20%20%20%20%20%20%20x%3D%22date%22%2C%0A%20%20%20%20%20%20%20%20y%3D%22score%22%2C%0A%20%20%20%20%20%20%20%20hue%3D%22bowler_id%22%2C%0A%20%20%20%20%20%20%20%20palette%3Dpalette%2C%0A%20%20%20%20%20%20%20%20s%3D60%2C%0A%20%20%20%20%20%20%20%20ax%3Dax%2C%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20Per-bowler%20LOWESS%20%E2%80%94%20only%20drawn%20when%20the%20bowler%20has%20enough%20points%0A%20%20%20%20min_date%20%3D%20winning_scores%5B%22date%22%5D.min()%0A%0A%20%20%20%20for%20bowler%2C%20color%20in%20palette.items()%3A%0A%20%20%20%20%20%20%20%20subset%20%3D%20winning_scores%5Bwinning_scores%5B%22bowler_id%22%5D%20%3D%3D%20bowler%5D%0A%20%20%20%20%20%20%20%20if%20len(subset)%20%3C%205%3A%20%20%23%20skip%20bowlers%20with%20too%20few%20games%20to%20smooth%0A%20%20%20%20%20%20%20%20%20%20%20%20continue%0A%20%20%20%20%20%20%20%20smoothed_b%20%3D%20lowess(%0A%20%20%20%20%20%20%20%20%20%20%20%20endog%3Dsubset%5B%22score%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20exog%3Dsubset%5B%22date_num%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20frac%3D0.3%2C%20%20%23%20wider%20frac%20per-bowler%20since%20subsets%20are%20smaller%0A%20%20%20%20%20%20%20%20%20%20%20%20it%3D1%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20ax.plot(%0A%20%20%20%20%20%20%20%20%20%20%20%20min_date%20%2B%20pd.to_timedelta(smoothed_b%5B%3A%2C%200%5D%2C%20unit%3D%22D%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20smoothed_b%5B%3A%2C%201%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3Dcolor%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20linewidth%3D2%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20linestyle%3D%22--%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20alpha%3D0.7%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%23%20Overall%20LOWESS%20on%20top%0A%20%20%20%20smoothed_all%20%3D%20lowess(%0A%20%20%20%20%20%20%20%20endog%3Dwinning_scores%5B%22score%22%5D%2C%0A%20%20%20%20%20%20%20%20exog%3Dwinning_scores%5B%22date_num%22%5D%2C%0A%20%20%20%20%20%20%20%20frac%3D0.1%2C%0A%20%20%20%20)%0A%20%20%20%20ax.plot(%0A%20%20%20%20%20%20%20%20min_date%20%2B%20pd.to_timedelta(smoothed_all%5B%3A%2C%200%5D%2C%20unit%3D%22D%22)%2C%0A%20%20%20%20%20%20%20%20smoothed_all%5B%3A%2C%201%5D%2C%0A%20%20%20%20%20%20%20%20color%3D%22black%22%2C%0A%20%20%20%20%20%20%20%20linewidth%3D2.5%2C%0A%20%20%20%20%20%20%20%20label%3D%22Smoothed%20Avg%20(all)%22%2C%0A%20%20%20%20)%0A%0A%20%20%20%20ax.set_xlabel(%22Date%22)%0A%20%20%20%20ax.set_ylabel(%22Winning%20Score%22)%0A%20%20%20%20ax.set_title(%22Winning%20Scores%20Over%20Time%20with%20Smoothed%20Averages%22)%0A%0A%20%20%20%20%23%20Rebuild%20legend%3A%20scatter%20already%20added%20bowler%20handles%3B%20append%20the%20overall%20line%0A%20%20%20%20handles%2C%20labels%20%3D%20ax.get_legend_handles_labels()%0A%20%20%20%20ax.legend(handles%2C%20labels%2C%20bbox_to_anchor%3D(1.05%2C%201)%2C%20loc%3D%22upper%20left%22)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20plt.show()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(pd%2C%20pl%2C%20plt%2C%20results%2C%20sns)%3A%0A%20%20%20%20def%20_()%3A%0A%20%20%20%20%20%20%20%20from%20statsmodels.nonparametric.smoothers_lowess%20import%20lowess%0A%0A%20%20%20%20%20%20%20%20losing_scores%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20results.filter(pl.col(%22outcome%22)%20%3D%3D%20%22loser%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20.select(%5B%22date%22%2C%20%22bowler_id%22%2C%20%22throws%22%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20.with_columns(pl.col(%22throws%22).bowling.compute_score().alias(%22score%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20.sort(%22date%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20.to_pandas()%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20losing_scores%5B%22date_num%22%5D%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20losing_scores%5B%22date%22%5D%20-%20losing_scores%5B%22date%22%5D.min()%0A%20%20%20%20%20%20%20%20).dt.days%0A%0A%20%20%20%20%20%20%20%20bowlers%20%3D%20losing_scores%5B%22bowler_id%22%5D.unique()%0A%20%20%20%20%20%20%20%20palette%20%3D%20dict(zip(bowlers%2C%20sns.color_palette(%22tab10%22%2C%20len(bowlers))))%0A%0A%20%20%20%20%20%20%20%20FRAC_B%20%3D%200.3%0A%20%20%20%20%20%20%20%20FRAC_ALL%20%3D%200.1%0A%20%20%20%20%20%20%20%20min_date%20%3D%20losing_scores%5B%22date%22%5D.min()%0A%0A%20%20%20%20%20%20%20%20fig%2C%20ax%20%3D%20plt.subplots(figsize%3D(14%2C%206))%0A%0A%20%20%20%20%20%20%20%20sns.scatterplot(%0A%20%20%20%20%20%20%20%20%20%20%20%20data%3Dlosing_scores%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D%22date%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D%22score%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20hue%3D%22bowler_id%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20palette%3Dpalette%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20s%3D60%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ax%3Dax%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20for%20bowler%2C%20color%20in%20palette.items()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20subset%20%3D%20losing_scores%5Blosing_scores%5B%22bowler_id%22%5D%20%3D%3D%20bowler%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20len(subset)%20%3C%205%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%0A%20%20%20%20%20%20%20%20%20%20%20%20smoothed_b%20%3D%20lowess(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20endog%3Dsubset%5B%22score%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20exog%3Dsubset%5B%22date_num%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20frac%3DFRAC_B%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20it%3D1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.plot(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20min_date%20%2B%20pd.to_timedelta(smoothed_b%5B%3A%2C%200%5D%2C%20unit%3D%22D%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20smoothed_b%5B%3A%2C%201%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%3Dcolor%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20linewidth%3D1.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20linestyle%3D%22--%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alpha%3D0.7%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20smoothed_all%20%3D%20lowess(%0A%20%20%20%20%20%20%20%20%20%20%20%20endog%3Dlosing_scores%5B%22score%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20exog%3Dlosing_scores%5B%22date_num%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20frac%3DFRAC_ALL%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20ax.plot(%0A%20%20%20%20%20%20%20%20%20%20%20%20min_date%20%2B%20pd.to_timedelta(smoothed_all%5B%3A%2C%200%5D%2C%20unit%3D%22D%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20smoothed_all%5B%3A%2C%201%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22black%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20linewidth%3D2.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20label%3D%22Smoothed%20Avg%20(all)%22%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20ax.set_xlabel(%22Date%22)%0A%20%20%20%20%20%20%20%20ax.set_ylabel(%22Losing%20Score%22)%0A%20%20%20%20%20%20%20%20ax.set_title(%22Losing%20Scores%20Over%20Time%20with%20Smoothed%20Averages%22)%0A%0A%20%20%20%20%20%20%20%20handles%2C%20labels%20%3D%20ax.get_legend_handles_labels()%0A%20%20%20%20%20%20%20%20ax.legend(handles%2C%20labels%2C%20bbox_to_anchor%3D(1.05%2C%201)%2C%20loc%3D%22upper%20left%22)%0A%0A%20%20%20%20%20%20%20%20plt.tight_layout()%0A%20%20%20%20%20%20%20%20return%20plt.show()%0A%0A%20%20%20%20_()%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
2bf10d6c5caa5394fb718374db515ffb