def _setup_canvas(table_frame, data: List[List[str]], column_widths: List[int] = None, height=200, width=None): if not column_widths: column_widths = _get_columns_widths(data) if not width: cells_width = sum(column_widths) * 8 # text len * char size cells_ipadx = len(column_widths) * 8 # inner padding # borders_width = len(column_widths) width = (cells_width + cells_ipadx) log.debug(f"got canvas width: {width}") canvas = Canvas(table_frame, borderwidth=0) canvas_frame = Frame(canvas) vsb = Scrollbar(table_frame, orient="vertical", command=canvas.yview) canvas.configure(yscrollcommand=vsb.set, width=width, heigh=height) vsb.pack(side="right", fill="y") canvas.pack(side="left", fill="both", expand=True) canvas.create_window((4, 4), window=canvas_frame, anchor="nw", tags="frame") # be sure that we call OnFrameConfigure on the right canvas canvas_frame.bind("<Configure>", lambda event, canvas=canvas: _OnFrameConfigure(canvas)) _fill_data(canvas_frame, data, column_widths)
def _get_columns_widths(data: List[List[str]]) -> List[int]: widths = [len(cell) for cell in data[0]] for row in data: for idx, cell in enumerate(row): widths[idx] = max(len(cell), widths[idx]) log.debug(f"columns widths: {widths}") return widths
def _get_values(self) -> Optional[Tuple[str, float, float, float]]: try: return self._var_title.get(), self._var_ratio_1.get( ), self._var_ratio_x.get(), self._var_ratio_2.get() except Exception as ex: log.debug( f"Exception while getting manual matches input values: {ex}") messagebox.showerror("Invalid input", "Try again with different values!") return None
def _get_from_to_values(text: str, max_value: int): try: values = tuple(int(value) for value in text.strip().split(" ")) if len(values) == 1: values = (values[0], values[0]) except ValueError: values = 0, max_value log.debug("got from-to values:", str(values)) return values
def __init__(self, parent, get_stats): log.debug(f"creating {type(self).__name__}...") super().__init__(parent, text=" Reports ") self.get_stats = get_stats Label(self, text="Report type: ").grid(row=0, column=0) self.combo_report = Combobox(self, values=self.REPORTS, state="readonly") self.combo_report.current(0) self.combo_report.grid(row=0, column=1, padx=PAD_X, pady=PAD_Y) Button(self, text="View", command=self.view_report).grid(row=0, column=2) Button(self, text="Save", command=self.save_report).grid(row=0, column=3)
def _get_pasted_matches(self) -> Optional[Matches]: try: log.debug("parsing pasted matches...") matches = Matches.PARSERS[self._get_pasted_text_fmt()]( self._get_pasted_text()) if matches: log.debug( f" got [{len(matches)}] new matches!\n{matches.table}") return matches except Exception as ex: log.exception("Error while parsing pasted matches!") messagebox.showerror("Error while parsing pasted text!", f" Exception: {str(ex)}, args:{ex.args}") return None
def test_delete(): tmp_dir = Path(gettempdir()).absolute().joinpath("tmp_dir_for_deletion") tmp_dir.mkdir() inner_dirs = ["d1", "d2", "d3"] inner_paths = [tmp_dir.joinpath(d) for d in inner_dirs] for ip in inner_paths: ip.mkdir(parents=True, exist_ok=True) inner_file = ip.joinpath("file.txt") log.debug(f'writing text to: {str(inner_file)}') inner_file.write_text("msome_Text", encoding="utf-8") log.debug(f"created temp dir structure at: {tmp_dir}") sys_util.delete(str(tmp_dir)) assert not tmp_dir.exists()
def __init__(self, parent, set_stats): log.debug(f"creating {type(self).__name__}...") super().__init__(parent, text=" Load Stats ") self.parent = parent self.set_stats = set_stats Label(self, text="Pick stats file: ").grid(row=0, column=0, sticky=W) self.file_input = Entry(self, width=60, text="Not set!", state="readonly") self.file_input.grid(row=0, column=1, sticky=EW) Button(self, text="Browse", command=self._browse_for_stats).grid(row=0, column=2, sticky=E) Button(self, text="Use Bundled", command=self._use_bundled_stats).grid(row=0, column=3, sticky=E) for child in self.winfo_children(): child.grid_configure(padx=PAD_X, pady=PAD_Y, sticky=EW)
def write_sheets(sheets: Dict[str, List[Dict[str, Union[int, float, str]]]], file: str): """ Writes multiple sheets data to a file. The column names for each sheet are the keys of the first dict record. Automatically suffixes the file name with .xlsx if missing Arguments: sheets(dict) A dict with format { "sheet name": [ sheet records as dicts ] } file(str) The output destination file Returns: dst_path(str) Absolute path to the output file """ dst_path = str(Path(file if file.endswith(".xlsx") else f"{file}.xlsx").absolute()) log.info(f"writing sheets data to [{file}] -> [{dst_path}]...") output_workbook = Workbook() for sheet_name, sheet_records in sheets.items(): if isinstance(sheet_name, float): sheet_name = f"{sheet_name:.02f}" sheet = output_workbook.add_sheet(sheet_name) sheet.show_headers = True columns = list(sheet_records[0].keys()) # write the headers for column_index, column_name in enumerate(columns): sheet.write(0, column_index, column_name) # write the records for row_index, record in enumerate(sheet_records): for column_index, column_name in enumerate(columns): value = record[column_name] if isinstance(value, float): sheet.write(row_index + 1, column_index, value, FLOAT_FMT) else: sheet.write(row_index + 1, column_index, value) output_workbook.save(dst_path) log.debug(f"done writing sheets data:\n{sheets}") return dst_path
def read_sheets(file: str) -> Dict[str, List[Dict[str, Union[int, float, str]]]]: src_path = str(Path(file).absolute()) log.debug(f"reading sheets data from: [{file}] -> [{src_path}]...") result = dict() with open_workbook(file) as workbook: for worksheet in workbook.sheets(): result[worksheet.name] = [] headers = [worksheet.cell_value(0, column_index) for column_index in range(worksheet.ncols)] for row_index in range(1, worksheet.nrows): row_data = {headers[column_index]: worksheet.cell_value(row_index, column_index) for column_index in range(worksheet.ncols)} result[worksheet.name].append(row_data) log.debug(f"done reading sheets data:\n{result}") return result
def __init__(self, parent, get_all, get_selection, set_selection): log.debug(f"creating {type(self).__name__}...") super().__init__(parent, text=" Filters ") self.parent = parent self.get_all = get_all self.get_selection = get_selection self.set_selection = set_selection Label(self, text="Country: ").grid(row=0, column=0, padx=PAD_X, pady=PAD_Y, sticky=EW) self.cb_country = Combobox(self, state="readonly", values=("All",), width=30) self.cb_country.bind("<<ComboboxSelected>>", self.apply_country_filter) self.cb_country.grid(row=0, column=1, padx=PAD_X, pady=PAD_Y, sticky=EW) self.cb_country.current(0) Label(self, text="Tournament: ").grid(row=0, column=2, padx=PAD_X, pady=PAD_Y, sticky=EW) self.cb_tournament = Combobox(self, state="readonly", values=("All",), width=50) self.cb_tournament.bind("<<ComboboxSelected>>", self.apply_tournament_filter) self.cb_tournament.current(0) self.cb_tournament.grid(row=0, column=3, padx=PAD_X, pady=PAD_Y, sticky=EW) Button(self, text="Reset", command=self.reset_filters).grid(row=0, column=4)
def get_ranks(first: float, second: float, third: float) -> Tuple[str, str, str]: """Gets the ranks of 3 values. Examples: >>> get_ranks(1,2,3) ('min', 'med', 'max') >>> get_ranks(1,2,2) ('min', 'med/max', 'med/max') """ all_ratios = (first, second, third) sorted_ratios = list(sorted(all_ratios)) ranks = [] for idx, ratio in enumerate(all_ratios): ratio_ranks = [] for sorted_ratio, rank in zip(sorted_ratios, ("min", "med", "max")): if ratio == sorted_ratio: ratio_ranks.append(rank) ranks.append("/".join(ratio_ranks)) log.debug(f"ranks of: {all_ratios} -> {ranks}") return tuple(ranks)
def get_tmp_location(path: str) -> str: log.debug(f"getting temp location for: [{path}]") src_path = Path(path) log.debug(f"got src path: [{str(src_path)}]") tmp_path = str( Path(gettempdir()).joinpath("".join( [src_path.stem, "_tmp_", get_utc_timestamp(), src_path.suffix]))) log.debug(f"got temp location: [{tmp_path}]") return tmp_path
def delete(path: str): path = Path(path) if not path.exists(): # pragma: no cover raise FileNotFoundError(str(path)) if path.is_file(): log.debug(f"deleting file at: [{str(path)}]") path.unlink() return if path.is_dir(): log.debug(f"deleting dir contents: [{str(path)}]") for child_path in path.iterdir(): delete(str(child_path)) log.debug(f"deleting dir at: [{str(path)}]") path.rmdir()
def copy(src_path: str, dst_path: str, exists_ok=False) -> str: log.debug(f"copying from [{src_path}] to [{dst_path}]") src_path = Path(src_path).absolute() if not src_path.exists(): # pragma: no cover raise FileNotFoundError(str(src_path)) dst_path = Path(dst_path).absolute() if dst_path.exists(): # pragma: no cover if exists_ok: delete(str(dst_path)) else: raise FileExistsError(str(dst_path)) if src_path.is_file(): log.debug( f"copying file from: [{str(src_path)}] to: [{str(dst_path)}]") return copyfile(str(src_path), str(dst_path)) if src_path.is_dir(): # pragma: no cover log.debug(f"copying dir from: [{str(src_path)}] to: [{str(dst_path)}]") return copytree(str(src_path), str(dst_path))
def _export_matches(self): title = "Matches" columns = self.matches.columns rows = [m.values for m in self.matches] log.debug(f"title:{title}\ncolumns:{columns}\nrows:{rows}") TableFrame(title, columns, rows)
def write_text(text: str, file: str): path = Path(file).absolute() log.debug(f"writing text to: [{str(path)}] ({len(text)} chars)") with path.open("wb") as out: out.write(text.encode("utf-8"))
def __init__(self, title, ratio_1, ratio_x, ratio_2): log.debug("creating Match(" "title={title}, " "ratio_1={ratio_1}, " "ratio_x={ratio_x}, " "ratio_2={ratio_2})...".format(title=title, ratio_1=ratio_1, ratio_x=ratio_x, ratio_2=ratio_2)) self.title = title self.ratio_1 = parse_float(ratio_1) self.ratio_x = parse_float(ratio_x) self.ratio_2 = parse_float(ratio_2) self.ratio_min, self.ratio_med, self.ratio_max = sorted( (self.ratio_1, self.ratio_x, self.ratio_2)) self.ratios = { "1": self.ratio_1, "X": self.ratio_x, "2": self.ratio_2, } self.ranks = { "min": self.ratio_min, "med": self.ratio_med, "max": self.ratio_max, } self.outcome_ranks = {"1": [], "X": [], "2": []} self.ranks_outcomes = { "min": [], "med": [], "max": [], } self.ranks_ratios = {} for outcome, outcome_ratio in self.ratios.items(): for rank, rank_ratio in self.ranks.items(): if outcome_ratio == rank_ratio: self.outcome_ranks[outcome].append(rank) self.ranks_outcomes[rank].append(outcome) self.ranks_ratios[rank] = rank_ratio for outcome, ranks in self.outcome_ranks.items(): if len(ranks) > 1: self.outcome_ranks[outcome] = "/".join(ranks) else: self.outcome_ranks[outcome] = ranks[0] for rank, outcomes in self.ranks_outcomes.items(): if len(outcomes) > 1: self.ranks_outcomes[rank] = "/".join(outcomes) else: self.ranks_outcomes[rank] = outcomes[0] self.tuple = ((title, ) + tuple(self.ratios.values()) + tuple(self.outcome_ranks.values()) + tuple(self.ranks_ratios.values()) + tuple(self.ranks_outcomes.values()))
def __init__(self, parent, text): log.debug(f"creating {type(self).__name__}...") super().__init__(parent, text=text)
def copy_to_tmp(src_path: str) -> str: dst_path = get_tmp_location(src_path) log.debug( f"copying [{str(src_path)}] to temp location: [{str(dst_path)}]...") return copy(str(src_path), str(dst_path), exists_ok=True)