Skip to content

Commit

Permalink
Merge pull request #51 from jatkinson1000/round_score_dev
Browse files Browse the repository at this point in the history
Separate score for round and score for passes into two functions
  • Loading branch information
jatkinson1000 authored Jan 9, 2024
2 parents 68043ff + 6916eb1 commit 581fed0
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 31 deletions.
4 changes: 2 additions & 2 deletions archeryutils/classifications/agb_indoor_classifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def agb_indoor_classification_scores(
hc_scheme,
hc_params,
round_score_up=True,
)[0]
)
for i, class_i in enumerate(group_data["classes"])
]

Expand All @@ -263,7 +263,7 @@ def agb_indoor_classification_scores(
hc_scheme,
hc_params,
round_score_up=True,
)[0]
)
if next_score == score:
# If already at max score this classification is impossible
if score == ALL_INDOOR_ROUNDS[roundname].max_score():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def agb_old_indoor_classification_scores(
"AGBold",
hc_params,
round_score_up=True,
)[0]
)
for i, class_i in enumerate(group_data["classes"])
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ def agb_outdoor_classification_scores(
"AGB",
hc_params,
round_score_up=True,
)[0]
)
for i in range(len(group_data["classes"]))
]

Expand Down
62 changes: 47 additions & 15 deletions archeryutils/handicaps/handicap_equations.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
AA & AA2 - J Park
"""
import json
from typing import Union, Optional, Tuple
from typing import Union, Optional
from dataclasses import dataclass, field
import numpy as np
import numpy.typing as npt
Expand Down Expand Up @@ -508,16 +508,57 @@ def arrow_score(
return s_bar


def score_for_passes(
rnd: rounds.Round,
handicap: Union[float, npt.NDArray[np.float_]],
hc_sys: str,
hc_dat: HcParams,
arw_d: Optional[float] = None,
) -> npt.NDArray[np.float_]:
"""
Calculate the expected score for all passes in a round at a given handicap rating.
Parameters
----------
rnd : rounds.Round
A Round class specifying the round being shot
handicap : ndarray or float
handicap value to calculate score for
hc_sys : string
identifier for the handicap system
hc_dat : HcParams
dataclass containing parameters for handicap equations
arw_d : float
arrow diameter in [metres] default = None -> (use defaults)
Returns
-------
pass_scores : list of float
average score for each pass in the round (unrounded decimal)
"""
pass_scores = np.array(
[
pass_i.n_arrows
* arrow_score(pass_i.target, handicap, hc_sys, hc_dat, arw_d=arw_d)
for pass_i in rnd.passes
]
)

return pass_scores


def score_for_round(
rnd: rounds.Round,
handicap: Union[float, npt.NDArray[np.float_]],
hc_sys: str,
hc_dat: HcParams,
arw_d: Optional[float] = None,
round_score_up: bool = True,
) -> Tuple[Union[float, np.float_, npt.NDArray[np.float_]], npt.NDArray[np.float_]]:
) -> Union[float, np.float_, npt.NDArray[np.float_]]:
"""
Calculate the average arrow score for a given target and handicap rating.
Calculate the expected score for a round at a given handicap rating.
Parameters
----------
Expand All @@ -532,29 +573,20 @@ def score_for_round(
arw_d : float
arrow diameter in [metres] default = None -> (use defaults)
round_score_up : bool
round score up to nearest integer value
round score up to nearest integer value?
Returns
-------
round_score : float
average score of the round for this set of parameters
pass_score : list of float
average score for each pass in the round
"""
# Two too many arguments. Makes sense at the moment => disable
# Could try and simplify hc_sys and hc_dat in future refactor
# pylint: disable=too-many-arguments
pass_score = np.array(
[
pass_i.n_arrows
* arrow_score(pass_i.target, handicap, hc_sys, hc_dat, arw_d=arw_d)
for pass_i in rnd.passes
]
)

round_score = np.sum(pass_score, axis=0)
round_score = np.sum(score_for_passes(rnd, handicap, hc_sys, hc_dat, arw_d), axis=0)

if round_score_up:
# Old AGB system uses plain rounding rather than ceil of other schemes
Expand All @@ -563,4 +595,4 @@ def score_for_round(
else:
round_score = np.ceil(round_score)

return round_score, pass_score
return round_score
12 changes: 6 additions & 6 deletions archeryutils/handicaps/handicap_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def handicap_from_score(
else:
handicap = np.ceil(handicap)

sc_int, _ = hc_eq.score_for_round(
sc_int = hc_eq.score_for_round(
rnd, handicap, hc_sys, hc_dat, arw_d, round_score_up=True
)

Expand All @@ -101,7 +101,7 @@ def handicap_from_score(
hstep = 1.0
while not min_h_flag:
handicap += hstep
sc_int, _ = hc_eq.score_for_round(
sc_int = hc_eq.score_for_round(
rnd, handicap, hc_sys, hc_dat, arw_d, round_score_up=True
)
if sc_int < score:
Expand Down Expand Up @@ -157,13 +157,13 @@ def get_max_score_handicap(
else:
round_lim = 1.0

s_max, _ = hc_eq.score_for_round(
s_max = hc_eq.score_for_round(
rnd, handicap, hc_sys, hc_dat, arw_d, round_score_up=False
)
# Work down to where we would round or ceil to max score
while s_max > max_score - round_lim:
handicap = handicap + delta_hc
s_max, _ = hc_eq.score_for_round(
s_max = hc_eq.score_for_round(
rnd, handicap, hc_sys, hc_dat, arw_d, round_score_up=False
)
handicap = handicap - delta_hc # Undo final iteration that overshoots
Expand Down Expand Up @@ -350,7 +350,7 @@ def f_root(
# Could try and simplify hc_sys and hc_dat in future refactor
# pylint: disable=too-many-arguments

val, _ = hc_eq.score_for_round(
val = hc_eq.score_for_round(
round_est, hc_est, sys, hc_data, arw_dia, round_score_up=False
)

Expand Down Expand Up @@ -425,7 +425,7 @@ def print_handicap_table(
)
table[:, 0] = hcs.copy()
for i, round_i in enumerate(round_list):
table[:, i + 1], _ = hc_eq.score_for_round(
table[:, i + 1] = hc_eq.score_for_round(
round_i,
hcs,
hc_sys,
Expand Down
4 changes: 2 additions & 2 deletions archeryutils/handicaps/tests/test_handicaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ def test_float_round_score(

assert hc_eq.score_for_round(
test_round, 20.0, hc_system, hc_eq.HcParams(), None, False
)[0] == pytest.approx(round_score_expected[0])
) == pytest.approx(round_score_expected[0])

@pytest.mark.parametrize(
"hc_system,round_score_expected",
Expand Down Expand Up @@ -534,7 +534,7 @@ def test_rounded_round_score(
assert (
hc_eq.score_for_round(
test_round, 20.0, hc_system, hc_eq.HcParams(), None, True
)[0]
)
== round_score_expected[0]
)

Expand Down
33 changes: 29 additions & 4 deletions examples.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@
"metadata": {},
"outputs": [],
"source": [
"score_from_hc, _ = hc_eq.score_for_round(\n",
"score_from_hc = hc_eq.score_for_round(\n",
" agb_outdoor.york,\n",
" 38,\n",
" \"AGB\",\n",
Expand All @@ -392,7 +392,7 @@
"metadata": {},
"outputs": [],
"source": [
"score_from_hc, _ = hc_eq.score_for_round(\n",
"score_from_hc = hc_eq.score_for_round(\n",
" agb_outdoor.york,\n",
" 38.25,\n",
" \"AGB\",\n",
Expand All @@ -417,7 +417,7 @@
"metadata": {},
"outputs": [],
"source": [
"score_from_hc, _ = hc_eq.score_for_round(\n",
"score_from_hc = hc_eq.score_for_round(\n",
" agb_outdoor.york,\n",
" 38.25,\n",
" \"AGB\",\n",
Expand All @@ -428,6 +428,31 @@
"print(f\"A handicap of 38.25 on a York is a decimal score of {score_from_hc}.\")"
]
},
{
"cell_type": "markdown",
"id": "ee860e8e-a23b-4a06-88a7-04ca209aa092",
"metadata": {},
"source": [
"It is also possible to get the predicted score for each pass in a round using the `score_for_passes` function:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b8f743c8-9199-48ea-a0a5-bf309f1a887b",
"metadata": {},
"outputs": [],
"source": [
"pass_scores = hc_eq.score_for_passes(\n",
" agb_outdoor.york,\n",
" 38,\n",
" \"AGB\",\n",
" hcparams,\n",
")\n",
"\n",
"print(f\"A handicap of 38 on a York gives pass scores of {pass_scores}.\")"
]
},
{
"cell_type": "markdown",
"id": "c43a0f46",
Expand Down Expand Up @@ -726,7 +751,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
"version": "3.10.13"
}
},
"nbformat": 4,
Expand Down

0 comments on commit 581fed0

Please sign in to comment.