Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Targetdiameter #52

Merged
merged 21 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b98911f
Specify target face sizes in cm by default
TomHall2020 Jan 10, 2024
e411b81
Add additional tests for target diamter conversion
TomHall2020 Jan 10, 2024
5dc07fc
Update Pass, load_rounds and test_cases to assume cm as default targe…
TomHall2020 Jan 10, 2024
3662727
Revert import sorting and formatting
TomHall2020 Jan 10, 2024
72e2f78
Docstrings for tests, replace xfail, rename diameter_unit
TomHall2020 Jan 10, 2024
5bd3701
Repackage distance aliases for linter
TomHall2020 Jan 10, 2024
d1d55c5
Support specifying target diameters in inches, pass units through Pas…
TomHall2020 Jan 10, 2024
0a8fffc
Additional testing for passthrough of diameter units from Pass to Target
TomHall2020 Jan 10, 2024
888dd82
Clean up unit conversion
TomHall2020 Jan 10, 2024
e966397
Unit conversion with helper class
TomHall2020 Jan 11, 2024
721606e
Fix max_distance for mixed units
TomHall2020 Jan 11, 2024
32838c4
Document Length conversion class
TomHall2020 Jan 12, 2024
8b831dd
rename conversions dict
TomHall2020 Jan 17, 2024
a225ec8
Add dedicated tests for Length helper class
TomHall2020 Jan 17, 2024
63cb557
formatting
TomHall2020 Jan 17, 2024
69b67f8
Enhanced docstrings and rename definitive_unit on Length methods
TomHall2020 Jan 17, 2024
3b3137d
Fix pydocstyle errors, add to lint optional dependencies
TomHall2020 Jan 17, 2024
d5eb769
Simplify max_distance check logic.
jatkinson1000 Jan 17, 2024
4f716af
Update examples notebook to incorporate changes.
jatkinson1000 Jan 17, 2024
4131229
Update rounds to standardise on 'diameter' (remove 'diam' instances).
jatkinson1000 Jan 17, 2024
c8f4ba9
Fix removal of spaces in docstring.
jatkinson1000 Jan 17, 2024
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
166 changes: 165 additions & 1 deletion archeryutils/constants.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,166 @@
"""Constants used in the archeryutils package."""
YARD_TO_METRE = 0.9144

_CONVERSIONS_TO_M = {
"metre": 1.0,
"yard": 0.9144,
"cm": 0.01,
"inch": 0.0254,
}

_YARD_ALIASES = {
"Yard",
"yard",
"Yards",
"yards",
"Y",
"y",
"Yd",
"yd",
"Yds",
"yds",
}

_METRE_ALIASES = {
"Metre",
"metre",
"Metres",
"metres",
"M",
"m",
"Ms",
"ms",
}

_CM_ALIASES = {
"Centimetre",
"centimetre",
"Centimetres",
"centimetres",
"CM",
"cm",
"CMs",
"cms",
}

_INCH_ALIASES = {
"Inch",
"inch",
"Inches",
"inches",
}

_ALIASES = {
"yard": _YARD_ALIASES,
"metre": _METRE_ALIASES,
"cm": _CM_ALIASES,
"inch": _INCH_ALIASES,
}


class Length:
jatkinson1000 marked this conversation as resolved.
Show resolved Hide resolved
"""
Utility class for Length unit conversions.

Contains common abbreviations, pluralisations and capitilizations for supported
units as sets to allow easy membership checks in combination.
Methods for conversions to and from metres are provided as classmethods.

Attributes
----------
yard : set[str]
metre : set[str]
cm: set[str]
inch: set[str]

Methods
-------
to_metres()
Convert distance in any supported unit to metres
from_metres()
Convert distance in metres to any supported unit
definitive_name()
Convert any string alias representing a distance unit to a single version.
"""

yard = _YARD_ALIASES
metre = _METRE_ALIASES
cm = _CM_ALIASES
inch = _INCH_ALIASES

_reversed = {alias: name for name in _CONVERSIONS_TO_M for alias in _ALIASES[name]}

_conversions = {
alias: factor
for name, factor in _CONVERSIONS_TO_M.items()
for alias in _ALIASES[name]
}

@classmethod
def to_metres(cls, value: float, unit: str) -> float:
"""
Convert value in metres to given unit.

Parameters
----------
value : float
scalar value of distance to be converted to metres
unit : str
units of distance to be converted to metres

Returns
-------
float
scalar value of converted distance in metres

Examples
--------
>>> Length.to_metres(10, "inches")
0.254
"""
return cls._conversions[unit] * value

