# Path: athlib/utils.py
# def str2num(s: str) -> Union[int, float]:
#     """convert string to int if possible else float
# 
#     :param s: string number
#     :returns: int(s) or float(s)
#     :raises ValueError: if conversion impossible
#     """
#     try:
#         return int(s)
#     except ValueError:
#         return float(s)
# 
# def normalize_gender(gender: Any) -> str:
#     """
#     Return M, F or raise a ValueError
# 
#     :param gender: M or F (case variations and suffixes accepted)
#     :returns: M or F
#     :raises ValueError: raises an exception
# 
#     """
#     if gender and isStr(gender):
#         g = gender.upper().strip()
#         if g:
#             g = g[0]
#             if g in ('M','F'):
#                 return g
#     raise ValueError('cannot normalize gender = %s' % repr(gender))
# 
# def parse_hms(t: Union[int, float, str]) -> Union[int, float]:
#     """
#     Parse a time duration with 0, 1 or 2 colons and return seconds.
# 
#     >>> from .utils import parse_hms
#     >>> parse_hms('10')
#     10
#     >>> parse_hms('1:10')
#     70
#     >>> parse_hms('1:1:10')
#     3670
#     >>> parse_hms('1:1:10.1')
#     3670.1
#     >>> parse_hms(3670.1)
#     3670.1
#     """
#     if isinstance(t, (float, int)):
#         return t
# 
#     # Try : and ; separators
#     for sep in ':;':
#         if sep not in t:
#             continue
# 
#         sec = 0
# 
#         for s in t.split(sep):
#             sec *= 60
# 
#             try:
#                 sec += str2num(s)
#             except ValueError:
#                 raise ValueError('cannot parse seconds from %s' % repr(t))
# 
#         return sec
#     try:
#         return str2num(t)
#     except ValueError:
#         raise ValueError('cannot parse seconds from %s' % repr(t))
# 
# Path: athlib/codes.py
# PAT_THROWS = re.compile(
#                         (
#                         r"^(?:"
#                         r"[sS]?[dD][tT](?P<dtnum>%s|)|"
#                         r"[sS]?[jJ][tT](?P<jtnum>[45678]00\s*g?|)|"
#                         r"[hH][tT](?P<htnum>%s|)|"
#                         r"[sS][pP](?P<spnum>%s|)|"
#                         r"[wW][tT](?P<wtnum>\d?%s|)|"
#                         r"[sS][sW][tT](?P<swtnum>%s|)|"
#                         r"[sS]?[bB][tT](?P<btnum>%s|)|"
#                         r"[sS][tT](?P<stnum>%s|)|"
#                         r"[gG][dD][tT](?P<gdtnum>%s|)|"
#                         r"[oO][tT](?P<otnum>\d+\s*g?|)|"
#                         r"[tT][aA][rR][tT]|"  # weight not relevant
#                         r"[cC][hH][tT]|"
#                         r"[oO][hH][tT]|"                         
#                         r"[Hh][1-9]|"
#                         r"[Ll][1-9]"
#                         ")$"
#                         ) % (_, _, _, _, _, _, _, _),
#                         )
# 
# PAT_JUMPS = re.compile(_orjoin(PAT_VERTICAL_JUMPS,PAT_HORIZONTAL_JUMPS))
# 
# PAT_TRACK = re.compile(r"^(?:(?:(?P<meters>\d+)\s*(?P<msfx>%s|[yY]|[wW])?)|[sS][cC]|[2345][mM][tT]|[lL][hH]|[sS][hH])$" % _)
# 
# PAT_ROAD = re.compile(r"^(?:(?:[mM][iI][lL][eE]|[mM][aA][rR]|[hH][mM])[wW]?|[xX][cC]|(?:\d{1,3}(\.\d\d?)?(?:[MKk]|[MKk][wW]|[wW])))$")


