Move trip new-country filtering into stats
This commit is contained in:
parent
ddfa77b152
commit
f22772d12d
5 changed files with 27 additions and 15 deletions
|
|
@ -32,4 +32,4 @@ This is a personal agenda web application built with Flask that tracks various e
|
||||||
- Personal data directory (`personal-data/`) is excluded from git
|
- Personal data directory (`personal-data/`) is excluded from git
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
- Trip stats new-country badges come from `agenda.stats.calculate_yearly_stats` via `year_stats.new_countries` (first-visit year); `templates/trip/stats.html` filters against `PREVIOUSLY_VISITED`.
|
- Trip stats new-country badges come from `agenda.stats.calculate_yearly_stats` via `year_stats.new_countries` (first-visit year, excluding `PREVIOUSLY_VISITED`).
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,13 @@ def conferences(trip: Trip, yearly_stats: Mapping[int, StrDict]) -> None:
|
||||||
yearly_stats[c["start"].year]["conferences"] += 1
|
yearly_stats[c["start"].year]["conferences"] += 1
|
||||||
|
|
||||||
|
|
||||||
def calculate_yearly_stats(trips: list[Trip]) -> dict[int, StrDict]:
|
def calculate_yearly_stats(
|
||||||
|
trips: list[Trip], previously_visited: set[str] | None = None
|
||||||
|
) -> dict[int, StrDict]:
|
||||||
"""Calculate total distance and distance by transport type grouped by year."""
|
"""Calculate total distance and distance by transport type grouped by year."""
|
||||||
yearly_stats: defaultdict[int, StrDict] = defaultdict(dict)
|
yearly_stats: defaultdict[int, StrDict] = defaultdict(dict)
|
||||||
first_visit_year: dict[str, int] = {}
|
first_visit_year: dict[str, int] = {}
|
||||||
|
excluded_new: set[str] = previously_visited or set()
|
||||||
|
|
||||||
for trip in trips:
|
for trip in trips:
|
||||||
year = trip.start.year
|
year = trip.start.year
|
||||||
|
|
@ -72,7 +75,10 @@ def calculate_yearly_stats(trips: list[Trip]) -> dict[int, StrDict]:
|
||||||
continue
|
continue
|
||||||
yearly_stats[year].setdefault("countries", set())
|
yearly_stats[year].setdefault("countries", set())
|
||||||
yearly_stats[year]["countries"].add(country)
|
yearly_stats[year]["countries"].add(country)
|
||||||
if first_visit_year.get(country.alpha_2) == year:
|
if (
|
||||||
|
first_visit_year.get(country.alpha_2) == year
|
||||||
|
and country.alpha_2 not in excluded_new
|
||||||
|
):
|
||||||
yearly_stats[year].setdefault("new_countries", set())
|
yearly_stats[year].setdefault("new_countries", set())
|
||||||
yearly_stats[year]["new_countries"].add(country)
|
yearly_stats[year]["new_countries"].add(country)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,19 +27,13 @@
|
||||||
<div>Trips in {{ year }}: {{ year_stats.count }}</div>
|
<div>Trips in {{ year }}: {{ year_stats.count }}</div>
|
||||||
<div>Conferences in {{ year }}: {{ year_stats.conferences }}</div>
|
<div>Conferences in {{ year }}: {{ year_stats.conferences }}</div>
|
||||||
<div>{{ countries | count }} countries visited in {{ year }}:
|
<div>{{ countries | count }} countries visited in {{ year }}:
|
||||||
{% set display_new_countries = [] %}
|
{% if new_countries %}
|
||||||
{% for c in new_countries %}
|
({{ new_countries | count }} new)
|
||||||
{% if c.alpha_2 not in previously_visited %}
|
|
||||||
{% set _ = display_new_countries.append(c) %}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% if display_new_countries %}
|
|
||||||
({{ display_new_countries | count }} new)
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for c in countries %}
|
{% for c in countries %}
|
||||||
<span class="d-inline-block border border-2 p-1 m-1">
|
<span class="d-inline-block border border-2 p-1 m-1">
|
||||||
{{ c.flag }} {{ c.name }} ({{ c.alpha_2 }})
|
{{ c.flag }} {{ c.name }} ({{ c.alpha_2 }})
|
||||||
{% if c in display_new_countries %}
|
{% if c in new_countries %}
|
||||||
<span class="badge text-bg-info">new</span>
|
<span class="badge text-bg-info">new</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
|
|
@ -27,3 +27,11 @@ def test_new_country_only_first_year() -> None:
|
||||||
assert czechia in yearly_stats[2024]["new_countries"]
|
assert czechia in yearly_stats[2024]["new_countries"]
|
||||||
assert czechia in yearly_stats[2026]["countries"]
|
assert czechia in yearly_stats[2026]["countries"]
|
||||||
assert "new_countries" not in yearly_stats[2026]
|
assert "new_countries" not in yearly_stats[2026]
|
||||||
|
|
||||||
|
|
||||||
|
def test_new_country_respects_previously_visited() -> None:
|
||||||
|
"""Ensure previously visited countries are excluded from new-country stats."""
|
||||||
|
trips = [make_trip(date(2024, 5, 1), "CZ")]
|
||||||
|
|
||||||
|
yearly_stats = calculate_yearly_stats(trips, {"CZ"})
|
||||||
|
assert "new_countries" not in yearly_stats[2024]
|
||||||
|
|
|
||||||
10
web_view.py
10
web_view.py
|
|
@ -461,7 +461,9 @@ def accommodation_list() -> str:
|
||||||
items = travel.parse_yaml("accommodation", data_dir)
|
items = travel.parse_yaml("accommodation", data_dir)
|
||||||
|
|
||||||
# Create a dictionary to hold stats for each year
|
# Create a dictionary to hold stats for each year
|
||||||
year_stats = defaultdict(lambda: {"total_nights": 0, "nights_abroad": 0})
|
year_stats: defaultdict[int, dict[str, int]] = defaultdict(
|
||||||
|
lambda: {"total_nights": 0, "nights_abroad": 0}
|
||||||
|
)
|
||||||
|
|
||||||
# Calculate stats for each year
|
# Calculate stats for each year
|
||||||
for stay in items:
|
for stay in items:
|
||||||
|
|
@ -536,7 +538,7 @@ def calc_total_distance(trips: list[Trip]) -> float:
|
||||||
|
|
||||||
def calc_total_co2_kg(trips: list[Trip]) -> float:
|
def calc_total_co2_kg(trips: list[Trip]) -> float:
|
||||||
"""Total CO₂ for trips."""
|
"""Total CO₂ for trips."""
|
||||||
return sum(item.total_co2_kg() for item in trips)
|
return sum(item.total_co2_kg() or 0.0 for item in trips)
|
||||||
|
|
||||||
|
|
||||||
def sum_distances_by_transport_type(trips: list[Trip]) -> list[tuple[str, float]]:
|
def sum_distances_by_transport_type(trips: list[Trip]) -> list[tuple[str, float]]:
|
||||||
|
|
@ -806,7 +808,9 @@ def trip_stats() -> str:
|
||||||
|
|
||||||
conferences = sum(len(item.conferences) for item in trip_list)
|
conferences = sum(len(item.conferences) for item in trip_list)
|
||||||
|
|
||||||
yearly_stats = agenda.stats.calculate_yearly_stats(trip_list)
|
yearly_stats = agenda.stats.calculate_yearly_stats(
|
||||||
|
trip_list, app.config.get("PREVIOUSLY_VISITED")
|
||||||
|
)
|
||||||
|
|
||||||
return flask.render_template(
|
return flask.render_template(
|
||||||
"trip/stats.html",
|
"trip/stats.html",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue