# Licensed under a MIT style license - see LICENSE.txt

"""MUSE-PHANGS plotting routines
"""

__authors__   = "Eric Emsellem"
__copyright__ = "(c) 2017, ESO + CRAL"
__license__   = "MIT License"
__contact__   = " <eric.emsellem@eso.org>"

# This module provides some functions to plot and check the data reduction
#
# Eric Emsellem adapted a March 2018 version, provided by Rebecca
# and adapted it to the pymusepipe package

# Importing modules
import numpy as np

# Standard modules
from os.path import join as joinpath

# Plotting routines
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.gridspec as gridspec

from .mpdaf_pipe import MuseSetImages, MuseSetSpectra
from .util_image import my_linear_model, get_flux_range

__version__ = '0.0.1 (23 March 2018)'

############################################################
#                      BEGIN
# The following parameters can be adjusted for the need of
# the specific pipeline to be used
############################################################

############################################################
#                      END
############################################################
PLOT = '\033[1;35;20m'
ENDC = '\033[0m'

def print_fig(text) :
    print(PLOT + "# GraphPipeInfo " + ENDC + text)

def open_new_wcs_figure(nfig, mywcs=None):
    """Open a new figure (with number nfig) with given wcs.
    If not WCS is provided, just opens a subplot in that figure.

    Input
    -----
    nfig : int
        Figure number to consider
    mywcs : astropy.wcs.WCS
        Input WCS to open a new figure (Default value = None)

    Returns
    -------
    fig, subplot
        Figure itself with the subplots using the wcs projection

    """

    # get the figure
    fig = plt.figure(nfig)

    # Clean the figure
    plt.clf()

    # Adding axes with WCS
    if mywcs is None:
        return fig, fig.add_subplot(1, 1, 1)
    else:
        return fig, fig.add_subplot(1, 1, 1, projection=mywcs)

def plot_compare_contours(data1, data2, plotwcs=None, labels=('Data1', 'Data2'), levels=None,
                          nlevels=10, fignum=1, namefig='dummy_contours.png', figfolder="",
                          savefig=False, **kwargs):
    """Creates a plot with the contours of two input datasets for comparison

    Input
    -----
    data1
    data2: 2d np.arrays
        Input arrays to compare
    plotwcs: WCS
        WCS used to set the plot if provided
    labels: tuple/list of 2 str
        Labels for the plot
    levels: list of floats
        Levels to be used for the contours. Calculated if None.
    fignum: int
        Number for the figure
    namefig: str
        Name of the figure to be saved (if savefig is True)
    figfolder: str
        Name of the folder for the figure
    savefig: bool
        If True, will save the figure as namefig

    Creates
    -------
    Plot with contours of the two input dataset
    """
    np.seterr(divide='ignore', invalid='ignore')

    # Getting the range of relevant fluxes
    lowlevel_d1, highlevel_d1 = get_flux_range(data1)

    fig, ax = open_new_wcs_figure(fignum, plotwcs)

    # Defining the levels for MUSE
    if levels is not None:
        levels_d1 = levels
    else:
        levels_d1 = np.linspace(np.log10(lowlevel_d1),
                                  np.log10(highlevel_d1),
                                  nlevels)
    # Plot contours for MUSE
    cdata1 = ax.contour(np.log10(data1), levels_d1, colors='k',
                          origin='lower', linestyles='solid')

    levels_d2 = cdata1.levels
    # Plot contours for Ref
    cdata2 = ax.contour(np.log10(data2), levels=levels_d2, colors='r',
                        origin='lower', alpha=0.5, linestyles='solid')

    ax.set_aspect('equal')
    h1, _ = cdata1.legend_elements()
    h2, _ = cdata2.legend_elements()
    ax.legend([h1[0], h2[0]], [labels[0], labels[1]])

    if "title" in kwargs:
        plt.title(kwargs.pop('title'))
    plt.tight_layout()
    if savefig:
        plt.savefig(joinpath(figfolder, namefig))
    np.seterr(divide='warn', invalid='warn')

def plot_compare_diff(data1, data2, plotwcs=None, figfolder="", percentage=5, fignum=1,
                      namefig="dummy_diff.ong", savefig=False, **kwargs):
    """

    Parameters
    ----------
    data1
    data2
    figfolder
    fignum
    namefig
    savefig
    kwargs

    Returns
    -------
    """
    fig, ax = open_new_wcs_figure(fignum, plotwcs)
    ratio = 100. * (data2 - data1) / (data1 + 1.e-12)
    im = ax.imshow(ratio, vmin=-percentage, vmax=percentage)
    cbar = fig.colorbar(im, shrink=0.8)

    if "title" in kwargs:
        plt.title(kwargs.pop('title'))
    plt.tight_layout()
    if savefig:
        plt.savefig(joinpath(figfolder, namefig))

def plot_compare_cuts(data1, data2, labels=('X', 'Y'), figfolder="", fignum=1,
                 namefig="dummy_polypar.png", ncuts=11, savefig=False, **kwargs):
    """

    Input
    -----
    data1
    data2
    label1
    label2
    figfolder
    fignum
    namefig
    savefig
    kwargs

    Creates
    -------
    Plot with a comparison of the two data arrays using regular X and Y cuts
    """

    fig, ax = open_new_wcs_figure(fignum)

    # Getting the range of relevant fluxes
    lowlevel_d1, highlevel_d1 = get_flux_range(data1)

    diffima = (data2 - data1) * 200. / (lowlevel_d1 + highlevel_d1)
    chunk_x = data1.shape[0] // (ncuts + 1)
    chunk_y = data1.shape[1] // (ncuts + 1)

    c1 = ax.plot(diffima[np.arange(ncuts) * chunk_x, :].T, 'k-', label=labels[0])
    c2 = ax.plot(diffima[:, np.arange(ncuts) * chunk_y], 'r-', label=labels[1])
    ax.legend(handles=[c1[0], c2[0]], loc=0)
    ax.set_ylim(-20, 20)
    ax.set_xlabel("[pixels]", fontsize=20)
    ax.set_ylabel("[%]", fontsize=20)

    if "title" in kwargs:
        plt.title(kwargs.pop('title'))
    plt.tight_layout()
    if savefig:
        plt.savefig(joinpath(figfolder, namefig))

def plot_polypar(polypar, labels=("Data 1","Data 2"), figfolder="", fignum=1,
                 namefig="dummy_polypar.png", savefig=False, **kwargs):
    """Creating a plot showing the normalisation arising from a polypar object

    Parameters
    ----------
    polypar
    label1
    label2
    foldfig
    namefig

    Returns
    -------

    """
    # Opening the figure
    fig, ax = open_new_wcs_figure(fignum)

    # Getting the x, y to plot
    (x, y) = (polypar.med[0][polypar.selection],
              polypar.med[1][polypar.selection])
    ax.plot(x, y, '.')
    ax.set_xlabel(labels[0])
    ax.set_ylabel(labels[1])
    ax.plot(x, my_linear_model(polypar.beta, x), 'k')

    if "title" in kwargs:
        plt.title(kwargs.pop('title'))
    plt.tight_layout()
    if savefig:
        plt.savefig(joinpath(figfolder, namefig))

#########################################################################
# Main class
#                           GraphMuse
#########################################################################
class GraphMuse(object):
    """Graphic output to check MUSE data reduction products
    """

    def __init__(self, pdf_name='drs_check.pdf',
            figsize=(10,14), rect_layout=[0, 0.03, 1, 0.95], verbose=True):
        """Initialise the class for plotting the outcome results
        """
        self.verbose = verbose
        self.pdf_name = pdf_name
        self.pp = PdfPages(pdf_name)
        self.figsize = figsize
        self.rect_layout = rect_layout
        self.npages = 0

    def close(self):
        self.pp.close()

    def savepage(self):
        self.pp.savefig()
        plt.close()
        self.npages += 1

    def start_page(self):
        """Start the page
        """
        if self.verbose :
            print_fig("Starting page {0}".format(self.npages+1))
        plt.figure(figsize=self.figsize)

    def plot_page(self, list_data):
        """Plot a set of blocks, each made of a set of spectra or
        images. This is for 1 page
        It first counts the number of lines needed according to the
        separation for images (default is 2 per line, each image taking 2 lines)
        and spectra (1 spectrum per line over 2 columns)
        """
        if len(list_data) == 0 :
            print_fig("WARNING: datalist is empty, no plots will be created")
            return

        self.start_page()
        nspectra_blocks, nimages_blocks = 0, 0
        nlines = 0
        if isinstance(list_data, MuseSetSpectra) | isinstance(list_data, MuseSetImages):
            plt.suptitle(list_data.subtitle)
            list_data = [list_data]

        for data in list_data :
            if isinstance(data, MuseSetSpectra):
                nspectra_blocks += 1
                nlines += data.__len__()
            elif isinstance(data, MuseSetImages):
                nimages_blocks += 1
                nlines += 2 * data.__len__()

        self.gs = gridspec.GridSpec(nlines, 2)
        self.list_ax = []
        self.count_lines = 0
        for data in list_data :
            if isinstance(data, MuseSetSpectra):
                self.plot_set_spectra(data)
            elif isinstance(data, MuseSetImages):
                self.plot_set_images(data)

        self.savepage()

    def plot_set_spectra(self, set_of_spectra=None):
        """Plotting a set of spectra
        Skipping the ones that are 'None'
        """

        # Set of sky lines to plot when relevant - add_sky_lines to True
        sky_lines = [5577., 6300., 6864., 7914., 8344., 8827.]

        if set_of_spectra is None:
            print_fig("ERROR: list of spectra is empty")
            return

        for spec in set_of_spectra:
            self.list_ax.append(plt.subplot(self.gs[self.count_lines,:]))
            self.count_lines += 1
            if spec is not None:
                spec.plot(title=spec.title, ax=self.list_ax[-1])
                if spec.add_sky_lines:
                    for line in sky_lines:
                        plt.axvline(x=line, color=spec.color_sky, linestyle=spec.linestyle_sky, alpha=spec.alpha_sky)

        plt.tight_layout(rect=self.rect_layout)

    def plot_set_images(self, set_of_images=None):
        """Plotting a set of images
        Skipping the ones that are 'None'
        """
        if set_of_images is None :
            print_fig("ERROR: list of images is empty")
            return

        for i in range(set_of_images.__len__()):
            image = set_of_images[i]
            count_cols = i%2
            if image is not None:
                self.list_ax.append(plt.subplot(self.gs[self.count_lines: self.count_lines + 2, count_cols]))
                image.plot(scale=image.scale, vmin=image.vmin, colorbar=image.colorbar, title=image.title, ax=self.list_ax[-1])
            self.count_lines += count_cols * 2

        plt.tight_layout(rect=self.rect_layout)


from src.admin.repository import AdminRepo
from src.admin.schemas import AdminUserData
from src.user.constants import SubscriptionType

class AdminService:
    def __init__(self, admin_repo: AdminRepo):
        self.admin_repo = admin_repo

    async def get_users(
        self,
        subscription_type: SubscriptionType | None = None,
        is_active: bool | None = None,
        is_activated: bool | None = None,
        search_keyword: str | None = None,
    ) -> list[AdminUserData]:
        return await self.admin_repo.get_users(
            search_keyword=search_keyword,
            subscription_type=subscription_type,
            is_active=is_active,
            is_activated=is_activated,
        )


import setuptools

with open("README.md", "r", encoding="utf-8") as fh:
    long_description = fh.read()

setuptools.setup(
    name='wutools',
    version='0.0.3',
    author='Jason Yunger',
    author_email='jason.yunger@gmail.com',
    description='Testing installation of Package',
    long_description=long_description,
    long_description_content_type="text/markdown",
    url='https://github.com/jyunger/wutest',
    project_urls = {
        "Bug Tracker": "https://github.com/jyunger/wutest/issues"
    },
    license='MIT',
    packages=setuptools.find_packages(),
    install_requires=['numpy', 'pandas', 'psutil', 'pyathena', 'graphviz', 'sqlalchemy', 'sqlparse'],
)


#!/usr/bin/env python3
import sys
sys.setrecursionlimit(10**6)
INF = 10 ** 9 + 1  # sys.maxsize # float("inf")
MOD = 10 ** 9 + 7

def debug(*x):
    print(*x, file=sys.stderr)

def solve(SOLVE_PARAMS):
    pass

