Paste.1X2.su
Новая паста
Новый пастебин
Обзор
!pip install fake-useragent pandarallel from google.colab import drive drive.mount('/content/gdrive') import bs4 import math import numpy as np import os import pandas as pd import re import requests import warnings from bs4 import BeautifulSoup from dataclasses import dataclass, field from fake_useragent import UserAgent from itertools import product, combinations from pandarallel import pandarallel from tqdm import tqdm from typing import List, Union, Any from collections import Counter import random tqdm().pandas() pandarallel.initialize(progress_bar=True) warnings.filterwarnings("ignore") FILE_PATH = '/content/gdrive/MyDrive/files/' HEADERS = {'User-Agent': UserAgent().chrome} RUN_DATA_HTML = 'toto_cs_home.html' PARSE_HTML = 'toto_current_game.html' BK_LIST_CS = ['BK_1:0', 'BK_2:0', 'BK_2:1', 'BK_3:0', 'BK_3:1', 'BK_3:2', 'BK_0:0', 'BK_1:1', 'BK_2:2', 'BK_3:3', 'BK_0:1', 'BK_0:2', 'BK_1:2', 'BK_0:3', 'BK_1:3', 'BK_2:3', 'BK_Other', ] POOL_LIST_CS = ['Pool_1:0', 'Pool_2:0', 'Pool_2:1', 'Pool_3:0', 'Pool_3:1', 'Pool_3:2', 'Pool_0:0', 'Pool_1:1', 'Pool_2:2', 'Pool_3:3', 'Pool_0:1', 'Pool_0:2', 'Pool_1:2', 'Pool_0:3', 'Pool_1:3', 'Pool_2:3', 'Pool_Other', ] COUPON_PRICE = 0.2 PACKET_SIZE = 125 MB_CS_HOME = 'http://azbet.com/sttot/pbstyle/sttot16.aspx?GMT=+3' CS_WAYS = ['A', 'B', 'C', 'G', 'H', 'I', 'K', 'L', 'M', 'Q', ] CS_UNDER = ['A', 'B', 'G', 'H', 'K', 'L', ] CS_SCORES = ['1:0', '2:0', '2:1', '0:0', '1:1', '2:2', '0:1', '0:2', '1:2', 'ЛД', ] def get_content(url: str, headers: dict): req = requests.get(url, headers=headers) req.raise_for_status() return req.text def write_data(file_path: str, data: str): with open(file_path, "w", encoding='utf-8') as f: f.write(data) def write_csv(file_path: str, data: pd.DataFrame, run: int, html: str): if not os.path.exists(f'{file_path}runs/{run}/'): os.makedirs(f'{file_path}runs/{run}/') data.to_csv(f'{file_path}runs/{run}/run_{run}.csv', mode='w', sep=';', index=False, encoding='utf-8') os.replace(f'{file_path}{html}', f'{file_path}runs/{run}/{html}') def check_variant(variant): char_counter = Counter(variant) variant_max = max(char_counter.values()) if variant else 0 variant_set = len(char_counter) under_ways = sum(1 for ch in variant if ch in CS_UNDER) return variant_max < 4 and variant_set > 4 and under_ways > 2 and under_ways < 6 def probes_normalizer(bk_probes: list): zero_indexes = [3, 4, 5, 9, 13, 14, 15, ] filtered_probes = [] for sublist in bk_probes: updated_sublist = [value for index, value in enumerate(sublist) if index not in zero_indexes] recalculated_probes = [round((value *100 / sum(updated_sublist)), 2) for value in updated_sublist] filtered_probes.append(recalculated_probes) return filtered_probes def ham_distance(incoming_string_1: str, incoming_string_2: str) -> int: return sum(char1 != char2 for char1, char2 in zip(incoming_string_1, incoming_string_2)) def check_candidate(current_candidate: str, checked_candidates: List[str]) -> bool: return all(ham_distance(current_candidate, s) > 2 for s in checked_candidates) def decrement_weights(ways_counts: List[List[int]], step_indices: List[int]): for i, row in enumerate(ways_counts): row[step_indices[i]] -= 1 @dataclass class RunDataParserCS: url: str file_path: str html: str _html_path: str = field(init=False) _src: str = field(init=False) run_url: str = field(init=False) run_number: str = field(init=False) def __post_init__(self): self._html_path = f'{self.file_path}{self.html}' self._parse_probes() self.run_url, self.run_number = self._extract_data() def _parse_probes(self): if os.path.isfile(f'{self._html_path}'): with open(f'{self._html_path}', encoding='utf-8') as file: self._src = file.read() else: _src = get_content(url=self.url, headers=HEADERS) file_writer = write_data(file_path=self._html_path, data=_src) with open(self._html_path, encoding='utf-8') as file: self._src = file.read() def _extract_data(self): soup = BeautifulSoup(self._src, 'html.parser') cs_runs_data = soup.select('tr.sttot-row') cs_runs_info = [] for row in cs_runs_data: cells = row.find_all('td', class_='tt-cell') href, status, run_number = None, None, None if len(cells) > 0: first_cell = cells[0] link = first_cell.find('a') if link: href = link.get('href') link_text = link.get_text(strip=True) run_raw_data = re.search(r'№(\d+)', link_text) run_number = int(run_raw_data.group(1)) if len(cells) > 2: third_cell = cells[2] status = third_cell.get_text(strip=True) cs_runs_info.append((href, status, run_number)) result = next(item for item in cs_runs_info if item[1] == 'Прием') os.remove(f'{self._html_path}') return result[0], result[2] def extract_content_data(data) -> pd.DataFrame: matches_info = [] for i, match in enumerate(data): number = match.find('td', attrs={'class': 'tt-cell-num'}).text.strip() teams = match.find('td', attrs={'class': 'tt-cell'}).text.strip() ways_1 = match.find_all('td', attrs={'class': 'common_1', 'id': f'n{i + 1}'}) ways_X = match.find_all('td', attrs={'class': 'common_x', 'id': f'n{i + 1}'}) ways_2 = match.find_all('td', attrs={'class': 'common_2', 'id': f'n{i + 1}'}) others = match.find_all('td', attrs={'class': 'common_oth', 'id': f'n{i + 1}'}) matches_info.append( { 'Number': number, 'Teams': teams, 'BK_1:0': ways_1[0]['title'].split('/')[0], 'BK_2:0': ways_1[1]['title'].split('/')[0], 'BK_2:1': ways_1[2]['title'].split('/')[0], 'BK_3:0': ways_1[3]['title'].split('/')[0], 'BK_3:1': ways_1[4]['title'].split('/')[0], 'BK_3:2': ways_1[5]['title'].split('/')[0], 'BK_0:0': ways_X[0]['title'].split('/')[0], 'BK_1:1': ways_X[1]['title'].split('/')[0], 'BK_2:2': ways_X[2]['title'].split('/')[0], 'BK_3:3': ways_X[3]['title'].split('/')[0], 'BK_0:1': ways_2[0]['title'].split('/')[0], 'BK_0:2': ways_2[1]['title'].split('/')[0], 'BK_1:2': ways_2[2]['title'].split('/')[0], 'BK_0:3': ways_2[3]['title'].split('/')[0], 'BK_1:3': ways_2[4]['title'].split('/')[0], 'BK_2:3': ways_2[5]['title'].split('/')[0], 'BK_Other': others[0]['title'].split('/')[0], 'Pool_1:0': ways_1[0]['title'].split('/')[1], 'Pool_2:0': ways_1[1]['title'].split('/')[1], 'Pool_2:1': ways_1[2]['title'].split('/')[1], 'Pool_3:0': ways_1[3]['title'].split('/')[1], 'Pool_3:1': ways_1[4]['title'].split('/')[1], 'Pool_3:2': ways_1[5]['title'].split('/')[1], 'Pool_0:0': ways_X[0]['title'].split('/')[1], 'Pool_1:1': ways_X[1]['title'].split('/')[1], 'Pool_2:2': ways_X[2]['title'].split('/')[1], 'Pool_3:3': ways_X[3]['title'].split('/')[1], 'Pool_0:1': ways_2[0]['title'].split('/')[1], 'Pool_0:2': ways_2[1]['title'].split('/')[1], 'Pool_1:2': ways_2[2]['title'].split('/')[1], 'Pool_0:3': ways_2[3]['title'].split('/')[1], 'Pool_1:3': ways_2[4]['title'].split('/')[1], 'Pool_2:3': ways_2[5]['title'].split('/')[1], 'Pool_Other': others[0]['title'].split('/')[1], } ) df_matches_data = pd.DataFrame( columns=['Number', 'Teams', 'BK_1:0', 'BK_2:0', 'BK_2:1', 'BK_3:0', 'BK_3:1', 'BK_3:2', 'BK_0:0', 'BK_1:1', 'BK_2:2', 'BK_3:3', 'BK_0:1', 'BK_0:2', 'BK_1:2', 'BK_0:3', 'BK_1:3', 'BK_2:3', 'BK_Other', 'Pool_1:0', 'Pool_2:0', 'Pool_2:1', 'Pool_3:0', 'Pool_3:1', 'Pool_3:2', 'Pool_0:0', 'Pool_1:1', 'Pool_2:2', 'Pool_3:3', 'Pool_0:1', 'Pool_0:2', 'Pool_1:2', 'Pool_0:3', 'Pool_1:3', 'Pool_2:3', 'Pool_Other']) df_matches_data = pd.concat([df_matches_data, pd.DataFrame(matches_info)], ignore_index=True) df_matches_data[['Number']] = df_matches_data[['Number']].astype('int') df_matches_data[['BK_1:0', 'BK_2:0', 'BK_2:1', 'BK_3:0', 'BK_3:1', 'BK_3:2', 'BK_0:0', 'BK_1:1', 'BK_2:2', 'BK_3:3', 'BK_0:1', 'BK_0:2', 'BK_1:2', 'BK_0:3', 'BK_1:3', 'BK_2:3', 'BK_Other', 'Pool_1:0', 'Pool_2:0', 'Pool_2:1', 'Pool_3:0', 'Pool_3:1', 'Pool_3:2', 'Pool_0:0', 'Pool_1:1', 'Pool_2:2', 'Pool_3:3', 'Pool_0:1', 'Pool_0:2', 'Pool_1:2', 'Pool_0:3', 'Pool_1:3', 'Pool_2:3', 'Pool_Other']] = df_matches_data[['BK_1:0', 'BK_2:0', 'BK_2:1', 'BK_3:0', 'BK_3:1', 'BK_3:2', 'BK_0:0', 'BK_1:1', 'BK_2:2', 'BK_3:3', 'BK_0:1', 'BK_0:2', 'BK_1:2', 'BK_0:3', 'BK_1:3', 'BK_2:3', 'BK_Other', 'Pool_1:0', 'Pool_2:0', 'Pool_2:1', 'Pool_3:0', 'Pool_3:1', 'Pool_3:2', 'Pool_0:0', 'Pool_1:1', 'Pool_2:2', 'Pool_3:3', 'Pool_0:1', 'Pool_0:2', 'Pool_1:2', 'Pool_0:3', 'Pool_1:3', 'Pool_2:3', 'Pool_Other']].astype('float') return df_matches_data @dataclass class ProbesParserCS: url: str file_path: str html: str run_number: int _full_url: str = field(init=False) _html_path: str = field(init=False) def __post_init__(self): self._full_url = f'http://azbet.com/sttot/pbstyle/{self.url}' self._html_path = f'{self.file_path}{self.html}' self._parse_probes() def _parse_probes(self): if os.path.isfile(f'{self.file_path}runs/{self.run_number}/{self.html}'): with open(f'{self.file_path}runs/{self.run_number}/{self.html}', encoding='utf-8') as file: src = file.read() else: src = get_content(url=self._full_url, headers=HEADERS) file_writer = write_data(file_path=self._html_path, data=src) with open(self._html_path, encoding='utf-8') as file: src = file.read() soup = BeautifulSoup(src, 'html.parser') matches = soup.find_all('tr', attrs={'class': 'sttot-row'}) extracting_data = extract_content_data(data=matches) write_csv(file_path=f'{self.file_path}', data=extracting_data, run=self.run_number, html=self.html) @dataclass class ProbesArrayCS: file_path: str run: int columns_bk: list columns_pool: list run_probes_bk_prep: list = field(init=False) run_probes_pool: list = field(init=False) run_probes_bk: list = field(init=False) def __post_init__(self): self.run_probes_bk_prep = self._get_probes_array(self.columns_bk) self.run_probes_pool = self._get_probes_array(self.columns_pool) self.run_probes_bk = [ self.run_probes_pool[i] if (sum(self.run_probes_bk_prep[i]) == 0) else self.run_probes_bk_prep[i] for i in range(len(self.run_probes_bk_prep))] def _get_probes_array(self, incoming_probes: list) -> list: df = pd.read_csv(f'{self.file_path}runs/{self.run}/run_{self.run}.csv', sep=';', decimal='.') probes_arr = df[incoming_probes].copy().values.tolist() del df return probes_arr @dataclass class WaysCount: probes_bk_list: List[List[float]] total_ways: int result_ways_list: List[List[int]] = field(init=False) def __post_init__(self): self.result_ways_list = self._run() def _run(self): int_parts = [[math.floor(x) for x in row] for row in self.probes_bk_list] frac_parts = [[round(x - math.floor(x), 2) for x in row] for row in self.probes_bk_list] ways_count = [[int((self.total_ways * x) / 100) for x in row] for row in self.probes_bk_list] ways_sum = [sum(row) for row in ways_count] sorted_indices = [[idx for idx, _ in sorted(enumerate(row), key=lambda x: x[1], reverse=True)] for row in frac_parts] ways_deficit = [(self.total_ways - x) for x in ways_sum] for i, deficit in enumerate(ways_deficit): if deficit <= 0: continue # Берем первые deficit индексов (не больше длины подсписка) indices_to_increment = sorted_indices[i][:deficit] for j in indices_to_increment: ways_count[i][j] += 1 return ways_count @dataclass class PacketCreator: ways_count: List[List[int]] packet_size: int incomming_variants: List[str] = field(default_factory=list) _most_common_indexes: List[int] = field(init=False) _ways_count_dec: List[List[int]] = field(init=False) packet_list: List[str] = field(init=False) def __post_init__(self): self._most_common_indexes = [0, 2, 4, 6, 8, 9, ] self._ways_count_dec = [[(value + 2) if index in self._most_common_indexes else (value + 1) for index, value in enumerate(sublist)] for sublist in self.ways_count] self.packet_list = self._run_until_zero() def _generate_candidate(self): # функция генерации индексов случайного варианта. Чем больше по количеству преобладает какой-то исход, тем больше шансов у него быть сгенерированным selected = [] for row in self._ways_count_dec: available = [j for j, v in enumerate(row) if v > 0] if not available: continue weights = [row[j] for j in available] chosen_j = random.choices(population=available, weights=weights, k=1)[0] selected.append(chosen_j) return selected def _run_until_zero(self): # функция основной логики формирования пакета history = self.incomming_variants.copy() while len(history) < (len(self.incomming_variants) + self.packet_size): step_indices = self._generate_candidate() if not step_indices: break step_variant = ''.join(CS_WAYS[i] for i in step_indices) # из сгенерированных индексов воссоздаем вариант if check_variant(variant=step_variant) and check_candidate(current_candidate=step_variant, checked_candidates=history): # проверяем, чтобы сгенерированный вариант не прилегал слишком близко к уже ранее сгенерированным вариантам и не создавал ненужные перекрытия history.append(step_variant) # если вариант подходит, добавляем в финальный пакет decrement_weights(ways_counts=self._ways_count_dec, step_indices=step_indices) # если вариант подходит, уменьшаем счетчики всех входящих в него исходов, чтобы при следующей генерации выпали варианты с и с другими исходами, а не было перекоса в сторону лишь одного исхода else: continue return history @dataclass class CouponCSForBetting: incoming_list: Any price: Union[int, float, str] file_path: str run_number: int = field(default=None) file_name: str = field(init=False) prepared_variants_list: List[str] = field(init=False) number_of_tickets: int = field(init=False) def __post_init__(self): self.number_of_tickets = len(self.incoming_list) self.file_name = self._create_filename() self.prepared_variants_list = self._create_coupons() self._strip_quotes() def _create_filename(self): return f'{self.file_path}runs/{self.run_number}/run{self.run_number}_{self.number_of_tickets}tickets.txt' def _create_coupons(self) -> List[str]: if not isinstance(self.incoming_list, (list, tuple)): self.incoming_list = [self.incoming_list] result = [] for variant in self.incoming_list: coupon = f'{self.price}|' for i in range(0, 8): searched_index = CS_WAYS.index(variant[i]) replaced_element = CS_SCORES[searched_index] coupon += str(i + 1) + f'-({replaced_element})' if i != 7: coupon += ';' else: coupon += '#' result.append(coupon) return result def _write_file(self): with open(f'{self.file_name}', 'w') as f: for line in self.prepared_variants_list: f.write(''.join(line) + '\n') def _strip_quotes(self) -> None: if self.run_number: with open(f'{self.file_name}', 'w') as f: for line in self.prepared_variants_list: f.write(''.join(line) + '\n') self._write_file() def main(): RunDataParserCS(MB_CS_HOME, FILE_PATH, RUN_DATA_HTML) run_url = RunDataParserCS(MB_CS_HOME, FILE_PATH, RUN_DATA_HTML).run_url run_number = RunDataParserCS(MB_CS_HOME, FILE_PATH, RUN_DATA_HTML).run_number ProbesParserCS(run_url, FILE_PATH, PARSE_HTML, run_number=run_number) run_settings = ProbesArrayCS(file_path=FILE_PATH, run=run_number, columns_bk=BK_LIST_CS, columns_pool=POOL_LIST_CS) run_probes_bk = run_settings.run_probes_bk run_probes_value_normalized = probes_normalizer(bk_probes=run_probes_bk) ways_count = WaysCount(probes_bk_list=run_probes_value_normalized, total_ways=PACKET_SIZE).result_ways_list result_packet = PacketCreator(ways_count=ways_count, packet_size=PACKET_SIZE).packet_list final_action = CouponCSForBetting(incoming_list=result_packet, price=COUPON_PRICE, file_path=FILE_PATH, run_number=run_number) if __name__ == '__main__': main()
Настройки пасты
Название :
[Опционально]
Paste Folder :
[Опционально]
Select
Подсветка синтаксиса :
[Опционально]
Select
Markup
CSS
JavaScript
Bash
C
C#
C++
Java
JSON
Lua
Plaintext
C-like
ABAP
ActionScript
Ada
Apache Configuration
APL
AppleScript
Arduino
ARFF
AsciiDoc
6502 Assembly
ASP.NET (C#)
AutoHotKey
AutoIt
Basic
Batch
Bison
Brainfuck
Bro
CoffeeScript
Clojure
Crystal
Content-Security-Policy
CSS Extras
D
Dart
Diff
Django/Jinja2
Docker
Eiffel
Elixir
Elm
ERB
Erlang
F#
Flow
Fortran
GEDCOM
Gherkin
Git
GLSL
GameMaker Language
Go
GraphQL
Groovy
Haml
Handlebars
Haskell
Haxe
HTTP
HTTP Public-Key-Pins
HTTP Strict-Transport-Security
IchigoJam
Icon
Inform 7
INI
IO
J
Jolie
Julia
Keyman
Kotlin
LaTeX
Less
Liquid
Lisp
LiveScript
LOLCODE
Makefile
Markdown
Markup templating
MATLAB
MEL
Mizar
Monkey
N4JS
NASM
nginx
Nim
Nix
NSIS
Objective-C
OCaml
OpenCL
Oz
PARI/GP
Parser
Pascal
Perl
PHP
PHP Extras
PL/SQL
PowerShell
Processing
Prolog
.properties
Protocol Buffers
Pug
Puppet
Pure
Python
Q (kdb+ database)
Qore
R
React JSX
React TSX
Ren'py
Reason
reST (reStructuredText)
Rip
Roboconf
Ruby
Rust
SAS
Sass (Sass)
Sass (Scss)
Scala
Scheme
Smalltalk
Smarty
SQL
Soy (Closure Template)
Stylus
Swift
TAP
Tcl
Textile
Template Toolkit 2
Twig
TypeScript
VB.Net
Velocity
Verilog
VHDL
vim
Visual Basic
WebAssembly
Wiki markup
Xeora
Xojo (REALbasic)
XQuery
YAML
HTML
Удалить :
[Опционально]
Никогда
Самоуничтожение
10 минут
1 час
1 день
1 неделя
2 недели
1 месяц
6 месяцев
1 год
Тип пасты :
[Опционально]
Публичный
Скрытый
Приватный (только для пользователей)
Пароль :
[Опционально]
Описание:
[Опционально]
Tags:
[Опционально]
Encrypt Paste
(
?
)
Создать новую пасту
You are currently not logged in, this means you can not edit or delete anything you paste.
Sign Up
или
Login