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) )
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) )
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)