def main():
    N, M = map(int, input().split())
    is_head = [True] * N
    from collections import defaultdict
    edges = defaultdict(list)
    for q in range(M):
        a, b = map(int, input().split())
        a -= 1
        b -= 1
        is_head[b] = False
        edges[a].append(b)

    to_tail = [-1] * N
    visited = [False] * N

    def dfs(x):
        buf = [0]
        visited[x] = True
        for v in edges[x]:
            if visited[v]:
                continue
            ret = to_tail[v]
            if ret == -1:
                ret = dfs(v)
                to_tail[v] = ret
            buf.append(ret)
        return max(buf) + 1

    buf = [1]
    for i in range(N):
        visited = [False] * N
        buf.append(dfs(i))

    # debug(": to_tail", to_tail)
    print(max(buf))

# tests
T1 = """
5 3
1 2
3 4
5 1
"""
TEST_T1 = """
>>> as_input(T1)
>>> main()
3
"""

T2 = """
4 10
1 2
2 1
1 2
2 1
1 2
1 3
1 4
2 3
2 4
3 4
"""
TEST_T2 = """
>>> as_input(T2)
>>> main()
4
"""

T3 = """
10 4
3 1
4 1
5 9
2 6
"""
TEST_T3 = """
>>> as_input(T3)
>>> main()
3
"""

def _test():
    import doctest
    doctest.testmod()
    g = globals()
    for k in sorted(g):
        if k.startswith("TEST_"):
            doctest.run_docstring_examples(g[k], g, name=k)

def as_input(s):
    "use in test, use given string as input file"
    import io
    f = io.StringIO(s.strip())
    g = globals()
    g["input"] = lambda: bytes(f.readline(), "ascii")
    g["read"] = lambda: bytes(f.read(), "ascii")

input = sys.stdin.buffer.readline
read = sys.stdin.buffer.read

if sys.argv[-1] == "-t":
    print("testing")
    _test()
    sys.exit()

main()


import sys
import time
import os
import tempfile
import shutil
import contextlib

import numpy as np
import h5py

from . import __version__ as tool_version
import stag.align as align

def load_genome_DB(database, tool_version, verbose):
    dirpath = tempfile.mkdtemp()
    shutil.unpack_archive(database, dirpath, "gztar")
    list_files = [f for f in os.listdir(dirpath) if os.path.isfile(os.path.join(dirpath, f))]
    for f in ("threshold_file.tsv", "hmm_lengths_file.tsv", "concatenated_genes_STAG_database.HDF5"):
        if f not in list_files:
            raise ValueError(f"[E::align] Error: {f} is missing.")

    with open(os.path.join(dirpath, "threshold_file.tsv")) as threshold_in:
        gene_thresholds = dict(line.rstrip().split("\t") for line in threshold_in)
        gene_order = list(gene_thresholds.keys())

    with open(os.path.join(dirpath, "hmm_lengths_file.tsv")) as hmm_lengths_in:
        ali_lengths = dict(line.rstrip().split("\t") for line in hmm_lengths_in)

    list_files.remove("threshold_file.tsv")
    list_files.remove("hmm_lengths_file.tsv")
    list_files.remove("concatenated_genes_STAG_database.HDF5")
    return list_files, dirpath, gene_thresholds, gene_order, ali_lengths, os.path.join(dirpath, "concatenated_genes_STAG_database.HDF5")

def load_db(hdf5_DB_path, protein_fasta_input=None, aligned_sequences=None, dir_output=None):
    with h5py.File(hdf5_DB_path, 'r') as db_in:
        params_out = open(os.path.join(dir_output, "parameters.tsv"), "w") if dir_output else contextlib.nullcontext()
        with params_out:
            # zero: tool version -------------------------------------------------------
            db_tool_version = db_in['tool_version'][0]
            use_proteins = db_in['align_protein'][0] # bool
            use_cmalign = db_in['use_cmalign'][0] # bool
            if dir_output:
                params_out.write("Tool version: "+str(db_tool_version)+"\n")
                params_out.write("Use proteins for the alignment: "+str(use_proteins)+"\n")
                params_out.write("Use cmalign instead of hmmalign: "+str(use_cmalign)+"\n")

        # check that it is the correct database, for 'classify', we need a single
        # gene
        if db_in['db_type'][0] != "single_gene":
            sys.stderr.write("[E::main] Error: this database is not designed to run with stag classify\n")
            sys.exit(1)
        # check if we used proteins
        if not aligned_sequences and not dir_output:
            if protein_fasta_input and not db_in['align_protein'][0]:
                # some proteins are provided in the classify but the db was constructed without using the proteins
                raise ValueError("Protein provided, but the database was constructed on genes.\n")
            elif not protein_fasta_input and db_in['align_protein'][0]:
                # the classify do not have proteins but the db was constructed WITH the proteins
                raise ValueError("Missing protein file (the database was constructed aligning proteins).\n")

        # first, we save a temporary file with the hmm file ------------------------
        hmm_file = tempfile.NamedTemporaryFile(delete=False, mode="w")
        with hmm_file:
            os.chmod(hmm_file.name, 0o644)
            hmm_file.write(db_in['hmm_file'][0])
            hmm_file.flush()
            os.fsync(hmm_file.fileno())

        if dir_output:
            shutil.move(hmm_file.name, os.path.join(dir_output, "hmmfile.hmm"))

        # second if we need to use cm_align ----------------------------------------
        use_cmalign = db_in['use_cmalign'][0] # bool

        # third: taxonomy ----------------------------------------------------------
        taxonomy = {key: list(db_in['taxonomy/{}'.format(key)]) for key in db_in['taxonomy']}
        if dir_output:
            tax_out = open(os.path.join(dir_output, "node_hierarchy.tsv"), "w")
            with tax_out:
                print("Node", "Children", sep="\t", file=tax_out)
                for key, values in taxonomy.items():
                    print(key, *map(str, values), sep="\t", file=tax_out)

        # fourth: tax_function -----------------------------------------------------
        tax_function = {str(key): np.array(db_in['tax_function/{}'.format(key)], dtype=np.float64)
                        for key in db_in['tax_function']}
        if dir_output:
            tax_func_out = open(os.path.join(dir_output, "taxonomy_function.tsv"), "w")
            with tax_func_out:
                for key, value in tax_function.items():
                    print(key, value, sep="\t", file=tax_func_out)

        # fifth: the classifiers ---------------------------------------------------
        classifiers = dict()
        class_out = open(os.path.join(dir_output, "classifiers_weights.tsv"), "w") if dir_output else contextlib.nullcontext()
        with class_out:
            for key in db_in['classifiers']:
                classifier = db_in['classifiers/{}'.format(key)]
                if not isinstance(classifier[0], str):
                    classifiers[key] = np.array(classifier, dtype=np.float64)
                else:
                    classifiers[key] = "no_negative_examples"
                if dir_output:
                    print(key, *classifiers[key], sep="\t", file=class_out)

    return hmm_file.name, use_cmalign, taxonomy, tax_function, classifiers, db_tool_version

def save_to_file(classifiers, full_taxonomy, tax_function, use_cmalign, output, hmm_file_path=None, protein_fasta_input=None):

    string_dt = h5py.special_dtype(vlen=str)
    with h5py.File(output, "w") as h5p_out:
        # zero: tool version -------------------------------------------------------
        h5p_out.create_dataset('tool_version', data=np.array([str(tool_version)], "S100"), dtype=string_dt)
        # and type of database
        h5p_out.create_dataset('db_type', data=np.array(["single_gene"], "S100"), dtype=string_dt)
        # was the alignment done at the protein level?
        h5p_out.create_dataset('align_protein', data=np.array([bool(protein_fasta_input)]), dtype=bool)
        # first we save the hmm file -----------------------------------------------
        hmm_string = "".join(line for line in open(hmm_file_path)) if hmm_file_path else "NA"
        h5p_out.create_dataset('hmm_file', data=np.array([hmm_string], "S" + str(len(hmm_string) + 100)), dtype=string_dt, compression="gzip")
        # second, save the use_cmalign info ----------------------------------------
        h5p_out.create_dataset('use_cmalign', data=np.array([use_cmalign]), dtype=bool)
        # third, we save the taxonomy ---------------------------------------------
        h5p_out.create_group("taxonomy")
        for node, _ in full_taxonomy.get_all_nodes(get_root=True):
            h5p_out.create_dataset(f"taxonomy/{node}", data=np.array(list(full_taxonomy[node].children.keys()), "S10000"), dtype=string_dt, compression="gzip")
        # fourth, the taxonomy function --------------------------------------------
        h5p_out.create_group("tax_function")
        for c in tax_function:
            # we append the intercept at the head (will have position 0)
            vals = np.append(tax_function[c].intercept_, tax_function[c].coef_)
            h5p_out.create_dataset("tax_function/" + str(c), data=vals, dtype=np.float64, compression="gzip")
        # fifth, save the classifiers ----------------------------------------------
        h5p_out.create_group("classifiers")
        for c in classifiers:
            if classifiers[c] != "no_negative_examples":
                vals = np.append(classifiers[c].intercept_, classifiers[c].coef_)
                h5p_out.create_dataset("classifiers/" + c, data=vals, dtype=np.float64, compression="gzip", compression_opts=8)
            else:
                # in this case, it always predict 1, we save it as an array of
                # with the string "no_negative_examples"
                h5p_out.create_dataset("classifiers/" + c, data=np.array(["no_negative_examples"], "S40"), dtype=string_dt, compression="gzip")

        h5p_out.flush()


class Solution:
    def largestLocal(self, grid: List[List[int]]) -> List[List[int]]:
        ans = []
        row = len(grid)
        col = len(grid[0])

        for i in range(row-2):
            temp = []
            for j in range(col-2):
                maxi = 0
                for k in range(i,i+3):
                    for z in range(j,j+3):
                        maxi = max(maxi,grid[k][z])
                temp.append(maxi)
            ans.append(temp)

        # count = 0
        # for i in range(row-2):
        #     temp = []
        #     for j in range(col-2):
        #         temp.append(arr[count])
        #         count += 1
        #     ans.append(temp)
        return ans


#%%
import numpy as np
import os
from sklearn.feature_extraction.text import CountVectorizer
from scipy.sparse import csr_matrix
from scipy.sparse import coo_matrix
import numba as nb
import time
import cupy as cp
#%% 讀取檔案

queriesPath ='C:\\Users\\User\\Desktop\\NTUST\\IR\\data\\ntust-ir-2020_hw4_v2\\queries'
docsPath = 'C:\\Users\\User\\Desktop\\NTUST\\IR\\data\\ntust-ir-2020_hw4_v2\\docs'

queriesList = os.listdir(queriesPath)
queriesList.sort()
docsList = os.listdir(docsPath)
docsList.sort()

queriesContext = []
docsContext = []

for query in queriesList:
    path = os.path.join(queriesPath,query)
    f = open(path)
    context = f.read()
    queriesContext.append(context)

for doc in docsList:
    path = os.path.join(docsPath,doc)
    f = open(path)
    context = f.read()
    docsContext.append(context)

#%% 計算各篇文章長度 ， 後面要用到
doc_len = np.zeros(len(docsContext))
for doc_id ,doc in enumerate(docsContext):
    words = doc.split()
    doc_len[doc_id] = len(words)