@classmethod
def from_metres(cls, metre_value: float, unit: str) -> float:
"""
Convert value in given unit to metres.

Parameters
----------
metre_value : float
scalar value of distance in metres to be converted
unit : str
units distance is to be converted TO

Returns
-------
float
scalar value of converted distance in the provided unit

Examples
--------
>>> Length.from_metres(18.3, "yards")
20.0131
"""
return metre_value / cls._conversions[unit]

@classmethod
def definitive_unit(cls, alias: str) -> str:
"""
Convert alias for unit into a single definied name set in constants.

Parameters
----------
alias : str
name of unit to be converted

Returns
-------
str
definitive name of unit

Examples
--------
>>> Length.definitive_unit("Metres")
"metre"
"""
return cls._reversed[alias]
19 changes: 9 additions & 10 deletions archeryutils/handicaps/tests/test_handicap_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,32 @@

import archeryutils.handicaps.handicap_equations as hc_eq
import archeryutils.handicaps.handicap_functions as hc_func
from archeryutils.rounds import Round, Pass

from archeryutils.rounds import Pass, Round

hc_params = hc_eq.HcParams()

# Define rounds used in these functions
york = Round(
"York",
[
Pass(72, 1.22, "5_zone", 100, "yard", False),
Pass(48, 1.22, "5_zone", 80, "yard", False),
Pass(24, 1.22, "5_zone", 60, "yard", False),
Pass(72, 122, "5_zone", 100, "yard", False),
Pass(48, 122, "5_zone", 80, "yard", False),
Pass(24, 122, "5_zone", 60, "yard", False),
],
)
hereford = Round(
"Hereford",
[
Pass(72, 1.22, "5_zone", 80, "yard", False),
Pass(48, 1.22, "5_zone", 60, "yard", False),
Pass(24, 1.22, "5_zone", 50, "yard", False),
Pass(72, 122, "5_zone", 80, "yard", False),
Pass(48, 122, "5_zone", 60, "yard", False),
Pass(24, 122, "5_zone", 50, "yard", False),
],
)
metric122_30 = Round(
"Metric 122-30",
[
Pass(36, 1.22, "10_zone", 30, "metre", False),
Pass(36, 1.22, "10_zone", 30, "metre", False),
Pass(36, 122, "10_zone", 30, "metre", False),
Pass(36, 122, "10_zone", 30, "metre", False),
],
)

Expand Down
70 changes: 35 additions & 35 deletions archeryutils/handicaps/tests/test_handicaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,62 +20,62 @@
york = Round(
"York",
[
Pass(72, 1.22, "5_zone", 100, "yard", False),
Pass(48, 1.22, "5_zone", 80, "yard", False),
Pass(24, 1.22, "5_zone", 60, "yard", False),
Pass(72, 122, "5_zone", 100, "yard", False),
Pass(48, 122, "5_zone", 80, "yard", False),
Pass(24, 122, "5_zone", 60, "yard", False),
],
)
hereford = Round(
"Hereford",
[
Pass(72, 1.22, "5_zone", 80, "yard", False),
Pass(48, 1.22, "5_zone", 60, "yard", False),
Pass(24, 1.22, "5_zone", 50, "yard", False),
Pass(72, 122, "5_zone", 80, "yard", False),
Pass(48, 122, "5_zone", 60, "yard", False),
Pass(24, 122, "5_zone", 50, "yard", False),
],
)
western = Round(
"Western",
[
Pass(48, 1.22, "5_zone", 60, "yard", False),
Pass(48, 1.22, "5_zone", 50, "yard", False),
Pass(48, 122, "5_zone", 60, "yard", False),
Pass(48, 122, "5_zone", 50, "yard", False),
],
)
vegas300 = Round(
"Vegas 300",
[
Pass(30, 0.4, "10_zone", 20, "yard", True),
Pass(30, 40, "10_zone", 20, "yard", True),
],
)
wa1440_90 = Round(
"WA1440 90m",
[
Pass(36, 1.22, "10_zone", 90, "metre", False),
Pass(36, 1.22, "10_zone", 70, "metre", False),
Pass(36, 0.8, "10_zone", 50, "metre", False),
Pass(36, 0.8, "10_zone", 30, "metre", False),
Pass(36, 122, "10_zone", 90, "metre", False),
Pass(36, 122, "10_zone", 70, "metre", False),
Pass(36, 80, "10_zone", 50, "metre", False),
Pass(36, 80, "10_zone", 30, "metre", False),
],
)
wa1440_70 = Round(
"WA1440 70m",
[
Pass(36, 1.22, "10_zone", 70, "metre", False),
Pass(36, 1.22, "10_zone", 60, "metre", False),
Pass(36, 0.8, "10_zone", 50, "metre", False),
Pass(36, 0.8, "10_zone", 30, "metre", False),
Pass(36, 122, "10_zone", 70, "metre", False),
Pass(36, 122, "10_zone", 60, "metre", False),
Pass(36, 80, "10_zone", 50, "metre", False),
Pass(36, 80, "10_zone", 30, "metre", False),
],
)
wa720_70 = Round(
"WA 720 70m",
[
Pass(36, 1.22, "10_zone", 70, "metre", False),
Pass(36, 1.22, "10_zone", 70, "metre", False),
Pass(36, 122, "10_zone", 70, "metre", False),
Pass(36, 122, "10_zone", 70, "metre", False),
],
)
metric122_30 = Round(
"Metric 122-30",
[
Pass(36, 1.22, "10_zone", 30, "metre", False),
Pass(36, 1.22, "10_zone", 30, "metre", False),
Pass(36, 122, "10_zone", 30, "metre", False),
Pass(36, 122, "10_zone", 30, "metre", False),
],
)

