def _parse_tie_scores(mhisto_elems, setnum, fin_score, is_super_tie):
    """fin_score (tie inner sup) must be equal last result_score"""
    num_pairs = []
    opener_side = None
    prev_result_score = None  # for site's errors handle
    for num, mhisto_el in enumerate(mhisto_elems, start=1):
        srvside = _parse_detgame_serve_side(mhisto_el)
        if num == 1:
            opener_side = srvside
        result_score = None
        try:
            pnt_res = _parse_out_result(mhisto_el)
            result_score = pnt_res.x, pnt_res.y
        except co.TennisScoreError as err:
            if prev_result_score is not None and prev_result_score == result_score:
                continue  # not meaning error score, skip it
            else:
                print("{} setnum: {} tiefinscr: {}".format(err, setnum, fin_score))
        num_pairs.append(result_score)
        if num == len(mhisto_elems) and result_score != fin_score:
            raise co.TennisScoreError(
                "tie fin_scr {} != result_scr {} open {}".format(
                    fin_score, result_score, opener_side
                )
            )
        prev_result_score = result_score
    wintie_side = co.LEFT if fin_score[0] > fin_score[1] else co.RIGHT
    return make_detailed_game(
        opener_side, wintie_side, num_pairs, tiebreak=True, is_super_tie=is_super_tie
    )
def _parse_detgame_serve_side(parent_elem):
    def is_serve(serve_elem):
        elem = co.find_first_xpath(
            serve_elem, "child::div[contains(@title, 'Serving player')]"
        )
        return elem is not None

    srv_elems = list(parent_elem.xpath("child::div[contains(@class,'servis')]"))
    if len(srv_elems) == 2:
        if is_serve(srv_elems[0]):
            return co.LEFT
        if is_serve(srv_elems[1]):
            return co.RIGHT
        raise co.TennisScoreError("nobody does servis in _parse_detgame_serve_side")
    else:
        raise co.TennisScoreError(
            "can not find two servis in _parse_detgame_serve_side"
        )
 def is_opener_win_point(prev_pair, pair):
     left_dist, right_dist = distances(prev_pair, pair)
     if opener_side.is_left():
         return left_dist > right_dist
     elif opener_side.is_right():
         return right_dist > left_dist
     raise co.TennisScoreError(
         "bad pts seq in make_detailed_game {} {}".format(prev_pair, pair)
     )
Example #4
0
 def from_text(text_item, strict=True):
     pair = (text_item.strip().replace("[", "").replace("]", "").replace(
         "40", "45").replace("AD", "60").replace("A", "60").split("-"))
     if len(pair) < 2:
         raise ValueError("no 2-column scr '{}'".format(text_item))
     if "*" in pair[0]:
         srv_side = co.LEFT
     elif "*" in pair[1]:
         srv_side = co.RIGHT
     elif not strict:
         srv_side = None
     else:
         raise co.TennisScoreError("absent * in '{}'".format(text_item))
     return SrvPair(srv_side, int(pair[0].replace("*", "")),
                    int(pair[1].replace("*", "")))
def _parse_detgame_tiesup_score(parent_elem) -> Tuple[Optional[int], Optional[int]]:
    def get_num(scr_elem):
        txt_num = scr_elem.text
        if txt_num:
            return int(txt_num.strip())

    scr_elems = list(
        parent_elem.xpath(
            "child::div[contains(@class,'scoreBox')]/div[contains(@class,'score')]/sup"
        )
    )
    if len(scr_elems) == 2:
        fst = get_num(scr_elems[0])
        snd = get_num(scr_elems[1])
        return fst, snd
    raise co.TennisScoreError("not found two tiesup in _parse_detgame_tiesup_score")
def _parse_detgame_lost_serve_side(parent_elem):
    def is_lost_serve(lostserve_elem):
        span_elem = co.find_first_xpath(
            lostserve_elem, "child::span[contains(text(), 'LOST SERVE')]"
        )
        return span_elem is not None

    lostsrv_elems = list(parent_elem.xpath("child::div[contains(@class,'lostServe')]"))
    if len(lostsrv_elems) == 2:
        if is_lost_serve(lostsrv_elems[0]):
            return co.LEFT
        if is_lost_serve(lostsrv_elems[1]):
            return co.RIGHT
        return None
    else:
        raise co.TennisScoreError(
            "can not find two lostServe elems in _parse_detgame_lost_serve_side"
        )