import json
import re
import os
from collections import namedtuple
from ..utils import str2num, normalize_gender, parse_hms
from ..codes import PAT_THROWS, PAT_JUMPS, PAT_TRACK, PAT_ROAD
        """
        >>> from athlib.wma.agegrader import AgeGrader
        >>> AgeGrader()._check_patterns()
        """
        for ec in self._all_event_codes:
            for p in (PAT_THROWS, PAT_JUMPS, PAT_TRACK, PAT_ROAD):
                if p.match(ec):
                    break
            else:
                print('could not match %s' % ec)

        nuc = []

        def ccase(x):
            if x.upper() != x:
                nuc.append(x)

        data = self.get_data()[self.data_year]

        for j in self.text_columns:
            self._check_table_column(data['m'], j, ccase)
            self._check_table_column(data['f'], j, ccase)

        if nuc:
            print('these strings need uppercasing in the json %s' %
                   ' '.join(repr(t) for t in list(set(nuc))))

    @staticmethod
    def event_code_to_kind(code):
        for n, p in (('throw', PAT_THROWS),

# Path: athlib/utils.py
# def str2num(s: str) -> Union[int, float]:
#     """convert string to int if possible else float
# 
#     :param s: string number
#     :returns: int(s) or float(s)
#     :raises ValueError: if conversion impossible
#     """
#     try:
#         return int(s)
#     except ValueError:
#         return float(s)
# 
# def normalize_gender(gender: Any) -> str:
#     """
#     Return M, F or raise a ValueError
# 
#     :param gender: M or F (case variations and suffixes accepted)
#     :returns: M or F
#     :raises ValueError: raises an exception
# 
#     """
#     if gender and isStr(gender):
#         g = gender.upper().strip()
#         if g:
#             g = g[0]
#             if g in ('M','F'):
#                 return g
#     raise ValueError('cannot normalize gender = %s' % repr(gender))
# 
# def parse_hms(t: Union[int, float, str]) -> Union[int, float]:
#     """
#     Parse a time duration with 0, 1 or 2 colons and return seconds.
# 
#     >>> from .utils import parse_hms
#     >>> parse_hms('10')
#     10
#     >>> parse_hms('1:10')
#     70
#     >>> parse_hms('1:1:10')
#     3670
#     >>> parse_hms('1:1:10.1')
#     3670.1
#     >>> parse_hms(3670.1)
#     3670.1
#     """
#     if isinstance(t, (float, int)):
#         return t
# 
#     # Try : and ; separators
#     for sep in ':;':
#         if sep not in t:
#             continue
# 
#         sec = 0
# 
#         for s in t.split(sep):
#             sec *= 60
# 
#             try:
#                 sec += str2num(s)
#             except ValueError:
#                 raise ValueError('cannot parse seconds from %s' % repr(t))
# 
#         return sec
#     try:
#         return str2num(t)
#     except ValueError:
#         raise ValueError('cannot parse seconds from %s' % repr(t))
# 
# Path: athlib/codes.py
# PAT_THROWS = re.compile(
#                         (
#                         r"^(?:"
#                         r"[sS]?[dD][tT](?P<dtnum>%s|)|"
#                         r"[sS]?[jJ][tT](?P<jtnum>[45678]00\s*g?|)|"
#                         r"[hH][tT](?P<htnum>%s|)|"
#                         r"[sS][pP](?P<spnum>%s|)|"
#                         r"[wW][tT](?P<wtnum>\d?%s|)|"
#                         r"[sS][sW][tT](?P<swtnum>%s|)|"
#                         r"[sS]?[bB][tT](?P<btnum>%s|)|"
#                         r"[sS][tT](?P<stnum>%s|)|"
#                         r"[gG][dD][tT](?P<gdtnum>%s|)|"
#                         r"[oO][tT](?P<otnum>\d+\s*g?|)|"
#                         r"[tT][aA][rR][tT]|"  # weight not relevant
#                         r"[cC][hH][tT]|"
#                         r"[oO][hH][tT]|"                         
#                         r"[Hh][1-9]|"
#                         r"[Ll][1-9]"
#                         ")$"
#                         ) % (_, _, _, _, _, _, _, _),
#                         )
# 
# PAT_JUMPS = re.compile(_orjoin(PAT_VERTICAL_JUMPS,PAT_HORIZONTAL_JUMPS))
# 
# PAT_TRACK = re.compile(r"^(?:(?:(?P<meters>\d+)\s*(?P<msfx>%s|[yY]|[wW])?)|[sS][cC]|[2345][mM][tT]|[lL][hH]|[sS][hH])$" % _)
# 
# PAT_ROAD = re.compile(r"^(?:(?:[mM][iI][lL][eE]|[mM][aA][rR]|[hH][mM])[wW]?|[xX][cC]|(?:\d{1,3}(\.\d\d?)?(?:[MKk]|[MKk][wW]|[wW])))$")


# Path: athlib/wma/agegrader.py
import json
import re
import os
from collections import namedtuple
from ..utils import str2num, normalize_gender, parse_hms
from ..codes import PAT_THROWS, PAT_JUMPS, PAT_TRACK, PAT_ROAD

        """
        >>> from athlib.wma.agegrader import AgeGrader
        >>> AgeGrader()._check_patterns()
        """
        for ec in self._all_event_codes:
            for p in (PAT_THROWS, PAT_JUMPS, PAT_TRACK, PAT_ROAD):
                if p.match(ec):
                    break
            else:
                print('could not match %s' % ec)

        nuc = []

        def ccase(x):
            if x.upper() != x:
                nuc.append(x)

        data = self.get_data()[self.data_year]

        for j in self.text_columns:
            self._check_table_column(data['m'], j, ccase)
            self._check_table_column(data['f'], j, ccase)

        if nuc:
            print('these strings need uppercasing in the json %s' %
                   ' '.join(repr(t) for t in list(set(nuc))))

    @staticmethod
    def event_code_to_kind(code):
        for n, p in (('throw', PAT_THROWS),

                     ('jump', PAT_JUMPS),