Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 37 additions & 11 deletions browser-extensions/extension/src/js/lib/challenges.js
Original file line number Diff line number Diff line change
Expand Up @@ -704,11 +704,15 @@ function generate_stat_most_runs_in_a_year(parkrun_results) {
}
}

function generate_stat_p_index(parkrun_results) {
function generate_stat_p_index(parkrun_results, options = {}) {
const display_name = 'p-index'
var help = "The number of parkruns that satisfy the equation 'p parkruns run at least p times', e.g. if you have run 4 different parkruns at least 4 times each, your p-index is 4."
const definition_help = "The number of parkruns that satisfy the equation 'p parkruns run at least p times', e.g. if you have run 4 different parkruns at least 4 times each, your p-index is 4."
var help = definition_help
var event_attendance_tally = {}
var qualifying = []
const geo_data = options.geo_data
const home_parkrun_info = options.home_parkrun_info
const include_home_distances = geo_data !== undefined && home_parkrun_info !== undefined && has_lat_lon(home_parkrun_info)

parkrun_results.forEach((parkrun_event) => {
if (!(parkrun_event.name in event_attendance_tally)) {
Expand All @@ -717,16 +721,36 @@ function generate_stat_p_index(parkrun_results) {
event_attendance_tally[parkrun_event.name] += 1
})

const event_attendance_sorted = Object.keys(event_attendance_tally).sort((a, b) => event_attendance_tally[b] - event_attendance_tally[a])
const event_attendance_sorted = Object.keys(event_attendance_tally).sort((a, b) => {
const count_difference = event_attendance_tally[b] - event_attendance_tally[a]
if (count_difference !== 0) {
return count_difference
}
return a.localeCompare(b)
})

event_attendance_sorted.forEach((event_name, index) => {
if (event_attendance_tally[event_name] > index) {
qualifying.push(`${event_name} (${event_attendance_tally[event_name]})`)
const finish_count = event_attendance_tally[event_name]
const finish_label = finish_count === 1 ? 'finish' : 'finishes'
let event_summary = `${event_name} (${finish_count} ${finish_label})`

if (include_home_distances && event_name in geo_data.data.events) {
const event_info = geo_data.data.events[event_name]
if (has_lat_lon(event_info)) {
const distance = calculate_great_circle_distance(event_info, home_parkrun_info)
event_summary = `${event_name} (${distance.toFixed(1)}km away, ${finish_count} ${finish_label})`
}
}

qualifying.push(event_summary)
}
})

var value = qualifying.length
help = `The number of parkrun events completed at least ${value} times. These are ${qualifying.join(", ")}.`
if (value >= 1) {
help = `The number of parkrun events completed at least ${value} times. These are:\n - ${qualifying.join("\n - ")}`
}
return { display_name, help, value }
}

Expand Down Expand Up @@ -1255,13 +1279,19 @@ function generate_stats(data) {

// Stats that only need the list of parkruns
if (data.info.has_parkrun_results) {
const p_index_options = {}
if (has_geo_data(data) && is_our_page(data) && data.info.has_home_parkrun) {
p_index_options.geo_data = data.geo_data
p_index_options.home_parkrun_info = data.user_data.home_parkrun_info
}

stats['total_runs'] = generate_stat_total_runs(data.parkrun_results)
stats['total_pbs'] = generate_stat_total_pbs(data.parkrun_results)
stats['longest_pb_streak'] = generate_stat_longest_pb_streak(data.parkrun_results)
stats['total_distance_ran'] = generate_stat_total_distance_ran(data.parkrun_results)
stats['most_runs_in_a_year'] = generate_stat_most_runs_in_a_year(data.parkrun_results)
stats['runs_this_year'] = generate_stat_runs_this_year(data.parkrun_results)
stats['p_index'] = generate_stat_p_index(data.parkrun_results)
stats['p_index'] = generate_stat_p_index(data.parkrun_results, p_index_options)
stats['wilson_index'] = generate_stat_wilson_index(data.parkrun_results)
stats['parkrun_birthday'] = generate_stat_parkrun_birthday(data.parkrun_results)
stats['years_parkrunning'] = generate_stat_years_parkrunning(data.parkrun_results)
Expand Down Expand Up @@ -1303,8 +1333,7 @@ function get_initial_letter(event_name) {

function get_flag_image_src(country) {
// Mapping countries to flag image files
var flag_map = {
"New Zealand": "nz",
const flag_map = {
"Australia": "au",
"Austria": "at",
"Canada": "ca",
Expand Down Expand Up @@ -1698,10 +1727,8 @@ function challenge_name_badge(data, params) {
}
}

console.log("number of subparts:" + o.subparts.length)
// Add in all the missing ones
for (i=0; i< o.subparts.length; i++) {
console.log(o.subparts_detail[i])
if (o.subparts_detail[i].info == "-") {

// if (grouped_events !== undefined) {
Expand All @@ -1713,7 +1740,6 @@ function challenge_name_badge(data, params) {
details = get_parkrun_event_details(data, event.name)
if (has_lat_lon(details)) {
o.all_qualifying_events[event.name] = details
console.log(event.name)
}
}
})
Expand Down
69 changes: 69 additions & 0 deletions browser-extensions/extension/src/js/tests/test/test_challenges.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,75 @@ var geoData = getGeoData();

describe("challenges.js", function () {
describe("stats", function () {
describe("generate_stat_p_index", function () {
const generate_stat_p_index = challenges.__get__("generate_stat_p_index");
const calculate_great_circle_distance = challenges.__get__(
"calculate_great_circle_distance",
);
const definitionHelp =
"The number of parkruns that satisfy the equation 'p parkruns run at least p times', e.g. if you have run 4 different parkruns at least 4 times each, your p-index is 4.";

it("should return the fixed definition tooltip when p-index is zero", function () {
const r = generate_stat_p_index([]);
assert.strictEqual(r.value, 0);
assert.strictEqual(r.help, definitionHelp);
});

it("should return dynamic multiline help without distance data", function () {
const parkrunResults = [createParkrunResult({ name: "Winchester" })];
const r = generate_stat_p_index(parkrunResults);
assert.strictEqual(r.value, 1);
assert.strictEqual(
r.help,
"The number of parkrun events completed at least 1 times. These are:\n - Winchester (1 finish)",
);
});

it("should return dynamic multiline help with distances when available", function () {
const parkrunResults = [
createParkrunResult({ name: "Winchester" }),
createParkrunResult({ name: "Winchester" }),
createParkrunResult({ name: "Bushy Park" }),
createParkrunResult({ name: "Bushy Park" }),
];
const homeParkrun = getParkrunEventInfo("Winchester");
const bushyDistance = calculate_great_circle_distance(
getParkrunEventInfo("Bushy Park"),
homeParkrun,
).toFixed(1);
const r = generate_stat_p_index(parkrunResults, {
geo_data: geoData,
home_parkrun_info: homeParkrun,
});

assert.strictEqual(r.value, 2);
assert.strictEqual(
r.help,
`The number of parkrun events completed at least 2 times. These are:\n - Bushy Park (${bushyDistance}km away, 2 finishes)\n - Winchester (0.0km away, 2 finishes)`,
);
});

it("should omit distance when an event location is unavailable", function () {
const parkrunResults = [
createParkrunResult({ name: "Unknown Event" }),
createParkrunResult({ name: "Unknown Event" }),
createParkrunResult({ name: "Winchester" }),
createParkrunResult({ name: "Winchester" }),
];
const homeParkrun = getParkrunEventInfo("Winchester");
const r = generate_stat_p_index(parkrunResults, {
geo_data: geoData,
home_parkrun_info: homeParkrun,
});

assert.strictEqual(r.value, 2);
assert.strictEqual(
r.help,
"The number of parkrun events completed at least 2 times. These are:\n - Unknown Event (2 finishes)\n - Winchester (0.0km away, 2 finishes)",
);
});
});

describe("generate_stat_furthest_travelled", function () {
// Use the special '__get__' accessor to get your private function.
var generate_stat_furthest_travelled = challenges.__get__(
Expand Down
14 changes: 8 additions & 6 deletions website/assets/js/running-challenges.user.js

Large diffs are not rendered by default.

Loading