geo-activity-playground 0.24.1__tar.gz → 0.24.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/PKG-INFO +1 -1
- geo_activity_playground-0.24.2/geo_activity_playground/webui/equipment/controller.py +114 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/equipment/templates/equipment/index.html.j2 +14 -3
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/summary/controller.py +11 -8
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/pyproject.toml +1 -1
- geo_activity_playground-0.24.1/geo_activity_playground/webui/equipment/controller.py +0 -73
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/LICENSE +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/__main__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/activities.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/activity_parsers.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/cache_migrations.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/config.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/coordinates.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/heatmap.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/paths.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/privacy_zones.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/similarity.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/tasks.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/test_tiles.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/test_time_conversion.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/tiles.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/core/time_conversion.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/explorer/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/explorer/grid_file.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/explorer/tile_visits.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/explorer/video.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/importers/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/importers/directory.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/importers/strava_api.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/importers/strava_checkout.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/importers/test_directory.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/importers/test_strava_api.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/activity/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/activity/blueprint.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/activity/controller.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/activity/templates/activity/day.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/activity/templates/activity/lines.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/activity/templates/activity/name.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/activity/templates/activity/show.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/app.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/calendar/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/calendar/blueprint.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/calendar/controller.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/calendar/templates/calendar/index.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/calendar/templates/calendar/month.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/eddington/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/eddington/blueprint.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/eddington/controller.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/eddington/templates/eddington/index.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/entry_controller.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/equipment/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/equipment/blueprint.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/explorer/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/explorer/blueprint.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/explorer/controller.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/explorer/templates/explorer/index.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/heatmap/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/heatmap/blueprint.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/heatmap/heatmap_controller.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/heatmap/templates/heatmap/index.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/search_controller.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/square_planner/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/square_planner/blueprint.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/square_planner/controller.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/square_planner/templates/square_planner/index.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/static/android-chrome-192x192.png +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/static/android-chrome-384x384.png +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/static/android-chrome-512x512.png +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/static/apple-touch-icon.png +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/static/browserconfig.xml +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/static/favicon-16x16.png +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/static/favicon-32x32.png +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/static/favicon.ico +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/static/mstile-150x150.png +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/static/safari-pinned-tab.svg +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/static/site.webmanifest +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/strava_controller.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/summary/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/summary/blueprint.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/summary/templates/summary/index.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/templates/home.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/templates/page.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/templates/search.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/templates/strava-connect.html.j2 +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/tile/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/tile/blueprint.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/tile/controller.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/upload/__init__.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/upload/blueprint.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/upload/controller.py +0 -0
- {geo_activity_playground-0.24.1 → geo_activity_playground-0.24.2}/geo_activity_playground/webui/upload/templates/upload/index.html.j2 +0 -0
@@ -0,0 +1,114 @@
|
|
1
|
+
import altair as alt
|
2
|
+
import pandas as pd
|
3
|
+
|
4
|
+
from geo_activity_playground.core.activities import ActivityRepository
|
5
|
+
from geo_activity_playground.core.config import get_config
|
6
|
+
|
7
|
+
|
8
|
+
class EquipmentController:
|
9
|
+
def __init__(self, repository: ActivityRepository) -> None:
|
10
|
+
self._repository = repository
|
11
|
+
|
12
|
+
def render(self) -> dict:
|
13
|
+
kind_per_equipment = self._repository.meta.groupby("equipment").apply(
|
14
|
+
lambda group: group.groupby("kind")
|
15
|
+
.apply(lambda group2: sum(group2["distance_km"]), include_groups=False)
|
16
|
+
.idxmax(),
|
17
|
+
include_groups=False,
|
18
|
+
)
|
19
|
+
|
20
|
+
equipment_summary = (
|
21
|
+
self._repository.meta.groupby("equipment")
|
22
|
+
.apply(
|
23
|
+
lambda group: pd.Series(
|
24
|
+
{
|
25
|
+
"total_distance_km": group["distance_km"].sum(),
|
26
|
+
"first_use": group["start"].iloc[0],
|
27
|
+
"last_use": group["start"].iloc[-1],
|
28
|
+
},
|
29
|
+
),
|
30
|
+
include_groups=False,
|
31
|
+
)
|
32
|
+
.sort_values("last_use", ascending=False)
|
33
|
+
)
|
34
|
+
|
35
|
+
equipment_summary["primarily_used_for"] = None
|
36
|
+
for equipment, kind in kind_per_equipment.items():
|
37
|
+
equipment_summary.loc[equipment, "primarily_used_for"] = kind
|
38
|
+
|
39
|
+
equipment_variables = {}
|
40
|
+
for equipment in equipment_summary.index:
|
41
|
+
selection = self._repository.meta.loc[
|
42
|
+
self._repository.meta["equipment"] == equipment
|
43
|
+
]
|
44
|
+
total_distances = pd.DataFrame(
|
45
|
+
{
|
46
|
+
"time": selection["start"],
|
47
|
+
"total_distance_km": selection["distance_km"].cumsum(),
|
48
|
+
}
|
49
|
+
)
|
50
|
+
|
51
|
+
total_distances_plot = (
|
52
|
+
alt.Chart(
|
53
|
+
total_distances,
|
54
|
+
height=300,
|
55
|
+
width=300,
|
56
|
+
title="Usage over Time",
|
57
|
+
)
|
58
|
+
.mark_line(interpolate="step-after")
|
59
|
+
.encode(
|
60
|
+
alt.X("time", title="Date"),
|
61
|
+
alt.Y("total_distance_km", title="Cumulative distance / km"),
|
62
|
+
)
|
63
|
+
.interactive()
|
64
|
+
.to_json(format="vega")
|
65
|
+
)
|
66
|
+
|
67
|
+
yearly_distance_plot = (
|
68
|
+
alt.Chart(
|
69
|
+
selection,
|
70
|
+
height=300,
|
71
|
+
title="Yearly distance",
|
72
|
+
)
|
73
|
+
.mark_bar()
|
74
|
+
.encode(
|
75
|
+
alt.X("year(start):O", title="Year"),
|
76
|
+
alt.Y("sum(distance_km)", title="Distance / km"),
|
77
|
+
)
|
78
|
+
.to_json(format="vega")
|
79
|
+
)
|
80
|
+
|
81
|
+
usages_plot = (
|
82
|
+
alt.Chart(
|
83
|
+
selection,
|
84
|
+
height=300,
|
85
|
+
title="Kinds",
|
86
|
+
)
|
87
|
+
.mark_bar()
|
88
|
+
.encode(
|
89
|
+
alt.X("kind", title="Year"),
|
90
|
+
alt.Y("sum(distance_km)", title="Distance / km"),
|
91
|
+
)
|
92
|
+
.to_json(format="vega")
|
93
|
+
)
|
94
|
+
|
95
|
+
equipment_variables[equipment] = {
|
96
|
+
"total_distances_plot": total_distances_plot,
|
97
|
+
"total_distances_plot_id": f"total_distances_plot_{hash(equipment)}",
|
98
|
+
"yearly_distance_plot": yearly_distance_plot,
|
99
|
+
"yearly_distance_plot_id": f"yearly_distance_plot_{hash(equipment)}",
|
100
|
+
"usages_plot": usages_plot,
|
101
|
+
"usages_plot_id": f"usages_plot_{hash(equipment)}",
|
102
|
+
}
|
103
|
+
|
104
|
+
config = get_config()
|
105
|
+
if "offsets" in config:
|
106
|
+
for equipment, offset in config["offsets"].items():
|
107
|
+
equipment_summary.loc[equipment, "total_distance_km"] += offset
|
108
|
+
|
109
|
+
return {
|
110
|
+
"equipment_variables": equipment_variables,
|
111
|
+
"equipment_summary": equipment_summary.reset_index().to_dict(
|
112
|
+
orient="records"
|
113
|
+
),
|
114
|
+
}
|
@@ -13,6 +13,7 @@
|
|
13
13
|
<thead>
|
14
14
|
<tr>
|
15
15
|
<th>Equipment</th>
|
16
|
+
<th>Primarily used for</th>
|
16
17
|
<th style="text-align: right;">Distance / km</th>
|
17
18
|
<th style="text-align: right;">First use</th>
|
18
19
|
<th style="text-align: right;">Last use</th>
|
@@ -22,6 +23,7 @@
|
|
22
23
|
{% for equipment in equipment_summary %}
|
23
24
|
<tr>
|
24
25
|
<td>{{ equipment.equipment }}</td>
|
26
|
+
<td>{{ equipment.primarily_used_for }}</td>
|
25
27
|
<td style="text-align: right;">{{ equipment.total_distance_km|int }}</td>
|
26
28
|
<td style="text-align: right;">{{ equipment.first_use.date() }}</td>
|
27
29
|
<td style="text-align: right;">{{ equipment.last_use.date() }}</td>
|
@@ -34,13 +36,22 @@
|
|
34
36
|
|
35
37
|
<div class="row mb-3">
|
36
38
|
<div class="col">
|
37
|
-
<h2>
|
39
|
+
<h2>Details for each equipment</h2>
|
38
40
|
</div>
|
39
41
|
</div>
|
40
42
|
|
43
|
+
{% for equipment, data in equipment_variables.items() %}
|
44
|
+
<h3>{{ equipment }}</h3>
|
41
45
|
<div class="row mb-3">
|
42
|
-
<div class="col">
|
43
|
-
{{ vega_direct(
|
46
|
+
<div class="col-md-4">
|
47
|
+
{{ vega_direct(data.total_distances_plot_id, data.total_distances_plot) }}
|
48
|
+
</div>
|
49
|
+
<div class="col-md-4">
|
50
|
+
{{ vega_direct(data.yearly_distance_plot_id, data.yearly_distance_plot) }}
|
51
|
+
</div>
|
52
|
+
<div class="col-md-4">
|
53
|
+
{{ vega_direct(data.usages_plot_id, data.usages_plot) }}
|
44
54
|
</div>
|
45
55
|
</div>
|
56
|
+
{% endfor %}
|
46
57
|
{% endblock %}
|
@@ -61,11 +61,13 @@ def nominate_activities(meta: pd.DataFrame) -> dict[int, list[str]]:
|
|
61
61
|
i = subset["elapsed_time"].idxmax()
|
62
62
|
nominations[i].append(f"Longest elapsed time: {meta.loc[i].elapsed_time}")
|
63
63
|
|
64
|
-
|
65
|
-
|
64
|
+
if "calories" in subset.columns:
|
65
|
+
i = subset["calories"].idxmax()
|
66
|
+
nominations[i].append(f"Most calories burnt: {meta.loc[i].calories:.0f} kcal")
|
66
67
|
|
67
|
-
|
68
|
-
|
68
|
+
if "steps" in subset:
|
69
|
+
i = subset["steps"].idxmax()
|
70
|
+
nominations[i].append(f"Most steps: {meta.loc[i].steps:.0f}")
|
69
71
|
|
70
72
|
for kind, group in meta.groupby("kind"):
|
71
73
|
for key, text in [
|
@@ -83,10 +85,11 @@ def nominate_activities(meta: pd.DataFrame) -> dict[int, list[str]]:
|
|
83
85
|
),
|
84
86
|
("steps", lambda row: f"Most steps for {row.kind}: {row.steps:.0f}"),
|
85
87
|
]:
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
88
|
+
if key in group.columns:
|
89
|
+
series = group[key]
|
90
|
+
i = series.idxmax()
|
91
|
+
if not pd.isna(i):
|
92
|
+
nominations[i].append(text(meta.loc[i]))
|
90
93
|
|
91
94
|
return nominations
|
92
95
|
|
@@ -1,73 +0,0 @@
|
|
1
|
-
import altair as alt
|
2
|
-
import pandas as pd
|
3
|
-
|
4
|
-
from geo_activity_playground.core.activities import ActivityRepository
|
5
|
-
from geo_activity_playground.core.config import get_config
|
6
|
-
|
7
|
-
|
8
|
-
class EquipmentController:
|
9
|
-
def __init__(self, repository: ActivityRepository) -> None:
|
10
|
-
self._repository = repository
|
11
|
-
|
12
|
-
def render(self) -> dict:
|
13
|
-
total_distances = (
|
14
|
-
self._repository.meta.groupby("equipment")
|
15
|
-
.apply(
|
16
|
-
lambda group: pd.DataFrame(
|
17
|
-
{
|
18
|
-
"time": group["start"],
|
19
|
-
"total_distance_km": group["distance_km"].cumsum(),
|
20
|
-
}
|
21
|
-
),
|
22
|
-
include_groups=False,
|
23
|
-
)
|
24
|
-
.reset_index()
|
25
|
-
)
|
26
|
-
|
27
|
-
plot = (
|
28
|
-
alt.Chart(
|
29
|
-
total_distances,
|
30
|
-
height=250,
|
31
|
-
width=250,
|
32
|
-
title="Equipment Usage over Time",
|
33
|
-
)
|
34
|
-
.mark_line(interpolate="step-after")
|
35
|
-
.encode(
|
36
|
-
alt.X("time", title="Date"),
|
37
|
-
alt.Y("total_distance_km", title="Cumulative distance / km"),
|
38
|
-
)
|
39
|
-
.facet("equipment", columns=4, title="Equipment")
|
40
|
-
.resolve_scale(y="independent")
|
41
|
-
.resolve_axis(x="independent")
|
42
|
-
.interactive()
|
43
|
-
.to_json(format="vega")
|
44
|
-
)
|
45
|
-
|
46
|
-
equipment_summary = (
|
47
|
-
self._repository.meta.groupby("equipment")
|
48
|
-
.apply(
|
49
|
-
lambda group: pd.DataFrame(
|
50
|
-
{
|
51
|
-
"total_distance_km": group["distance_km"].sum(),
|
52
|
-
"first_use": group["start"].iloc[0],
|
53
|
-
"last_use": group["start"].iloc[-1],
|
54
|
-
},
|
55
|
-
index=[0],
|
56
|
-
),
|
57
|
-
include_groups=False,
|
58
|
-
)
|
59
|
-
.reset_index()
|
60
|
-
.sort_values("last_use", ascending=False)
|
61
|
-
)
|
62
|
-
|
63
|
-
config = get_config()
|
64
|
-
if "offsets" in config:
|
65
|
-
for equipment, offset in config["offsets"].items():
|
66
|
-
equipment_summary.loc[
|
67
|
-
equipment_summary["equipment"] == equipment, "total_distance_km"
|
68
|
-
] += offset
|
69
|
-
|
70
|
-
return {
|
71
|
-
"total_distances_plot": plot,
|
72
|
-
"equipment_summary": equipment_summary.to_dict(orient="records"),
|
73
|
-
}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|