diff --git a/formula10/__init__.py b/formula10/__init__.py index 9da6e30..4ed1088 100644 --- a/formula10/__init__.py +++ b/formula10/__init__.py @@ -27,6 +27,7 @@ db.init_app(app) # NOTE: These imports are required to register the routes. They need to be imported after "app" is declared import formula10.controller.race_controller # type: ignore import formula10.controller.season_controller +import formula10.controller.leaderboard_controller import formula10.controller.statistics_controller import formula10.controller.rules_controller import formula10.controller.admin_controller diff --git a/formula10/controller/admin_controller.py b/formula10/controller/admin_controller.py index 8ced1b8..5153bdd 100644 --- a/formula10/controller/admin_controller.py +++ b/formula10/controller/admin_controller.py @@ -58,7 +58,7 @@ def result_active_race(race_name: str) -> str: model = TemplateModel(active_user_name=None, active_result_race_name=race_name) - return render_template("enter.jinja", model=model) + return render_template("result.jinja", model=model) @app.route("/result-enter/", methods=["POST"]) diff --git a/formula10/controller/leaderboard_controller.py b/formula10/controller/leaderboard_controller.py new file mode 100644 index 0000000..7290f86 --- /dev/null +++ b/formula10/controller/leaderboard_controller.py @@ -0,0 +1,11 @@ +from flask import render_template +from formula10 import app +from formula10.domain.points_model import PointsModel +from formula10.domain.template_model import TemplateModel + +@app.route("/graphs") +def graphs_root() -> str: + model = TemplateModel(active_user_name=None, active_result_race_name=None) + points = PointsModel() + + return render_template("leaderboard.jinja", model=model, points=points) \ No newline at end of file diff --git a/formula10/controller/statistics_controller.py b/formula10/controller/statistics_controller.py index 8d49c83..272edff 100644 --- a/formula10/controller/statistics_controller.py +++ b/formula10/controller/statistics_controller.py @@ -1,10 +1,11 @@ + from flask import render_template from formula10 import app from formula10.domain.points_model import PointsModel from formula10.domain.template_model import TemplateModel -@app.route("/graphs") -def graphs_root() -> str: +@app.route("/stats") +def stats_root() -> str: model = TemplateModel(active_user_name=None, active_result_race_name=None) points = PointsModel() diff --git a/formula10/domain/points_model.py b/formula10/domain/points_model.py index 962a7d3..4ffab08 100644 --- a/formula10/domain/points_model.py +++ b/formula10/domain/points_model.py @@ -7,6 +7,7 @@ from formula10.domain.model.race_guess import RaceGuess from formula10.domain.model.race_result import RaceResult from formula10.domain.model.season_guess import SeasonGuess from formula10.domain.model.season_guess_result import SeasonGuessResult +from formula10.domain.model.team import Team from formula10.domain.model.user import User RACE_GUESS_OFFSET_POINTS: Dict[int, int] = { @@ -292,6 +293,14 @@ class PointsModel(Model): return most_lost_names + def drivers_sorted_by_points(self) -> List[Driver]: + comparator: Callable[[Driver], int] = lambda driver: self.wdc_standing_by_driver()[driver.name] + return sorted(self.all_drivers(include_none=False), key=comparator) + + def teams_sorted_by_points(self) -> List[Team]: + comparator: Callable[[Team], int] = lambda team: self.wcc_standing_by_team()[team.name] + return sorted(self.all_teams(include_none=False), key=comparator) + def points_per_step_cumulative(self) -> Dict[str, List[int]]: """ Returns a dictionary of lists, containing cumulative points per race for each user. diff --git a/formula10/templates/base.jinja b/formula10/templates/base.jinja index 4a9d974..883ae10 100644 --- a/formula10/templates/base.jinja +++ b/formula10/templates/base.jinja @@ -204,6 +204,7 @@ {{ nav_selector(page="/race/" ~ model.active_user_name_sanitized_or_everyone(), text="Race Picks") }} {{ nav_selector(page="/season/" ~ model.active_user_name_sanitized_or_everyone(), text="Season Picks") }} {{ nav_selector(page="/graphs", text="Leaderboard") }} + {{ nav_selector(page="/stats", text="Statistics") }} {{ nav_selector(page="/rules", text="Rules") }} diff --git a/formula10/templates/leaderboard.jinja b/formula10/templates/leaderboard.jinja new file mode 100644 index 0000000..904f983 --- /dev/null +++ b/formula10/templates/leaderboard.jinja @@ -0,0 +1,59 @@ +{% extends 'base.jinja' %} + +{% block title %}Formula 10 - Leaderboard{% endblock title %} + +{% set active_page = "/graphs" %} + +{% block body %} + +
+
+
Leaderboard
+
Points only include race picks
+ + + + + + + + + + + + + + + {% for user in points.users_sorted_by_points() %} + {% set user_standing = points.user_standing()[user.name] %} + + + + + + + + + {% endfor %} + +
PlaceUserPointsTotal picksCorrect picksPoints per pick
{{ user_standing }}{{ user.name }}{{ points.total_points_by(user.name) }}{{ points.picks_count(user.name) }}{{ points.picks_with_points_count(user.name) }}{{ "%0.2f" % points.points_per_pick(user.name) }}
+
+
+ + {#
#} + {#
#} + {#
History
#} + + {# Line chart of point history with a line per user #} + {#
#} + {#
#} + + {#
#} + {#
#} + {#
Statistics
#} + + {# Various statistics: Driver voted most for DNF #} + {#
#} + {#
#} + +{% endblock body %} diff --git a/formula10/templates/enter.jinja b/formula10/templates/result.jinja similarity index 100% rename from formula10/templates/enter.jinja rename to formula10/templates/result.jinja diff --git a/formula10/templates/statistics.jinja b/formula10/templates/statistics.jinja index 904f983..3729fe5 100644 --- a/formula10/templates/statistics.jinja +++ b/formula10/templates/statistics.jinja @@ -1,59 +1,69 @@ {% extends 'base.jinja' %} -{% block title %}Formula 10 - Leaderboard{% endblock title %} +{% block title %}Formula 10 - Statistics{% endblock title %} -{% set active_page = "/graphs" %} +{% set active_page = "/stats" %} {% block body %} -
-
-
Leaderboard
-
Points only include race picks
+
- - - - - - - - - - - +
+
+
Drivers
-
- {% for user in points.users_sorted_by_points() %} - {% set user_standing = points.user_standing()[user.name] %} - - - - - - - +
PlaceUserPointsTotal picksCorrect picksPoints per pick
{{ user_standing }}{{ user.name }}{{ points.total_points_by(user.name) }}{{ points.picks_count(user.name) }}{{ points.picks_with_points_count(user.name) }}{{ "%0.2f" % points.points_per_pick(user.name) }}
+ + + + + + - {% endfor %} - -
PlaceDriverPointsDNFs
+ + + + {% for driver in points.drivers_sorted_by_points() %} + {% set driver_standing = points.wdc_standing_by_driver()[driver.name] %} + + {{ driver_standing }} + {{ driver.name }} + {{ points.wdc_points()[driver.name] }} + {{ points.dnfs()[driver.name] }} + + {% endfor %} + + +
+ +
+
+
Constructors
+ + + + + + + + + + + + {% for team in points.teams_sorted_by_points() %} + {% set team_standing = points.wcc_standing_by_team()[team.name] %} + + + + + + {% endfor %} + +
PlaceTeamPoints
{{ team_standing }}{{ team.name }}{{ points.wcc_points()[team.name] }}
+
+
+
- {#
#} - {#
#} - {#
History
#} - - {# Line chart of point history with a line per user #} - {#
#} - {#
#} - - {#
#} - {#
#} - {#
Statistics
#} - - {# Various statistics: Driver voted most for DNF #} - {#
#} - {#
#} - {% endblock body %}