import os
import logging
from dotenv import load_dotenv
from ingestion.logconfig import c_handler
# from ingestion.logconfig import f_handler

# Setup Logger
logger = logging.getLogger(__name__)
logger.setLevel('DEBUG')
logger.addHandler(c_handler)
# logger.addHandler(f_handler)

class BatchIngestor:
    '''
    Represents a base class for ingestor.

    Params:
        bearer_token = [str] Twitter's BearerToken.
        query_params = [dict] Query and filds to request the API, please see Twitter's API Documentation for more info.
        n_requests = [int] Number of hits at the API to pull tweets.
        api_cls = [subclass of TweetOauth2API] API Object to pull tweets.
        writers_cls = [class FileWriter or list of FileWriter] Class responsible for writing data permanently, more than one writer can be used.
        folder_name = [str] Optional. Folder name, usually API's name.
    '''

    def __init__(self, query_params, n_requests, api_cls, folder_name, writers_cls):
        if os.getenv('ENVIRONMENT') == "local":
            load_dotenv()
        self.api_cls = api_cls
        self.bearer_token = os.environ.get("BEARER_TOKEN")
        self.query_params = query_params
        self.n_requests = n_requests
        self.folder_name = folder_name
        if not isinstance(writers_cls, list):
            self.writers_cls = [writers_cls]
        else:
            self.writers_cls = writers_cls
            logger.debug("List of writers ",self.writers_cls)

    def _get_data(self):
        return self.api_cls(self.bearer_token).get_tweets(self.query_params, self.n_requests)

    def ingest(self):
        data = self._get_data()
        for writer in self.writers_cls:
            writer(self.folder_name).write_file(data)


import json
import psycopg2

def create_database(database_name: str, params: dict):
    """Создание базы данных и таблиц для сохранения данных."""

    conn = psycopg2.connect(dbname='postgres', **params)
    conn.autocommit = True
    cur = conn.cursor()

    cur.execute(f"DROP DATABASE IF EXISTS {database_name}")
    cur.execute(f"CREATE DATABASE {database_name}")

    cur.close()
    conn.close()

    conn = psycopg2.connect(dbname=database_name, **params)

    with conn.cursor() as cur:
        cur.execute("""CREATE TABLE employers (
                    id_employer SERIAL PRIMARY KEY,
                    name VARCHAR(255) NOT NULL,
                    url_employer TEXT,
                    open_vacancies INTEGER
                )
            """)

    with conn.cursor() as cur:
        cur.execute("""CREATE TABLE vacancies (
                    id_vacancy SERIAL PRIMARY KEY,
                    name_employer VARCHAR(255) NOT NULL,
                    name_vacancy VARCHAR(255) NOT NULL,
                    salary_from INTEGER,
                    salary_to INTEGER,
                    url_vacancy TEXT
                )
            """)

    conn.commit()
    conn.close()

def save_data_to_database_emp(database_name: str, params: dict):
    """Заполнение БД данными о работодателях из json файла """

    conn = psycopg2.connect(dbname=database_name, **params)
    with conn.cursor() as cur:
        with open('src/employer.json', 'r', encoding='utf-8') as file:
            employer = json.load(file)
            for emp in employer:
                name = emp['name']
                url_employer = emp['alternate_url']
                open_vacancies = emp['open_vacancies']
                cur.execute(
                    """
                    INSERT INTO employers (name, url_employer, open_vacancies)
                    VALUES (%s, %s, %s)
                    """,
                    (name, url_employer, open_vacancies)
                )

    conn.commit()
    conn.close()

def save_data_to_database_vac(database_name: str, params: dict):
    """Заполнение БД данными о вакансиях из json файла """

    conn = psycopg2.connect(dbname=database_name, **params)
    with conn.cursor() as cur:
        with open('src/vacancies.json', 'r', encoding='utf-8') as file:
            vacancies = json.load(file)
            for vac in vacancies:
                name_employer = vac['employer']['name']
                name_vacancy = vac['name']
                if vac['salary'] is None:
                    salary_from = 0
                    salary_to = 0
                else:
                    salary_from = vac['salary']['from']
                    if salary_from is None:
                        salary_from = 0

                    salary_to = vac['salary']['to']
                    if salary_to is None:
                        salary_to = 0

                url_vacancy = vac['alternate_url']
                cur.execute(
                    """
                    INSERT INTO vacancies (name_employer, name_vacancy, salary_from, salary_to,
                    url_vacancy)
                    VALUES (%s, %s, %s, %s, %s)
                    """,
                    (name_employer, name_vacancy, salary_from, salary_to,
                     url_vacancy)
                )

    conn.commit()
    conn.close()


import time
import curses
import asyncio
import random

from obstacles import Obstacle
from game_scenario import PHRASES, get_garbage_delay_tics
from physics import update_speed
from explosion import explode
from itertools import cycle
from curses_tools import draw_frame, read_controls, get_frame_size

TIC_TIMEOUT = 0.1
SYMBOLS = ['+', '*', '.', ':']
YEAR = 1957
coroutines = []
obstacles = []
obstacles_in_last_collisions = []

async def sleep(tics):
    for _ in range(tics):
        await asyncio.sleep(0)

async def show_gameover(canvas):
    with open("gameover/gameover.txt", "r") as gameover_file:
        gameover_frame = gameover_file.read()

    rows, columns = canvas.getmaxyx()
    gameover_lines = gameover_frame.splitlines()

    start_row = (rows - len(gameover_lines)) // 2
    start_column = (columns - max(len(line) for line in gameover_lines)) // 2

    while True:
        for i, line in enumerate(gameover_lines):
            canvas.addstr(start_row + i, start_column, line, curses.A_DIM)

        await asyncio.sleep(0)

async def blink(canvas, row, column, symbol, offset_tics):
    while True:
        canvas.addstr(row, column, symbol, curses.A_DIM)
        await sleep(offset_tics)

        canvas.addstr(row, column, symbol)
        await sleep(3)

        canvas.addstr(row, column, symbol, curses.A_BOLD)
        await sleep(5)

        canvas.addstr(row, column, symbol)
        await sleep(3)

async def fire(canvas, start_row, start_column, rows_speed=-0.3, columns_speed=0):
    row, column = start_row, start_column

    canvas.addstr(round(row), round(column), '*')
    await asyncio.sleep(0)

    canvas.addstr(round(row), round(column), 'O')
    await asyncio.sleep(0)
    canvas.addstr(round(row), round(column), ' ')

    row += rows_speed
    column += columns_speed

    symbol = '-' if columns_speed else '|'

    rows, columns = canvas.getmaxyx()
    max_row, max_column = rows - 1, columns - 1

    curses.beep()
    while 0 < row < max_row and 0 < column < max_column:
        canvas.addstr(round(row), round(column), symbol)

        for obstacle in obstacles.copy():
            if obstacle.has_collision(round(row), round(column)):
                obstacles.remove(obstacle)
                obstacles_in_last_collisions.append(obstacle)
                canvas.addstr(round(row), round(column), ' ')
                return

        await asyncio.sleep(0)
        canvas.addstr(round(row), round(column), ' ')
        row += rows_speed
        column += columns_speed

    canvas.addstr(round(row), round(column), ' ')

async def animate_spaceship(canvas, row, column, spaceship_frames):
    spaceships = cycle(spaceship_frames)
    row_speed = column_speed = 0
    while True:
        spaceship = next(spaceships)
        draw_frame(canvas, row, column, spaceship)
        await asyncio.sleep(0)
        draw_frame(canvas, row, column, spaceship, negative=True)
        rows_dir, columns_dir, space_pressed = read_controls(canvas)

        if space_pressed and YEAR >= 2020:
            coroutines.append(fire(canvas, row, column + 2))
        row_speed, column_speed = update_speed(row_speed, column_speed, rows_dir, columns_dir)

        max_row, max_column = canvas.getmaxyx()

        rows, columns = get_frame_size(spaceship)

        row += row_speed
        column += column_speed

        row = min(max(row + rows_dir, 0), max_row - rows)
        column = min(max(column + columns_dir, 0), max_column - columns)

        for obstacle in obstacles:
            if obstacle.has_collision(row, column, rows, columns):
                coroutines.append(show_gameover(canvas))
                return

async def fly_garbage(canvas, column, garbage_frame, speed=0.5):
    rows_number, columns_number = canvas.getmaxyx()

    column = max(column, 0)
    column = min(column, columns_number - 1)

    row = 0

    rows, columns = get_frame_size(garbage_frame)
    while row < rows_number:
        new_obstacle = Obstacle(row, column, rows, columns)
        obstacles.append(new_obstacle)

        draw_frame(canvas, round(row), round(column), garbage_frame)
        await asyncio.sleep(0)
        draw_frame(canvas, round(row), round(column), garbage_frame, negative=True)
        row += speed
        for garbage in obstacles_in_last_collisions:
            if new_obstacle.has_collision(garbage.row, garbage.column):
                obstacles_in_last_collisions.remove(garbage)
                await explode(canvas, round(new_obstacle.row), round(new_obstacle.column))
                return

        if new_obstacle in obstacles:
            obstacles.remove(new_obstacle)

async def fill_orbit_with_garbage(canvas, garbage_frames):
    max_row, max_column = canvas.getmaxyx()
    distance_from_borders_min = 5
    distance_from_borders_max = 15

    while True:
        garbage_frame = random.choice(garbage_frames)

        if YEAR >= 1961:
            delay_tics = get_garbage_delay_tics(YEAR)
            if delay_tics:
                col = random.randint(distance_from_borders_min, max_column - distance_from_borders_max)
                coroutines.append(fly_garbage(canvas, col, garbage_frame))
                await sleep(delay_tics)

        await sleep(12)

async def increase_year():
    global YEAR
    while True:
        await sleep(2)
        YEAR += 1

async def display_year(canvas):
    max_row, max_column = canvas.getmaxyx()
    while True:
        year_str = f" Year: {YEAR}"
        canvas.addstr(max_row - 2, max_column // 2 - len(year_str) // 2, year_str, curses.A_BOLD)
        await asyncio.sleep(0)

async def display_phrase(canvas):
    max_row, max_column = canvas.getmaxyx()
    while True:
        phrase = PHRASES.get(YEAR)
        if phrase:
            phrase_length = len(phrase)
            row = max_row - 1
            column = max_column // 2 - phrase_length // 2
            for _ in range(phrase_length + 1):
                canvas.addstr(row, column, phrase[:_], curses.A_BOLD)
                await asyncio.sleep(0)
            for _ in range(phrase_length, 0, -1):
                canvas.addstr(row, column, phrase[:_], curses.A_BOLD)
                await asyncio.sleep(0)
        if YEAR > 2020:
            canvas.border()
        await asyncio.sleep(0)

def draw(canvas):
    canvas.border()
    canvas.nodelay(True)
    curses.curs_set(False)
    max_row, max_column = canvas.getmaxyx()
    distance_from_borders_min = 1
    distance_from_borders_max = 2
    spaceship_frames = []
    garbage_frames = []
    for spaceship in ['rocket_frame_1.txt', 'rocket_frame_1.txt', 'rocket_frame_2.txt', 'rocket_frame_2.txt']:
        with open(f"spaceship/{spaceship}", "r") as spaceship_file:
            spaceship_frames.append(spaceship_file.read())
    for garbage in ['trash_large.txt', 'trash_small.txt', 'trash_xl.txt', 'duck.txt', 'lamp.txt', 'hubble.txt']:
        with open(f"garbage/{garbage}", "r") as garbage_file:
            garbage_frames.append(garbage_file.read())
    for _ in range(80):
        row = random.randint(distance_from_borders_min, max_row - distance_from_borders_max)
        col = random.randint(distance_from_borders_min, max_column - distance_from_borders_max)
        symbol = random.choice(SYMBOLS)
        coroutines.append(blink(canvas, row, col, symbol, random.randint(1, 20)))
    coroutines.append(animate_spaceship(canvas, max_row / 2, max_column / 2, spaceship_frames))
    coroutines.append(fill_orbit_with_garbage(canvas, garbage_frames))
    coroutines.append(display_year(canvas))
    coroutines.append(display_phrase(canvas))
    coroutines.append(increase_year())
    while True:
        for coroutine in coroutines.copy():
            try:
                coroutine.send(None)
            except StopIteration:
                coroutines.remove(coroutine)
        canvas.refresh()
        time.sleep(TIC_TIMEOUT)

if __name__ == '__main__':
    curses.update_lines_cols()
    curses.wrapper(draw)


from app.models import db, Topping, environment, SCHEMA
from sqlalchemy.sql import text

def seed_toppings(all_customizations):

    topping1 = Topping(
        customization_id=1,
        caramelCrunchTopping='light'
    )

    topping2 = Topping(
        customization_id=2,
        cookieCrumbleTopping='light'
    )

    topping3 = Topping(
        customization_id=3,
        caramelDrizzle='extra'
    )

    topping4 = Topping(
        customization_id=4,
        whippedCream='regular'
    )

    all_toppings = [topping1, topping2, topping3, topping4]
    add_toppings = [db.session.add(topping)
                      for topping in all_toppings]
    db.session.commit()

    return all_toppings

def undo_toppings():
    if environment == "production":
        db.session.execute(
            f"TRUNCATE table {SCHEMA}.toppings RESTART IDENTITY CASCADE;")
    else:
        db.session.execute(text("DELETE FROM toppings"))

    db.session.commit()


import re
import sys
import json
import math

sys.path.append('/opt/grpc')
sys.path.append('/opt/scripts')

from logs import logger
from db import redis_cli
from conf import conf

def insert_data(data):
    for item in data:
        # 合并fields与tags
        params = item.get('fields')
        params.update(item.get('tags'))
        insert_depth_data(params)
        insert_read_len_data(params)

def cell(path):
    """计算cell编号"""
    # 验证文件路径
    pattern = re.compile(r'[/\w+-]+/([\w-]+)/\w+\.csv')
    match = re.match(pattern, path)
    if not match:
        exit(200)
    return match.groups()[0]

def insert_read_len_data(item):
    """保存长度统计"""
    ont_conf = conf.get('ont')
    read_length_step = ont_conf.get('read_length_step')
    redis_key = 'CELL:READ_LEN:%(cell)s' % {'cell': cell(item.get('path'))}
    barcode = item.get('barcode')
    read_len = item.get('read_len')
    section = math.ceil(read_len / read_length_step)
    for i in range(1, section + 1):
        if i == section:
            key = '%(barcode)s_%(section)s' % {'barcode': barcode, 'section': section}
            redis_cli.hincrby(redis_key, key)
        else:
            key = '%(barcode)s_%(section)s' % {'barcode': barcode, 'section': i}
            redis_cli.hsetnx(redis_key, key, 0)

def insert_depth_data(item):
    """保存深度统计"""
    # 跳过start_coords为0的数据
    start = item.get('start_coords')
    if start == 0:
        return
    end = item.get('end_coords')
    barcode = item.get('barcode')
    ont_conf = conf.get('ont')
    depth_position_step = ont_conf.get('depth_position_step')
    read_length_step = ont_conf.get('depth_read_length_step')
    # 计算位置
    if start % depth_position_step == 0 and start != 0:
        r_start = int(start / depth_position_step) - 1
    else:
        r_start = math.floor(start / depth_position_step)
    r_end = math.ceil(end / depth_position_step)
    # 计算读长
    read_len = math.ceil(item.get('read_len') / read_length_step)
    # 保存数据
    for i in range(r_start, r_end):
        for ii in range(0, read_len):
            key = '%s_%s_%s' % (i, barcode, ii)
            redis_cli.hincrby('CELL:DEPTH:%s' % cell(item.get('path')), key)
    for i in range(1, r_end):
        for ii in range(0, read_len):
            key = '%s_%s_%s' % (i, barcode, ii)
            redis_cli.hsetnx('CELL:DEPTH:%s' % cell(item.get('path')), key, 0)

def handle():
    for line in sys.stdin.readlines():
        if not line:
            break
        else:
            try:
                insert_data(json.loads(line).get('metrics'))
            except Exception as e:
                logger.info(e)

if __name__ == '__main__':
    handle()


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()

df_cancer = pd.DataFrame(np.c_[cancer['data'], cancer['target']], columns = np.append(cancer['feature_names'], ['target']))

# print(df_cancer.head())
# print(df_cancer.shape)
# print(df_cancer.columns)

df_cancerMean = df_cancer[df_cancer.columns[:10]]
df_cancerMean = df_cancer.iloc[:, list(range(10)) + [-1]]
# print(df_cancer.columns)

# sns.pairplot(df_cancerMean, hue = 'target', vars = ['mean radius', 'mean texture', 'mean perimeter','mean area','mean smoothness', 'mean compactness', 'mean concavity',
#        'mean concave points', 'mean symmetry', 'mean fractal dimension'] )
# plt.show()

# plt.figure(figsize=(20,12))
# sns.heatmap(df_cancer.corr(), annot=True)
# plt.show()

X = df_cancerMean.drop(['target'], axis = 1)
# X.head()

y = df_cancerMean['target']

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 20)

X_train_scaled = (X_train - X_train.min())/(X_train.max() - X_train.min())
X_test_scaled = (X_test - X_test.min())/(X_test.max() - X_test.min())

from sklearn.svm import SVC
svc_model = SVC()
# print(svc_model)
svc_model.fit(X_train_scaled, y_train)
y_predict = svc_model.predict(X_test_scaled)

from sklearn.metrics import classification_report, confusion_matrix
cm = np.array(confusion_matrix(y_test, y_predict, labels=[1,0]))
confusion = pd.DataFrame(cm, index=['is_cancer', 'is_healthy'],
                         columns=['predicted_cancer','predicted_healthy'])
# print(confusion)
sns.heatmap(confusion, annot=True)
plt.show()
print(classification_report(y_test, y_predict))

param_grid = {'C': [0.1, 1, 10, 100], 'gamma': [1, 0.1, 0.01, 0.001], 'kernel': ['rbf']}
from sklearn.model_selection import GridSearchCV
grid = GridSearchCV(SVC(),param_grid,refit=True,verbose=4)
grid.fit(X_train_scaled,y_train)

print (grid.best_params_)
print ('\n')
print (grid.best_estimator_)

from sklearn.metrics import classification_report, confusion_matrix
grid_predictions = grid.predict(X_test_scaled)
cm = np.array(confusion_matrix(y_test, grid_predictions, labels=[1,0]))
confusion = pd.DataFrame(cm, index=['is_cancer', 'is_healthy'],
                         columns=['predicted_cancer','predicted_healthy'])

sns.heatmap(confusion, annot=True)
plt.show()
print(classification_report(y_test, grid_predictions))


import argparse
from config import get_config

def parse_option():
    parser = argparse.ArgumentParser('Swin Transformer script', add_help=False)
    #
    #
    #
    args, unparsed = parser.parse_known_args()
    config = get_config(args)
    return args, config

def main(cfg):
    loader = build_loader(cfg)

if __name__ == "__main__":
    _, cfg= parse_option()
    main(cfg)