def _make_next_key(det_score, setnum, cur_score):
    """makes next key for det_score dict. setnum and cur_score are new data.
    cur_score (is 2-tuple). det_score is prev data."""
    keys = list(det_score.keys())
    if len(keys) == 0:
        return (cur_score,)
    last_key = keys[-1]
    last_setnum = len(last_key)
    if last_setnum == setnum:
        return last_key[0 : setnum - 1] + (cur_score,)
    elif (last_setnum + 1) == setnum:
        if det_score[last_key].left_wingame:
            last_set_sc = (last_key[-1][0] + 1, last_key[-1][1])
        else:
            last_set_sc = (last_key[-1][0], last_key[-1][1] + 1)
        return last_key[0 : last_setnum - 1] + (last_set_sc,) + (cur_score,)
    else:
        raise co.TennisScoreError(
            "bad sets seq in _make_next_key {} {} in ".format(last_setnum, setnum)
        )
Example #8
0
def _initialize_results_sex(sex,
                            max_rating,
                            max_rating_dif,
                            min_date=None,
                            max_date=None):
    sql = """select tours.DATE_T, tours.NAME_T, tours.RANK_T, tours.PRIZE_T, 
                   games.ID_R_G, games.RESULT_G, games.ID1_G, games.ID2_G
             from Tours_{0} AS tours, games_{0} AS games, Players_{0} AS fst_plr
             where games.ID_T_G = tours.ID_T 
               and games.ID1_G = fst_plr.ID_P
               and (tours.NAME_T Not Like '%juniors%')
               and (fst_plr.NAME_P Not Like '%/%') """.format(sex)
    sql += dba.sql_dates_condition(min_date, max_date)
    sql += " order by tours.DATE_T;"
    with closing(dba.get_connect().cursor()) as cursor:
        for (
                tour_dt,
                tour_name,
                db_rank,
                db_money,
                rnd_id,
                score_txt,
                fst_id,
                snd_id,
        ) in cursor.execute(sql):
            date = tour_dt.date() if tour_dt else None
            if date is None:
                raise co.TennisScoreError("none date {}".format(tour_name))
            if not score_txt:
                continue
            scr = sc.Score(score_txt)
            if scr.retired:
                continue
            sets_count = scr.sets_count(full=True)
            if sets_count != 3 or scr.best_of_five():
                continue
            set3_score = scr[2]
            if set3_score[0] < set3_score[1]:
                raise co.TennisScoreError(
                    "right winner unexpected {}".format(scr))
            money = oncourt_db.get_money(db_money)
            rank = None if db_rank is None else int(db_rank)
            if rank is None:
                log.error("none rank date: {} scr: {} name: {}".format(
                    date, scr, tour_name))
            if not isinstance(rank, int):
                raise co.TennisError(
                    "not int rank '{}' date: {} scr: {} name: {}".format(
                        rank, date, scr, tour_name))
            rawname, level = oncourt_db.get_name_level(sex, tour_name.strip(),
                                                       rank, money, date)
            if level in DISABLE_LEVELS:
                continue
            if level is None:
                raise co.TennisError(
                    "none level date: {} scr: {} name: {}".format(
                        date, scr, tour_name))
            rnd = tennis.Round.from_oncourt_id(rnd_id)
            soft_level = tennis.soft_level(level, rnd)
            if soft_level is None:
                raise co.TennisError(
                    "none soft_level date: {} scr: {} name: {}".format(
                        date, scr, tour_name))
            mdata = _get_match_data(sex, date, fst_id, snd_id, scr, max_rating,
                                    max_rating_dif)
            if mdata is not None:
                past_monday = tt.past_monday_date(date)
                ywn = tt.get_year_weeknum(past_monday)
                data_dict[(sex, soft_level)][ywn][(mdata.set1_score,
                                                   mdata.set2_score)].hit(
                                                       mdata.decided_win)