#%% tf matrix & get sparse matrix
vectorizer = CountVectorizer(stop_words=None, token_pattern="(?u)\\b\\w+\\b") #get tf-matrix
X = vectorizer.fit_transform(docsContext) #得到文章對於所有word的 tf - matrix
print(X.shape)
#%%
#@nb.jit()
# axis = 0 保留行
# axis = 1 保留列
def PLSA_sparseMatrix(matrix , iteration , numOfTopic):
    sparse = coo_matrix(matrix)
    sparse_data = sparse.data
    sparse_row = sparse.row
    sparse_col = sparse.col
    sparse_size = sparse_data.shape[0]
    p_tk_wi_dj = cp.zeros((sparse_size , numOfTopic))
    p_tk_dj = cp.zeros((numOfTopic , matrix.shape[0]))
    p_wi_tk = cp.zeros(( matrix.shape[1] , numOfTopic))
    print ("Initializing...")
    # randomly assign values
    p_tk_dj = cp.random.random(size = (numOfTopic , matrix.shape[0]))
    doc_toic_sum = cp.sum(p_tk_dj,axis = 0)
    p_tk_dj = p_tk_dj / doc_toic_sum
    p_wi_tk = cp.random.random(size = (matrix.shape[1] , numOfTopic))
    term_topic_sum = cp.sum(p_wi_tk , axis = 0)
    p_wi_tk = p_wi_tk / term_topic_sum

    for loop in range(iteration):
        # E_step
        print('iter : '  + str(loop))
        s1 = time.time()
        print('E step')
        for index in range(len(sparse_data)):
            p_tk_wi_dj[index,:] = p_wi_tk[sparse_col[index] , :] * p_tk_dj[ : , sparse_row[index]]
        topic_normal = cp.sum(p_tk_wi_dj , axis = 1)
        for topic in range(numOfTopic):
            p_tk_wi_dj [:,topic] = p_tk_wi_dj [:,topic] / topic_normal
        print('end E step')
        # M step
        print('M step')
        M_step_molecular = sparse_data[:,np.newaxis] * p_tk_wi_dj
        for index in range(len(sparse_data)):
            #if index % 10000 == 0:
                #print(index)
            p_wi_tk[sparse_col[index],:] += M_step_molecular[index,:]
        m_step_normalize = cp.sum(p_wi_tk, axis = 0)[np.newaxis,:]
        print(cp.sum(p_wi_tk, axis = 0)[cp.newaxis,:].shape)
        p_wi_tk /= m_step_normalize
        print('end M step')
        # update p(tk|dj)
        print('update p(tk|dj)')
        for index in range(len(sparse_data)):
            doc_index = sparse_row[index]
            p_tk_dj[:,doc_index] += M_step_molecular[index,:]
        tk_dj_normalize = cp.sum(p_tk_dj, axis = 0)[cp.newaxis,:]
        print(np.sum(p_tk_dj, axis = 0)[cp.newaxis,:].shape)
        p_tk_dj /= tk_dj_normalize
        print('end p(tk|dj)')
        s2 = time.time()
        print(str(loop)  + ' time : ' , str(s2 - s1) + 's')

    return p_tk_dj,p_wi_tk
#%%
p_tk_dj,p_wi_tk = PLSA_sparseMatrix(X,45,128)
#%%
queryword = []
for query in queriesContext:
    words = query.split()
    print(words)
    for word in words:
        if word not in queryword:
            queryword.append(word)
#%% cal_p(wi|dj)
p_wi_dj = np.zeros([14955,len(queryword)])
print(p_wi_dj[:,0].shape)
for i ,name in enumerate(queryword):
    index = vectorizer.get_feature_names().index(name) # 得到query_word_index
    p_wi_dj[:,i] = X[:,index].toarray().reshape(14955)
    p_wi_dj[:,i] /= doc_len
#%% cal_ p(wi | BG)
p_wi_BG = np.zeros(len(queryword))
totalword = np.sum(doc_len)
for i,name in enumerate(queryword):
    index = vectorizer.get_feature_names().index(name)
    p_wi_BG[i] = np.sum(X[:,index].toarray()) / totalword
#%% p(q|dj)
p_q_dj = np.zeros([len(docsContext),len(queriesContext)])
alpha =0.7       #自訂的可調參數alpha
beta = 0.2

for num , query in enumerate(queriesContext):
    words = query.split() #這篇query幾個單字
    out_arr = np.zeros(len(docsContext))

    for index , word in enumerate (words):
        w_index = vectorizer.get_feature_names().index(word)
        em = p_wi_tk[w_index,:].reshape(p_wi_tk.shape[1],-1) * p_tk_dj # sumation  p(wi|tk) * p(tk|dj) #all_topic
        em = np.sum(em, axis = 0)
        middle = beta * em
        front = alpha * p_wi_dj[:, queryword.index(word)]
        back = (1 - alpha - beta) * p_wi_BG[queryword.index(word)]
        prob = front + middle + back
        if index == 0:
            out_arr = prob
        else:
            out_arr = out_arr * prob

    p_q_dj[: , num] = out_arr
#%%
res = {}
save_file_name = 'C:\\Users\\ipprlab\\Desktop\\2020-information-retrieval-and-applications-hw4-v2\\sparse_test2.txt'
fp = open(save_file_name, "w")
fp.seek(0)
fp.write("Query,RetrievedDocuments\n")

for loop in range (len(queriesList)):
    write_string = queriesList[loop][0:-4] + ","
    for i,j in zip(docsList,p_q_dj[:,loop]):
        res[i[0:-4]] = j
    sorted_x = sorted(res.items(), key=lambda kv: kv[1],reverse = True)
    for iteration , doc in enumerate(sorted_x):
        if iteration >= 1000:
            break
        write_string += doc[0] + " "
    write_string += "\n"
    fp.write(write_string)
    res.clear()
    sorted_x.clear()
fp.truncate()
fp.close()


from osv import fields,osv
from osv import orm
import pooler

def test_prof(self, cr, uid, prof_id, pid, answers_ids):
#return True if the partner pid fetch the profile rule prof_id
    ids_to_check = pooler.get_pool(cr.dbname).get('segmentation.profile').get_parents(cr, uid, [prof_id])
    [yes_answers, no_answers] = pooler.get_pool(cr.dbname).get('segmentation.profile').get_answers(cr, uid, ids_to_check)
    temp = True
    for y_ans in yes_answers:
        if y_ans not in answers_ids:
            temp = False
            break
    if temp:
        for ans in answers_ids:
            if ans in no_answers:
                temp = False
                break
    if temp:
        return True
    return False

def _recompute_profiles(self, cr, uid, pid, answers_ids):
    ok =  []

    cr.execute('''
        select id
        from segmentation_profile
        order by id''')

    for prof_id in cr.fetchall():
        if test_prof(self, cr, uid, prof_id[0], pid, answers_ids):
            ok.append(prof_id[0])
    return ok

class question(osv.osv):
    _name="segmentation.question"
    _description= "Question"
    _columns={
        'name': fields.char("Question",size=128, required=True),
        'answers_ids': fields.one2many("segmentation.answer","question_id","Avalaible answers",),
        }
question()

class answer(osv.osv):
    _name="segmentation.answer"
    _description="Answer"
    _columns={
        "name": fields.char("Answer",size=128, required=True),
        "question_id": fields.many2one('segmentation.question',"Question"),
        }
answer()

class questionnaire(osv.osv):
    _name="segmentation.questionnaire"
    _description= "Questionnaire"
    _columns={
        'name': fields.char("Questionnaire",size=128, required=True),
        'description':fields.text("Description", required=True),
        'questions_ids': fields.many2many('segmentation.question','profile_questionnaire_quest_rel','questionnaire', 'question', "Questions"),
        }
questionnaire()

class profile(osv.osv):

    def get_answers(self, cr, uid, ids):
        query = """
        select distinct(answer)
        from profile_question_yes_rel
        where profile in (%s)"""% ','.join([str(i) for i in ids ])

        cr.execute(query)
        ans_yes = [x[0] for x in cr.fetchall()]

        query = """
        select distinct(answer)
        from profile_question_no_rel
        where profile in (%s)"""% ','.join([str(i) for i in ids ])

        cr.execute(query)
        ans_no = [x[0] for x in cr.fetchall()]

        return [ans_yes, ans_no]

    def get_parents(self, cr, uid, ids):
        ids_to_check = ids
        cr.execute("""
         select distinct(parent_id)
         from segmentation_profile
         where parent_id is not null
         and id in (%s)""" % ','.join([str(i) for i in ids ]))

        parent_ids = [x[0] for x in cr.fetchall()]

        trigger = False
        for x in parent_ids:
            if x not in ids_to_check:
                ids_to_check.append(x)
                trigger = True

        if trigger:
            ids_to_check = pooler.get_pool(cr.dbname).get('segmentation.profile').get_parents(cr, uid, ids_to_check)

        return ids_to_check

    def process_continue(self, cr, uid, ids, state=False):
        cr.execute('delete from partner_profile_rel where profile_id=%s', (ids[0],))

        cr.execute('select id from res_partner order by id ')
        partners = [x[0] for x in cr.fetchall()]
        to_remove_list=[]
        for pid in partners:

            cr.execute('select distinct(answer) from partner_question_rel where partner=%s' % pid)
            answers_ids = [x[0] for x in cr.fetchall()]
            if (not test_prof(self, cr, uid, ids[0], pid, answers_ids)):
                to_remove_list.append(pid)

        for pid in to_remove_list:
            partners.remove(pid)

        for partner_id in partners:
            cr.execute('insert into partner_profile_rel (profile_id,partner_id) values (%s,%s)', (ids[0],partner_id))
        cr.commit()

        cr.commit()
        return True

    _name="segmentation.profile"
    _description="Profile"
    _columns={
        "name": fields.char("Description",size=128, required=True),
        "answer_yes": fields.many2many("segmentation.answer","profile_question_yes_rel","profile","answer","Inclued Answers"),
        "answer_no": fields.many2many("segmentation.answer","profile_question_no_rel","profile","answer","Excluded Answers"),
        'parent_id': fields.many2one('segmentation.profile', 'Parent Profile'),
        'child_ids': fields.one2many('segmentation.profile', 'parent_id', 'Children Profile'),
        }
    _constraints = [
        (orm.orm.check_recursion, 'Error ! You can not create recursive profiles.', ['parent_id'])
    ]
profile()

class partner(osv.osv):

    def write(self, cr, uid, ids, vals, context=None):
        if not context:
            context={}
        if 'answers_ids' in vals:
            vals['profiles_ids']=[[6, 0, _recompute_profiles(self, cr, uid, ids[0],vals['answers_ids'][0][2])]]
        return super(partner, self).write(cr, uid, ids, vals, context=context)

    _inherit="res.partner"
    _columns={
        "answers_ids": fields.many2many("segmentation.answer","partner_question_rel","partner","answer","Answers"),
        "profiles_ids":fields.many2many("segmentation.profile","partner_profile_rel","partner_id","profile_id","Matching Profiles", readonly=True, select="2"),
        }
partner()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:


from db.dbconnect import connection
from flask import jsonify

def querydb(data, operation, check=None, user2flower_id=None):
    try:
        c, conn = connection()
        if c == {'msg': 'Circuit breaker is open, reconnection in porgress'}:
            return c, 500

        if operation == 'POST':
            executeQuery(c, conn, data)
            return {"msg": "New user2flower added to DB."}, 201

        if operation == 'GET':

            c.execute(data)

            if check == 'list':
                data = c.fetchall()
                payload = []

                if data is not None and c.rowcount != 0:
                    for userflower in data:
                        date = userflower[3]
                        date = date.strftime('%Y-%m-%d')
                        content = {"user2flower_id": str(userflower[0]), "user_id": str(userflower[1]),
                                   "flower_id": str(userflower[2]), "date_of_inception": date,
                                   "email": userflower[4]}
                        payload.append(content)
                    c.close()
                    conn.close()
                    return jsonify(payload)
                else:
                    c.close()
                    conn.close()
                    return {'msg': 'No data to return.'}

            if check == 'tuple':
                data = c.fetchone()
                if data is not None and c.rowcount != 0:
                    date = data[3]
                    date = date.strftime('%Y-%m-%d')
                    content = {"user2flower_id": str(data[0]), "user_id": str(data[1]),
                               "flower_id": str(data[2]), "date_of_inception": date,
                               "email": data[4]}
                    c.close()
                    conn.close()
                    return content
                else:
                    c.close()
                    conn.close()
                    return "No data to return."

        if operation == 'PUT':
            executeQuery(c, conn, data)
            return {"msg": "User2flower with user2flower_id " + str(user2flower_id) + " is updated."}

        if operation == 'DELETE':
            executeQuery(c, conn, data)
            return {"msg": "User2flower with user2flower_id " + str(user2flower_id) + " is deleted from DB."}

    except Exception as e:
        c.close()
        conn.close()
        print(e)
        return {'msg': 'Something went wrong while executing ' + operation + ' operation on users2flowers.'}, 500

def executeQuery(c, conn, data):
    c.execute(data)
    conn.commit()

    c.close()
    conn.close()


import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
#https://www.tensorflow.org/versions/r1.12/api_docs/python/tf/ones
a= tf.ones((4,3))

b = tf.ones((2,3))

with tf.Session():
  result = a.eval()
  rb = b.eval()
  tf.assert_negative (a)

print(result,rb )


import torch
from game import DataGenArena
from torch.autograd import Variable
from torch.utils.data import DataLoader
import os

# criterion = torch.nn.SmoothL1Loss()
# optimizer = torch.optim.SGD(model.parameters(), lr=0.001)

class AITrainer:
    # TODO: concurrent usage of self.model and player.network makes me nervous
    # TODO: add name? hmmm
    # also unsure about loss and optimizer params
    # TODO: remove gen parameter (?)
    def __init__(self, player, model_name=None, model_dir=None, matches=100, batch_size=8,
                 loss=torch.nn.SmoothL1Loss, optimizer=torch.optim.SGD, lr=0.001, gen=0):
        self.player = player
        self.matches = matches
        self.batch_size = batch_size
        self.epochs = 2

        self.model_dir = model_dir
        self.gen = gen
        # TODO: fix use of preexisting model
        self.model_path = model_name
        if self.model_path is not None:
            print("Hi")
            self.player.load_model(self.model_path)
            # TODO: figure out how to get gen from somewhere
            self.gen = gen
        else:
            self.gen = 0
            self.model_path = self.full_path()
            self.player.save_model(self.model_path)

        # self.model = player.network
        self.loss = loss()
        self.optimizer = optimizer(self.player.network.parameters(), lr=lr)
        self.generations()

    def generation(self):
        print(self.gen)
        path = self.full_path()
        self.player.load_model(path)
        model = self.player.network
        data = DataGenArena(self.player, matches=self.matches)
        train_loader = DataLoader(dataset=data,
                                  batch_size=self.batch_size,
                                  shuffle=True,
                                  num_workers=2)

        for epoch in range(self.epochs):
            for i, data in enumerate(train_loader, 0):
                # get the inputs
                inputs, labels = data

                # wrap them in Variable
                inputs, labels = Variable(inputs), Variable(labels)

                # Forward pass: Compute predicted y by passing x to the model
                y_pred = model(inputs.float())

                # Compute and print loss
                loss = self.loss(y_pred, labels)
                print(epoch, i, loss.data.item())

                # Zero gradients, perform a backward pass, and update the weights.
                self.optimizer.zero_grad()
                loss.backward()
                self.optimizer.step()

        self.gen += 1

        path = self.full_path()
        model.save_model(path)

    def generations(self):
        while True:
            self.generation()

    def full_path(self):
        # if not os.path.exists(file_path):
        #     os.makedirs(file_path)
        # TODO: implement player __repr__?
        file_name = f'{self.player.name}{self.player.shape}_gen{self.gen}.pt'
        if self.model_dir is not None:
            path = os.path.join(self.model_dir, file_name)
        else:
            path = file_name
        return path

if __name__ == '__main__':
    from players.nn_ai import NNAI
    shape = 7, 7
    gen = 4
    ai = NNAI("nnai", *shape, exploration_turns=5, explore_chance=0.15)
    file_name = f'{ai.name}{ai.shape}_gen{gen}.pt'
    trainer = AITrainer(ai, model_name=file_name, gen=gen)


import sqlite3

def create_table():
        sqlstr = "create table user (sid int(5) primary key, \
        name varchar(10), email varchar(25))"
        conn.execute(sqlstr)
        print("create table successfully")
        conn.close()

def initiate_table():
        cur = conn.cursor()
        sqlstr1 = "insert into user(sid, name, email) values(1001, '张大山', 'zhangds@163.com') "
        cur.execute(sqlstr1)
        sqlstr2 = "insert into user(sid, name, email) values(1002, '李晓丽', 'lixli@163.com') "
        cur.execute(sqlstr2)
        sqlstr3 = "insert into user(sid, name, email) values(1003, '赵四方', 'zaoshi@163.com') "
        cur.execute(sqlstr3)
        conn.commit()
        print("Records created successfully")
        conn.close()
def get_data():
        cur = conn.cursor()
        sqlstr = "select * from  user"
        s = cur.execute(sqlstr)
        for row in s:   #得到的赋值给s
                print("sid=", row[0])
                print("name=", row[1])
                print("email=", row[2], '\n')
        conn.close()
def updata_data():

        cur = conn.cursor()
        sql_update = "update user set email='zhaosf@abc.com' where sid=1003"
        cur.execute(sql_update)
        conn.commit()

        sql_select = "select * from  user where sid=1003"
        s = cur.execute(sql_select)
        for row in s:
                print("sid=", row[0])
                print("name=", row[1])
                print("email=", row[2], '\n')
        conn.close()
def delete_data():
        cur = conn.cursor()
        sql_update = "delete from user  where sid=1002"
        cur.execute(sql_update)
        conn.commit()
        sql_select = "select * from  user"
        s = cur.execute(sql_select)
        for row in s:
                print("sid=", row[0])
                print("name=", row[1])
                print("email=", row[2], '\n')
        conn.close()

if __name__=="__main__":
        conn = sqlite3.connect("d:/groupdatabase.db")
        get_data()
        # conn = sqlite3.connect("d:/groupdatabase.db")
        # updata_data()
        # conn = sqlite3.connect("d:/groupdatabase.db")
        # delete_data()


"""
Yonan Abraha

Lab 5
"""

def main():

	#encodedWord = "WBLARF8TTS"
	#encodedWord = "L8KAOUL"
	#encodedWord = "E8N8N8"
	#encodedWord = "8TRA8DY T8LA"
	#encodedWord = "8TT LHA TILLTA LIMAS"
	#encodedWord = "LHA GRAAN FIATD GTA8MS IN LHA W8RM SUNEABMS"
	encodedWord = "TONG T8E T8CKS L8SLY L8CO LIMA 8L TA8SL T8LATY"

	#encodedWord = "UUHO"  		#Used for Bonus
	#encodedWord = "EOUUUUOUU" 	#Used for Bonus

	print(DecodeWord(encodedWord))

#Your code goes here.
def DecodeWord(encodword): #creating a function
  decodedWord = "" # needed a variable to exist for the next line of codes
  for i in encodword: # checking each letter in the encodedword
    if i=="L": # if the letter is "L"
      decodedWord += "T" # REPLACE IT WITH "T"
    elif i=="T": # if the letter is "T"
      decodedWord += "L"# REPLACE IT WITH "L"
    elif i=="8": #if the letter is "8"
      decodedWord += "A"# REPLACE IT WITH "A"
    elif i=="B": #if the letter is "B"
      decodedWord += "A"# REPLACE IT WITH "A"
    elif i=="A":#if the letter is "A"
      decodedWord += "E"# REPLACE IT WITH "E"
    elif i=="E":#if the letter is "E"
      decodedWord += "B"# REPLACE IT WITH "B"
    else:
      decodedWord += i
  return decodedWord

#This code triggers the main to run
#we'll talk about this more in chapters 6,7, & 8.
if __name__ == "__main__":
	main()


"""
https://www.algoexpert.io/questions/common-characters
"""

def commonCharacters(strings):
    # Write your code here.
    result = []
    first = strings.pop(0)
    size = len(strings)

    for char in first:
        count = 0
        for arr in strings:
            if char not in arr:
                continue
            count += 1
        if count == size:
            if char not in result:
                result.append(char)

    return result


import raw_read
import subprocess as sp
from matplotlib import pyplot
import numpy as np
from files import *
from sklearn.metrics import mean_squared_error

[arrs1,plots]=raw_read.rawread('output/rawfile.raw')
# time
stime = arrs1[0]
res_out = arrs1[1:-1]
x=res_out.T
temp = np.linalg.pinv(x)
vref=np.load("output/ref.npy")
vref=vref.T
w_out = np.load("output/w_out.npy")
outlayer=1

readout=np.zeros((res_out.shape[1],outlayer))
for t in range(0, res_out.shape[1]):
     # readout[t]=np.dot(res[:,:,t],w_out)
    readout[t] = np.dot(res_out[:, t], w_out)

# error = abs(readout - vref)
error = abs(readout[1:] - vref[1:])
error1= mean_squared_error(readout[1:], vref[1:],squared=False)

print(error1)

pyplot.figure(figsize=(10,6))
pyplot.subplots_adjust(wspace =0, hspace =0.2)
pyplot.plot(stime[1:],vref[1:],'r')
pyplot.plot(stime[1:],readout[1:],'mediumspringgreen')

pyplot.xlabel("Time (s)",fontsize=15)
pyplot.show()

###################################plot########################################
# stime = arrs1[0]
# current = arrs1[1:19]
# memstate=arrs1[21:39]
#
# current1=arrs1[1]
# state1=arrs1[21]
#
#
# pyplot.figure(figsize=(10,3))
# pyplot.subplots_adjust(wspace =0, hspace =0.2)
# # pyplot.plot(stime[1:],current1[1:],'r')
# pyplot.plot(stime[1:],state1[1:],'mediumspringgreen')
#
# pyplot.xlabel("Time (s)",fontsize=15)
# pyplot.show()
#
# pyplot.figure(figsize=(10,3))
# pyplot.subplots_adjust(wspace =0, hspace =0.2)
# pyplot.plot(stime[1:],current1[1:],'r')
# # pyplot.plot(stime[1:],state1[1:],'mediumspringgreen')
# pyplot.xlabel("Time (s)",fontsize=15)
# pyplot.show()


from django.urls import path
from cart.views import cart_add, cart_remove, cart_details, cart_clear, cart_update

urlpatterns = [
    path('cart_details/', cart_details, name='cart_details'),
    path('cart_add/', cart_add, name='cart_add'),
    path('cart_update/', cart_update, name='cart_update'),
    path('cart_remove/', cart_remove, name='cart_remove'),
    path('cart_clear/', cart_clear, name='cart_clear'),

]


#-*- coding: utf-8 -*-
u"""

.. moduleauthor:: Martí Congost <marti.congost@whads.com>
"""
import cherrypy
from cocktail.pkgutils import resolve
from woost.controllers.basecmscontroller import BaseCMSController
from woost.extensions.payments.paymentgateway import PaymentGateway

class PaymentRootController(BaseCMSController):
    """Root controller for all payment related requests.

    This controller does nothing by itself, it merely identifies the payment
    gateway that should handle an incomming request and forwards the request to
    the gateway's controller (an instance of L{PaymentGatewayController}).
    """

    def resolve(self, path):

        if not path:
            raise cherrypy.NotFound()

        # Identify the gateway involved in the payment
        gateway_id = path.pop(0)

        try:
            gateway_id = int(gateway_id)
        except:
            raise cherrypy.HTTPError(400)

        gateway = PaymentGateway.get_instance(gateway_id)

        if gateway is None:
            raise cherrypy.NotFound()

        # Forward the request to the gateway's controller
        controller_class = resolve(gateway.payment_gateway_controller_class)
        return controller_class(gateway)


import veri
import logs

class uartClass(logs.driverClass):
    def __init__(self,Path,Monitors,rxd='rxd',txd='txd'):
        logs.driverClass.__init__(self,Path,Monitors)
        self.rxd = rxd
        self.txd = txd
        self.baudRate = 100*32
        self.txQueue = []
        self.txWaiting=0

        self.rxState = 'idle'
        self.rxQueue = []
        self.rxWaiting=0
        self.rxByte=''
        self.force(self.rxd,1)
        self.RxStr = ''
        self.Silence = 100
        self.silentCounter = 0

    def busy(self,Why=False):
        Busy0 = self.silentCounter < (self.Silence * self.baudRate)
        if Why:
            logs.log_info("UART BUSY busy0=%s tx=%s rx=%s wtx=%s wrx=%s" % (Busy0,len(self.txQueue),len(self.rxQueue),(self.txWaiting>0),(self.rxWaiting>0)))
        return Busy0 or (self.rxState!='idle') or (self.txQueue != []) or (self.rxQueue != []) or (self.txWaiting>0) or (self.rxWaiting>0)

    def run(self):
        self.runTx()
        self.runRx()
        Rxd = self.peek(self.txd)
        if Rxd == 0:
            self.silentCounter = 0
        else:
            self.silentCounter  += 1

    def action(self,Str,Origs=[]):
        Wrds  = Str.split()
        if Wrds[0]=='txfile':
            Fname = Wrds[1]
            File = open(Fname)
            Str = File.read()
            File.close()
            Words = Str.split()
            for Wrd in Words:
                self.send(Wrd)
            self.send('\x0a')

        elif Wrds[0]=='tx':
            for Wrd in Wrds[1:]:
                self.send(Wrd)
            logs.log_info("TXUART %s %s" % (self.txd,str(Wrds[1:])),'fpga')
            self.send('\x0a')
        elif Wrds[0]=='baudrate':
            self.baudRate = eval(Wrds[1])
        elif Wrds[0]=='rx':
            logs.log_info('UART RX  "%s" '%(self.RxStr))
        else:
            logs.log_error('action by uart is not : %s'%(Str))

    def send(self,Byte):
        if type(Byte) is str:
            if len(Byte)==1:
                Byte = ord(Byte)
                self.send(Byte)
                return
            elif Byte == 'CRLF':
                self.send(10)
                return
            else:
                for Chr in Byte:
                    self.send(Chr)
                return
        self.txQueue.append(0)
        for II in range(0,8):
            Val = (Byte>>II)&1
            self.txQueue.append(Val)
        logs.log_info('txQueue %02x   %d' % (Byte,self.baudRate))
        self.txQueue.append(1)
        self.txQueue.append(1)
        self.txQueue.append(1)

    def runTx(self):
        if self.txWaiting>0:
            self.txWaiting -= 1
            return

        if self.txQueue==[]:
            self.force(self.rxd,1)
            return

        Bit = self.txQueue.pop(0)
        self.force(self.rxd,Bit)
        self.txWaiting = self.baudRate

    def runRx(self):
        if self.rxWaiting>0:
            self.rxWaiting -= 1
            veri.force('tb.midbit','0')
#            if (self.rxWaiting == 1):
#                logs.log_info("rxwait %s %s " % (self.rxState,self.rxByte))
            return
        if self.rxState in ['bitx','bit0','stop']:
            veri.force('tb.midbit','1')
        else:
            veri.force('tb.midbit','0')
        if self.rxState=='idle':
            Rxd = self.peek(self.txd)
            if Rxd==0:
                self.rxState='bit0'
                self.rxWaiting = self.baudRate/2
                return
        elif self.rxState=='bit0':
                self.rxState='bitx'
                self.rxWaiting = self.baudRate
                Rxd = self.peek(self.txd)
                if Rxd!=0:
                    logs.log_error('ilia rxd start bit isnt there')
                    self.rxState='idle'
                return
        elif self.rxState=='bitx':
            Rxd = self.peek(self.txd)
            self.rxByte = str(Rxd) + self.rxByte
            if len(self.rxByte)==8:
                self.rxState = 'stop'
#                self.rxQueue.append(self.rxByte)
                Int = logs.intx(self.rxByte)
                if ((Int>=0)and(Int<256)):
                    Chr = chr(logs.intx(self.rxByte))
                else:
                    Chr = '(ERR%s)'%self.rxByte
                self.RxStr += Chr
#                logs.log_info('uart rxByte %s   "%s" '%(self.rxByte,self.RxStr))
                try:
                    if ord(Chr) <= 10:
                        logs.log_info('UART RX  "%s" '%(self.RxStr[:-1]))
                        self.RxStr = ''
                except:
                    logs.log_error('UART RX ERROR |%s|  "%s" '%(Chr,self.RxStr))
                    self.RxStr = ''

#                veri.force('tb.marker','0b'+self.rxByte)
                self.rxByte=''
            self.rxWaiting = self.baudRate
        elif self.rxState=='stop':
            Rxd = self.peek(self.txd)
            if Rxd==0:
                logs.log_error('ilia rxd stop bit isnt there')
            self.rxState='idle'

    def onFinish(self):
        return


#!/usr/bin/env python3
#
# graph timing from timing file

import sys
import pylab
import numpy
import matplotlib.pyplot as plot
from argparse import ArgumentParser
from collections import defaultdict

time_xlabel="Time in seconds"
bytes_ylabel="GB processed"

def parse_pair(line):
    h = line[11:13]
    m = line[14:16]
    s = line[17:19]
    time = (int(h) * 60 + int(m)) * 60 + int(s)
    count = int(line[24:])
    return time, count

def read_timing(timing_file):
    time_list = list()
    total_bytes_list = list()

    with open(timing_file, 'r') as infile:
        first = True
        offset = 0
        total = 0
        for line in infile:
           time, count = parse_pair(line)
           if first:
               offset = time
               first = False
           time_list.append(time - offset)
           total += count
           total_bytes_list.append(total/1000000000.0)
    return (time_list, total_bytes_list)

def plot_timing(time_list, total_bytes_list, outfile):
    plot.plot(time_list, total_bytes_list, '-bo')
    plot.xlabel(time_xlabel)
    plot.ylabel(bytes_ylabel)
    plot.title("Bytes processed over time")
    plot.savefig(outfile)

if __name__=="__main__":
    parser = ArgumentParser(prog='plot_dots.py',
                  description='Plot timestamp progress')
    parser.add_argument('timing_file', help= 'timing file')
    args = parser.parse_args()
    timing_file = args.timing_file
    if timing_file[:7] != 'logfile':
        raise ValueError("Invalid prefix '%s'" % timing_file[:7])

    time_list, total_bytes_list = read_timing(timing_file)
    for time in time_list:
        print("time: %d\n" % time)
    for total_bytes in total_bytes_list:
        print("total bytes: %d\n" % total_bytes)
    outfile = "out_%s.png" % timing_file
    plot_timing(time_list, total_bytes_list, outfile)


from collections import defaultdict, deque

class Solution:
    def isBipartite(self, graph: List[List[int]]) -> bool:
        color = defaultdict(int)
        seen = set()
        q = deque()
        for node1 in range(len(graph)):
            if node1 in seen:
                continue
            color[node1] = 1
            parent_color = 1
            q.extend([n for n in graph[node1] if n not in seen])
            seen.add(node1)
            while q:
                l = len(q)
                for _ in range(l):
                    node = q.popleft()
                    must_color = parent_color * -1 #invert color
                    if color[node] == 0:
                        color[node] = must_color
                        seen.add(node)
                    elif color[node] != must_color:
                        #print(node, graph[node], q, color[node], must_color)
                        return False
                    q.extend([n for n in graph[node] if n not in seen])
                parent_color = parent_color * -1 #invert color
        return True


import rhino_unwrapper.meshUtils.meshLoad as meshLoad
import rhino_unwrapper.meshUtils.mesh as mesh
import rhino_unwrapper.cutSelection.userCuts as userCuts
import rhino_unwrapper.cutSelection.autoCuts as autoCuts
import rhino_unwrapper.weight_functions as weight_functions
import rhino_unwrapper.unfold as unfold
import rhino_unwrapper.distribute as distribute
reload(meshLoad)
reload(mesh)
reload(userCuts)
reload(autoCuts)
reload(weight_functions)
reload(unfold)
reload(distribute)

#def all_weight_functions():
    #return dict([m for m in inspect.getmembers(weight_functions, inspect.isfunction)])

#hardcode a selection for wieght function for now
weight_function = weight_functions.edgeAngle

# SET UP MESH
uMesh = meshLoad.user_select_mesh()
jMesh = mesh.Mesh(uMesh)
displayer = mesh.MeshDisplayer(jMesh)

# SET CUTS
user_cuts = userCuts.get_user_cuts(jMesh,displayer)
cuts = autoCuts.auto_fill_cuts(jMesh,user_cuts,weight_function)
displayer.display_edges(cuts) #NOTE right now this will duplicate-draw user-cuts

# UNFOLD
unfolder = unfold.UnFolder(jMesh)
net = unfolder.unfold()
net.display()

#DISTRIBUTE
distribute.spread_out_islands_horizontally(net)


# 스도쿠
#
# 스도쿠를 돌면서 빈자리(-1)를 탐색한다
# 빈자리에 1~9 를 넣어보고 가능하다면 재귀함수를 호출한다.
# 만약 가능한 케이스가 발견되면 즉시 함수를 종료한다.

# 열쇠 -> test 함수에서 순회할 때 빈자리에 뭐가 들어갈 수 있는지 업데이트해서 재검사를 방지한다.

from copy import deepcopy

# row,col에 새로운 값이 들어왔을 때, 가능한지 검사하는 함수
def test(s: list[list[int]], row: int, col: int) -> bool:
    # row 검사
    cnt = 0
    nums = []  # 0이 아닌 모든 수를 저장
    empty = []  # 숫자가 빈자리를 저장
    for i in range(9):
        if s[row][i] == 0:  # 0이면 empty에 넣기
            empty.append((row, i))
        elif i != col:  # 0이 아니고 자기자신도 아니면 nums에 넣기
            nums.append(s[row][i])
        if s[row][i] != s[row][col] and i != col:  # 숫자가 안겹치면
            cnt += 1
    if len(empty) > 0:
        for e in empty:
            # 다시 꺼내서 nums에 있는 모든 수를 제외하고 저장
            poss_value[e] = [x for x in poss_value[e] if x not in nums]
    if cnt != 8:
        return False

    # col 검사
    cnt = 0
    nums = []  # 0이 아닌 모든 수를 저장
    empty = []  # 숫자가 빈자리를 저장
    for i in range(9):
        if s[i][col] == 0:
            empty.append((i, col))
        elif i != row:
            nums.append(s[i][col])
        if s[i][col] != s[row][col] and i != row:
            cnt += 1
    if len(empty) > 0:
        for e in empty:
            # 다시 꺼내서 nums에 있는 모든 수를 제외하고 저장
            poss_value[e] = [x for x in poss_value[e] if x not in nums]
    if cnt != 8:
        return False

    # 칸 검사

    sections = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
    row_section = []  # 칸에 해당하는 행들
    col_section = []  # 칸에 해당하는 열들
    for section in sections:
        if row in section:
            row_section = section
            break
    for section in sections:
        if col in section:
            col_section = section
            break

    cnt = 0
    nums = []  # 0이 아닌 모든 수를 저장
    empty = []  # 숫자가 빈자리를 저장

    for r in row_section:
        for c in col_section:
            if s[r][c] == 0:
                empty.append((r, c))
            elif (r, c) != (row, col):
                nums.append(s[r][c])
            if s[r][c] != s[row][col] and (r, c) != (row, col):
                cnt += 1
    if len(empty) > 0:
        for e in empty:
            # 다시 꺼내서 nums에 있는 모든 수를 제외하고 저장
            poss_value[e] = [x for x in poss_value[e] if x not in nums]
    if cnt != 8:
        return False

    return True  # 다 통과하면 가능

sudoku = [list(map(int, input().split())) for _ in range(9)]  # 스도쿠 판
empty_place: list[tuple[int, int]] = []  # 빈자리 [(row,col)]
for row in range(9):
    for col in range(9):
        if sudoku[row][col] == 0:
            empty_place.append((row, col))

poss_value = {}  # 각 빈자리마다 들어갈 수 있는 값을 관리하는 딕셔너리 (초기값은 1~9)
for e in empty_place:
    poss_value[e] = list(range(1, 10))
res = [[]]

def dfs(s: list[list[int]], empty_place: list[tuple[int, int]]):
    if len(empty_place) == 0:
        global res
        res = s
        return True
    for i in range(len(empty_place)):
        row = empty_place[i][0]
        col = empty_place[i][1]
        for num in poss_value[empty_place[i]]:
            new_sudoku = deepcopy(s)
            new_sudoku[row][col] = num
            new_empty_place = deepcopy(empty_place)
            del new_empty_place[i]
            if test(new_sudoku, row, col):  # 그곳에 num을 넣어도 괜찮은가?
                flag = dfs(new_sudoku, new_empty_place)
                if flag == True:
                    return True

print()
dfs(sudoku, empty_place)
# for r in res:
#     for c in r:
#         print(c, end=" ")
#     print()

# for p in poss_value.keys():
#     print(p, poss_value[p])

result = [
    [1, 3, 5, 4, 6, 9, 2, 7, 8],
    [7, 8, 2, 1, 3, 5, 6, 4, 9],
    [4, 6, 9, 2, 7, 8, 1, 3, 5],
    [3, 2, 1, 5, 4, 6, 8, 9, 7],
    [8, 7, 4, 9, 1, 3, 5, 2, 6],
    [5, 9, 6, 8, 2, 7, 4, 1, 3],
    [9, 1, 7, 6, 5, 2, 3, 8, 4],
    [6, 4, 3, 7, 8, 1, 9, 5, 2],
    [2, 5, 8, 3, 9, 4, 7, 6, 1],
]

print(res == result)


#1)list using Array

import sys
def getListDetails(l):
    #size = sys.getsizeof(l)
    #capacity = (size of list - size of empty list) // (size of one block)
    #size of empty list maens total number of bits for empty list
    capacity = (sys.getsizeof(l)-64)//8
    left_size = ((sys.getsizeof(l)-64)-len(l)*8)//8
    #(size-36)//4 for 32bit system
    #(size-64)//8 for 64bit system
    print('size of list is ',sys.getsizeof(l))
    print('capacity is ',capacity)
    print('remaining capacity is ',left_size)

def insertAtBegin(l,ele):
    l.insert(0,ele)
def insertInBetween(l,index,ele):
    l.insert(index,ele)
def insertAtEnd(l,ele):
    l.append(ele)

def deleteAtBegin(l):
    l.pop(0)
def deleteAtBetween(l,index):
    l.pop(index)
def deleteAtEnd(l):
    l.pop(-1)

l = list()
getListDetails(l)

#inserting element at begin
insertAtBegin(l,1)

#inserting element in between
insertInBetween(l,1,2)

#inserting element at end
insertAtEnd(l,3)

#deleting at begin
deleteAtBegin(l)

print(l)
getListDetails(l)
'''
= RESTART: F:/python/python_programs/5competetive programming/7linear data structures/3.linklinst.py
size of list is  64
capacity is  0
remaining capacity is  0
[2, 3]
size of list is  96
capacity is  4
remaining capacity is  2
>>>
'''

#but implementing link list using dynamic array i.e list have some disadvantages
'''
such that even it perform dynamic memory allocation still it having some issues like
1)involes shiftng of elements in insertion and deletion.
2)while insertion when list is full then it increases its capacity by double of its previous capacity,
    this may cause wastage of memory in the form reserved space

Exaple,
    consider list l of capacity 10,
        <insert element 1 to 10  #it will insert 1...10 elements in list
        <insert element 11  # here list is full , so it creates list of size 10*2=20(previous capacity * 2) and
                                shifts the elements this new list
                                and add new element 11 to increased caacity list.
        when is capacity get reache then it again increase the size by 20*2=40 and perform shifting of elements
        and insert new element and so on.
    therefore array list involves shifting of elements and memory wastage.

'''
print('------------------------------------------singly link list------------------------------------------')
#using classes and objects

#class to create node
class Node:
    def __init__(self,data):
        self.__data = data
        self.__next = None

    def getData(self):
        return self.__data

    def setData(self,data):
        self.__data = data

    def getNext(self):
        return self.__next

    def setNext(self,next_node):
        self.__next = next_node

class LinkedList:
    def __init__(self):
        self.__head = None

    def getHead(self):
        return self.__head

    def insertAtBegin(self,node):
        if self.__head == None :
            self.__head = node
        else :
            node.setNext(self.__head)
            self.__head = node
        print('insertion done successfully...')

    def insertInBetween(self,key,node):
        temp = self.__head
        while(temp.getNext()!=None and temp.getData()!=key):
            temp = temp.getNext()
        if(temp.getData()!=key):
            print('key not found\nInsertion faild!!!')
        else:
            node.setNext(temp.getNext())
            temp.setNext(node)
            print('insertion done successfully...')

    def insertAtEnd(self,node):
        if self.__head == None :
            self.__head = node
        else :
            temp = self.__head
            while(temp.getNext()!=None):
                temp = temp.getNext()
            temp.setNext(node)
        print('insertion done successfully...')

    def deleteAtBegin(self):
        self.__head  =  self.__head.getNext()
        print('deletion done successfully')

    def deleteInBetween(self,key):
        temp = self.__head
        while(temp.getNext()!=None and temp.getData()!=key):
            delete_node = temp
            temp = temp.getNext()
        if(temp.getData()!=key):
            print('key not found\nInsertion faild!!!')
        else:
            delete_node.setNext((delete_node.getNext()).getNext())
            print('deletion done successfully')

    def deleteAtEnd(self):
        temp = self.__head
        while(temp.getNext()!=None ):
            delete_node = temp
            temp = temp.getNext()
        delete_node.setNext(None)
        print('deletion done successfully')

    def travelsing(self):
        if self.__head == None :
            print('Empty List!!!')
        else:
            temp = self.__head
            #print(temp.getData())
            while(temp!=None):
                print(temp.getData())
                temp = temp.getNext()

link_list = LinkedList()            #it will create empty list

while(True):
    print('\n1.insertion\n2.deletion\n3.display\n4.quit\n Enter your choice')
    ch = int(input())
    if ch == 1:
        #create node
        data = int(input('Enter data '))
        node = Node(data)

        #insertion of node in link list
        print('1.Insert At begining\n 2.Insert  In Between\n 3.Insert At End')
        ch2 = int(input('Enter your choice'))
        if ch2 == 1:
            link_list.insertAtBegin(node)
        elif ch2 == 2:
            key = int(input('Enter after which you want to insert node'))
            link_list.insertInBetween(key,node)
        elif ch2 == 3:
            link_list.insertAtEnd(node)
        else : print('Enter correct choice !!!')

    elif ch == 2:
        #ask for where to delete
        if link_list.getHead() == None:
            print('list is Empty!!!')
        else :
            print('1.Delete At begining\n 2.Delete  In Between\n 3.Delete At End')
            ch2 = int(input('Enter your choice'))
            if ch2 == 1:
                link_list.deleteAtBegin()
            elif ch2 == 2:
                key = int(input('Enter  which you want to delete node'))
                link_list.deleteInBetween(key)
            elif ch2 == 3:
                link_list.deleteAtEnd()
            else : print('Enter correct choice !!!')

    elif ch == 3:
        link_list.travelsing()

    elif ch == 4:
        break

    else : print('Enter correct choice !!!')

print('------------------------------------------doubly link list------------------------------------------')

#class to create node
class Node:
    def __init__(self,data):
        self.__pre = None
        self.__data = data
        self.__next = None

    def getData(self):
        return self.__data

    def setData(self,data):
        self.__data = data

    def getNext(self):
        return self.__next

    def setNext(self,next_node):
        self.__next = next_node

    def getpre(self):
        return self.__pre

    def setNext(self,pre_node):
        self.__pre = pre_node

7Algo and Datastructures/1linear DS/3.linklinst.py


import pandas as pd

from objects_API.StrainJ import StrainJson
from objects_API.BacteriumJ import BacteriumJson
from objects_API.BacteriophageJ import BacteriophageJson
from objects_API.CoupleJ import CoupleJson

from configuration.configuration_api import ConfigurationAPI
from rest_client.AuthenticationRest import AuthenticationAPI

from objects_new.Couples_new import Couple
from objects_new.Organisms_new import Organism

def readCSVToDF(path_csv):
    data = pd.read_csv(path_csv)
    return data

def getBacteriophageByACCNEWDB(acc_value:str):
    bacteriophage_obj_new = BacteriophageJson.getByAccnumber(acc_value)
    id_bacteriophage_new = bacteriophage_obj_new.id
    return id_bacteriophage_new

def getBacteriumByACCNEWDB(acc_value:str):
    bacterium_obj_new = BacteriumJson.getByAccnumber(acc_value)
    id_bacterium_new = bacterium_obj_new.id
    return id_bacterium_new

def obtainBacteriumIdFromOldDBId(id_bacterium_old_db:int):
    organism_obj = Organism.get_organism_by_id(id_bacterium_old_db)
    fk_strain_old_db = organism_obj.fk_strain
    return fk_strain_old_db

def obtainBacteriumACCnumberFromOldDBId(id_bacterium_old_db:int):
    organism_obj = Organism.get_organism_by_id(id_bacterium_old_db)
    acc_number = organism_obj.acc_num
    return acc_number

def obtainphageACCnumberFromOldDBId(id_bacteriophage_old_db:int):
    organism_obj = Organism.get_organism_by_id(id_bacteriophage_old_db)
    acc_number = organism_obj.acc_num
    return acc_number

def getIdStrainNewDBByStrainBactOldDB(strain_id_old:int, dataframe_strains_id):
    dataframe_line = dataframe_strains_id.loc[dataframe_strains_id['strain_db'] == strain_id_old]
    new_db_id_strain = int(dataframe_line['strain_api'].values[0])
    return new_db_id_strain

def getBacteriumListIdsByStrainId(strain_id:int):
    list_bacterium_ids_treated = []
    strain_obj = StrainJson.getByID(strain_id)
    list_bacterium_ids = strain_obj.bacteria
    for bacterium in list_bacterium_ids:
        bacterium = bacterium.replace('http://trex.lan.iict.ch:8080/api/bacterium/','')[:-1]
        list_bacterium_ids_treated.append(bacterium)
    return list_bacterium_ids_treated

conf_obj = ConfigurationAPI()
conf_obj.load_data_from_ini()
AuthenticationAPI().createAutenthicationToken()

path_csv_strains_correspondence = 'correspondenceIDSStrains2.csv'
datafram_csv = readCSVToDF(path_csv_strains_correspondence)

list_couples_old_db = Couple.get_all_couples()
count_error = 0
count_many = 0
count_pos_list = 0
#list_couples_old_db = list_couples_old_db[9602:]
#list_couples_old_db = list_couples_old_db[-2:]
dict_convert_phages_id = {}
dict_convert_phages_id[4656] = 6265

for couple_element in list_couples_old_db:
    if couple_element.fk_source_data == 1 and couple_element.fk_level_interact == 3:
        print('It is the {0} : couple id {1} : pos in list total {2}'.format(count_many, couple_element.id_couple, count_pos_list))
        id_bacterium = couple_element.fk_bacteria
        acc_bacterium = obtainBacteriumACCnumberFromOldDBId(id_bacterium)

        id_new_bacterium_db = -1
        try:
            id_new_bacterium_db = getBacteriumByACCNEWDB(acc_bacterium)
        except:
            id_new_bacterium_db = -1
        #If necessary, check if they have the acc for public data for bacterium
        #strain_id = obtainBacteriumIdFromOldDBId(id_bacterium)
        #strain_id_new_db = getIdStrainNewDBByStrainBactOldDB(strain_id, datafram_csv)
        #list_bacterium_id = getBacteriumListIdsByStrainId(strain_id_new_db)
        #

        id_phage = couple_element.fk_phage
        acc_bacteriophage = obtainphageACCnumberFromOldDBId(id_phage)
        id_new_phage_db = -1
        if id_phage in dict_convert_phages_id:
            id_new_phage_db = dict_convert_phages_id[id_phage]
        else:
            try:
                id_new_phage_db = getBacteriophageByACCNEWDB(acc_bacteriophage)

            except:
                id_new_phage_db = -1
        if id_new_phage_db != -1 and id_new_bacterium_db != -1:
            try:
                couple_obj = CoupleJson.getByBacteriumPhageIds(id_new_bacterium_db, id_new_phage_db)
            except:
                count_error += 1
                interaction_type_cp = couple_element.interact_pn
                id_bacterium_cp = id_new_bacterium_db
                id_phage_cp = id_new_phage_db
                validity_id_cp = 4 #not validate
                level_interaction_cp = 2
                source_data_cp = 1
                person_responsible_cp = 3

                couple_obj_json = CoupleJson(interaction_type = interaction_type_cp,
                                             bacteriophage = id_phage_cp,
                                             bacterium = id_bacterium_cp,
                                             level = level_interaction_cp,
                                             person_responsible = person_responsible_cp,
                                             source_data = source_data_cp,
                                             validity = validity_id_cp)
                couple_obj = couple_obj_json.setCouple()
                print(couple_obj)
                print('INSERTEDDD NEW')
        else:
            count_error += 1
        #print(couple_obj)
        count_many += 1
    count_pos_list += 1

print(len(list_couples_old_db))
print('Hello')


from datetime import datetime

from models.library_item import LibraryItem
from models.rent import Rent
from models.user import User
from services.handlers.rent_handlers.apply_discount_handler import ApplyDiscountHandler
from services.handlers.rent_handlers.calculate_fine_price_handler import (
    CalculateFinePriceHandler,
)
from services.handlers.rent_handlers.calculate_rent_price_handler import (
    CalculateRentPriceHandler,
)
from services.handlers.rent_handlers.inspect_item_handlers import InspectItemHandler
from services.handlers.rent_handlers.rent_request_payment_handler import (
    RentRequestPaymentHandler,
)
from services.handlers.rent_handlers.rent_return_payment_handler import (
    RentReturnPaymentHandler,
)
from services.handlers.rent_handlers.save_rent_handler import SaveRentHandler
from services.handlers.rent_handlers.update_book_catalogue_handler import (
    UpdateBookCatalogueHandler,
)
from services.payment.bank_account_payment_strategy import BankAccountPaymentStrategy
from services.payment.card_payment_strategy import CardPaymentStrategy
from services.payment.payment_strategy import PaymentStrategy
from services.singleton.singleton import singleton

@singleton
class LibraryManager:
    @classmethod
    def rent_library_item(
        cls,
        library_item: LibraryItem,
        user: User,
        expected_rent_end_date: datetime,
        payment_type: str,
    ):
        rent = cls.__create_rent(
            library_item=library_item,
            user=user,
            expected_rent_end_date=expected_rent_end_date,
        )

        payment_strategy = cls.__get_payment_strategy_from_type(payment_type)

        handler = cls.__get_rent_request_handlers()
        handler.handle(rent, payment_strategy)

        return rent

    @classmethod
    def return_library_item(
        cls,
        rent: Rent,
        payment_type: str,
    ):
        rent.rent_end_date = datetime.utcnow().date()
        payment_strategy = cls.__get_payment_strategy_from_type(payment_type)

        handler = cls.__get_rent_return_handlers()
        handler.handle(rent, payment_strategy)

        return rent

    @staticmethod
    def __create_rent(
        library_item: LibraryItem,
        user: User,
        expected_rent_end_date: datetime,
    ) -> Rent:
        rent = Rent(
            library_item=library_item,
            library_user=user,
            rent_start_date=datetime.utcnow(),
            expected_rent_end_date=expected_rent_end_date,
        )
        return rent

    @staticmethod
    def __get_rent_request_handlers():
        handler = CalculateRentPriceHandler()
        handler.set_next(ApplyDiscountHandler()).set_next(
            RentRequestPaymentHandler()
        ).set_next(UpdateBookCatalogueHandler()).set_next(SaveRentHandler())
        return handler

    @staticmethod
    def __get_rent_return_handlers():
        handler = InspectItemHandler()
        handler.set_next(CalculateFinePriceHandler()).set_next(
            RentReturnPaymentHandler()
        ).set_next(UpdateBookCatalogueHandler()).set_next(SaveRentHandler())
        return handler

    @staticmethod
    def __get_payment_strategy_from_type(payment_type: str) -> PaymentStrategy:
        if payment_type == "card":
            payment_strategy = CardPaymentStrategy()
        else:
            payment_strategy = BankAccountPaymentStrategy()
        return payment_strategy


# a simple client socket
import socket

# define socket address
TCP_IP = 'pip install request'  # ip of the server we want to connect to
TCP_PORT = 5000  # port used for communicating with the server

# create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print ("Socket created successfully.")

# connect to server
s.connect((TCP_IP, TCP_PORT))
print ("Established connection with the server." )

message = "I've been sent from the client!"
# send message to the server
s.send(message)
print ("Message sent to server.")


import pygame
from random import randint

class Enemy(pygame.sprite.Sprite):
    def __init__(self, x, y, level):
        super().__init__()
        self.image_list = []
        self.level = level
        self.frame = 0

        for index in range(10):
            image_name = 'Pic\\Enemy' + str(level) + '\\Enemy' + str(level) + '_' + str(index+1) + '.png'
            self.image_list.append(pygame.image.load(image_name).convert_alpha())

        self.image_order = 0
        self.image = self.image_list[self.image_order]
        # self.image = pygame.image.load('Pic\Enemy1\Enemy1.png').convert_alpha()
        self.rect = self.image.get_rect(topleft=(x, y))

        self.speed = 1
        '''speed for each level'''
        # if self.level%4 >= 0.5:
        #     self.speed = 1*ceil(self.level/4)
        # elif self.level%4 < 0.5:
        #     self.speed = 1*floor(self.level/4)

        # print(f'level: {level}')
        # print(self.speed)

        self.lasers = pygame.sprite.Group()
        '''Make it collide perfectly'''
        self.mask = pygame.mask.from_surface(self.image)

        '''special enemy'''
        special_number = randint(0, 10)
        if special_number == 4:
            self.special = 'heart'
        elif special_number == 1:
            self.special = 'item'
        else:
            self.special = 'none'

        self.check_game_over = True

    def move(self):
        '''Movement speed of Enemy1'''
        if self.rect.x > 0:
            self.rect.x -= self.speed
        elif self.rect.x == 0:
            '''Constraint for enemies pos'''
            self.check_game_over = False
            # pygame.quit()
            # sys.exit()

    def pic(self):

        self.frame += 1
        if self.frame == 12:
            self.frame = 0
            self.image_order += 1

            if self.image_order >= len(self.image_list):
                self.image_order = 0

        self.image = self.image_list[self.image_order]

    def update(self):
        self.move()
        self.pic()
        if self.check_game_over is False:
            return False


import numpy as np
import torch
from torch.utils.data import Dataset
import constants as C

def _get_existing_group(gb, i):
    try: group_df = gb.get_group(i)
    except KeyError: group_df = None
    return group_df

def get_dist_matrix(struct_df):
    locs = struct_df[['x','y','z']].values
    n_atoms = len(locs)
    loc_tile = np.tile(locs.T, (n_atoms,1,1))
    dist_mat = np.sqrt(((loc_tile - loc_tile.T)**2).sum(axis=1))
    return dist_mat

class MoleculeDataset(Dataset):
    """Dataset returning inputs and targets per molecule."""
    def __init__(self, mol_ids, gb_mol_sc, gb_mol_atom, gb_mol_bond,
                 gb_mol_struct, gb_mol_angle_in, gb_mol_angle_out,
                 gb_mol_graph_dist):
        """Dataset is constructed from dataframes grouped by molecule_id."""
        self.n = len(mol_ids)
        self.mol_ids = mol_ids
        self.gb_mol_sc = gb_mol_sc
        self.gb_mol_atom = gb_mol_atom
        self.gb_mol_bond = gb_mol_bond
        self.gb_mol_struct = gb_mol_struct
        self.gb_mol_angle_in = gb_mol_angle_in
        self.gb_mol_angle_out = gb_mol_angle_out
        self.gb_mol_graph_dist = gb_mol_graph_dist

    def __len__(self):
        return self.n

    def __getitem__(self, idx):
        return (self.gb_mol_sc.get_group(self.mol_ids[idx]),
                self.gb_mol_atom.get_group(self.mol_ids[idx]),
                self.gb_mol_bond.get_group(self.mol_ids[idx]),
                self.gb_mol_struct.get_group(self.mol_ids[idx]),
                self.gb_mol_angle_in.get_group(self.mol_ids[idx]),
                _get_existing_group(self.gb_mol_angle_out, self.mol_ids[idx]),
                self.gb_mol_graph_dist.get_group(self.mol_ids[idx]))

def arr_lst_to_padded_batch(arr_lst, dtype=torch.float,
                            pad_val=C.BATCH_PAD_VAL):
    tensor_list = [torch.Tensor(arr).type(dtype) for arr in arr_lst]
    batch = torch.nn.utils.rnn.pad_sequence(
        tensor_list, batch_first=True, padding_value=pad_val)
    return batch.contiguous()

def collate_parallel_fn(batch, test=False):
    """
    Transforms input dataframes grouped by molecule into a batch of input and
    target tensors for a 'batch_size' number of molecules. The first dimension
    is used as the batch dimension.

    Returns:
        - atom_x: features at the atom level
        - bond_x: features at the chemical bond level
        - sc_x: features describing the scalar coupling atom_0 and atom_1 pairs
        - sc_m_x: in addition to the set of features in 'sc_x', includes
            features at the molecule level.
        - eucl_dists: 3D euclidean distance matrices
        - graph_dists: graph distance matrices
        - angles: cosine angles between all chemical bonds
        - mask: binary mask of dim=(batch_size, max_n_atoms, max_n_atoms),
            where max_n_atoms is the largest number of atoms per molecule in
            'batch'
        - bond_idx: tensor of dim=(batch_size, max_n_bonds, 2), containing the
            indices of atom_0 and atom_1 pairs that form chemical bonds
        - sc_idx: tensor of dim=(batch_size, max_n_sc, 2), containing the
            indices of atom_0 and atom_1 pairs that form a scalar coupling
            pair
        - angles_idx: tensor of dim=(batch_size, max_n_angles, 1), mapping
            angles to the chemical bonds in the molecule.
        - sc_types: scalar coupling types
        - sc_vals: scalar coupling contributions (first 4 columns) and constant
            (last column)
    """
    batch_size, n_atom_sum, n_pairs_sum = len(batch), 0, 0
    atom_x, bond_x, sc_x, sc_m_x = [], [], [], []
    eucl_dists, graph_dists = [], []
    angles_in, angles_out = [], []
    mask, bond_idx, sc_idx = [], [], []
    angles_in_idx, angles_out_idx = [], []
    sc_types, sc_vals = [], []

    for b in range(batch_size):
        (sc_df, atom_df, bond_df, struct_df, angle_in_df, angle_out_df,
         graph_dist_df) = batch[b]
        n_atoms, n_pairs, n_sc = len(atom_df), len(bond_df), len(sc_df)
        n_pad = C.MAX_N_ATOMS - n_atoms
        eucl_dists_ = get_dist_matrix(struct_df)
        eucl_dists_ = np.pad(eucl_dists_, [(0, 0), (0, n_pad)], 'constant',
                             constant_values=999)

        atom_x.append(atom_df[C.ATOM_FEATS].values)
        bond_x.append(bond_df[C.BOND_FEATS].values)
        sc_x.append(sc_df[C.SC_EDGE_FEATS].values)
        sc_m_x.append(sc_df[C.SC_MOL_FEATS].values)
        sc_types.append(sc_df['type'].values)
        if not test:
            n_sc_pad = C.MAX_N_SC - n_sc
            sc_vals_ = sc_df[C.CONTRIB_COLS+[C.TARGET_COL]].values
            sc_vals.append(np.pad(sc_vals_, [(0, n_sc_pad), (0, 0)], 'constant',
                                  constant_values=-999))
        eucl_dists.append(eucl_dists_)
        graph_dists.append(graph_dist_df.values[:,:-1])
        angles_in.append(angle_in_df['cos_angle'].values)
        if angle_out_df is not None:
            angles_out.append(angle_out_df['cos_angle'].values)
        else:
            angles_out.append(np.array([C.BATCH_PAD_VAL]))

        mask.append(np.pad(np.ones(2 * [n_atoms]), [(0, 0), (0, n_pad)],
                           'constant'))
        bond_idx.append(bond_df[['idx_0', 'idx_1']].values)
        sc_idx.append(sc_df[['atom_index_0', 'atom_index_1']].values)
        angles_in_idx.append(angle_in_df['b_idx'].values)
        if angle_out_df is not None:
            angles_out_idx.append(angle_out_df['b_idx'].values)
        else:
            angles_out_idx.append(np.array([0.]))

        n_atom_sum += n_atoms
        n_pairs_sum += n_pairs

    atom_x = arr_lst_to_padded_batch(atom_x, pad_val=0.)
    bond_x = arr_lst_to_padded_batch(bond_x)
    max_n_atoms = atom_x.size(1)
    max_n_bonds = bond_x.size(1)
    angles_out_idx = [a + max_n_bonds for a in angles_out_idx]

    sc_x = arr_lst_to_padded_batch(sc_x)
    sc_m_x =arr_lst_to_padded_batch(sc_m_x)
    if not test: sc_vals = arr_lst_to_padded_batch(sc_vals)
    else: sc_vals = torch.tensor([0.] * batch_size)
    sc_types = arr_lst_to_padded_batch(sc_types, torch.long)
    mask = arr_lst_to_padded_batch(mask, torch.uint8, 0)
    mask = mask[:,:,:max_n_atoms].contiguous()
    bond_idx = arr_lst_to_padded_batch(bond_idx, torch.long, 0)
    sc_idx = arr_lst_to_padded_batch(sc_idx, torch.long, 0)
    angles_in_idx = arr_lst_to_padded_batch(angles_in_idx, torch.long, 0)
    angles_out_idx = arr_lst_to_padded_batch(angles_out_idx, torch.long, 0)
    angles_idx = torch.cat((angles_in_idx, angles_out_idx), dim=-1).contiguous()
    eucl_dists = arr_lst_to_padded_batch(eucl_dists, pad_val=999)
    eucl_dists = eucl_dists[:,:,:max_n_atoms].contiguous()
    graph_dists = arr_lst_to_padded_batch(graph_dists, torch.long, 10)
    graph_dists = graph_dists[:,:,:max_n_atoms].contiguous()
    angles_in = arr_lst_to_padded_batch(angles_in)
    angles_out = arr_lst_to_padded_batch(angles_out)
    angles = torch.cat((angles_in, angles_out), dim=-1).contiguous()

    return (atom_x, bond_x, sc_x, sc_m_x, eucl_dists, graph_dists, angles, mask,
            bond_idx, sc_idx, angles_idx, sc_types), sc_vals


#! /bin/python

import os
import sys
import json
from concurrent import futures

import luigi
import numpy as np
import nifty.tools as nt

import elf.segmentation.features as feats
import elf.segmentation.multicut as mc
from vigra.analysis import relabelConsecutive

import cluster_tools.utils.volume_utils as vu
import cluster_tools.utils.function_utils as fu
from cluster_tools.cluster_tasks import SlurmTask, LocalTask, LSFTask

#
# SliceAgglomeration Tasks
#

class SliceAgglomerationBase(luigi.Task):
    """ SliceAgglomeration base class
    """

    task_name = 'slice_agglomeration'
    src_file = os.path.abspath(__file__)

    # input and output volumes
    input_path = luigi.Parameter()
    input_key = luigi.Parameter()
    output_path = luigi.Parameter()
    output_key = luigi.Parameter()
    have_ignore_label = luigi.BoolParameter()
    dependency = luigi.TaskParameter()

    def requires(self):
        return self.dependency

    @staticmethod
    def default_task_config():
        config = LocalTask.default_task_config()
        config.update({'beta_stitch': 0.5,
                       'beta': 0.75,
                       'invert_inputs': False,
                       'channel_begin': None,
                       'channel_end': None})
        return config

    def clean_up_for_retry(self, block_list):
        super().clean_up_for_retry(block_list)
        # TODO remove any output of failed blocks because it might be corrupted

    def run_impl(self):
        # get the global config and init configs
        shebang, block_shape, roi_begin, roi_end = self.global_config_values()
        self.init(shebang)

        # get volume shape and chunks
        with vu.file_reader(self.output_path, 'r') as f:
            shape = f[self.output_key].shape
            chunks = f[self.output_key].chunks
        assert len(shape) == 3

        # load the slice_agglomeration config
        config = self.get_task_config()

        # we deal with different block shapes:
        # - block_shape: the block shape used for watershed calculation
        # - slice_shape: the (2d) shape of a single slice
        # - slice_block_shape: the watershed volume chunks in z + full slice shape
        slice_shape = shape[1:]
        slice_block_shape = (chunks[0],) + slice_shape

        # update the config with input and output paths and keys
        # as well as block shape
        config.update({'input_path': self.input_path, 'input_key': self.input_key,
                       'output_path': self.output_path, 'output_key': self.output_key,
                       'block_shape': slice_block_shape, 'have_ignore_label': self.have_ignore_label,
                       'block_shape_2d': block_shape[1:]})

        if self.n_retries == 0:
            block_list = vu.blocks_in_volume(shape, slice_block_shape, roi_begin, roi_end)
        else:
            block_list = self.block_list
            self.clean_up_for_retry(block_list)

        self._write_log('scheduling %i blocks to be processed' % len(block_list))
        n_jobs = min(len(block_list), self.max_jobs)

        # prime and run the jobs
        self.prepare_jobs(n_jobs, block_list, config)
        self.submit_jobs(n_jobs)

        # wait till jobs finish and check for job success
        self.wait_for_jobs()
        self.check_jobs(n_jobs)

class SliceAgglomerationLocal(SliceAgglomerationBase, LocalTask):
    """
    SliceAgglomeration on local machine
    """
    pass

class SliceAgglomerationSlurm(SliceAgglomerationBase, SlurmTask):
    """
    SliceAgglomeration on slurm cluster
    """
    pass

class SliceAgglomerationLSF(SliceAgglomerationBase, LSFTask):
    """
    SliceAgglomeration on lsf cluster
    """
    pass

#
# Implementation
#

def agglomerate_slice(seg, input_, z, config):
    # check if this slic is empty
    if np.sum(seg) == 0:
        return seg

    have_ignore_label = config['have_ignore_label']
    block_shape = config['block_shape_2d']

    foreground_mask = seg != 0

    # relabel the segmentation
    _, max_id, _ = relabelConsecutive(seg, out=seg, keep_zeros=True, start_label=1)
    seg = seg.astype('uint32')

    # construct rag and get edge features
    rag = feats.compute_rag(seg, n_labels=max_id + 1, n_threads=1)
    edge_features = feats.compute_boundary_mean_and_length(rag, input_, n_threads=1)[:, 0]

    # set edges to ignore label to be maximally repulsive
    if have_ignore_label:
        uv_ids = rag.uvIds()
        ignore_mask = (uv_ids == 0).any(axis=1)
        edge_features[ignore_mask] = 1

    # get the stitiching edges
    stitch_edges = feats.get_stitch_edges(rag, seg, block_shape)
    beta1 = config.get('beta_stitch', 0.5)
    beta2 = config.get('beta', 0.75)

    costs = np.zeros_like(edge_features)
    costs[stitch_edges] = mc.compute_edge_costs(edge_features[stitch_edges], beta=beta1)
    costs[~stitch_edges] = mc.compute_edge_costs(edge_features[~stitch_edges], beta=beta2)
    node_labels = mc.multicut_kernighan_lin(rag, costs)

    node_labels, max_id, _ = relabelConsecutive(node_labels, start_label=1, keep_zeros=True)

    # project node labels back to segmentation
    seg = feats.project_node_labels_to_pixels(rag, node_labels, n_threads=1).astype('uint64')

    # we change to slice base id offset
    id_offset = z * np.prod(list(seg.shape))
    assert id_offset < np.iinfo('uint64').max, "Id overflow"

    # add offset back to segmentation
    seg[foreground_mask] += id_offset
    return seg

def _slice_agglomeration(blocking, block_id, ds_in, ds_out, config):
    fu.log("start processing block %i" % block_id)

    n_threads = config['threads_per_job']
    ds_in.n_threads = n_threads
    ds_out.n_threads = n_threads

    invert_inputs = config.get('invert_inputs', False)

    bb = vu.block_to_bb(blocking.getBlock(block_id))
    # load the segmentation / output
    seg = ds_out[bb]

    # load the input data
    ndim_in = ds_in.ndim
    # we are conservative and always accumulate affinities with max
    if ndim_in == 4:
        channel_begin = config.get('channel_begin', None)
        channel_end = config.get('channel_end', None)
        channel_begin = 0 if channel_begin is None else channel_begin
        channel_end = ds_in.shape[0] if channel_end is None else channel_end
        bb_in = (slice(channel_begin, channel_end),) + bb
        input_ = ds_in[bb_in]
        if invert_inputs:
            input_ = 1. - input_
        input_ = vu.normalize(np.max(input_, axis=0))
    else:
        input_ = vu.normalize(ds_in[bb])
        if invert_inputs:
            input_ = 1. - input_

    with futures.ThreadPoolExecutor(n_threads) as tp:
        tasks = [tp.submit(agglomerate_slice, seg[z], input_[z], z, config)
                 for z in range(seg.shape[0])]
        slice_segs = [t.result() for t in tasks]

    seg = np.concatenate([sseg[None] for sseg in slice_segs], axis=0)
    ds_out[bb] = seg

    # log block success
    fu.log_block_success(block_id)

def slice_agglomeration(job_id, config_path):
    fu.log("start processing job %i" % job_id)
    fu.log("reading config from %s" % config_path)
    with open(config_path, 'r') as f:
        config = json.load(f)

    # read the input cofig
    input_path = config['input_path']
    input_key = config['input_key']
    shape = list(vu.get_shape(input_path, input_key))
    if len(shape) == 4:
        shape = shape[1:]

    block_shape = list(config['block_shape'])
    block_list = config['block_list']

    # read the output config
    output_path = config['output_path']
    output_key = config['output_key']

    # get the blocking
    blocking = nt.blocking([0, 0, 0], shape, block_shape)

    # submit blocks
    with vu.file_reader(input_path, 'r') as f_in, vu.file_reader(output_path) as f_out:
        ds_in = f_in[input_key]
        assert ds_in.ndim in (3, 4)
        ds_out = f_out[output_key]
        assert ds_out.ndim == 3
        for block_id in block_list:
            _slice_agglomeration(blocking, block_id, ds_in, ds_out, config)

    # log success
    fu.log_job_success(job_id)

if __name__ == '__main__':
    path = sys.argv[1]
    assert os.path.exists(path), path
    job_id = int(os.path.split(path)[1].split('.')[0].split('_')[-1])
    slice_agglomeration(job_id, path)


import inspect
from functools import partial

import jax.numpy as jnp
from jax import jit, lax

from onnx_jax.handlers.backend_handler import BackendHandler
from onnx_jax.handlers.handler import onnx_op
from onnx_jax.pb_wrapper import OnnxNode

@onnx_op("MaxPool")
class MaxPool(BackendHandler):
    @classmethod
    def _common(cls, node: OnnxNode, **kwargs):
        if len(node.outputs) > 1:
            raise Exception('MaxPool with indices is not supported')

        cls._rewrite(node)
        cls._prepare(node)

        return onnx_maxpool

    @classmethod
    def version_1(cls, node, **kwargs):
        return cls._common(node, **kwargs)

    @classmethod
    def version_8(cls, node, **kwargs):
        return cls._common(node, **kwargs)

    @classmethod
    def version_10(cls, node, **kwargs):
        return cls._common(node, **kwargs)

    @classmethod
    def version_11(cls, node, **kwargs):
        return cls._common(node, **kwargs)

    @classmethod
    def version_12(cls, node, **kwargs):
        return cls._common(node, **kwargs)

    @classmethod
    def _rewrite(cls, node: OnnxNode):
        if 'auto_pad' not in node.attrs:
            node.attrs['auto_pad'] = 'NOTSET'
        if 'ceil_mode' not in node.attrs:
            node.attrs['ceil_mode'] = 0
        if 'storage_order' not in node.attrs:
            node.attrs['storage_order'] = 0

    @classmethod
    def _prepare(cls, node: OnnxNode):
        args = list(inspect.signature(onnx_maxpool).parameters.keys())
        attrs = [node.attrs.get(k, None) for k in args[node.len_inputs :]]
        node.attrs_list.extend(attrs)

def pad_helper(input_rank, pads=None):
    pad_pairs = len(pads) // 2 if pads else 0

    pad_width = []
    for _ in range(input_rank - pad_pairs):
        pad_width.append((0, 0))
    for idx in range(pad_pairs):
        pad_width.append((pads[idx], pads[idx + pad_pairs]))
    return pad_width

@partial(jit, static_argnums=(1, 2, 3, 4, 5, 6, 7))
def onnx_maxpool(
    x,
    kernel_shape,
    pads=None,
    strides=None,
    dilations=None,
    auto_pad='NOTSET',
    ceil_mode=0,
    storage_order=0,
):
    dims = (1,) * (x.ndim - len(kernel_shape)) + tuple(kernel_shape)
    strides = (
        ((1,) * (x.ndim - len(strides)) + tuple(strides)) if strides else (1,) * x.ndim
    )
    dilations = (
        ((1,) * (x.ndim - len(dilations)) + tuple(dilations))
        if dilations
        else (1,) * x.ndim
    )

    if auto_pad == "NOTSET":
        pads = pad_helper(x.ndim, pads) if pads else 'VALID'
    elif auto_pad == "SAME_UPPER":
        pads = "SAME"
    elif auto_pad == "VALID":
        pads = "VALID"
    elif auto_pad == "SAME_LOWER":
        raise NotImplemented("MaxPool with auto_pad `SAME_LOWER`")
    else:
        raise ValueError(f"Invalid auto_pad attribute: {auto_pad}")

    return lax.reduce_window(x, -jnp.inf, lax.max, dims, strides, pads, None, dilations)