Skip to content

Instantly share code, notes, and snippets.

@joshparkerj
Created June 7, 2021 23:45
Show Gist options
  • Save joshparkerj/d1a13ccfe61a08ff1e78ce7795dab785 to your computer and use it in GitHub Desktop.
Save joshparkerj/d1a13ccfe61a08ff1e78ce7795dab785 to your computer and use it in GitHub Desktop.
function that aggregates the win probabilities on fivethirtyeight's nba predictions page
function getPredictions(teamAbbreviation) {
// run this at https://projects.fivethirtyeight.com/2021-nba-predictions/games/
// teamAbbreviation can be one of the following:
// 'DEN' 'PHX' 'LAC' 'UTA'
return new Promise((resolve) => {
document.getElementById('js-upcoming-expander').click();
const afterTimeout = () => {
const selector = `#upcoming-days tr[data-team="${teamAbbreviation}"]`;
const toFraction = (e) => Number(e.textContent.replace('%', '')) / 100;
const chances = Array.from(document.querySelectorAll(`${selector} .chance`), toFraction);
const teamName = document.querySelector(`${selector} .team`).textContent;
const oppAbbreviation = document.querySelector(`#upcoming-days table.${teamAbbreviation}`).getAttribute('class').match(/[A-Z]{3}/g).filter(e => e !== teamAbbreviation)[0];
const oppSelector = `#upcoming-days tr[data-team="${oppAbbreviation}"]`;
const oppName = document.querySelector(`${oppSelector} .team`).textContent;
const translator = s => {
if (s.slice(0, 4) === '0000') {
return `${oppName} in 4`;
} else if (s.slice(0, 4) === '1111') {
return `${teamName} in 4`;
} else if (s.slice(0, 5).replace('1', '') === '0000') {
return `${oppName} in 5`;
} else if (s.slice(0, 5).replace('0', '') === '1111') {
return `${teamName} in 5`;
} else if (s.slice(0, 6).replaceAll('1', '') === '0000') {
return `${oppName} in 6`;
} else if (s.slice(0, 6).replaceAll('0', '') === '1111') {
return `${teamName} in 6`;
} else if (s.replaceAll('1', '') === '0000') {
return `${oppName} in 7`;
} else if (s.replaceAll('0', '') === '1111') {
return `${teamName} in 7`;
}
};
const allOutcomes = Array.from(new Array(128), (e, i) => {
const s = i.toString(2).padStart(7, '0');
return {
probability: [...s].reduce((acc, e, i) => acc * (e === '0' ? 1 - chances[i] : chances[i]), 1),
outcome: translator(s)
};
});
const reducedOutcomes = allOutcomes.reduce((acc, e) => {
if (e.outcome in acc) {
acc[e.outcome] += e.probability;
} else {
acc[e.outcome] = e.probability;
}
return acc;
}, {});
resolve(reducedOutcomes);
};
setTimeout(afterTimeout, 1000);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment