from typing import Callable

import numpy as np
import pandas as pd
from shapely.geometry import Point

from econtools import load_or_build

from epa_airpoll import (blocks_population, monitors_annual_summary,
                         load_blocks_shape_info, monitors_data,
                         load_block_shape)
from multisatpm import msat_northamer_1year, multisat_conus_year

from util.env import data_path
from analysis.geo_exposure import (multisatpm_exposure_block_conus,
                                   multisatpm_exposure_bg_conus,
                                   _xy_to_int_multisat, _int_to_xy_multisat)

xy_int = ['x_int', 'y_int']
xy = ['x', 'y']

# Block Level
@load_or_build(data_path('block_has_monitor_{}.pkl'), path_args=[0])
def block_has_monitor(year: int) -> pd.Series:
    """
    Bool Series 'this block shares a 0.01 grid cell with a monitor',
    index `block_id`
    """
    df = load_blocks_shape_info()
    df[xy_int] = _xy_to_int_multisat(df[xy])
    df = df.reset_index()   # otherwise `block_id` lost in merge

    mons = counties_monitor(year)
    mons[xy_int] = _xy_to_int_multisat(mons[xy])

    colname = f'{year}_mon_mean'
    df = df.merge(mons[xy_int + [colname]], on=xy_int, how='left')

    df['has_mon'] = df[colname].notnull()

    df = df.set_index('block_id')['has_mon'].squeeze()

    return df

@load_or_build(data_path('blocks_multisatpm_withpop_panel.pkl'))
def blocks_multisatpm_withpop_panel() -> pd.DataFrame:
    dfs = [blocks_multisatpm_withpop(y) for y in range(2000, 2016 + 1)]
    df = pd.concat(dfs, axis=1)
    del dfs

    return df

@load_or_build(data_path('blocks_multisatpm_withpop_{}.pkl'), path_args=[0])
def blocks_multisatpm_withpop(year):
    df = (multisatpm_exposure_block_conus(year)
          .squeeze()
          .to_frame(year))
    df = merge_blocks_pop(df)

    df = df[df['pop'] > 0].copy()

    del df['pop']

    return df

def merge_blocks_pop(df):
    """ Join blocks' population to `df` w/ block_id index """
    pop = blocks_population()
    pop.index.name = 'block_id'
    new_df = df.join(pop)
    assert new_df['pop'].notnull().min()
    return new_df

def merge_blocks_xy(df):
    blocks = load_blocks_shape_info()[xy]
    new_df = df.join(blocks)
    assert new_df['x'].notnull().min()
    return new_df

# Block Group Level
@load_or_build(data_path('bg_multisatpm_withpop_panel.pkl'))
def bg_multisatpm_withpop_panel():
    dfs = [bg_multisatpm_withpop(y) for y in range(2000, 2016 + 1)]
    df = pd.concat(dfs, axis=1)
    del dfs

    return df

@load_or_build(data_path('bg_multisatpm_withpop_{}.pkl'), path_args=[0])
def bg_multisatpm_withpop(year):
    df = (multisatpm_exposure_bg_conus(year)
          .squeeze()
          .to_frame(year))
    df = merge_bg_pop(df)

    df = df[df['pop'] > 0].copy()

    del df['pop']

    return df

def merge_bg_pop(df):
    """ Join block group population to `df` w/ bg_id index """
    pop = blocks_population().to_frame('pop')
    pop['bg_id'] = pop.index.astype(str).str[0:12]
    pop = pop.groupby('bg_id')['pop'].sum().to_frame('pop')
    new_df = df.join(pop)
    assert new_df['pop'].notnull().min()
    return new_df

def counties_monitor(year):
    mon = monitors_annual_summary(year)

    mon = mon[(mon['parameter_code'] == 88101) &
              (mon['pollutant_standard'] == 'PM25 Annual 2006') &
              (mon['event_type'] == 'No Events')]

    mon = mon.rename(columns={'latitude': 'y', 'longitude': 'x',
                              'arithmetic_mean': f'{year}_mon_mean'})

    mon['fips'] = (mon['state_code'].astype(str).str.zfill(2) +
                   mon['county_code'].astype(str).str.zfill(3))

    # Keep only max monitor in county
    mon = mon.sort_values(['fips', f'{year}_mon_mean'])
    mon = mon.drop_duplicates('fips', keep='last')

    return mon

@load_or_build(data_path('monitors_block.pkl'))
def monitors_block():
    df = monitors_data()
    df = df[df['state_code'] != 'CC']
    df['state_code'] = df['state_code'].astype(int)
    df = df[df['state_code'] < 80]      # No Mexico!
    df = df.set_index('monitor_id')
    assert df.index.is_unique

    df = df[df['parameter_code'] == 88101]
    df = df[df['longitude'].notnull()]
    out_df = pd.Series(index=df.index)
    out_df.name = 'block_id'
    out_df.loc[:] = 'x'*15
    for state_code, state_mon in df.groupby('state_code'):

        print(f"Loading shape {state_code}...", end='')
        state_shape = load_block_shape(str(state_code).zfill(2))
        state_shape = state_shape.set_index('GEOID10')
        state_shape.index.name = 'block_id'
        print("done!")

        for county_code, county_mon in state_mon.groupby('county_code'):
            print(f"Finding in county {county_code}")
            county_str = str(county_code).zfill(3)
            county_shape = state_shape[state_shape['COUNTYFP10'] == county_str]
            for monitor_id, monitor_row in county_mon.iterrows():
                this_point = Point(monitor_row['longitude'],
                                   monitor_row['latitude'])
                winner = county_shape.contains(this_point)
                count = winner.sum()
                if count < 1 or winner.empty:
                    winner = state_shape.contains(this_point)
                    count = winner.sum()
                    assert count == 1
                elif count == 1:
                    pass
                else:
                    raise AssertionError

                out_df.at[monitor_id] = winner[winner].index[0]

    return out_df[out_df != 'x'*15]

# Satellite Data - Block Level
def multisatpm_years_block(start_year, end_year):       # XXX DEPRECATE
    years = range(start_year, (end_year+1))
    exp_dfs = [(multisatpm_exposure_block_conus(year).squeeze().to_frame(year))
               for year in years]
    df = pd.concat(exp_dfs, axis=1)
    del exp_dfs

    return df

@load_or_build(data_path('tmp_multisatpm_3year_wlag_block.pkl'))
def prep_multisatpm_3year_wlag_block():
    df = blocks_multisatpm_withpop_panel()
    out = panel_to_3lag(df)

    return out

@load_or_build(data_path('tmp_multisatpm_3year_block.pkl'))
def prep_multisatpm_3year_block():
    df = blocks_multisatpm_withpop_panel()
    out = panel_to_3nolag(df)

    return out

# Satellite Data - Block Group Level
def multisatpm_years_bg(start_year, end_year):
    years = range(start_year, (end_year+1))
    exp_dfs = [(multisatpm_exposure_bg_conus(year).squeeze().to_frame(year))
               for year in years]
    df = pd.concat(exp_dfs, axis=1)
    del exp_dfs

    return df

@load_or_build(data_path('tmp_multisatpm_3year_wlag_bg.pkl'))
def prep_multisatpm_3year_wlag_bg():
    df = bg_multisatpm_withpop_panel()
    out = panel_to_3lag(df)

    return out

@load_or_build(data_path('tmp_multisatpm_3year_bg.pkl'))
def prep_multisatpm_3year_bg():
    df = bg_multisatpm_withpop_panel()
    out = panel_to_3nolag(df)

    return out

# multisatpm aux's
@load_or_build(data_path('tmp_multisatpm_3lag_{}.pkl'), path_args=[0])
def multisatpm_3lag_year(year: int) -> pd.Series:
    return multisatpm_3lag_panel()[year].squeeze()

@load_or_build(data_path('tmp_multisatpm_3lag_panel.pkl'))
def multisatpm_3lag_panel() -> pd.DataFrame:
    df = multisatpm_panel()
    out = panel_to_3lag(df)
    return out

def multisatpm_panel() -> pd.DataFrame:
    year_func = multisat_conus_year
    return _panel_guts(year_func)

# msatna (new) data
@load_or_build(data_path('tmp_msatna_bg_3lag_{}.pkl'), path_args=[0])
def msatna_bg_3lag_year(year: int) -> pd.Series:
    df = msatna_blocks_3lag_year(year).to_frame(year)
    df = merge_blocks_pop(df)
    df['bg_id'] = df.index.astype(str).str[0:12]

    # pop weights
    bgs_pop = df.groupby('bg_id')['pop'].sum()
    df = df.join(bgs_pop.to_frame('bgs_pop'), on='bg_id')
    df['weight'] = df['pop'] / df['bgs_pop']
    df['exp_weighted'] = df[year] * df['weight']

    df = df.groupby('bg_id')['exp_weighted'].sum()
    df.name = year

    return df

@load_or_build(data_path('tmp_msatna_blocks_3lag_{}.pkl'), path_args=[0])
def msatna_blocks_3lag_year(year: int) -> pd.Series:
    """ Convenience, just for the caching """
    return msatna_blocks_3lag_panel()[year]

@load_or_build(data_path('tmp_msatna_blocks_3lag_panel.pkl'))
def msatna_blocks_3lag_panel() -> pd.DataFrame:
    exp = msatna_3lag_panel()
    df = merge_blocks_msatna(exp)

    return df

@load_or_build(data_path('tmp_msatna_blocks_panel.pkl'))
def msatna_blocks_panel() -> pd.DataFrame:
    exp = msatna_panel()
    df = merge_blocks_msatna(exp)

    return df

def merge_blocks_msatna(exp0: pd.DataFrame) -> pd.DataFrame:
    # blocks
    df = load_blocks_shape_info()
    df[xy_int] = _xy_to_int_multisat(df[xy])

    # exposure
    exp = exp0.reset_index()
    exp[xy_int] = _xy_to_int_multisat(exp[xy])
    exp = exp.set_index(xy_int).drop(xy, axis=1)

    df = df.join(exp, on=xy_int)
    df = df.drop(xy_int + xy + ['area'], axis=1)
    df.columns = df.columns.astype(int)

    return df

@load_or_build(data_path('tmp_msatna_3lag_{}.pkl'), path_args=[0])
def msatna_3lag_year(year: int) -> pd.Series:
    return msatna_3lag_panel()[year]

@load_or_build(data_path('tmp_msatna_3lag_panel.pkl'))
def msatna_3lag_panel() -> pd.DataFrame:
    df = msatna_panel()
    out = panel_to_3lag(df)
    return out

def msatna_panel() -> pd.DataFrame:
    year_func = msat_northamer_1year
    return _panel_guts(year_func)

def _panel_guts(year_func: Callable) -> pd.DataFrame:
    years = range(2002, 2016 + 1)
    exp_dfs = [_prep_df_for_merge(year_func(year), year)
               for year in years]
    df = pd.concat(exp_dfs, axis=1)
    del exp_dfs

    df = df.reset_index()
    df[xy] = _int_to_xy_multisat(df[xy_int])
    df = (df
          .set_index(xy)
          .drop(xy_int, axis=1))

    df.columns = df.columns.astype(int)

    return df

def _prep_df_for_merge(df0: pd.DataFrame, year: int) -> pd.DataFrame:
    df = df0.reset_index()
    df[xy_int] = _xy_to_int_multisat(df[xy])
    df = (df
          .drop(xy, axis=1)
          .set_index(xy_int)
          .squeeze()
          .to_frame(year))
    return df

# Aux functions
def panel_to_3lag(df: pd.DataFrame) -> pd.DataFrame:
    N, __ = df.shape
    years = df.columns[3:].values.tolist()
    years.append(max(years) + 1)
    out = pd.DataFrame(np.zeros((N, len(years))),
                       index=df.index,
                       columns=years)

    for y in years:
        out[y] = df.loc[:, y-3:y-1].mean(axis=1)

    return out

def panel_to_3nolag(df: pd.DataFrame) -> pd.DataFrame:
    N, __ = df.shape
    years = df.columns[2:].values.tolist()
    out = pd.DataFrame(np.zeros((N, len(years))),
                       index=df.index,
                       columns=years)

    for y in years:
        out[y] = df.loc[:, y-2:y].mean(axis=1)

    return out

if __name__ == '__main__':
    df = msatna_blocks_3lag_panel()


# encoding:utf-8
import copy
import random
import bisect #bisect_left　これで二部探索の大小検索が行える
import fractions #最小公倍数などはこっち
import math
import sys
import collections

mod = 10**9+7
sys.setrecursionlimit(mod) # 再帰回数上限はでdefault1000

d = collections.deque()
def LI(): return list(map(int, sys.stdin.readline().split()))

H, W = LI()
c = []
for i in range(10):
    c.append(LI())

A = []
for i in range(H):
    A = A + LI()

for k in range(10):
    for i in range(10):
        for j in range(10):
            c[i][j] = min(c[i][j], c[i][k] + c[k][j])

ans = 0
for a in A:
    if a != -1:
        ans += c[a][1]

print(ans)


import os
import h5py
import pyBigWig
import numpy as np
import tqdm
import click

def fetch_bigwig_paths(base_path, tf_name, tf_cont_mapping_path):
    """
    Reads in the set of BigWig paths corresponding to TF-ChIPseq profiles and
    control profiles. These BigWigs should be generated by
    `generate_ENCODE_profile_labels.sh`. This function performs error-checking
    to ensure that the proper files are there under `base_path`.
    Arguments:
        `base_path`: path containing the BigWig profiles
        `tf_name`: name of the TF (i.e. the profiles for the TF-ChIPseq runs
            should start with this name)
        `tf_cont_mapping_path`: path to TSV mapping TF-ChIPseq experiment IDs
            to their matched control ChIPseq experiment IDs
    Returns a list of pairs, where each pair is the BigWig tracks for the
    negative and positive strands (in that order). The first half of this
    list-of-pairs is for the TF-ChIPseq profiles, and the second half are the
    corresponding control profiles. The BigWigs are ordered such that the
    TF-ChIPseq experiment IDs are in sorted order, and the control experiment
    IDs are in a parallel matched order.
    """
    tf_cont_mapping = {}
    with open(tf_cont_mapping_path, "r") as f:
        for line in f:
            tokens = line.strip().split("\t")
            tf_cont_mapping[tokens[0]] = tokens[1]  # Map TF ID to control ID

    bigwig_list = [
        item for item in os.listdir(base_path) if item.endswith(".bw")
    ]

    # Read in names, organizing into
    # tf_name/control : experiment/cell line : strand
    bigwig_dict = {}
    for name in bigwig_list:
        tokens = name[:-3].split("_")
        assert len(tokens) == 4, \
            "Found BigWig of improperly formatted name: %s" % name
        cond = tokens[0]
        expid_cline = (tokens[1], tokens[2])
        strand = tokens[3]
        assert cond in (tf_name, "control"), \
            "Found BigWig not of type %s or control" % tf_name
        assert strand in ("neg", "pos"), "Found BigWig of strand other than pos/neg"

        if cond not in bigwig_dict:
            bigwig_dict[cond] = {}
        if expid_cline not in bigwig_dict[cond]:
            bigwig_dict[cond][expid_cline] = {}
        assert strand not in bigwig_dict[cond][expid_cline], \
            "Found duplicate BigWig for %s, %s, %s" % \
            (cond, expid_cline, strand)
        bigwig_dict[cond][expid_cline][strand] = os.path.join(base_path, name)

    # Verify that the expected conditions, experiments/cell lines, and strands
    # are all present
    assert sorted(bigwig_dict.keys()) == sorted([tf_name, "control"]), \
        "Did not find tracks for both %s and control" % tf_name

    tf_clines = sorted([pair[1] for pair in bigwig_dict[tf_name].keys()])
    cont_clines = sorted([pair[1] for pair in bigwig_dict["control"].keys()])
    assert tf_clines == cont_clines, \
        "Did not have same cell lines for %s and control" %  tf_name

    for cond, cond_dict in bigwig_dict.items():
        for expid_cline, expid_cline_dict in cond_dict.items():
            assert sorted(expid_cline_dict.keys()) == ["neg", "pos"], \
                "Did not find both strands for %s, %s" % (cond, expid_cline)

    # Reformat dictionary into list of pairs
    paths = []
    tf_expids = []
    for expid_cline in sorted(bigwig_dict[tf_name].keys(), key=lambda p: p[0]):
        expid = expid_cline[0]
        assert expid in tf_cont_mapping.keys(), \
            "Did not find %s as TF-ChIPseq experiment in mapping" % expid
        strand_dict = bigwig_dict[tf_name][expid_cline]
        paths.append([strand_dict["neg"], strand_dict["pos"]])
        tf_expids.append(expid)
    assert len(tf_expids) == len(set(tf_expids)), \
        "Found duplicate TF-ChIPseq experiment IDs"
    for tf_expid in tf_expids:
        try:
            cont_expid = tf_cont_mapping[tf_expid]
        except KeyError:
            raise ValueError("Did not find mapped control for %s" % tf_expid)
        expid_cline = [
            key for key in bigwig_dict["control"] if key[0] == cont_expid
        ]
        assert len(expid_cline) == 1, \
            "Did not find exactly 1 experiment for mapped control %s" % \
            cont_expid
        strand_dict = bigwig_dict["control"][expid_cline[0]]
        paths.append([strand_dict["neg"], strand_dict["pos"]])

    return paths

def create_hdf5(
    bigwig_paths, chrom_sizes_path, out_path, chunk_size, batch_size=100
):
    """
    Creates an HDF5 file containing all BigWig tracks.
    Arguments:
        `bigwig_paths`: a list of pairs of paths, as returned by
            `fetch_bigwig_paths`
        `chrom_sizes_path`: path to canonical chromosome sizes
        `out_path`: where to write the HDF5
        `chunk_size`: chunk size to use in HDF5 along the chromosome size
            dimension; this is recommended to be the expected size of the
            queries made
        `batch_size`: number of chunks to write at a time
    This creates an HDF5 file, containing a dataset for each chromosome. Each
    dataset will be a large array of shape L x 2T x 2, where L is the length of
    the chromosome, T is the number of tasks (i.e. T experiment/cell lines, one
    for each TF and one for matched control), 2 is for both strands. The HDF5
    will also contain a dataset which has the paths to the corresponding source
    BigWigs, stored as a 2T x 2 array of paths.
    """
    bigwig_readers = [
        [pyBigWig.open(path1), pyBigWig.open(path2)]
        for path1, path2 in bigwig_paths
    ]

    # Read in chromosome sizes
    with open(chrom_sizes_path, "r") as f:
        chrom_sizes = {}
        for line in f:
            tokens = line.strip().split("\t")
            chrom_sizes[tokens[0]] = int(tokens[1])

    # Convert batch size to be in terms of rows, not number of chunks
    batch_size = batch_size * chunk_size

    with h5py.File(out_path, "w") as f:
        # Store source paths
        f.create_dataset("bigwig_paths", data=np.array(bigwig_paths, dtype="S"))
        for chrom in sorted(chrom_sizes.keys()):
            chrom_size = chrom_sizes[chrom]
            num_batches = int(np.ceil(chrom_size / batch_size))
            chrom_dset = f.create_dataset(
                chrom, (chrom_size, len(bigwig_paths), 2), dtype="f",
                compression="gzip", chunks=(chunk_size, len(bigwig_paths), 2)
            )
            for i in tqdm.trange(num_batches, desc=chrom):
                start = i * batch_size
                end = min(chrom_size, (i + 1) * batch_size)

                values = np.stack([
                    np.stack([
                        np.nan_to_num(reader1.values(chrom, start, end)),
                        np.nan_to_num(reader2.values(chrom, start, end))
                    ], axis=1) for reader1, reader2 in bigwig_readers
                ], axis=1)

                chrom_dset[start : end] = values

@click.command()
@click.option(
    "--tf-name", "-t", required=True,
    help="Name of TF, needs to match prefix of TF-ChIPseq BigWig files"
)
@click.option(
    "--base-path", "-b", default=None,
    help="Path to directory containing BigWigs; defaults to /users/amtseng/att_priors/data/interim/ENCODE_TFChIP/profile/{tf_name}/"
)
@click.option(
    "--tf-cont-mapping-path", "-m", default=None,
    help="Path to mapping between TF-ChIPseq and control ChIPseq experiment IDs; defaults to /users/amtseng/att_priors/data/raw/ENCODE_TFChIP/{tf_name}/tf_cont_mapping.tsv"
)
@click.option(
    "--chrom-sizes-path", "-c",
    default="/users/amtseng/genomes/hg38.canon.chrom.sizes",
    help="Path to canonical chromosome sizes"
)
@click.option(
    "--out-path", "-o", default=None,
    help="Destination for new HDF5; defaults to /users/amtseng/att_priors/data/processed/ENCODE_TFChIP/profile/labels/{tf_name}/{tf_name}_profiles.h5"
)
@click.option(
    "--chunk-size", "-s", default=1500,
    help="Chunk size along chromosome length dimension for HDF5"
)
def main(
    tf_name, base_path, tf_cont_mapping_path, chrom_sizes_path, out_path,
    chunk_size
):
    """
    Converts TF-ChIPseq and control ChIPseq profile BigWigs into an HDF5 file.
    HDF5 has separate datasets for each chromosome. Each chromosome's dataset
    is stored as an L x 2T x 2 array, where L is the size of the chromosome,
    T is the number of matched experiments (i.e. tasks), and 2 is for each
    strand. The dataset under the key `bigwig_paths` stores the paths for the
    source BigWigs.
    """
    if not base_path:
        base_path = "/users/amtseng/att_priors/data/interim/ENCODE_TFChIP/profile/%s" % tf_name
    if not tf_cont_mapping_path:
        tf_cont_mapping_path = \
            "/users/amtseng/att_priors/data/raw/ENCODE_TFChIP/%s/tf_cont_mapping.tsv" % tf_name
    if not out_path:
        out_path = \
            "/users/amtseng/att_priors/data/processed/ENCODE_TFChIP/profile/labels/%s/%s_profiles.h5" % (tf_name, tf_name)

    bigwig_paths = fetch_bigwig_paths(base_path, tf_name, tf_cont_mapping_path)
    print("Found %d matched experiments/tasks" % (len(bigwig_paths) // 2))
    create_hdf5(bigwig_paths, chrom_sizes_path, out_path, chunk_size)

if __name__ == "__main__":
    main()


from scipy.io import loadmat
import numpy as np
import skimage.io as io
import os
import skimage as skimg
from utils import *
import argparse
from numpy.testing import assert_allclose

def main(opts):
	"""Performs the whole algorithm i.e given video frames,
	performs its 3D reconstruction

	Args:
	opts: command line arguments

	Returns:
	None
	"""

	#loading images
	pathnames = [os.path.join(opts.dataDir, x) for x in sorted(os.listdir(opts.dataDir)) if x.split('.')[-1] in opts.ext]
	imgs = io.ImageCollection(pathnames)
	num_imgs = len(imgs)

	#hardcoded for now for testing purposes
	focal_length = 719.5459

	#if bigger image than our limit, reshaping image and adjusting
	#camera intrinsics.
	opts.maxSize = 1024
	imsize = imgs[0].shape
	if opts.maxSize < np.max(imsize):
	    scale = opts.maxSize / np.max(imsize)
	    focal_length = focal_length * scale
	    imsize = skimg.transform.resize(imgs[0], scale).shape

	#constructing camera intrinsic matrix
	K = f2K(focal_length)

	essential_matrices = list()
	for index, img in enumerate(imgs[:len(imgs) - 1]):
		#sift feature matching (taking pre-computed points for now for testing purposes)
		feats = matFileToFeatures('./matlab_cache/sift-keypoints/point'+str(index+1)+'.mat', imgs[0].shape, imgs[1].shape)

		# #fundamental matrix estimation
		# F = estimateFundamentalMatrixRANSAC()

		# Loading the fundamental matrix
		F = loadmat('./matlab_cache/fundamental-matrix/F_matrix' + str(index + 1))['f_matrix']

		#essential matrix estimation
		E = estimateEssentialMatrix(K, F, False)
		essential_matrices.append(E)
		#camera projection matrix

		#triangulation

		#bundle adjustment

	# Testing the essential matrices (comparing with orginal matrices)
	essential_matrices_original = list()
	for i in range(len(imgs) - 1):
		E = loadmat('./matlab_cache/essential-matrix/E_matrix' + str(i + 1))['e_matrix']
		essential_matrices_original.append(E)

	test_essential_matrices(np.array(essential_matrices_original), np.array(essential_matrices))
	pass

def test_essential_matrices(E_original, E):
	assert_allclose(E_original, E)

def set_arguments(parser):
    parser.add_argument('-dataDir',action='store', type=str, default='../data/', dest='dataDir')
    parser.add_argument('-ext', action='store',type=list, default=['png', 'jpg'], dest='ext')
    parser.add_argument('-maxSize',action='store', type=int, default=1024, dest='maxSize')

if __name__=='__main__':
	#setting parser for command-line arguments
	parser = argparse.ArgumentParser()
	set_arguments(parser)

	#parsing arguments now..
	opts = parser.parse_args()

	#running the complete algorithm now..
	main(opts)


#!/usr/bin/env python3

import argparse
import logging
import os
import textwrap
from functools import partial
from multiprocessing import Pool

import matplotlib
import pandas as pd
from rich.logging import RichHandler
from rich.progress import Progress

from your.utils.misc import YourArgparseFormatter
from your.utils.plotter import plot_h5

os.environ["HDF5_USE_FILE_LOCKING"] = "FALSE"
matplotlib.use("Agg")

def mapper(save, detrend_ft, publication, mad_filter, out_dir, h5_file):
    # maps the variables so the function will be imap friendly
    plot_h5(
        h5_file=h5_file,
        save=save,
        detrend_ft=detrend_ft,
        publication=publication,
        mad_filter=mad_filter,
        outdir=out_dir,
    )

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        prog="your_h5plotter.py",
        description="Plot candidate h5 files.",
        formatter_class=YourArgparseFormatter,
        epilog=textwrap.dedent(
            """\
            This script can be used to plot and save the candidate HDF5 format files generated by your_candmaker.py or by the Candidate class.
            """
        ),
    )
    parser.add_argument("-v", "--verbose", help="Be verbose", action="store_true")
    parser.add_argument(
        "-f", "--files", help="h5 files to be plotted", nargs="+", required=False
    )
    parser.add_argument(
        "-c", "--results_csv", help="Plot positives in results.csv", required=False
    )
    parser.add_argument(
        "--publish", help="Make publication quality plots", action="store_true"
    )
    parser.add_argument(
        "--no_detrend_ft", help="Detrend the frequency-time plot", action="store_false"
    )
    parser.add_argument(
        "--no_save", help="Do not save the plot", action="store_false", default=True
    )
    parser.add_argument(
        "-o",
        "--out_dir",
        help="Directory to save pngs (default: h5 dir)",
        type=str,
        default=None,
        required=False,
    )
    parser.add_argument(
        "-mad",
        "--mad_filter",
        help="Median Absolute Deviation spectal clipper, default 3 sigma",
        nargs="?",
        const=3.0,
        default=False,
    )
    parser.add_argument(
        "-n",
        "--nproc",
        help="Number of processors to use in parallel (default: 4)",
        type=int,
        default=4,
        required=False,
    )
    parser.add_argument(
        "--no_progress",
        help="Do not show the tqdm bar",
        action="store_true",
    )
    parser.add_argument(
        "--no_log_file", help="Do not write a log file", action="store_true"
    )

    values = parser.parse_args()
    logging_format = (
        "%(asctime)s - %(funcName)s -%(name)s - %(levelname)s - %(message)s"
    )

    if values.verbose:
        logging.basicConfig(
            level=logging.DEBUG,
            format=logging_format,
            handlers=[RichHandler(rich_tracebacks=True)],
        )

    else:
        logging.basicConfig(
            level=logging.INFO,
            format=logging_format,
            handlers=[RichHandler(rich_tracebacks=True)],
        )

    matplotlib_logger = logging.getLogger("matplotlib")
    matplotlib_logger.setLevel(logging.INFO)

    if values.files:
        h5_files = values.files
    elif values.results_csv:
        df = pd.read_csv(values.results_csv)
        h5_files = list(df["candidate"][df["label"] == 1])
    else:
        raise ValueError(f"Need either --files or --results_csv argument.")

    with Pool(processes=values.nproc) as p:
        max_ = len(h5_files)
        func = partial(
            mapper,
            values.no_save,
            values.no_detrend_ft,
            values.publish,
            values.mad_filter,
            values.out_dir,
        )

        with Progress() as progress:
            if values.no_progress:
                task = progress.add_task("[green]Writing...", total=max_, visible=False)
            else:
                task = progress.add_task("[green]Writing...", total=max_)
            for i, _ in enumerate(p.imap_unordered(func, h5_files, chunksize=2)):
                progress.update(task, advance=1)


# 450. 删除二叉搜索树中的节点
# 给定一个二叉搜索树的根节点 root 和一个值 key，删除二叉搜索树中的 key 对应的节点，并保证二叉搜索树的性质不变。返回二叉搜索树（有可能被更新）的根节点的引用。

# 一般来说，删除节点可分为两个步骤：

# 首先找到需要删除的节点；
# 如果找到了，删除它。

# 来源：力扣（LeetCode）
# 链接：https://leetcode.cn/problems/delete-node-in-a-bst
# 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。

# Definition for a binary tree node.
from typing import Optional

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
        if not root:
            return None
        if key > root.val:
            root.right=self.deleteNode(root.right,key)
        elif key<root.val:
            root.left = self.deleteNode(root.left,key)
        else:
            if not root.left:
                return root.right
            if not root.right:
                return root.left
            tmp = root.right
            while tmp.left:
                tmp=tmp.left
            tmp.left=root.left
            root=root.right
        return root


from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sect_comp import Sector
import pandas as pd

engine = create_engine('sqlite:///sector_comp.db')

Session = sessionmaker(bind=engine)
session = Session()

s = pd.read_csv('/home/pallabeedey/Indian_fins/data/sec2.csv')
l1=len(s)

for i in range(0,l1):
    code= s['sector_code'][i]
    name= s['sector_name'][i]
    session.add(Sector(name, code))

session.commit()


from pyspark.sql import SparkSession
from pyspark.sql.functions import col, unix_timestamp

# Initialize SparkSession
spark = SparkSession.builder.appName('nyc_taxi_data_processing').getOrCreate()

# Load the dataset
df = spark.read.csv('../data/train.csv', inferSchema=True, header=True)

# Data exploration
df.show()
df.printSchema()

# Data transformation
timeFmt = "yyyy-MM-dd HH:mm:ss"
df = df.withColumn('pickup_time', unix_timestamp(col('pickup_datetime'), timeFmt))
df = df.withColumn('dropoff_time', unix_timestamp(col('dropoff_datetime'), timeFmt))

# Data analysis
df = df.withColumn('actual_duration', (col('dropoff_time') - col('pickup_time')) / 60)
result = df.select('id', 'trip_duration', 'actual_duration')

# Display the first few rows of the result
result.show()

# Save the results
result.coalesce(1).write.option('header', 'true').csv('nyc_taxi_durations.csv')


#!/usr/bin/env python

from setuptools import setup

PACKAGE = 'timingandestimationplugin'

setup(name=PACKAGE,
      description='Plugin to make Trac support time estimation and tracking',
      keywords='trac plugin estimation timetracking',
      version='0.1.5',
      url='',
      license='http://www.opensource.org/licenses/mit-license.php',
      author='Russ Tyndall at Acceleration.net',
      author_email='russ@acceleration.net',
      long_description="""
      This Trac 0.10 plugin provides support for Time estimation and tracking.

      See http://trac-hacks.org/wiki/TimeEstimationAndQuotingSpecification for details.
      """,
      packages=[PACKAGE],
      package_data={PACKAGE : ['templates/*.cs', 'htdocs/*']},
      entry_points={'trac.plugins': '%s = %s' % (PACKAGE, PACKAGE)})


import pygame
from graphics import Graphics
from graphics import Video
from . import _ASSETS_PATH
import os
from enum import Enum

class Menu(object):
    """
    Menu is a class with methods that can draw different menu items or screens
    to the display.
    """

    #: The different states that the menu can take
    State = Enum('State', 'Splash Menu Building Playing Testing Exit')

    #: Becomes true when the first screen (title screen) has been clicked on.
    #: A higher order class can watch this and proceed to the actual menu.
    splashScreenPressed = False

    #: Becomes true when the "start demo" button has been pressed. A higher order
    #: class can watch this and take appropriate action on change
    demoPressed = False

    #: Becomes true when the Rocket builder button has been pressed. A higher
    #: order class can watch htis and take appropriate action on change.
    builderPressed = False

    #: Becomes true when the quit button has been pressed. A higher order class can
    #: watch this and take appropriate action on change
    quitPressed = False

    #: Becomes true when the tests button has been pressed. A higher order class can
    #: watch this and take appropriate action on change
    testsPressed = False

    #: The color to use for the menu buttons
    _menuButtonColor = ((255, 255, 255, 64), (255, 255, 255, 128))
    #: Icons made by `Freepik <www.freepic.com>`_ from `Flaticon <https://www.flaticon.com/>`_. Licensed by `CC 3.0 BY <http://creativecommons.org/licenses/by/3.0/>`_
    _fullscreen_icon = pygame.image.load(os.path.abspath(os.path.join(_ASSETS_PATH, "image", "open_fullscreen.png")))
    #: Icons made by `Freepik <www.freepic.com>`_ from `Flaticon <https://www.flaticon.com/>`_. Licensed by `CC 3.0 BY <http://creativecommons.org/licenses/by/3.0/>`_
    _windowed_icon = pygame.image.load(os.path.abspath(os.path.join(_ASSETS_PATH, "image", "close_fullscreen.png")))

    @classmethod
    def drawBackground(cls, color_rgb, opacity):
        """
        Draws the background using the given color and opacity alpha value.

        :param color_rgb: The color of the background
        :type color_rgb: :py:class:`pygame.Color`
        :param int opacity: The alpha value with which to draw the background
        """
        dispSurface = pygame.display.get_surface()
        surfaceSize = dispSurface.get_size()
        background = pygame.surface.Surface(surfaceSize)
        background.fill(color_rgb)
        background.set_alpha(opacity)
        dispSurface.blit(background, (0,0))

    @classmethod
    def drawSplashScreen(cls, opacity):
        """
        Draws the title screen to pygame's current display surface.

        :param int opacity: The alpha value with which to draw the splash screen background
        """
        surface = pygame.display.get_surface()
        surfaceSize = surface.get_size()
        surfaceCenter = (surfaceSize[0] / 2, surfaceSize[1] / 2)
        titleCenter = (surfaceCenter[0], surfaceCenter[1] - 20)
        subtitleCenter = (surfaceCenter[0], surfaceCenter[1] + 20)

        # fill surface with black
        cls.drawBackground((0, 0, 0), opacity)

        # draw a button
        Graphics.drawButton(surface, (0, 0), surfaceSize,
                            ((0, 0, 0, 0), (0, 0, 0, 0)),
                            0, 0, cls._splashCallback)

        # In the future, may want to draw an image onto the surface
        # as a background
        # for now, just draw text
        titleFont = pygame.font.SysFont("lucidaconsole", 40)
        subtitleFont = pygame.font.SysFont("lucidaconsole", 20)

        Graphics.drawTextCenter(titleCenter, "Flat Earth Space Program",
                                titleFont, (255, 255, 255))
        Graphics.drawTextCenter(subtitleCenter, "Click Anywhere to Continue",
                                subtitleFont, (255, 255, 255))

    @classmethod
    def drawMenu(cls, opacity, tests=False):
        """
        Draws the menu screen and buttons to pygame's current display surface.

        :param int opacity: The alpha value with which to draw the menu background
        """
        surface = pygame.display.get_surface()
        surfaceSize = surface.get_size()
        surfaceCenter = (surfaceSize[0] / 2, surfaceSize[1] / 2)

        titleCenter = (surfaceCenter[0], surfaceCenter[1] - 100)

        # fill screen with black
        cls.drawBackground((0, 0, 0), opacity)

        buttonSize = (400, 50)
        buttonPosition = lambda i: (surfaceCenter[0] - buttonSize[0]/2,
                                    surfaceCenter[1] - buttonSize[1]/2 + 65*i)
        titleFont = pygame.font.SysFont("lucidaconsole", 40)

        Graphics.drawTextCenter(titleCenter, "Flat Earth Space Program",
                                titleFont, (255,255,255))
        Graphics.drawButton(surface, buttonPosition(0), buttonSize,
                            cls._menuButtonColor, "Start Demo", 25,
                            cls._demoCallback)
        Graphics.drawButton(surface, buttonPosition(1), buttonSize,
                            cls._menuButtonColor, "Rocket Builder", 25,
                            cls._builderCallback)
        if tests:
            Graphics.drawButton(surface, buttonPosition(2), buttonSize,
                                cls._menuButtonColor, "Test Suite (Console)", 25,
                                cls._testsCallback)
            Graphics.drawButton(surface, buttonPosition(3), buttonSize,
                                cls._menuButtonColor, "Exit to Desktop", 25,
                                cls._quitCallback)
        else:
            Graphics.drawButton(surface, buttonPosition(2), buttonSize,
                                cls._menuButtonColor, "Exit to Desktop", 25,
                                cls._quitCallback)

        fullscreenSize = (32,32)
        fullscreenPos = (25,25)

        isFullscreen = Video.get_fullscreen()
        icon = cls._windowed_icon if isFullscreen else cls._fullscreen_icon
        Graphics.drawButton(surface, fullscreenPos, fullscreenSize,
                            pygame.Color("black"), "", 25,
                            Video.toggle_fullscreen)
        surface.blit(icon, fullscreenPos)

    @classmethod
    def _splashCallback(cls):
        """
        Callback function to be called when the title screen is clicked. This sets the
        splashScreenPressed bool to be true.
        """
        cls.splashScreenPressed = True

    @classmethod
    def _builderCallback(cls):
        """
        Callback function to be called when the Rocket Builder button is clicked. This sets the
        builderPressed bool to be true.
        """
        cls.builderPressed = True

    @classmethod
    def _quitCallback(cls):
        """
        Callback function to be called when the quit button is clicked. This sets the
        quitPressed bool to be true.
        """
        cls.quitPressed = True

    @classmethod
    def _demoCallback(cls):
        """
        Callback function to be called when the "start demo" button is clicked. This sets the
        demoPressed bool to be true.
        """
        cls.demoPressed = True

    @classmethod
    def _testsCallback(cls):
        """
        Callback function to be called when the "test suite" button is clicked. This sets the
        testsPressed bool to be true.
        """
        cls.testsPressed = True


import itertools
from itertools import product, chain, combinations
from sympy.combinatorics import Permutation

class Sigma:

    ALL_SIGMA = {}
    ALL_PERMS = {}
    MEMO = {}

    def __init__(self, tuples):
        self.dom = set()
        self.rng = set()
        self.id = True
        self.tuple_inverse = list()
        self.length = len(tuples)
        self.tuple_form = list()
        self.keys = []
        self.values = []
        for pair in tuples:
            if (pair[0] is None) or (pair[1] is None):
                continue
            if pair[0] != pair[1]:
                self.id = False
            self.tuple_form.append(pair)
            self.keys.append(pair[0])
            self.values.append(pair[1])
            self.tuple_inverse.append((pair[1], pair[0]))
            self.dom.add(pair[0])
            self.rng.add(pair[1])

        self.hs = hash(frozenset(self.tuple_form))

    def len(self):
        return len(self.tuple_form)

    def __str__(self):
        if len(self.tuple_form) == 0:
            return "{}"
        return str(self.tuple_form).replace("\'", "")

    def __contains__(self, item):
        return item in self.keys

    def __add__(self, other: "Sigma"):
        new_tuples = set()
        for t in self.tuple_form:
            key, value = t
            if value in other:
                new_tuples.add((key, other[value]))
        return Sigma(new_tuples)

    def __eq__(self, other: "Sigma"):
        return set(self.tuple_form) == set(other.tuple_form)

    def __le__(self, other: "Sigma"):
        return self.tuple_form.issubset(other.tuple_form)

    def __getitem__(self, key):
        try:
            index = self.keys.index(key)
        except IndexError:
            raise IndexError("Error - key {} non-existent.".format(key))
        return self.values[index]

    def __hash__(self):
        return self.hs

    def in_dom(self, s):
        return s in self.dom

    def in_rng(self, s):
        return s in self.rng

    def dom_sub(self, s: set):
        return s - self.dom

    def rng_sub(self, s: set):
        return s - self.rng

    def reverse(self):
        return Sigma(self.tuple_inverse)

    def __copy__(self):
        return Sigma(self.tuple_form)

    def invert(self):
        return Sigma(self.tuple_inverse)

    def is_id(self):
        return self.id

    def get_tuple_form(self):
        return self.tuple_form

    def harpoon(self, q1, q2, RA) -> "Sigma":
        s1, s2 = RA.s_map[q1], RA.s_map[q2]
        new_tuples = set()
        for current_tuple in self.tuple_form:
            if (current_tuple[0] in s1) and (current_tuple[1] in s2):
                new_tuples.add(current_tuple)
        return Sigma(new_tuples)

    def generate_temp_sigma(self, key, value) -> "Sigma":
        keys = list(self.keys)
        values = list(self.values)
        if key not in keys:
            values.append(None)
            keys.append(key)
        i1 = keys.index(key)
        if value not in values:
            keys.append(None)
            values.append(value)
        i2 = values.index(value)
        values[i2] = None
        values[i1] = value
        # try:
        #     assert len(keys) == len(values)
        # except AssertionError:
        #     print(keys, key)
        #     print(values, value)
        #     exit(5)
        while None in keys:
            index = keys.index(None)
            keys.pop(index)
            values.pop(index)
        while None in values:
            index = values.index(None)
            keys.pop(index)
            values.pop(index)
        tuples = set(zip(keys, values))
        return Sigma(tuples)

    @classmethod
    def eliminate(cls, l1: list, l2: list, s: set) -> None:
        i = 0
        while i < len(l1):
            if l1[i] is None:
                i += 1
                continue
            if l1[i] not in s:
                del l1[i]
                del l2[i]
            else:
                i += 1

    @classmethod
    def generate_sigmas(cls, s1, s2):
        f1 = frozenset(s1)
        f2 = frozenset(s2)
        if (f1, f2) not in Sigma.ALL_SIGMA:
            all_sigmas = set()
            if len(s1) >= len(s2):
                length = len(s2)
                zip_set = s1
            else:
                length = len(s1)
                zip_set = s2
            f_temp = frozenset(zip_set)
            if not (f_temp, length) in Sigma.ALL_PERMS:
                Sigma.ALL_PERMS[(f_temp, length)] = set(itertools.permutations(zip_set, length))
            if len(s1) >= len(s2):
                perm = [list(zip(x, s2)) for x in Sigma.ALL_PERMS[(f_temp, length)]]
            else:
                perm = [list(zip(s1, x)) for x in Sigma.ALL_PERMS[(f_temp, length)]]
            for p in perm:
                new_sig = Sigma(set(p))
                if new_sig not in all_sigmas:
                    all_sigmas.add(new_sig)
                # sets = powerset(p)
                # for s in sets:
                #     new_sig = Sigma(set(s))
                #     if new_sig not in all_sigmas:
                #         all_sigmas.add(new_sig)
            Sigma.ALL_SIGMA[(f1, f2)] = frozenset(all_sigmas)
        return Sigma.ALL_SIGMA[(f1, f2)]

def unique_permutations(the_list: list):
    l_list = range(len(the_list) - 1, -1, -1)
    k_list = l_list[1:]
    the_list = sorted(the_list)
    while True:
        yield the_list
        found = False
        for k in k_list:
            if the_list[k] < the_list[k+1]:
                found = True
                break
        if not found:
            return
        val = the_list[k]
        for i in l_list:
            if val < the_list[i]:
                break
        the_list[k], the_list[i] = the_list[i], the_list[k]
        the_list[k + 1:] = the_list[-1:k:-1]

def powerset(iterable):
    s = list(iterable)
    return itertools.chain.from_iterable(itertools.combinations(s, r) for r in range(len(s)+1))


import keyboard
from time import sleep

start = int(input("Please provide the starting number: "))
end = int(input("Please provide the end number: "))
print('''The program will start shortly, tab into discord to start.''')
sleep(4)
for i in range(start,end+1):
    keyboard.write(str(i),0.02)
    sleep(3) #shorten this to make it more fast
    keyboard.press("enter")
    sleep(0.01)
    keyboard.release("enter")


import contextlib
import glob
import json
import os
from functools import reduce

from core.parse_config import Parse, CustomError
from log.log import logger

class CreatPTFile(Parse):
    def __init__(self, ost, wavs_map, _save_path):
        """
        :param config_path: config文件路径
        :param wav_path: 对应音频文件路径
        """
        super(CreatPTFile, self).__init__(ost)
        self.wav_time_map = wavs_map  # 创建音频地址映射关系
        self._save_path = _save_path

    @staticmethod
    def mkdir(path):
        if not os.path.exists(path):
            os.mkdir(path)
        return path

    def run(self, custom_classfy):
        """
        遍历config文件和音频路径，将其新平台文本格式信息写到output/result.txt文件中
        :param custom_classfy: 自定义分包条数，默认按spk音频数分包
        """
        logger.debug('遍历wav_name,text信息')
        wav_suf = 'wav'
        counter = 0
        wavs_info_map = {}

        for SPK, wav_name, content in self.get_info():  # 遍历说话人id，音频名，音频内容 信息
            logger.debug('[wav_info] %s - %s - %s ' % (SPK, wav_name, content))

            if wav_name not in self.wav_time_map:
                logger.warning('[%s] 未找到音频' % wav_name)
                continue

            wav_time = self.wav_time_map.get(wav_name)
            if not wav_time:
                continue

            wav_info = [  # 填充新平台文本格式
                {
                    "Wav_name": wav_name,
                    "Length_time": wav_time,
                    "Data": [
                        {
                            "text": content,
                            "start_time": 0,
                            "end_time": wav_time
                        }
                    ],
                    "Wav_suf": wav_suf
                }
            ]

            if custom_classfy:  # 指定分包数的模式
                id = f'line_{counter}'
                if id not in wavs_info_map:
                    wavs_info_map[id] = [wav_info]

                else:
                    if len(wavs_info_map[id]) == custom_classfy - 1:
                        counter += 1

                    wavs_info_map[id].append(wav_info)

            else:  # 默认分包模式
                if SPK not in wavs_info_map:
                    wavs_info_map[SPK] = [wav_info]
                else:
                    wavs_info_map[SPK].append(wav_info)

        logger.info(
            '处理完毕！ 共 %s 批次 [%s]' % (len(wavs_info_map.keys()), wavs_info_map.keys()) if not custom_classfy else (
                counter, len(reduce(lambda x, y: x + y, wavs_info_map.values()))))

        with open(self._save_path, 'w', encoding='utf-8') as f:
            for key, value in wavs_info_map.items():
                f.write(json.dumps(value, ensure_ascii=False) + '\n')


#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#    @Author : tangkaize
#
#              _____               ______
#     ____====  ]OO|_n_n__][.      |    |]
#    [________]_|__|________)<
#     oo    oo  'oo OOOO-| oo\_   ~o~~~o~'
# +--+--+--+--+--+--+--+--+--+--+--+--+--+
#    @Time : 2022/12/30 11:09
#    @FIle： demo23.py 依赖性 Depends()的用法
#    @Software: PyCharm
from typing import Union

import uvicorn
from fastapi import FastAPI, Depends

app = FastAPI()

async def common_parameters(
        q: Union[str, None] = None, skip: int = 0, limit: int = 100
):
    return {"q": q, "skip": skip, "limit": limit}

# 依赖的注入
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
    return commons

@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
    return commons

if __name__ == '__main__':
    uvicorn.run('demo23:app', host='0.0.0.0', port=8000)


import unittest
from collections import namedtuple
from day_24 import find_strongest_bridge, find_longest_bridge

class TestBridge(unittest.TestCase):
    """Test Bridge."""

    def test_find_strongest_bridge(self):
        Test = namedtuple('Test', ['components', 'expected'])
        tests = [
            Test(expected=([(0, 1), (1, 10), (10, 9)], 31),
                 components=[(2, 0), (2, 2), (2, 3), (3, 4),
                             (3, 5), (0, 1), (10, 1), (9, 10)])
        ]

        for test in tests:
            result = find_strongest_bridge(test.components)
            self.assertEqual(result, test.expected)

    def test_find_longest_bridge(self):
        Test = namedtuple('Test', ['components', 'expected'])
        tests = [
            Test(expected=([(0, 2), (2, 2), (2, 3), (3, 5)], 19),
                 components=[(2, 0), (2, 2), (2, 3), (3, 4),
                             (3, 5), (0, 1), (10, 1), (9, 10)])
        ]

        for test in tests:
            result = find_longest_bridge(test.components)
            self.assertEqual(result, test.expected)

if __name__ == '__main__':
    unittest.main()

Advent of Code 2017/Day 24/test_day_24.py


import numpy as np
from scipy import linalg
from sklearn.feature_selection import SelectKBest, mutual_info_classif
from min2net.utils import butter_bandpass_filter
# Note that we modify CSP function using MNE-Python package (version 0.20).
# Reference:
# - https://github.com/mne-tools/mne-python
# - A. Gramfort, M. Luessi, E. Larson, D. Engemann, D. Strohmeier, C. Brodbeck, R. Goj, M. Jas, T. Brooks, L. Parkkonen, and M. Ha ̈ma ̈la ̈inen, “Meg and eeg data analysis with mne-python,” Frontiers in Neuroscience, vol. 7, p. 267, 2013.
# Sources:
# - Common Spatial Pattern revisited by Riemannian geometry
# - Model based generalization analysis of common spatial pattern in brain computer interfaces

class SpectralSpatialMapping():
    def __init__(self,
                bands,
                smp_freq,
                num_class=2,
                order=5,
                n_components=10,
                n_pick_bands=20):
        self.bands = bands
        self.smp_freq = smp_freq
        self.n_components = n_components
        self.n_pick_bands = n_pick_bands
        self.cov_type = 'epoch'
        self.classes = None
        self.order = order
        self.n_classes = num_class
        if self.n_classes == 2:
            self.component_order = 'alternate'
        else:
            self.component_order = 'mutual_info'
        self.norm_trace = False

    def __covariance(self, X):
        # covariance = np.dot(X, X.T)/X.shape[0]
        # return covariance
        return np.dot(X,X.T)/np.trace(np.dot(X,X.T))

    # spatialFilter returns the spatial filter for mean covariance matrices on each class
    def __get_spatial_filter(self, covs, sample_weights):
        eigen_vectors, eigen_values = self.__decompose_covs(covs, sample_weights)
        # CSP requires the eigenvalues and eigenvector be sorted in descending order
        sorted_index = self.__order_components(covs, sample_weights, eigen_vectors, eigen_values)
        eigen_vectors = eigen_vectors[:, sorted_index]
        sp_filters = eigen_vectors.T
        pick_filters = sp_filters[:self.n_components]
        return pick_filters, sp_filters

    def __decompose_covs(self, covs, sample_weights):
        n_classes = len(covs)
        if n_classes == 2:
            eigen_values, eigen_vectors = linalg.eigh(covs[0], covs.sum(0))
        else:
            # The multiclass case is adapted from
            # http://github.com/alexandrebarachant/pyRiemann
            eigen_vectors, D = self.__ajd_pham(covs)
            eigen_vectors = self.__normalize_eigenvectors(eigen_vectors.T, covs, sample_weights)
            eigen_values = None
        return eigen_vectors, eigen_values

    def __calculate_covariance_matrices(self, data, y_class):
        '''The data is in the form of samples x channels x sampled_time_points'''
        if len(data.shape) != 3:
            raise Exception('Dimension is not match!')
        n_samples, n_channels, n_points = data.shape

        if self.cov_type == 'concat':
            cov_estimator = self.__concat_cov
        elif self.cov_type == 'epoch':
            cov_estimator = self.__epoch_cov

        covs = []
        sample_weights = []
        self.classes = np.unique(y_class)
        n_classes = len(self.classes)
        # print('The numbers of class used are {} and type of class {}'.format(n_classes, self.classes))
        for id_class in self.classes:
            cov, weight = cov_estimator(data[y_class == id_class])
            if self.norm_trace:
                cov /= np.trace(cov)
            covs.append(cov)
            sample_weights.append(weight)
        return np.stack(covs), np.array(sample_weights)

    def __concat_cov(self, X_class):
        '''The data is in the form of samples x channels x sampled_time_points'''
        '''Concatenate epochs before computing the covariance.'''
        n_samples, n_channels, n_points = X_class.shape
        X_class = np.transpose(X_class, [1, 0, 2])
        X_class = X_class.reshape(n_channels, -1)
        cov = self.__covariance(X_class)
        # The covariace with norm trace is used to provide better results
        # cov = np.cov(X_class)
        weight = X_class.shape[0]
        return cov, weight

    def __epoch_cov(self, X_class):
        '''The data is in the form of samples x channels x sampled_time_points'''
        '''Mean of per-epoch covariances.'''
        cov = sum(self.__covariance(data) for data in X_class)
        cov /= len(X_class)
        weight = len(X_class)
        return cov, weight

    def __compute_mutual_info(self, covs, sample_weights, eigen_vectors):
        class_probas = sample_weights / sample_weights.sum()

        mutual_info = []
        for jj in range(eigen_vectors.shape[1]):
            aa, bb = 0, 0
            for (cov, prob) in zip(covs, class_probas):
                tmp = np.dot(np.dot(eigen_vectors[:, jj].T, cov),
                             eigen_vectors[:, jj])
                aa += prob * np.log(np.sqrt(tmp))
                bb += prob * (tmp ** 2 - 1)
            mi = - (aa + (3.0 / 16) * (bb ** 2))
            mutual_info.append(mi)

        return mutual_info

    def __normalize_eigenvectors(self, eigen_vectors, covs, sample_weights):
        # Here we apply an euclidean mean. See pyRiemann for other metrics
        mean_cov = np.average(covs, axis=0, weights=sample_weights)

        for ii in range(eigen_vectors.shape[1]):
            tmp = np.dot(np.dot(eigen_vectors[:, ii].T, mean_cov),
                         eigen_vectors[:, ii])
            eigen_vectors[:, ii] /= np.sqrt(tmp)
        return eigen_vectors

    def __order_components(self, covs, sample_weights, eigen_vectors, eigen_values):
        if self.component_order == 'mutual_info' and self.n_classes > 2:
            mutual_info = self.__compute_mutual_info(covs, sample_weights, eigen_vectors)
            ix = np.argsort(mutual_info)[::-1]
        elif self.component_order == 'mutual_info' and self.n_classes == 2:
            ix = np.argsort(np.abs(eigen_values - 0.5))[::-1]
        elif self.component_order == 'alternate' and self.n_classes == 2:
            i = np.argsort(eigen_values)
            ix = np.empty_like(i)
            ix[1::2] = i[:len(i) // 2]
            ix[0::2] = i[len(i) // 2:][::-1]
        return ix

    def __ajd_pham(self, X, eps=1e-6, max_iter=15):
        '''Approximate joint diagonalization based on Pham's algorithm.
        This is a direct implementation of the PHAM's AJD algorithm [1].
        Parameters
        ----------
        X : ndarray, shape (n_epochs, n_channels, n_channels)
            A set of covariance matrices to diagonalize.
        eps : float, default 1e-6
            The tolerance for stopping criterion.
        max_iter : int, default 1000
            The maximum number of iteration to reach convergence.
        Returns
        -------
        V : ndarray, shape (n_channels, n_channels)
            The diagonalizer.
        D : ndarray, shape (n_epochs, n_channels, n_channels)
            The set of quasi diagonal matrices.
        References
        ----------
        .. [1] Pham, Dinh Tuan. 'Joint approximate diagonalization of positive
               definite Hermitian matrices.' SIAM Journal on Matrix Analysis and
               Applications 22, no. 4 (2001): 1136-1152.
        '''
        # Adapted from http://github.com/alexandrebarachant/pyRiemann
        n_epochs = X.shape[0]

        # Reshape input matrix
        A = np.concatenate(X, axis=0).T

        # Init variables
        n_times, n_m = A.shape
        V = np.eye(n_times)
        epsilon = n_times * (n_times - 1) * eps

        for it in range(max_iter):
            decr = 0
            for ii in range(1, n_times):
                for jj in range(ii):
                    Ii = np.arange(ii, n_m, n_times)
                    Ij = np.arange(jj, n_m, n_times)

                    c1 = A[ii, Ii]
                    c2 = A[jj, Ij]

                    g12 = np.mean(A[ii, Ij] / c1)
                    g21 = np.mean(A[ii, Ij] / c2)

                    omega21 = np.mean(c1 / c2)
                    omega12 = np.mean(c2 / c1)
                    omega = np.sqrt(omega12 * omega21)

                    tmp = np.sqrt(omega21 / omega12)
                    tmp1 = (tmp * g12 + g21) / (omega + 1)
                    tmp2 = (tmp * g12 - g21) / max(omega - 1, 1e-9)

                    h12 = tmp1 + tmp2
                    h21 = np.conj((tmp1 - tmp2) / tmp)

                    decr += n_epochs * (g12 * np.conj(h12) + g21 * h21) / 2.0

                    tmp = 1 + 1.j * 0.5 * np.imag(h12 * h21)
                    tmp = np.real(tmp + np.sqrt(tmp ** 2 - h12 * h21))
                    tau = np.array([[1, -h12 / tmp], [-h21 / tmp, 1]])

                    A[[ii, jj], :] = np.dot(tau, A[[ii, jj], :])
                    tmp = np.c_[A[:, Ii], A[:, Ij]]
                    tmp = np.reshape(tmp, (n_times * n_epochs, 2), order='F')
                    tmp = np.dot(tmp, tau.T)

                    tmp = np.reshape(tmp, (n_times, n_epochs * 2), order='F')
                    A[:, Ii] = tmp[:, :n_epochs]
                    A[:, Ij] = tmp[:, n_epochs:]
                    V[[ii, jj], :] = np.dot(tau, V[[ii, jj], :])
            if decr < epsilon:
                break
        D = np.reshape(A, (n_times, -1, n_times)).transpose(1, 0, 2)
        return V, D

    def __get_log_var_feats(self, spatial_filt, data):
        data_dot = np.dot(spatial_filt, data) # spatially filtered signals
        data_var = np.var(data_dot)
        # We use log(var) instead of averaging
        data_log = np.log(data_var)
        return data_log

    def get_transformed_feats(self, spatial_filt, data):
        data_dot = np.dot(spatial_filt, data) # spatially filtered signals
        data_cov = self.__covariance(data_dot)
        return data_cov

    def spatial_spectral_with_valset(self, X_tr, y_tr, X_val, X_te):
        if len(X_tr.shape) != 3:
            raise Exception('Dimension is not match!')

        # Empty array for getting the transformed features in each frequency band
        X_tr_transformed_var = np.zeros((len(self.bands), X_tr.shape[0]))

        # Empty array for getting the covariance matrix
        X_tr_transformed_cov = np.zeros((len(self.bands), X_tr.shape[0], X_tr.shape[1], X_tr.shape[1]))
        X_val_transformed_cov = np.zeros((len(self.bands), X_val.shape[0], X_val.shape[1], X_val.shape[1]))
        X_te_transformed_cov = np.zeros((len(self.bands), X_te.shape[0], X_te.shape[1], X_te.shape[1]))

        for id_band, freq_band in enumerate(self.bands):
            print('The process is holding on ID {} and Freq Interval {}'.format(id_band, freq_band))

            X_tr_filtered = butter_bandpass_filter(X_tr, freq_band[0], freq_band[1], self.smp_freq, self.order)
            X_val_filtered = butter_bandpass_filter(X_val, freq_band[0], freq_band[1], self.smp_freq, self.order)
            X_te_filtered = butter_bandpass_filter(X_te, freq_band[0], freq_band[1], self.smp_freq, self.order)

            # Calculating covariance only on training set
            covs, sample_weights =  self.__calculate_covariance_matrices(X_tr_filtered, y_tr)
            spf_sel, spf_org = self.__get_spatial_filter(covs, sample_weights)

            # Calculate the variance of spatially filtered signals and then compute the logarithm in each single EEG trial
            for sample_tr in range(X_tr_filtered.shape[0]):
                X_tr_transformed_var[id_band, sample_tr] = self.__get_log_var_feats(spf_sel, X_tr_filtered[sample_tr,:,:])
                X_tr_transformed_cov[id_band, sample_tr,:,:] = self.get_transformed_feats(spf_org, X_tr_filtered[sample_tr,:,:])

            for sample_val in range(X_val_filtered.shape[0]):
                X_val_transformed_cov[id_band, sample_val,:,:] = self.get_transformed_feats(spf_org, X_val_filtered[sample_val,:,:])

            for sample_te in range(X_te_filtered.shape[0]):
                X_te_transformed_cov[id_band, sample_te,:,:] = self.get_transformed_feats(spf_org, X_te_filtered[sample_te,:,:])

        # Prepare the most suited form of data for rearanging all frequency bands
        X_tr_transformed_var_sw = np.swapaxes(X_tr_transformed_var,0,1)

        # Rearrange all frequency bands from the largest MI value to smallest MI value and pick k frequency bands by considering the most k largest MI values.
        # This procedure considered only traning set obtaning the order of k frequnecy bands that provide the largest MI value.
        selector = SelectKBest(score_func=mutual_info_classif, k=self.n_pick_bands)
        X_tr_picked_band = selector.fit_transform(X_tr_transformed_var_sw, y_tr)
        des_order_list = selector.get_support(indices=True)

        # Display the selected subbands
        for idx_band in des_order_list:
            print('band_name:', self.bands[idx_band] ,'---', 'Index_is:', idx_band)

        X_tr_se_band = np.take(np.swapaxes(X_tr_transformed_cov,0,1), des_order_list, axis=1)
        X_val_se_band = np.take(np.swapaxes(X_val_transformed_cov,0,1), des_order_list, axis=1)
        X_te_se_band = np.take(np.swapaxes(X_te_transformed_cov,0,1), des_order_list, axis=1)
        # All data are in the form of (n_samples,n_subbands,n_components,n_components)
        return X_tr_se_band, X_val_se_band, X_te_se_band


import torch
import torch.autograd as autograd
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from toolz.sandbox import unzip
from torch.utils.data import Dataset
from torchvision import transforms
import more_itertools
import numpy as np

class FeedForwardLayer(nn.Module):
    def __init__(self, input_dim, output_dim, dropout, activator=nn.ReLU()):
        super().__init__()
        self.linear = nn.Linear(input_dim, output_dim)
        self.dropout = nn.Dropout(dropout)
        self.norm = nn.BatchNorm1d(output_dim)
        self.activator = activator
        self.residule = (input_dim == output_dim)

    def forward(self, x):
        tmp = self.linear(x)
        shape = tmp.shape
        tmp = tmp.view(shape[0], -1, shape[-1]).permute(0, 2, 1).contiguous()
        tmp = self.dropout(self.activator(self.norm(tmp)))
        tmp = tmp.view(*shape)
        if self.residule:
            return x + tmp
        else:
            return tmp

class MultiLayerFeedForwardLayer(nn.Module):
    def __init__(self, n_layer, input_dim, hidden_size, output_dim, dropout, activator=nn.ReLU(), last_no_activate=False):
        super().__init__()
        linear_stack = [FeedForwardLayer(input_dim, hidden_size, dropout, activator=activator)]
        linear_stack += [FeedForwardLayer(hidden_size, hidden_size, dropout, activator=activator) for _ in range(n_layer-2)]
        linear_stack += [nn.Linear(hidden_size, output_dim)] if last_no_activate else [
            FeedForwardLayer(hidden_size, output_dim, dropout, activator=activator)]
        self.feed_forward_layers = nn.Sequential(
            *linear_stack
        )

    def forward(self, x):
        return self.feed_forward_layers(x)

class ConvolutionLayer(nn.Module):
    def __init__(self, in_channels, output_channels, kernel_size, padding, stride=1,
                 dropout=0.2, activator=nn.ReLU(), dimention=1, pool="max",
                 pool_kernel_size=2, pool_stride=2, pool_pad=0):
        super().__init__()
        self.conv = nn.Conv2d(in_channels=in_channels, out_channels=output_channels,
                              kernel_size=kernel_size, padding=padding, stride=stride)
        self.dropout = nn.Dropout(dropout)
        self.norm = nn.BatchNorm2d(output_channels)
        self.activator = activator
        self.residule = (in_channels == output_channels)
        if pool == "max":
            self.pool = nn.MaxPool2d(pool_kernel_size, stride=pool_stride, padding=pool_pad)

    def forward(self, x):
        tmp = self.dropout(self.activator(self.pool(self.norm(self.conv(x)))))
        if self.residule:
            return x + tmp
        else:
            return tmp

class MultiConvolutionLayer(nn.Module):
    def __init__(self, n_layer, in_channels, output_channels, kernel_size, padding, stride=1,
                 dropout=0.2, activator=nn.ReLU(), pool="max"):
        super().__init__()
        self.feed_forward_layers = nn.Sequential(
            *([ConvolutionLayer(in_channels, output_channels, kernel_size, padding, stride,
                                dropout, activator=activator)] +
              [ConvolutionLayer(output_channels, output_channels, kernel_size, padding, stride,
                                dropout, activator=activator) for _ in range(n_layer - 1)])
        )

    def forward(self, x):
        return self.feed_forward_layers(x)


"""
출처: https://www.acmicpc.net/problem/11051
"""

import collections
import sys

dp = collections.defaultdict(int)
f_dp = collections.defaultdict(int)

def factorial(n: int) -> int:
    if f_dp[n]:
        return f_dp[n]

    f_dp[0] = 1
    for i in range(1, n + 1):
        f_dp[i] = f_dp[i - 1] * i
    return f_dp[i]

def combination(n: int, r: int) -> int:
    if dp[(n, r)]:
        return dp[(n, r)]

    if n == r or r == 0:
        dp[(n, r)] = 1
        return dp[(n, r)]

    dp[(n, r)] = (factorial(n) // (factorial(r) * factorial(n - r))) % 10007
    return dp[(n, r)]

if __name__ == '__main__':
    n, r = map(int, sys.stdin.readline().rstrip().split())
    print(combination(n, r))


from collections import Counter

def solution(topping):
    answer = 0
    topDic = Counter(topping) # 토핑 딕셔너리
    setDic = set() # 비교를 위한 딕셔너리

    for i in topping:
        topDic[i] -= 1 # 개수를 하나 빼주고
        setDic.add(i) # 여기서는 더 해준다 (종류의 수만 같으면 되므로)

        if topDic[i] == 0: # 0개가 되면 (아예 종류를 삭제)
            topDic.pop(i)

        if len(setDic) == len(topDic): # 서로 종류의 수가 같다면 +1 을 해준다.
            answer += 1

    return answer


import os

basedir = os.path.abspath(os.path.dirname(__file__))

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'this is a hard to guess string'
    SQLALCHEMY_TRACK_MODIFICATIONS = False

    @staticmethod
    def init_app(app):
        pass

class DevelopmentConfig(Config):
    DEBUG = True
    SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \
        'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')

class TestingConfig(Config):
    TEST = True
    SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \
        'sqlite://'

class ProductionConfig(Config):
    DEBUG = False
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
        'sqlite:///' + os.path.join(basedir, 'data.sqlite')

    @classmethod
    def init_app(cls, app):
        Config.init_app(app)

class DockerConfig(ProductionConfig):
    @classmethod
    def init_app(cls, app):
        ProductionConfig.init_app(app)

        # log to stderr
        import logging
        from logging import StreamHandler
        file_handler = StreamHandler()
        file_handler.setLevel(logging.INFO)
        app.logger.addHandler(file_handler)

config = {
    'development': DevelopmentConfig,
    'testing': TestingConfig,
    'production': ProductionConfig,
    'docker': DockerConfig,
    'default': DevelopmentConfig
}


import logging
import functools
import requests
import json
from cfg import config
import time

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger()

def interface_log(log_type):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            tmp = list(args)
            if kw:
                tmp.append(kw)
            try:
                r = func(*args, **kw)
                logger.info('%s,func:%s,args:%s' % (log_type, func.__name__, ','.join(str(x) for x in tmp)))
                return r
            except Exception as e:
                logger.error(e)
                logger.error('%s,func:%s,args:%s' % (log_type, func.__name__, ','.join(str(x) for x in tmp)))

        return wrapper

    return decorator

def get_match_tasks():
    match_tasks = []
    workers = config.workers
    while True:
        for worker in workers:
            ip, port = worker, 4040
            while True:
                uri = 'http://%s:%s/api/v1/applications' % (ip, port)
                try:
                    rsp = requests.get(uri)
                    # only one task would refer to one couple ip:port
                    rsp_content = json.loads(rsp.content)[0]
                    task_name = rsp_content.get('name')
                    if 'match_faces_in_aimDB' not in task_name:
                        continue
                    driver_id = rsp_content.get('id')
                    match_tasks.append(driver_id)
                except requests.exceptions.ConnectionError:
                    # if connect time out then means no any more task on this worker
                    break
                finally:
                    port += 1
        if match_tasks:
            break
        time.sleep(3)
    return match_tasks


import base64
import datetime

import dash_bootstrap_components as dbc

from dash import html, dcc, callback, dash_table, no_update
from dash.dependencies import Input, Output, State

from utils.upload import UploadIO

def render_reading_exception(upload, exc):
    file_name = upload.file_name
    error_name = exc.__class__.__name__
    error_message = str(exc)

    return html.P(
        className='alert alert-danger',
        children=[
            html.Strong(f'{file_name} - {error_name}'),
            f': {error_message}'
        ])

def render_unsupported_upload(u):
    return html.P(
        className='alert alert-danger',
        children=[
            html.Strong(f'{u.file_name} - Formato no soportado'),
            f': {u.content_type}'
        ])

def render_upload(upload):
    df = upload.df.head(10)

    return html.Div([
        html.H5(upload.file_name),
        html.H6(datetime.datetime.fromtimestamp(upload.modified_date)),
        dash_table.DataTable(
            df.to_dict('records'),
            [{'name': i, 'id': i} for i in df.columns]
        ),
    ])

class UploadInput(object):
    def __init__(
        self,
        id_suffix,
        outputs,
        upload_fn,
        reading=True,
        rendering_uploads=False,
    ):
        self.upload_id = f'upload-data-{id_suffix}'
        self.output_id = f'output-upload-data-{id_suffix}'
        self.outputs = outputs
        self.reading = reading
        self.rendering_uploads = rendering_uploads
        self.upload_fn = upload_fn

    def display(self):
        layout = self.render_components()
        self.register_callbacks()

        return layout

    def register_callbacks(self):
        @callback(
            Output(self.output_id, 'children'),
            *self.outputs,
            Input(self.upload_id, 'contents'),
            State(self.upload_id, 'filename'),
            State(self.upload_id, 'last_modified'),
            prevent_initial_call=True,
        )
        def upload_main_callback(contents, filenames, dates):
            no_updates = [no_update for n in self.outputs]

            if contents is None:
                return ([], *no_updates)

            uploads = [
                UploadIO(c, n, d) for c, n, d in
                zip(contents, filenames, dates)
            ]

            unsupported = [u for u in uploads if u.validate_support() == False]
            if (len(unsupported) > 0):
                children = [render_unsupported_upload(u) for u in unsupported]
                return (children, *no_updates)

            if self.reading:
                for u in uploads:
                    try:
                        u.read()
                    except Exception as e:
                        children = render_reading_exception(u, e)
                        return (children, *no_updates)

            (error_layout, *values) = self.upload_fn(uploads)
            if (error_layout):
                return (error_layout, *no_updates)
            elif (self.rendering_uploads):
                children = [render_upload(u) for u in uploads]
                return (children, *values)
            else:
                return (no_update, *values)

    def render_components(self):
        return dbc.Container(
            [
                dcc.Upload(
                    id=self.upload_id,
                    children=html.Div([
                        'Agregar archivos\n(click o arrastre)',
                    ]),
                    style={
                        'width': '100%',
                        'height': '60px',
                        'lineHeight': '60px',
                        'borderWidth': '1px',
                        'borderStyle': 'dashed',
                        'borderRadius': '5px',
                        'textAlign': 'center',
                        'margin': '10px',
                        'cursor': 'pointer',
                        'userSelect': 'none',
                    },
                    multiple=True
                ),
                html.Div(id=self.output_id),
            ]
        )


from typing import List

def find_max_consecutive_ones(nums: List[int]) -> int:
    count = max_count = 0

    for num in nums:

        if num == 1:

            # Increment the count of 1's by one.
            count += 1

        else:

            # Find the maximum till now.
            max_count = max(max_count, count)

            # Reset count of 1.
            count = 0

    return max(max_count, count)


from matplotlib import pyplot as plt
import math
import numpy as np

from sympy import symbols, Eq, solve

co=[0]*10

print("Root locus is drawn with help of OLTF, so give value of OLTF")
print("For ax^3+bx^2+cx^1+d, consider this is denomenator and give value of a,b,c,d" )

a1=int(input())
b1=int(input())
c1=int(input())
d1=int(input())

print("For ax^3+bx^2+cx^1+d, consider this is numerator and give value of a,b,c,d" )
a2=int(input())
b2=int(input())
c2=int(input())
d2=int(input())

X=list()
Y=list()
for k in range(0,10000,1):
    k1=k/100
    print(k1)
    x = symbols('x')

    sol = solve(a1*(x**3)+b1*(x**2)+c1*(x**1)+d1+k1*(a2*(x**3)+b2*(x**2)+c2*(x**1)+d2))
    for i in range(0,len(sol)):

        co[i]=complex(sol[i])

        X.append(co[i].real)
        Y.append(co[i].imag)

plt.plot(X,Y,'ro')
plt.show()


import click

from services.service_mesh.src.oci_cli_service_mesh.service_mesh_troubleshoot.task_request import TaskRequest, \
    TaskRequestType, FileTaskRequest
from services.service_mesh.src.oci_cli_service_mesh.service_mesh_troubleshoot.tasks.task_worker import MeshTask
from services.service_mesh.src.oci_cli_service_mesh.service_mesh_troubleshoot.utils.bundle_helper import \
    BundleHelper
from services.service_mesh.src.oci_cli_service_mesh.service_mesh_troubleshoot.utils.summary import MeshData

class CsvTask(MeshTask):
    def __init__(self, k8s_context=None):
        super(CsvTask, self).__init__(TaskRequestType.CSV_PROCESSOR)
        self.k8s_context = k8s_context

    def do_work(self, task_request: TaskRequest, kube_command_helper):
        try:
            output_events, tasks = [], []
            data = task_request.get_task_data()
            operator_namespace = data['operator_namespace']
            mesh_id = data['mesh_id']

            csv = kube_command_helper.get_csv(operator_namespace)

            if mesh_id is None:
                relative_path = ""
            else:
                relative_path = MeshData(mesh_id=mesh_id).get_mesh_hierarchy()
            file_task_request = FileTaskRequest(TaskRequestType.FILE_PROCESSOR,
                                                [],
                                                relative_path,
                                                BundleHelper.get_csv_file_name(),
                                                csv)
            tasks.append(file_task_request)
            return tasks, output_events
        except Exception as error:
            click.echo('CsvTask Exception: {}'.format(error))


import cv2
import numpy as np

# Erosion
# https://docs.opencv.org/4.2.0/d9/d61/tutorial_py_morphological_ops.html No. 1

# Read an image using cv2.imread
img = cv2.imread('../../resources/lena.png')

# As in cv2.dilate a matrix, called kernel, is needed
kernel = np.ones((5, 5), np.uint8)

# The dilated image is used since this is normally performed on binary images
# and img_edges is so thin on its edges that it disappears when eroded
img_edges = cv2.Canny(img, 100, 100)

img_dilation = cv2.dilate(img_edges, kernel, iterations=2)
cv2.imshow('Dilation Image', img_dilation)

''' cv2.erode
Parameters
    img: image
        Image from cv2.imread
    kernel: matrix
        All the pixels near boundary will be discarded depending upon the size of kernel
    iteration: integer
        How many iterations are wanted for the matrix to move around,
        which affects the thickness
'''
img_erosion = cv2.erode(img_dilation, kernel, iterations=2)
cv2.imshow('Erosion Image', img_erosion)

cv2.waitKey(0)
cv2.destroyAllWindows()


from manillen_classes import man_player, man_team, man_game, viewer

import manillen_const
import cards
import time
import logging
from manillen_game_logic import card_allowed

class engine:
    def __init__(self, test_module=None):
        logging.basicConfig(level=logging.INFO)
        self.logger_engine = logging.getLogger('engine_working')
        self.logger_game = logging.getLogger('engine_game')

        self.handler = logging.FileHandler('logs/games.log')
        self.handler.setLevel(logging.INFO)

        formatter = logging.Formatter('%(asctime)s ,%(message)s')
        self.handler.setFormatter(formatter)

        self.logger_game.addHandler(self.handler)

        self.logger_engine.info("created engine")

        self.game_set = {}
        self.id_set_games = {}
        self.id_set_player = {}
        self.id_set_viewer = {}

        self.valuedict = {"10": 5, "A": 4, "K": 3, "Q": 2, "J": 1, "9": 0, "8": 0, "7": 0}
        self.comparevalue = {"10": 7, "A": 6, "K": 5, "Q": 4, "J": 3, "9": 2, "8": 1, "7": 0}

        self.function_dict = {"add_player": self.add_player, "answer_troef": self.receive_troef, "answer_card": self.receive_card, "add_viewer": self.add_viewer, "disconnect": self.remove_subscriber, "reset_game": self.reset_game, "keep_waiting" : self.keep_waiting}

        self.test_mod = test_module

    def get_functions(self):
        return self.function_dict

    def restart_play(self, game):
        self.send_all_players("restarted_game", game)
        if game.troef_choosen:
            self.play_cards(game)
        else:
            game.players[game.troef_chooser_pos].send("choose_troef")

    def start_play(self, game):
        if not game.started:
            game.started = True

            team_names = [team.name for team in game.teams]

            game.set_default_indices()

            self.send_all_players("set_teams", game, team_names)

            self.play_round(game)
        else:
            self.logger_engine.error("game should be restarted, not started")

    def play_round(self, game):

        self.distribute_cards(game)

        if game.troef_choosen:
            game.troef_choosen = False
            game.troef_chooser_pos = (game.troef_chooser_pos + 1) % 4
            game.round_start_pos = (game.troef_chooser_pos + 1) % 4
            game.troef = None
            game.cards_played = 0

            score = 0
            for card in game.teams[0].cards:
                score += self.valuedict[card[1:]]

            for team in game.teams:
                team.reset_round()

            if score < 30:
                game.teams[1].add_points(30 - score)
            else:
                game.teams[0].add_points(score - 30)

            self.send_all_players("update_score", game, data={"team0":game.teams[0].prev_scores,"team1":game.teams[1].prev_scores})

            for team in game.teams:
                if team.score > manillen_const.score_end:
                    self.end_game(game)
        troef_chooser = game.players[game.troef_chooser_pos]
        self.logger_engine.info("  " + troef_chooser.name + " was asked for troef")
        troef_chooser.send("choose_troef")

    def distribute_cards(self, game):
        player_cards = cards.getCards({"min": "7", "split_stack": 4, "shuffle": True, "sorted": True})

        for i in range(4):
            game.players[i].set_cards(player_cards[i])

            game.players[i].send("receive_play_cards", data=player_cards[i])

    def play_cards(self, game):
        if game.round_play_offset == 4:
            # see to which team the cards should go
            troef_active = False
            winning_index = 0
            starting_suit = game.table_cards[0][0]
            for i in range(len(game.table_cards)):
                if troef_active:
                    if self.comparevalue[game.table_cards[i][1:]] > self.comparevalue[game.table_cards[winning_index][1:]] and game.table_cards[i][0] == game.troef:
                        winning_index = i
                else:
                    if game.table_cards[i][0] == game.troef:
                        winning_index = i
                        troef_active = True
                    elif game.table_cards[i][0] == starting_suit \
                            and self.comparevalue[game.table_cards[i][1:]] > self.comparevalue[game.table_cards[winning_index][1:]]:
                        winning_index = i
            self.logger_engine.info(" These cards were played: " + str(game.table_cards)
                                    + " and " + str(game.table_cards[winning_index])
                                    + " won, this is player: " + game.players[(game.round_start_pos + winning_index)%4].name)

            game.round_start_pos = (game.round_start_pos + winning_index)%4
            game.players[game.round_start_pos].team.cards.extend(game.table_cards)
            game.table_cards = []
            game.round_play_offset = 0
            game.cards_played += 1

            self.send_all_players("clear_board", game)

        if game.cards_played == 8:
            self.play_round(game)

        else:
            current_player = game.players[(game.round_start_pos + game.round_play_offset) % 4]
            self.logger_engine.info("  " + current_player.name + " was asked to play card")
            current_player.send("play_card")

    def end_game(self, game):
        a = 5

    def send_all_players(self, command, game, data=None, viewer=True):
        for player in game.players:
            if player is not None:
                player.send(command, data=data)

        if viewer:
            for viewer in game.viewers:
                viewer.send(command, data)

    def receive_card(self, id, card):
        # check if valid card and allowed to play
        this_game = self.id_set_games[id]
        this_player = self.id_set_player[id]
        self.logger_engine.info(" received card from: " + this_player.name + " from team: " + this_player.team.name)

        card_from_player = card in this_player.cards
        should_be_index = this_game.players.index(this_player)
        current_index = (this_game.round_start_pos + this_game.round_play_offset)%4
        allowed = should_be_index == current_index

        if allowed and card_from_player and card_allowed(card, this_game.table_cards, this_player.cards, this_game.troef):
            self.logger_engine.info(" card is valid")
            this_player.send("valid_card")
            this_game.table_cards.append(card)

            self.send_all_players("new_table_card", this_game, data= {"card": card, "index": len(this_game.table_cards) - 1})

            this_game.round_play_offset += 1
            this_player.cards.remove(card)

            self.logger_game.info("card;" + str(this_player.position) + ";" + card)

            self.play_cards(this_game)
        else:
            self.logger_engine.info(" card is NOT valid")
            this_player.send("invalid_card")

    def receive_troef(self, id, data):
        # check if players card and allowed to choose troef
        this_game = self.id_set_games[id]
        this_player = self.id_set_player[id]

        # allow for sending full card and only the char
        for card in this_player.cards:
            if data[0] == card[0]:
                card_from_player = True
                break

        allowed = not this_game.troef_choosen and this_game.players.index(this_player) == this_game.troef_chooser_pos

        if card_from_player and allowed:
            self.send_all_players("send_troef", this_game, data=data[0])

            this_game.troef_choosen = True
            this_game.troef = data[0]

            self.logger_game.info("troef;" + str(this_player.position) + ";" + data)

            self.play_cards(this_game)
        else:
            this_player.send("invalid_troef")

    def add_viewer(self, id, data):
        table_name = data["table_name"]
        comm_module = data["comm_module"]

        this_viewer = viewer(id, comm_module)

        if table_name in self.game_set:
            this_game = self.game_set[table_name]
        else:
            this_game = man_game(table_name)
            self.game_set[table_name] = this_game

        this_game.add_viewer(this_viewer)
        self.id_set_viewer[id] = this_viewer
        this_viewer.set_game(this_game)
        this_viewer.send("allow_viewing")

    def add_player(self, id, data):
        table_name = data["game_name"]
        team_name = data["team_name"]
        position_in_team = int(data["location_in_team"])
        position_of_team = int(data["location_of_team"])
        position = position_of_team + 2 * position_in_team
        player_name = data["player_name"]
        comm_module = data["comm_module"]

        if table_name in self.game_set:
            this_game = self.game_set[table_name]
        else:
            this_game = man_game(table_name)
            self.game_set[table_name] = this_game

        if this_game.get_state("rejoin_waiting") or this_game.get_state("wait_decision"):
            this_player = this_game.get_deleted_player(player_name)
            if this_player is not None:
                this_game.reinstate_player(this_player)
                this_player.id = id
                self.id_set_games[id] = this_game
                self.id_set_player[id] = this_player

                team_names = [team.name for team in this_game.teams]

                this_player.send("set_teams", data=team_names)

                this_player.send("receive_play_cards", data=this_player.cards)

                this_player.send("wait_other_players")

                if len(this_game) == 4:
                    self.restart_play(this_game)
        else:
            this_player = man_player(player_name, id, comm_module, position=position)

            this_player.set_game(this_game)

            this_team = this_game.get_team(team_name)
            # team doesn't exist
            if this_team is None:
                this_team = man_team(team_name, position_of_team)
                this_game.add_team(this_team)
                this_team.set_game(this_game)

            this_team.add_player(this_player)
            this_player.add_team(this_team)
            self.id_set_games[id] = this_game
            self.id_set_player[id] = this_player
            this_game.add_player(this_player)

            if len(this_game) == 4:
                if not this_game.started:
                    self.start_play(this_game)

            this_player.send("wait_other_players")

        return id

    def reset_game(self, id):
        this_game = self.id_set_games[id]
        this_game.reset()
        this_game.set_state("not_started")

    def keep_waiting(self, id):
        this_game = self.id_set_games[id]
        this_game.set_state("rejoin_waiting")

    # can be player of viewer
    def remove_subscriber(self, id):
        self.logger_game.info("  player has left game")
        if id in self.id_set_viewer:
            this_viewer = self.id_set_viewer[id]
            this_game = this_viewer.game

            this_game.remove_viewer(this_viewer)
            self.id_set_viewer.pop(id)
        elif id in self.id_set_player:
            this_player = self.id_set_player[id]
            this_game = this_player.game

            this_game.remove_player(this_player)
            self.id_set_player.pop(id)
            self.id_set_games.pop(id)
            self.return_to_test_set(this_player)
            if this_game.started:
                self.send_all_players("reset_game_lost_player", this_game, viewer=False)
                this_game.set_state("wait_decision")

    def return_to_test_set(self, player):
        if self.test_mod is not None:
            table_name = player.game.name
            team_name = player.team.name
            player_name = player.name
            team_location = player.team.position
            in_team_location = player.position // 2

            self.test_mod.return_vector({'game_name': table_name, 'team_name': team_name,
             'player_name': player_name, 'team_location_input': team_location,
             "team_player_location_input": in_team_location})

    def create_player(self, name, id, cards, position, comm):
        return man_player(name, id, comm, position=position, cards=cards)

    def create_team(self, name, position, players):
        this_team = man_team(name, position, players=players)

        for player in players:
            player.set_team(this_team)
        return this_team

    def create_game(self, table_name, teams):
        this_game = man_team(table_name)

        for team in teams:
            this_game.add_team(team)
        return this_game

if __name__ == "__main__":
    print("========== testing engine ==========")
    en = engine()
    print("========== card allowed ==========")
    # card, table cards, player_cards, troef
    # player should play K10
    print(en.card_allowed("KJ", ["K8", "KQ"], ["K10", "H9", "KJ"], 'H') == False)
    # player should buy
    print(en.card_allowed("S10", ["K8", "KQ"], ["S10", "H9", "SJ"], 'H') == False)
    #valid play
    print(en.card_allowed("K10", ["K8", "KQ"], ["S10", "K10", "KJ"], 'H') == True)
    #valid play
    print(en.card_allowed("S10", ["KQ", "K8"], ["S10", "H9", "SJ"], 'H') == True)


import logging
import config
from cube_session import CubeSession

class CubeParser(object):

    def __init__(self):
        self.logger = logging.getLogger(config.logger_name)

    def parse_current_result(self, id, full_json, is_current):
        results = full_json["results"]

        if is_current:
            if len(results) == 0:
                self.logger.error("No results found for %s.", id)
                return None
            elif len(results) > 1:
                self.logger.warning("Too many results found. Using only first.")

        zipped = dict(zip(full_json["field_list"], results[0]))
        zipped['id'] = id

        return zipped

    def get_devices(self, session):
        response = session.get("%s/devices/" % config.RES)
        result = response.json()
        # print(response.headers)
        # print(result)
        return result

    def get_data(self):
        session = CubeSession.get_session()
        result = self.get_devices(session)
        parsed_datas = []
        if result["ok"]:
            for device in result["devices"]:
                cube_data_response = session.get('%s/devices/%s/current' % (config.RES, device["uid"]))
                parsed = self.parse_current_result(device["uid"], cube_data_response.json(), True)
                if parsed:
                    parsed_datas.append(parsed)
        else:
            self.logger.error("Failed to get devices %s", str(result))

        return parsed_datas

if __name__ == '__main__':
    CubeParser().get_data()