Expand Down Expand Up @@ -387,7 +387,7 @@ def test_different_handicap_systems(

"""
arrow_score = hc_eq.arrow_score(
target=Target(0.40, "10_zone_5_ring_compound", 20.0, "metre", indoor),
target=Target(40, "10_zone_5_ring_compound", 20.0, "metre", indoor),
handicap=20.0,
hc_sys=hc_system,
hc_dat=hc_params,
Expand Down Expand Up @@ -420,7 +420,7 @@ def test_different_target_faces(
Check correct arrow scores returned for different target faces
"""
arrow_score = hc_eq.arrow_score(
target=Target(0.80, target_face, 50.0, "metre", False),
target=Target(80, target_face, 50.0, "metre", False),
handicap=38.0,
hc_sys="AGB",
hc_dat=hc_params,
Expand Down Expand Up @@ -490,9 +490,9 @@ def test_float_round_score(
test_round = Round(
"MyRound",
[
Pass(10, 1.22, "10_zone", 100, "metre", False),
Pass(10, 0.80, "10_zone", 80, "metre", False),
Pass(10, 1.22, "5_zone", 60, "metre", False),
Pass(10, 122, "10_zone", 100, "metre", False),
Pass(10, 80, "10_zone", 80, "metre", False),
Pass(10, 122, "5_zone", 60, "metre", False),
],
)

Expand Down Expand Up @@ -525,9 +525,9 @@ def test_rounded_round_score(
test_round = Round(
"MyRound",
[
Pass(10, 1.22, "10_zone", 100, "metre", False),
Pass(10, 0.80, "10_zone", 80, "metre", False),
Pass(10, 1.22, "5_zone", 60, "metre", False),
Pass(10, 122, "10_zone", 100, "metre", False),
Pass(10, 80, "10_zone", 80, "metre", False),
Pass(10, 122, "5_zone", 60, "metre", False),
],
)

Expand Down Expand Up @@ -624,8 +624,8 @@ def test_score_over_max(self) -> None:
test_round = Round(
"TestRound",
[
Pass(10, 1.22, "10_zone", 50, "metre", False),
Pass(10, 0.80, "10_zone", 50, "metre", False),
Pass(10, 122, "10_zone", 50, "metre", False),
Pass(10, 80, "10_zone", 50, "metre", False),
],
)

Expand All @@ -645,8 +645,8 @@ def test_score_of_zero(self) -> None:
test_round = Round(
"TestRound",
[
Pass(10, 1.22, "10_zone", 50, "metre", False),
Pass(10, 0.80, "10_zone", 50, "metre", False),
Pass(10, 122, "10_zone", 50, "metre", False),
Pass(10, 80, "10_zone", 50, "metre", False),
],
)

Expand All @@ -666,8 +666,8 @@ def test_score_below_zero(self) -> None:
test_round = Round(
"TestRound",
[
Pass(10, 1.22, "10_zone", 50, "metre", False),
Pass(10, 0.80, "10_zone", 50, "metre", False),
Pass(10, 122, "10_zone", 50, "metre", False),
Pass(10, 80, "10_zone", 50, "metre", False),
],
)

Expand Down
2 changes: 1 addition & 1 deletion archeryutils/load_rounds.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def read_json_to_round_dict(json_filelist: Union[str, List[str]]) -> Dict[str, R
passes = [
Pass(
pass_i["n_arrows"],
pass_i["diameter"] / 100,
pass_i["diameter"],
pass_i["scoring"],
pass_i["distance"],
dist_unit=pass_i["dist_unit"],
Expand Down
Loading