def work(self): tbeg = time.perf_counter() _drv.live_page_refresh() events = get_events( _drv.page(), skip_levels=skip_levels_work(), match_status=MatchStatus.scheduled, ) for event in events: if self.is_event_towork(event): if (event.sex, event.tour_name) in _tourinfo_cache: tour_id, level, surface = _tourinfo_cache[( event.sex, event.tour_name)] event.tour_id = tour_id event.tour_info.level = level event.tour_info.surface = surface event.define_features() tour = co.find_first( weeked_tours.tail_tours(event.sex), lambda t: t.ident == event.tour_id, ) if tour is not None: for match in event.matches: if self.is_match_towork(match): match.define_players("FS", event.sex) # weeked_tours may updated: match.fill_details_tried = False match.fill_details(tour) log_preparing_match(match, comment='YEScached') self.prepare(match) else: # two next statements makes more long algo event.define_features() event.define_players(company_name="FS") event.define_level() if event.tour_info is not None and event.tour_id is not None: tour = co.find_first( weeked_tours.tail_tours(event.sex), lambda t: t.ident == event.tour_id, ) if tour is not None: for match in event.matches: if self.is_match_towork(match): # weeked tours may updated match.fill_details_tried = False match.fill_details(tour) log_preparing_match(match, comment='NOTcached') self.prepare(match) if event.tour_id is not None: _tourinfo_cache[(event.sex, event.tour_name)] = ( event.tour_id, event.level, event.surface, ) self.work_count += 1 tend = time.perf_counter() log.info(f"MatchDataScript work done in {tend - tbeg:0.1f} seconds")
def player_features(features: List[Feature], name: str) -> Tuple[Feature, Feature]: f1 = co.find_first(features, lambda f: f.name == "fst_" + name) if not f1: raise cco.FeatureError("not found/empty {}".format("fst_" + name)) f2 = co.find_first(features, lambda f: f.name == "snd_" + name) if not f2: raise cco.FeatureError("not found/empty {}".format("snd_" + name)) return f1, f2
def complete_with_today(tours, today_tours, with_unscored_matches=False): """дополняем tours недостающими матчами из today_tours (или целыми недост. тур-ми). Предв-но из today_tours del матчи без счета-рез-та (if not with_unscored_matches) """ def same_players(fst_match, snd_match): if ( fst_match.first_player is None or fst_match.second_player is None or snd_match.first_player is None or snd_match.second_player is None ): return False if ( not fst_match.first_player.name or not fst_match.second_player.name or not snd_match.first_player.name or not snd_match.second_player.name ): return False return ( fst_match.first_player.name == snd_match.first_player.name and fst_match.second_player.name == snd_match.second_player.name ) or ( fst_match.first_player.name == snd_match.second_player.name and fst_match.second_player.name == snd_match.first_player.name ) def remain_scored_tours(tours): for tidx in list(reversed(list(range(len(tours))))): tour = tours[tidx] for rnd in list(tour.matches_from_rnd.keys()): for midx in list( reversed(list(range(len(tour.matches_from_rnd[rnd])))) ): match = tour.matches_from_rnd[rnd][midx] if match.score is None: del tour.matches_from_rnd[rnd][midx] if len(tour.matches_from_rnd[rnd]) == 0: del tour.matches_from_rnd[rnd] if len(tour.matches_from_rnd) == 0: del tours[tidx] if not with_unscored_matches: remain_scored_tours(today_tours) for today_tour in today_tours: tour = co.find_first(tours, lambda t, tot=today_tour: t.ident == tot.ident) if tour is None: tours.append(today_tour) else: for rnd in today_tour.matches_from_rnd.keys(): for tm in today_tour.matches_from_rnd[rnd]: match = co.find_first( tour.matches_from_rnd[rnd], lambda m, tom=tm: same_players(m, tom), ) if match is None and tm.first_player and tm.second_player: tour.matches_from_rnd[rnd].append(copy.deepcopy(tm))
def prep_plr_feature(name): fst_name = f"fst_{name}" snd_name = f"snd_{name}" fst_feat = co.find_first(match.features, lambda f: f.name == fst_name) snd_feat = co.find_first(match.features, lambda f: f.name == snd_name) if fst_feat is not None and snd_feat is not None: dct[fst_name] = fst_feat.value dct[snd_name] = snd_feat.value
def prep_plr_sv_feature(name): fst_name = f"fst_{name}" snd_name = f"snd_{name}" fst_feat = co.find_first(match.features, lambda f: f.name == fst_name) snd_feat = co.find_first(match.features, lambda f: f.name == snd_name) if (fst_feat is not None and snd_feat is not None and isinstance(fst_feat.value, (SizedValue, WinLoss)) and isinstance(snd_feat.value, (SizedValue, WinLoss))): dct[fst_name] = (fst_feat.value.value, fst_feat.value.size) dct[snd_name] = (snd_feat.value.value, snd_feat.value.size)
def after_retired_results(idents: Set[int], sex: str, date: datetime.date) -> List[PlayerResult]: """ fetch from db. Вернет тех, кто retired in [date - MAX_DAYS_FOR_RETIRED, date), и после этого не играл """ min_date = date - datetime.timedelta(MAX_DAYS_FOR_RETIRED) ret_results = get_presence_results(idents, sex, min_date=min_date, max_date=date, with_retired=True) ret_idents = {r.id for r in ret_results} noret_results = get_presence_results(ret_idents, sex, min_date=min_date, max_date=date, with_retired=False) results = [] for pr in ret_results: noret_res = co.find_first(noret_results, lambda r: r.id == pr.id) if noret_res.days_ago < pr.days_ago: continue # after retired player was active results.append(pr) return results
def read_pers_det(self, sex): if self.ident is None: return player = co.find_first(oncourt_players.players(sex), lambda p: p.ident == self.ident) if player is not None: self.lefty = player.lefty
def mixed(self, other_report_lines): mixed_lines = [] for report_line in self._report_lines: rl_key = report_line.key oposite_line = co.find_first( other_report_lines, predicate=lambda x, rk=rl_key: x.key == rk) if oposite_line: mixed_lines.append(report_line + oposite_line) else: mixed_lines.append(report_line) for report_line in other_report_lines: if (co.find_first(mixed_lines, predicate=lambda x: x.key == report_line.key) is None): mixed_lines.append(report_line) return ReportLineList(items=mixed_lines)
def recently_won_h2h_side(self): feat = co.find_first(self.features, lambda f: f.name == "recently_winner_id") if feat and feat.value: winner_pid = feat.value if winner_pid == self.first_player.ident: return co.LEFT elif winner_pid == self.second_player.ident: return co.RIGHT
def get_score(self, tour_id, rnd, left_id, right_id): if self.records: match_rec = co.find_first( self.records, (lambda r: r.tour_id == tour_id and r.rnd == rnd and r.left_id == left_id and r.right_id == right_id), ) if match_rec is not None: return match_rec.score
def test_find_wang_in_oncourt_players(self): plr: Player = co.find_first( self.players_wta, lambda p: p.cou == 'CHN' and p.disp_name( "flashscore") == "Wang Xin.") self.assertTrue(plr is not None) if plr is not None: self.assertTrue(plr.ident is not None) self.assertEqual(plr.name, "Xin Yu Wang") self.assertEqual(plr.disp_name('betfair'), "Xinyu Wang")
def get_predict_result_proba(self, sex: str, date: datetime.date, case_name: str, back_id: int, oppo_id: int): if self.records: rec = co.find_first( self.records, (lambda r: r.sex == sex and r.date == date and r.case_name == case_name and r.back_id == back_id and r.oppo_id == oppo_id), ) if rec is not None: return rec.predict_result, rec.predict_proba
def identify_player(company_name, sex, player_short_name, cou=None): if company_name == "FS": company_key = "flashscore" else: raise co.TennisError( "unexpected company_name '{}'".format(company_name)) if cou is None: player = co.find_first( oncourt_players.players(sex), lambda p: p.disp_name(company_key) == player_short_name, ) else: player = co.find_first( oncourt_players.players(sex), lambda p: p.cou == cou and p.disp_name(company_key) == player_short_name, ) if player is not None: return player abbrname = AbbrName(player_short_name) return abbrname.find_player(oncourt_players.players(sex), sex)
def fill_matches_details(self): if self.tour_info is not None and self.tour_id is not None: tour = co.find_first( weeked_tours.tail_tours(self.sex), lambda t: t.ident == self.tour_id ) if tour is None: log.error( "no found tour by id {} for {}".format(self.tour_id, str(self)) ) return for match in self.matches: match.fill_details(tour) self.filled_matches_key = copy.copy(self.matches_key)
def find_dboffer(sex, tour_id, fst_plr_id, snd_plr_id, bettor_id): dboffers = db_offers(sex, bettor_id=bettor_id) predicate = lambda o: o.tour_id == tour_id and ( (o.first_player_id == fst_plr_id and o.second_player_id == snd_plr_id) or (o.first_player_id == snd_plr_id and o.second_player_id == fst_plr_id) ) db_offer = co.find_first(dboffers, predicate) if db_offer is not None: if db_offer.win_coefs: if ( db_offer.first_player_id == snd_plr_id and db_offer.second_player_id == fst_plr_id ): db_offer.flip() return db_offer
def fill_offer(self, sex, tour_id, tour_date, alter_bettor): """alter_bettor: None - only try1 default bettor; False try1 default then if fail try2 alter bettor; True try2 alter bettor. """ if alter_bettor: bettor_id = bet_coefs.ALTER_BETTOR else: bettor_id = bet_coefs.DEFAULT_BETTOR db_offers = bet_coefs.db_offers(sex, tour_date, bettor_id) predicate = (lambda o: o.tour_id == tour_id and o.rnd == self.rnd and ( (o.first_player_id == self.first_player.ident and o. second_player_id == self.second_player.ident) or (o.first_player_id == self.second_player.ident and o. second_player_id == self.first_player.ident))) if self.rnd is None: predicate = lambda o: o.tour_id == tour_id and ( (o.first_player_id == self.first_player.ident and o. second_player_id == self.second_player.ident) or (o.first_player_id == self.second_player.ident and o. second_player_id == self.first_player.ident)) db_offer = co.find_first(db_offers, predicate) if db_offer is not None: if self.rnd is None and db_offer.rnd is not None: self.rnd = db_offer.rnd self.offer.company = db_offer.company if db_offer.win_coefs: self.offer.win_coefs = db_offer.win_coefs if db_offer.total_coefs: self.offer.total_coefs = db_offer.total_coefs if db_offer.sets_coefs: self.offer.sets_coefs = db_offer.sets_coefs if db_offer.handicap_coefs: self.offer.handicap_coefs = db_offer.handicap_coefs if (db_offer.first_player_id == self.second_player.ident and db_offer.second_player_id == self.first_player.ident): self.offer.flip() return True # ok elif alter_bettor is False: # it was try1 failed if bet_coefs.ALL_BETTORS: return self.fill_offer(sex, tour_id, tour_date, alter_bettor=True) else: log.warn( "bet_coefs.ALL_BETTORS=False with try2 in {}".format(self)) return False
def report_threshold(self, dirname, threshold): pid_wl_list = [ (pid, wl) for (thr, pid), wl in self.data_dict.items() if thr == threshold and wl.size >= self.min_size ] pid_wl_list.sort(key=lambda i: i[1].ratio, reverse=False) shortname = "fav_{:.2f}".format(threshold).replace(".", "") filename = os.path.join(dirname, "{}.txt".format(shortname)) with open(filename, "w") as fh: for pid, wl in pid_wl_list: plr = co.find_first( self.actual_players, predicate=lambda p: p.ident == pid ) if plr: fh.write("{}__{}\n".format(plr, wl))
def _find_player(sex: str, disp_name: str, cou: str): cache = wta_today_players_cache if sex == "wta" else atp_today_players_cache if cache: return cache[(disp_name, cou)] if deep_find_player_mode: plr = player_name_ident.identify_player("FS", sex, disp_name, cou) if init_players_cache_mode: if plr is not None: cache[(disp_name, cou)] = plr else: log.warn("fail player ident {} '{}' {}".format( sex, disp_name, cou)) return plr else: return co.find_first( oncourt_players.players(sex), lambda p: p.cou == cou and p.disp_name("flashscore") == disp_name, )
def __find_player(self, name): if name: return co.find_first(self.players, lambda p: p.name == name)
def find_tail_tour_by_id(sex, tour_id): if sex not in tail_tours_from_sex: init_tail_tours(sex) return co.find_first(tail_tours_from_sex[sex], lambda t: t.ident == tour_id)
def get_marathon_company(): return co.find_first(companies, lambda c: c.name == "Mar")
def get_pinnacle_company(): return co.find_first(companies, lambda c: c.name == "Pin")
def avgset(self): feat = co.find_first(self.features, lambda f: f.name == "tour_avgset") if feat is not None: return feat.value
def get_betcity_company(): return co.find_first(companies, lambda c: c.name == "BC")
def is_player_feature(features: List[Feature], name: str, is_first: bool) -> bool: prefix = "fst_" if is_first else "snd_" feat = co.find_first(features, lambda f: f.name == (prefix + name)) return feat is not None and not feat.empty()
def player_feature(features: List[Feature], name: str, is_first: bool) -> Feature: prefix = "fst_" if is_first else "snd_" feat = co.find_first(features, lambda f: f.name == (prefix + name)) if feat is None or feat.value is None: raise cco.FeatureError("not found/empty {}".format(prefix + name)) return feat
def get_company_by_id(ident): return co.find_first(companies, lambda c: c.ident == ident)
def get_player(sex, pid): """convenient for debugs/tests/experiments""" return co.find_first(players(sex), lambda p: p.ident == pid)