"""
.. warning:: if using only ``mov_stack`` = 1, no MWCS jobs is inserted in the
    database and consequently, no MWCS calculation will be done! FIX!

Following Clarke et al (2011), we apply the :ref:`mwcs`
to study the relative dephasing between Moving-Window stacks ("Current") and a
Reference using Moving-Window Cross-Spectral analysis. The *jobs* "T"o do have
been inserted in the datavase during the stack procedure.

Filter Configuration Parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* ``mwcs_low``: The lower frequency bound of the linear regression done in
  MWCS (in Hz)
* ``mwcs_high``: The upper frequency bound of the linear regression done in
  MWCS (in Hz)
* ``mwcs_wlen``: Window length (in seconds) to perform MWCS
* ``mwcs_step``: Step (in seconds) of the windowing procedure in MWCS

* |hpc| | *new in 1.6*

In short, both time series are sliced in several overlapping windows and
preprocessed. The similarity of the two time-series is assessed using the
cross-coherence between energy densities in the frequency domain. The time
delay between the two cross correlations is found in the unwrapped phase of
the cross spectrum and is linearly proportional to frequency. This "Delay" for
each window between two signals is the slope of a weighted linear regression
(WLS) of the samples within the frequency band of interest.

For each filter, the frequency band can be configured using ``mwcs_low``
and ``mwcs_high``, and the window and overlap lengths using ``mwcs_wlen`` and
``mwcs_step``.

The output of this process is a table of delays measured at each window in the
functions. The following is an example for lag times between -115 and -90.
In this case, the window length was 10 seconds with an overlap of 5 seconds.

.. code-block:: python

          LAG_TIME          DELAY           ERROR         MEAN COHERENCE
    -1.1500000000e+02 -1.4781146383e-01 5.3727119135e-02 2.7585243911e-01
    -1.1000000000e+02 -6.8207526992e-02 2.0546644311e-02 3.1620999352e-01
    -1.0500000000e+02 -1.0337029577e-01 8.6645155402e-03 4.2439269880e-01
    -1.0000000000e+02 -2.8668775696e-02 6.2522215988e-03 5.7159849528e-01
    -9.5000000000e+01  4.1803941008e-02 1.5102285789e-02 4.1238557789e-01
    -9.0000000000e+01  4.8139400233e-02 3.2700657018e-02 3.0586187792e-01

This process is job-based, so it is possible to run several instances in
parallel.

Once done, each job is marked "D"one in the database and, unless ``hpc`` is
``Y``, DTT jobs are inserted/updated in the database.

To run this step:

.. code-block:: sh

    $ msnoise cc dvv compute_mwcs

This step also supports parallel processing/threading:

.. code-block:: sh

    $ msnoise -t 4 cc dvv compute_mwcs

will start 4 instances of the code (after 1 second delay to avoid database
conflicts). This works both with SQLite and MySQL but be aware problems
could occur with SQLite.

.. versionadded:: 1.4
    Parallel Processing
"""

from .api import *
from .move2obspy import mwcs

import logbook
from obspy.signal.regression import linear_regression
import scipy.optimize
import scipy.signal
from scipy.stats import scoreatpercentile
from obspy.signal.invsim import cosine_taper
from obspy.signal.regression import linear_regression

import scipy

import scipy.fft as sf
from scipy.fft import next_fast_len

def get_window(window="boxcar", half_win=3):
    window_len = 2 * half_win + 1
    if window == "boxcar":
        w = scipy.signal.boxcar(window_len).astype('complex')
    else:
        w = scipy.signal.windows.hann(window_len).astype('complex')
    return w / window_len

def getCoherence(dcs, ds1, ds2):
    # TODO: docsting
    n = len(dcs)
    coh = np.zeros(n).astype('complex')
    valids = np.argwhere(np.logical_and(np.abs(ds1) > 0,
                                        np.abs(
                                            ds2 > 0)))
    coh[valids] = dcs[valids] / (
            ds1[valids] * ds2[valids])
    coh[coh > (1.0 + 0j)] = 1.0 + 0j
    return coh

def main(loglevel="INFO"):

    # Reconfigure logger to show the pid number in log records
    global logger
    logger = get_logger('msnoise.compute_mwcs_child', loglevel,
                        with_pid=True)
    logger.info('*** Starting: Compute MWCS ***')

    db = connect()
    params = get_params(db)
    taxis = get_t_axis(db)
    export_format = params.export_format
    if export_format == "BOTH":
        extension = ".MSEED"
    else:
        extension = "." + export_format
    mov_stacks = params.mov_stack

    goal_sampling_rate = params.cc_sampling_rate
    maxlag = params.maxlag

    logger.debug('Ready to compute')
    # Then we compute the jobs
    outfolders = []
    filters = get_filters(db, all=False)
    time.sleep(np.random.random() * 5)
    smoothing_half_win= 5
    hanningwindow = get_window("hanning", smoothing_half_win)
    while is_dtt_next_job(db, flag='T', jobtype='MWCS'):
        # TODO would it be possible to make the next 8 lines in the API ?
        jobs = get_dtt_next_job(db, flag='T', jobtype='MWCS')

        if not len(jobs):
            # edge case, should only occur when is_next returns true, but
            # get_next receives no jobs (heavily parallelised calls).
            time.sleep(np.random.random())
            continue
        pair = jobs[0].pair
        refs, days = zip(*[[job.ref, job.day] for job in jobs])

        logger.info(
            "There are MWCS jobs for some days to recompute for %s" % pair)
        for f in filters:
            filterid = int(f.ref)
            freqmin = f.mwcs_low
            freqmax = f.mwcs_high
            low = f.low
            high = f.high

            def ww(a):
                from .move2obspy import whiten
                n = next_fast_len(len(a))
                return whiten(a, n, 1./params.cc_sampling_rate,
                              low, high, returntime=True)
            for components in params.all_components:
                ref_name = pair.replace(':', '_')
                station1, station2 = pair.split(":")

                try:
                    ref = xr_get_ref(station1, station2, components, filterid, taxis)
                    ref = ref.CCF.values
                except FileNotFoundError as fullpath:
                    logger.error("FILE DOES NOT EXIST: %s, skipping" % fullpath)
                    continue
                if not len(ref):
                    continue
                # print("Whitening ref")
                # ref = ww(ref)

                for mov_stack in mov_stacks:
                    output = []
                    try:
                        data = xr_get_ccf(station1, station2, components, filterid, mov_stack, taxis)
                    except FileNotFoundError as fullpath:
                        logger.error("FILE DOES NOT EXIST: %s, skipping" % fullpath)
                        continue
                    logger.debug("Processing %s:%s f%i m%i %s" % (station1, station2, filterid, mov_stack, components))
                    todo = data.index.intersection(pd.to_datetime(days))
                    data = data.loc[todo]
                    data = data.dropna()
                    # print("Whitening %s" % fn)
                    # data = pd.DataFrame(data)
                    # data = data.apply(ww, axis=1, result_type="broadcast")

                    # work on 2D mwcs:
                    window_length_samples = int(
                        f.mwcs_wlen * goal_sampling_rate)

                    padd = int(2 ** (nextpow2(window_length_samples) + 2))

                    count = 0
                    tp = cosine_taper(window_length_samples, 0.85)
                    minind = 0
                    maxind = window_length_samples
                    freq_vec = sf.fftfreq(padd, 1. / goal_sampling_rate)[
                               :padd // 2]
                    # Find the values the frequency range of interest
                    index_range = np.argwhere(
                        np.logical_and(freq_vec >= freqmin,
                                       freq_vec <= freqmax)).flatten()
                    cci = np.empty((data.shape[0], window_length_samples))
                    while maxind <= data.shape[1]:
                        cci[:] = data.iloc[:,
                                 minind:(minind + window_length_samples)].values
                        scipy.signal.detrend(cci, type="linear", axis=1,
                                             overwrite_data=True)
                        for i in range(cci.shape[0]):
                            cci[i] *= tp

                        cri = ref[
                              minind:(minind + window_length_samples)].copy()
                        scipy.signal.detrend(cri, type='linear',
                                             overwrite_data=True)
                        cri *= tp

                        minind += int(f.mwcs_step * goal_sampling_rate)
                        maxind += int(f.mwcs_step * goal_sampling_rate)

                        fcur = sf.fft(cci, axis=1, n=padd)[:, :padd // 2]
                        fref = sf.fft(cri, n=padd)[:padd // 2]

                        fcur2 = np.real(fcur) ** 2 + np.imag(fcur) ** 2
                        fcur2 = fcur2.astype(float)
                        fref2 = np.real(fref) ** 2 + np.imag(fref) ** 2
                        fref2 = fref2.astype(float)

                        X = fref * fcur.conj()
                        if smoothing_half_win != 0:
                            for i in range(fcur2.shape[0]):
                                fcur2[i] = np.sqrt(
                                    scipy.signal.convolve(fcur2[i],
                                                          hanningwindow.real,
                                                          "same"))

                            fref2 = np.sqrt(scipy.signal.convolve(fref2,
                                                                  hanningwindow.real,
                                                                  "same"))

                            for i in range(X.shape[0]):
                                X[i] = scipy.signal.convolve(X[i],
                                                             hanningwindow,
                                                             "same")

                        else:
                            fcur2 = fcur2.apply(np.sqrt)
                            fref2 = fref2.apply(np.sqrt)

                        dcs = np.abs(X)

                        # Get Coherence and its mean value
                        W = []
                        MCOH = []
                        for i in range(dcs.shape[0]):
                            coh = getCoherence(dcs[i, index_range],
                                               fref2[index_range],
                                               fcur2[i, index_range])
                            mcoh = np.mean(coh)
                            MCOH.append(np.real(mcoh))
                            # Get Weights, avoid zero division here below:
                            coh[coh==1] = 1.0-1e-9
                            w = 1.0 / (1.0 / (coh ** 2) - 1.0)
                            w[coh >= 0.99] = 1.0 / (1.0 / 0.9801 - 1.0)
                            w = np.sqrt(w * np.sqrt(dcs[i][index_range]))
                            w = np.real(w)
                            W.append(w)

                        W = np.asarray(W)
                        #                     # Frequency array:
                        v = np.real(freq_vec[index_range]) * 2 * np.pi

                        # Phase:

                        phi = np.angle(X)
                        phi = phi.astype(float)
                        phi[:, 0] = 0.0
                        phi = np.unwrap(phi, axis=1)
                        phi = phi[:, index_range]

                        # Calculate the slope with a weighted least square linear regression
                        # forced through the origin
                        # weights for the WLS must be the variance !

                        result = np.array([linear_regression(v.flatten(),
                                                             phi[i].flatten(),
                                                             W[i].flatten(),
                                                             ) for i in
                                           range(phi.shape[0])])

                        M = result[:, 0]
                        e = np.sum((phi - np.outer(M, v)) ** 2, axis=1) / (
                                    len(v) - 1)
                        s2x2 = np.sum(v ** 2 * W ** 2, axis=1)
                        sx2 = np.sum(W * v ** 2, axis=1)
                        E = np.sqrt(e * s2x2 / sx2 ** 2)

                        ti = -params.maxlag + f.mwcs_wlen / 2. + count * f.mwcs_step
                        # print("Finished processing t_center=", ti, "s")
                        S = pd.DataFrame(np.array([M, E, MCOH]).T,
                                         index=data.index,
                                         columns=["M", "EM", "MCOH"])
                        S.columns = pd.MultiIndex.from_product(
                            [[ti], S.columns])
                        output.append(S)
                        count += 1
                        del fcur, fref, fcur2, fref2, result, cri
                        del X
                        del M, E, MCOH
                    output = pd.concat(output, axis=1)
                    # output.to_csv(fn.replace('.nc','.csv'))

                    xr_save_mwcs(station1, station2, components, filterid, mov_stack, taxis, output)

        massive_update_job(db, jobs, "D")
        if not params.hpc:
            for job in jobs:
                update_job(db, job.day, job.pair, 'DTT', 'T')
    logger.info('*** Finished: Compute MWCS ***')


import cv2 as cv
from cv2 import absdiff
from cv2 import boundingRect
import numpy as np

webcam = cv.VideoCapture("videos/vidTest.avi")
ret, imageframe1 = webcam.read() # get frame per frame from the webcam
ret, imageframe2 = webcam.read()
if webcam.isOpened():
    while True:
        diff = absdiff(imageframe1,imageframe2)
        gray = cv.cvtColor(diff,cv.COLOR_BGR2GRAY)
        blur = cv.GaussianBlur(gray,(5,5),0)
        _,thresh = cv.threshold(blur,20,255,cv.THRESH_BINARY)
        dilate = cv.dilate(thresh,None,3)
        contours,_ =cv.findContours(dilate,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
        for contour in contours:
            (x,y,w,h)=boundingRect(contour)

            if cv.contourArea(contour)<700:
                continue
            cv.rectangle(imageframe1,(x,y),(x+w,y+h),(0,255,0),2)
        #cv.drawContours(imageframe1,contours,-1,(0,255,0),2)
        if ret:
            cv.imshow('CApVideos', imageframe1) # show the frame
            imageframe1 = imageframe2
            ret,imageframe2 = webcam.read()
        else:
            print('No image available')
        keystroke = cv.waitKey(20) # Wait for Key press
        if (keystroke == 27):
            break # if key pressed is ESC then escape the loop

    webcam.release()
    cv.destroyAllWindows()


##############################################################################################
################ Cleaning and Preprocessing the publications related to COVID-19 #############
##############################################################################################

########################################################################
# Importing the required libraries.
import csv, pandas as pd, sys
from abc import ABC, abstractmethod
########################################################################

class Preprocess(ABC):
    # Datasets enumeration.
    ARXIV = "arxiv"
    BIORXIV = "biorxiv"
    PUBMED = "pubmed"
    SCOPUS = "scopus"
    FINAL = "final"

    # Method that perform the specific process of cleaning and preprocessing.
    @abstractmethod
    def _preprocess(self):
        pass

    # Method that perform the generic process of cleaning and preprocessing.
    def process_raw_data(self, raw_data, preprocessed_data, dtypes_raw_data = None):
        # Creating a dataframe from the raw data.
        self._dataframe = pd.read_csv(raw_data, header=0, dtype=dtypes_raw_data)

        # Cleaning and preprocessing the raw data.
        self._preprocess()

        # Exporting the data to CSV file.
        self._dataframe.to_csv(preprocessed_data, index=False, quoting=csv.QUOTE_ALL)

    # Method that generate a specific process of cleaning and preprocessing.
    @staticmethod
    def factory_process(dataset):
        if dataset == Preprocess.ARXIV:
            from preprocess_arxiv import ProcessArxiv
            return ProcessArxiv()
        elif dataset == Preprocess.BIORXIV:
            from preprocess_biorxiv import ProcessBiorxiv
            return ProcessBiorxiv()
        elif dataset == Preprocess.PUBMED:
            from preprocess_pubmed import ProcessPubmed
            return ProcessPubmed()
        elif dataset == Preprocess.SCOPUS:
            from preprocess_scopus import ProcessScopus
            return ProcessScopus()
        elif dataset == Preprocess.FINAL:
            from preprocess_final import ProcessFinal
            return ProcessFinal()
        else:
            raise FileNotFoundError("This dataset does not exist.")

# Executing the cleaning and preprocessing process of raw data.
if __name__ == "__main__":
    if len(sys.argv) == 1:
        Preprocess.factory_process(Preprocess.ARXIV).process_raw_data(
            "data/raw/arxiv_raw.csv", "data/prepared/arxiv_covid_19.csv")
        Preprocess.factory_process(Preprocess.BIORXIV).process_raw_data(
            "data/raw/biorxiv_raw.csv", "data/prepared/biorxiv_covid_19.csv")
        Preprocess.factory_process(Preprocess.PUBMED).process_raw_data(
            "data/raw/pubmed_raw.csv", "data/prepared/pubmed_covid_19.csv", object)
        Preprocess.factory_process(Preprocess.SCOPUS).process_raw_data(
            "data/raw/scopus_raw.csv", "data/prepared/scopus_covid_19.csv", object)
    elif sys.argv[1] == "final":
        Preprocess.factory_process(Preprocess.FINAL).process_raw_data(
            "data/raw/final_raw.csv", "data/prepared/final_covid_19.csv", object)


#!/usr/bin/python3
"""
Search current directory for git repositories and print their status.
"""

import os
import subprocess as sp
import re
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--show-clean',
    help='Show status for clean, up-to-date repositories',
    action='store_true')
parser.add_argument('--fetch',
    help='Run git fetch in each repository',
    action='store_true')
parser.add_argument('dir',
    help='Directory to search for repositories.',
    nargs='?', default=os.getcwd())
args,unknown = parser.parse_known_args()

class col:
    RED = '\033[0;31m'
    YELLOW = '\033[0;33m'
    GREEN = '\033[0;32m'
    PURPLE = '\033[0;35m'
    ENDC = '\033[0m'

# Patterns to parse output of git status
pattern_uptodate = re.compile('Your branch is up to date with')
pattern_nochanges = re.compile('nothing to commit, working tree clean')

for root,dirs,files in os.walk(args.dir, topdown=True):
    if '.git' in dirs:
        dirs.clear()  # do not traverse further down once git repo is found

        up_to_date = False
        no_changes = False

        repo_name = os.path.basename(os.path.normpath(root))
        repo_name = col.PURPLE + repo_name + col.ENDC

        if args.fetch:
            print(repo_name)
            sp.run(['git', 'fetch'], cwd=root)
            continue

        result = sp.run(['git', 'status'], cwd=root, stdout=sp.PIPE)
        output = result.stdout.decode('utf-8')

        if pattern_uptodate.search(output):
            up_to_date = True
        if pattern_nochanges.search(output):
            no_changes = True

        if up_to_date and no_changes and args.show_clean:
            print(repo_name)
            print(col.GREEN + 'Up to date with remote. Nothing to commit.\n' +
                col.ENDC)
            continue
        if not no_changes:
            print(repo_name)
            print(col.RED + 'Changed since last commit.\n' + col.ENDC)
            continue
        if not up_to_date:
            print(repo_name)
            print(col.YELLOW + 'Out of sync with remote.\n' + col.ENDC)
            continue


#!/usr/bin/python

import codecs
import os
from xlwt import *
import xlrd
import numpy as np
import xgboost as xgb
from xgboost import plot_importance
import time
import pickle
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['Arial Unicode MS']    # 指定默认字体：解决plot不能显示中文问题
mpl.rcParams['axes.unicode_minus'] = False           # 解决保存图像是负号'-'显示为方块的问题

version = 'v1'
date = '20210304-20210406'

def read_xls(file_name):
    team_query_data = xlrd.open_workbook(file_name)
    table_data = team_query_data.sheet_by_index(0)
    return table_data

def write_xls(data, result_file):
    file = Workbook(encoding='utf-8')
    table = file.add_sheet("result")
    for index, each_data in enumerate(data):
        for i in range(len(each_data)):
            table.write(index, i, str(each_data[i]))
    file.save(result_file)

def read_txt(file_name):
    with codecs.open(file_name, "r") as fr:
        data = fr.read()
    data = [line for line in data.split("\n") if line]
    return data

def write_txt(data, file_name):
    fw = open(file_name, "w+")
    for line in data:
        if isinstance(line, list):
            fw.write("\t".join([str(elem) for elem in line]) + "\n")
        else:
            fw.write(str(line) + "\n")
    fw.close()

def train(feature_dir):
    data_dir = feature_dir
    if not os.path.exists(data_dir):
        os.makedirs(data_dir)
    file_name = 'acfeature_{}_'.format(date)
    xg_train = xgb.DMatrix(data_dir + "/" + file_name + "train.txt")
    xg_test = xgb.DMatrix(data_dir + "/" + file_name + "val.txt")
    data = read_txt(data_dir + "/" + file_name + "val.txt")

    test_Y = []
    for line in data:
        line_split = line.split(" ")
        test_Y.append(int(line_split[0]))
    test_Y = np.array(test_Y)

    param = {}
    param['objective'] = 'multi:softmax'
    param['eta'] = 0.1
    param['max_depth'] = 6
    param['silent'] = 1
    param['nthread'] = 4
    param['num_class'] = 13
    watchlist = [(xg_train, 'train'), (xg_test, 'test')]
    num_round = 50

    # 训练：方法1
    # bst = xgb.train(param, xg_train, num_round, watchlist)
    # pred = bst.predict(xg_test)
    # print('predicting, classification error=%f' % (sum(int(pred[i]) != test_Y[i] for i in range(len(test_Y))) / float(len(test_Y))))

    # 训练：方法2
    param['objective'] = 'multi:softprob'
    bst = xgb.train(param, xg_train, num_round, watchlist)

    # 模型保存与加载
    # 方式1
    pickle.dump(bst, open(feature_dir + "/model_1.dat", "wb"))
    # bst = pickle.load(open(feature_dir + "/model.dat", "rb"))
    # 方式2
    # bst.dump_model(feature_dir + "/model.txt")
    # bst.save_model(feature_dir + "/xgboost_python.model")
    # bst = xgb.Booster({'nthread': 4})
    # bst.load_model(feature_dir + "/xgboost_python.model")

    pdf = PdfPages(feature_dir + "/feature_importance.pdf")
    xgb.plot_importance(bst, max_num_features=10, importance_type="gain")
    pdf.savefig()
    plt.close()
    pdf.close()

    # Note: this convention has been changed since xgboost-unity
    # get prediction, this is in 1D array, need reshape to (ndata, nclass)
    time_begin = time.time()
    yprob = bst.predict(xg_test).reshape(test_Y.shape[0], param['num_class'])
    ylabel = np.argmax(yprob, axis=1)
    time_end = time.time()
    print('解析query用时: {}'.format(time_end - time_begin))
    print('predicting, classification error=%f' % (sum(int(ylabel[i]) != test_Y[i] for i in range(len(test_Y))) / float(len(test_Y))))

    result = []
    for cur_label, line in zip(test_Y, yprob):
        one_result = []
        sorted_result = sorted(enumerate(line), key=lambda x: x[1], reverse=True)
        for index in range(len(sorted_result)):
            # 输出top几
            if index >= 1:
                break
            one_result.append(str(int(sorted_result[index][0])) + "_" + str(float(sorted_result[index][1])))
        result.append(str(int(cur_label)) + "\t" + "\t".join(one_result))
    write_txt(result, feature_dir + "/pred_{}_val_py.txt".format(date))

def main():
    feature_dir = "/Users/sunhaowen/Documents/data/3.ivr_log/final_data/{}".format(version)
    if not os.path.exists(feature_dir):
        os.makedirs(feature_dir)
    train(feature_dir)

if __name__ == "__main__":
    main()


import sys
from consolation.BaseConsoleDisplay import BaseConsoleDisplay
from consolation.PosixTiles import PosixTiles
from consolation.TermcapUtility import TermcapUtility

__copying__="""
Written by Thomas Hori

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/."""

class PosixDisplay(BaseConsoleDisplay):
    """Display for POSIX (GNU, OSX et cetera) via ANSI escapes, termios and optionally
    curses/termcap/terminfo."""
    _tiles_class = PosixTiles
    def __init__(self, *a, **kw):
        self._plotcache = {}
        super(PosixDisplay, self).__init__(*a, **kw)
        self._reset_to=None
        #Clear the screen
        print("\x1b[2J") #pylint: disable = superfluous-parens
    @staticmethod
    def works_p():
        try:
            import termios, os #pylint: disable = import-error, unused-variable
            return os.name == "posix"
        except ImportError:
            return 0
    def _engage_message_formatting(self):
        sys.stderr.write("\x1b[1;37m")
        sys.stderr.flush()
    def _end_message_formatting(self):
        sys.stderr.write("\x1b[m")
        sys.stderr.flush()
        self._engage_message_formatting()
    def goto_point(self, x, y):
        del self.point[:]
        self.point.extend([x, y])
        sys.stderr.write("\x1B[%d;%dH"%(y+1, x+1))
        sys.stderr.flush()
    def set_window_title(self, title):
        sys.stderr.write("\x1b]0;"+title+"\x1b\\")
        sys.stderr.flush()
    def get_key_event(self):
        self.dump_messages()
        s = self._getch()
        if s != "\x1B":
            return s
        s += self._getch()
        c = self._getch()
        while ord(c) in list(range(32,48)):
            s += c
            c = self._getch()
        s += c #Terminator character
        if s[-1] == "A":
            return "up"
        elif s[-1] == "B":
            return "down"
        elif s[-1] == "C":
            return "right"
        elif s[-1] == "D":
            return "left"
        return s
    def _plot_character(self, y, x, c):
        if (x, y) not in self._plotcache:
            self._plotcache[(x, y)] = " "
        if self._plotcache[(x, y)] == c:
            return
        rx, ry = self.point
        sys.stderr.write("\x1B[%d;%dH%s\x1B[%d;%dH\x1B[m" % (y+1, x+1, c, ry+1, rx+1))
        sys.stderr.flush()
    #
    def _getch(self, reset_afterwards=0):
        import termios, tty  #pylint: disable = import-error
        if not self._reset_to:
            self._reset_to = termios.tcgetattr(0)
        tty.setcbreak(0, termios.TCSANOW)
        char = sys.stdin.read(1)
        if reset_afterwards:
            self._reset_terminal()
        return char
    def _reset_terminal(self):
        import termios  #pylint: disable = import-error
        if self._reset_to:
            termios.tcsetattr(0, termios.TCSANOW, self._reset_to)
    def get_dimensions(self):
        return TermcapUtility.dimensions()


import os, inspect, sys, shutil
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + "/../")
import logging
import logging.config

import datetime
from pymongo import MongoClient
from conf.serverconf import MONGODB_HOST, MONGODB_PORT, MONGODB_DATABASE, CLIENT_TMP_DIR, ADMIN_ACCOUNTS, MAX_GUEST_DAYS, MAX_JOB_DAYS

from src.common.Util import sendEmail

def cleanDatabases(force=False):
    log("Starting Clean Databases routine")

    connection = MongoClient(MONGODB_HOST, MONGODB_PORT)

    import os
    ROOT_DIRECTORY = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../") + "/"

    # STEP 1. GET ALL USERS BY DIRECTORY
    user_dirs = os.listdir(CLIENT_TMP_DIR)

    if "nologin" in user_dirs:
        user_dirs.remove("nologin")

    # STEP 2. GET ALL USERS IN DB
    users_list = connection[MONGODB_DATABASE]['userCollection'].find()

    # STEP 3. CHECK CURRENT INFORMATION
    #Users that are out of date (guest users)
    users_to_remove = []
    #Users that for any reason have lost the data dir -> create new one and clean files and Jobs from DB
    users_to_fix = []
    #Jobs that are out of date (normal and guest users)
    jobs_to_remove = {}
    #Jobs that need to be reminded (normal users)
    jobs_to_remind = {}
    #In addition we have to clean all files from db and dir

    # TODO: "nologin" user will not be present in the DB
    for user in users_list:
        user_id = int(user["userID"])
        if str(user_id) in user_dirs:
            # User is in database, so dir is OK
            user_dirs.remove(str(user_id))
        else:
            #Data dir missing, need to be fixed
            log("User " + str(user_id) + " marked to be fixed.")
            users_to_fix.append(user_id)

        force_remove = False
        if "is_guest" in user and user["is_guest"] == True and checkRemoveGuestUser(user, user_id):
            # If guest user, check if should be removed
            users_to_remove.append(user_id)
            force_remove = True
        else:
            # Check if user has jobs to be removed soon that need to be remained about
            # (only for "no guest" accounts)
            reminders = checkRemindJobsForUser(connection, user_id)

            if len(reminders) > 0:
                jobs_to_remind[user_id] = reminders

        # If check if user has jobs that should be removed
        aux = checkRemoveJobsForUser(connection, user_id, force_remove)
        if len(aux) > 0:
            jobs_to_remove[user_id] = aux

    log("Summary:")
    log("   - " + str(str(sum(len(x) for x in jobs_to_remove.values()))) + " jobs will be removed.")
    log("   - " + str(str(sum(len(x) for x in jobs_to_remind.values()))) + " reminder e-mails will be sent.")
    log("   - " + str(len(users_to_remove)) + " users will be removed.")
    log("   - " + str(len(users_to_fix)) + " users will be fixed.")
    log("   - " + str(len(user_dirs)) + " orphan directories will be removed.")
    log("")

    if not force:
        if not confirm(prompt='"Proceed?', resp=False):
            log("Bye.")
            return

    # STEP 4. REMOVE ALL OUTDATED JOBS (+ FEATURES AND FILES)
    for user_id, jobs_to_remove in jobs_to_remove.items():
        for job_id in jobs_to_remove:
            removeJobByJobID(connection, user_id, job_id)

    # STEP 5. REMOVE ALL OUTDATED GUEST USERS (+ FILES)
    for user_id in users_to_remove:
        #IF USER IN TO_FIX REMOVE IT
        if user_id in users_to_fix:
            users_to_fix.remove(user_id)
        #Jobs have been already removed
        removeAllFilesByUserID(connection, user_id)
        removeUserByUserID(connection, user_id)

    # STEP 6. FIX ALL ERRONEOUS USERS (BUT CLEAN FIRST THE BED2GENES, JOBS AND FILES)
    for user_id in users_to_fix:
        removeAllFilesByUserID(connection, user_id, only_db=True)
        fixUserDataByUserID(connection, user_id)

    # STEP 7. REMOVE THE ORPHAN DIRECTORIES
    for user_id in user_dirs:
        removeDirectoryByUserID(user_id)

    # STEP 8. SEND REMINDER E-MAILS
    for user_id, jobs_to_remind in jobs_to_remind.items():
        for job_id in jobs_to_remind:
            remindJobByJobID(connection, user_id, job_id, ROOT_DIRECTORY)

    # STEP 9. REBUILD INDEXES
    rebuildIndexes(connection)

def checkRemoveGuestUser(user, user_id):
    last_login = datetime.datetime.strptime(user['last_login'], "%Y%m%d").date()
    max_date = datetime.date.today() - datetime.timedelta(days=MAX_GUEST_DAYS)
    remove = (last_login < max_date)
    if remove:
        log("User " + str(user_id) + " marked to be removed.")
    return remove

def checkRemoveJobsForUser(connection, user_id, force_remove=False):
    #Get all jobs for user
    jobs_list = connection[MONGODB_DATABASE]['jobInstanceCollection'].find({"userID":str(user_id)})
    max_date = datetime.date.today() - datetime.timedelta(days=MAX_JOB_DAYS)
    jobs_remove = []
    # for each job
    for job in jobs_list:
        #Check if date OR if force_remove
        date = datetime.datetime.strptime(job['accessDate'][0:8], "%Y%m%d").date()
        if force_remove or date < max_date:
            log("Job " + str(job["jobID"]) + " (user " + str(user_id) + ") marked to be removed.")
            jobs_remove.append(job['jobID'])
    return jobs_remove

def checkRemindJobsForUser(connection, user_id):
    #Get all jobs for user
    jobs_list = connection[MONGODB_DATABASE]['jobInstanceCollection'].find({"userID":str(user_id),
                                                                            "reminderSent": {"$exists": False}
                                                                            })
    max_date = datetime.date.today() - datetime.timedelta(days=MAX_JOB_DAYS + 7)
    min_date = datetime.date.today() - datetime.timedelta(days=MAX_JOB_DAYS)
    jobs_remind = []
    # for each job
    for job in jobs_list:
        #Check if date OR if force_remove
        date = datetime.datetime.strptime(job['accessDate'][0:8], "%Y%m%d").date()
        # Avoid sending reminders of jobs that will be deleted today
        if date >= max_date and date < min_date:
            log("Job " + str(job["jobID"]) + " (user " + str(user_id) + ") marked to be reminded.")
            jobs_remind.append(job['jobID'])
    return jobs_remind

def removeJobByJobID(connection, user_id, job_id):
    log("Removing job " + job_id)
    #STEP 1. REMOVE ALL THE FEATURES ASSOCIATED TO JOB
    connection[MONGODB_DATABASE]['featuresCollection'].remove({"jobID": job_id})
    #STEP 2. REMOVE ALL THE FEATURES ASSOCIATED TO JOB
    connection[MONGODB_DATABASE]['visualOptionsCollection'].remove({"jobID": job_id})
    #STEP 3.REMOVE THE JOB FROM DATABASE
    connection[MONGODB_DATABASE]['jobInstanceCollection'].remove({"jobID": job_id})
    #STEP 4. REMOVE THE JOB DIRECTORY FROM USER DIR
    removeDirectoryByUserID(user_id, job_id)

def remindJobByJobID(connection, user_id, job_id, ROOT_DIRECTORY):
    log("Reminding job " + job_id)

    ROOT_DIRECTORY_CORRECTED = os.path.abspath(ROOT_DIRECTORY + '/../../../PaintomicsClient/') + '/'

    try:
        job_data = connection[MONGODB_DATABASE]['jobInstanceCollection'].find_one({"jobID": job_id})
        user_data = connection[MONGODB_DATABASE]['userCollection'].find_one({"userID": user_id})

        message = ''
        message += ""
        message += "  "
        message += ""
        message += "

"
        message += "
Your Paintomics job " + job_id + " will be deleted soon!
"
        message += "
Hello, " + user_data["userName"] + "! Your job with ID " + job_id + " will be deleted in one week.
"
        message += "
To avoid it, please visit the following link to update the accession date:
"
        message += "
http://www.paintomics.org/?jobID=" + job_id + "

"
        message += "

"
        message += "
Problems? E-mail " + "paintomics4@outlook.com" + "
"
        message += "
Legal notice: you are receiving this e-mail because you accepted Paintomics conditions. Your data will be stored for the"
        message += "solely purpose of informing you about actions involving your jobs."
        message += ''

        sendEmail(ROOT_DIRECTORY_CORRECTED, user_data["email"], user_data["userName"], "Paintomics 3: one job is going to expire soon",
                  message, isHTML=True)
    except Exception as e:
        logging.error("Failed to send the email.")

    #STEP 3.REMOVE THE JOB FROM DATABASE
    connection[MONGODB_DATABASE]['jobInstanceCollection'].update({"jobID": job_id}, {'$set': {"reminderSent": 1}}, upsert=False)

def removeAllFilesByUserID(connection, user_id, only_db=False):
    log("Removing files for user " + str(user_id) + " from database")
    #STEP 1. REMOVE ALL THE FEATURES ASSOCIATED TO JOB
    connection[MONGODB_DATABASE]['fileCollection'].remove({"userID": str(user_id)})
    #STEP 2. REMOVE THE DIRECTORIES FOR USER
    if not only_db:
        removeDirectoryByUserID(user_id)

def removeDirectoryByUserID(user_id, job_id=None):
    #STEP 1. BUILD THE PATH
    dir = CLIENT_TMP_DIR.rstrip("/") + "/" + str(user_id)
    if job_id != None:
        dir+= "/jobsData/" + job_id
    #STEP 2. REMOVE THE DIRECTORY AND ALL CHILDREN
    if os.path.isdir(dir):
        log("Removing files for user " + str(user_id) + " from directory " + dir)
        shutil.rmtree(dir)
    else:
        log("Directory " + dir + " not found!")

def removeUserByUserID(connection, user_id):
    #STEP 1. REMOVE THE USER ENTRY
    user = connection[MONGODB_DATABASE]['userCollection'].find_one({"userID": user_id})
    if not user["userName"] in ADMIN_ACCOUNTS: #prevent admin accounts to be removed
        log("Removing user " + str(user_id) + " from database.")
        connection[MONGODB_DATABASE]['userCollection'].remove({"userID": user_id})
    else:
        log("User " + user["userName"] + " cannot be removed.")

def fixUserDataByUserID(connection, user_id):
    log("Fixing user " + str(user_id))
    #STEP 1. REMOVE ALL FILES ENTRIES
    removeAllFilesByUserID(connection, user_id, only_db=True)
    #STEP 2. REMOVE ALL JOBS
    jobs_to_remove = checkRemoveJobsForUser(connection, user_id, force_remove=True)
    for job_id in jobs_to_remove:
        removeJobByJobID(connection, user_id, job_id)
    #STEP 3. CREATE THE DIRECTORIES
    dir = CLIENT_TMP_DIR.rstrip("/") + "/" + str(user_id)
    log("Creating directories at " + dir)
    os.mkdir(dir)
    os.mkdir(dir + "/inputData")
    os.mkdir(dir + "/jobsData/")
    os.mkdir(dir + "/tmp/")

def rebuildIndexes(connection):
    dbs = ['userCollection', 'jobInstanceCollection', 'foundFeaturesCollection', 'featuresCollection', 'pathwaysCollection', 'visualOptionsCollection', 'fileCollection', 'messageCollection']
    for db in dbs:
        log("Rebuilding indexes for database " + db)
        connection[MONGODB_DATABASE][db].reindex()

def log(msg):
    print(msg)
    frame,filename,line_number,function_name,lines,index=inspect.getouterframes(inspect.currentframe())[1]
    line=lines[0]
    indentation_level=line.find(line.lstrip())
    logging.info('{i} {m}'.format(i=' '*indentation_level,m=msg))

def readConfigurationFile():
    import os
    ROOT_DIRECTORY = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../") + "/"
    #PREPARE LOGGING
    logging.config.fileConfig(ROOT_DIRECTORY + 'conf/logging.cfg')

def confirm(prompt=None, resp=False):
    """prompts for yes or no response from the user. Returns True for yes and
    False for no.

    'resp' should be set to the default value assumed by the caller when
    user simply types ENTER.

    >>> confirm(prompt='Create Directory?', resp=True)
    Create Directory? [y]|n:
    True
    >>> confirm(prompt='Create Directory?', resp=False)
    Create Directory? [n]|y:
    False
    >>>
    Create Directory? [n]|y: y
    True

    """

    if prompt is None:
        prompt = 'Confirm'

    if resp:
        prompt = '%s [%s]|%s: ' % (prompt, 'y', 'n')
    else:
        prompt = '%s [%s]|%s: ' % (prompt, 'n', 'y')

    while True:
        ans = input(prompt)
        if not ans:
            return resp
        if ans not in ['y', 'Y', 'n', 'N']:
            print('please enter y or n.')
            continue
        if ans == 'y' or ans == 'Y':
            return True
        if ans == 'n' or ans == 'N':
            return False

# cleanDatabases(force=True)


"""
Audiencias, paths
"""
from datetime import date
from typing import List
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

from lib.database import get_db

from .crud import get_audiencia, get_audiencias
from .schemas import AudienciaOut

audiencias = APIRouter()

@audiencias.get("", response_model=List[AudienciaOut])
async def listar_audiencias(
    autoridad_id: int,
    fecha: date = None,
    ano: int = None,
    db: Session = Depends(get_db),
):
    """Lista de audiencias"""
    resultados = []
    try:
        for audiencia, autoridad, distrito in get_audiencias(db, autoridad_id=autoridad_id, fecha=fecha, ano=ano):
            resultados.append(
                AudienciaOut(
                    id=audiencia.id,
                    distrito_id=distrito.id,
                    distrito=distrito.nombre,
                    autoridad_id=autoridad.id,
                    autoridad=autoridad.descripcion,
                    tiempo=audiencia.tiempo,
                    tipo_audiencia=audiencia.tipo_audiencia,
                    expediente=audiencia.expediente,
                    actores=audiencia.actores,
                    demandados=audiencia.demandados,
                    sala=audiencia.sala,
                    caracter=audiencia.caracter,
                    causa_penal=audiencia.causa_penal,
                    delitos=audiencia.delitos,
                    toca=audiencia.toca,
                    expediente_origen=audiencia.expediente_origen,
                    imputados=audiencia.imputados,
                    origen=audiencia.origen,
                )
            )
    except IndexError as error:
        raise HTTPException(status_code=404, detail=f"Not found: {str(error)}") from error
    except ValueError as error:
        raise HTTPException(status_code=406, detail=f"Not acceptable: {str(error)}") from error
    return resultados

@audiencias.get("/{audiencia_id}", response_model=AudienciaOut)
async def consultar_un_audiencia(audiencia_id: int, db: Session = Depends(get_db)):
    """Consultar un audiencia"""
    try:
        audiencia = get_audiencia(db, audiencia_id)
    except IndexError as error:
        raise HTTPException(status_code=404, detail=f"Not found: {str(error)}") from error
    except ValueError as error:
        raise HTTPException(status_code=406, detail=f"Not acceptable: {str(error)}") from error
    return AudienciaOut(
        id=audiencia.id,
        distrito_id=audiencia.autoridad.distrito.id,
        distrito=audiencia.autoridad.distrito.nombre,
        autoridad_id=audiencia.autoridad.id,
        autoridad=audiencia.autoridad.descripcion,
        tiempo=audiencia.tiempo,
        tipo_audiencia=audiencia.tipo_audiencia,
        expediente=audiencia.expediente,
        actores=audiencia.actores,
        demandados=audiencia.demandados,
        sala=audiencia.sala,
        caracter=audiencia.caracter,
        causa_penal=audiencia.causa_penal,
        delitos=audiencia.delitos,
        toca=audiencia.toca,
        expediente_origen=audiencia.expediente_origen,
        imputados=audiencia.imputados,
        origen=audiencia.origen,
    )


class Solution:
    def partition(self, s: str) -> List[List[str]]:
        # create a var to store the result
        result_arr = []
        # get the length of the string
        length_s = len(s)

        # create a bfs function
        def bfs(start_index, combination):
            # if the start_index is greater than or equal to the length of the string, then append it
            if start_index >= length_s:
                result_arr.append(combination.copy())
                return
            # otherwise iterate over the string
            else:
                for end_index in range(start_index, length_s):
                    # if the substring is a palindrome then append it to the combination and call the bfs function
                    if s[start_index:end_index + 1] == s[start_index:end_index + 1][::-1]:
                        combination.append(s[start_index:end_index + 1])
                        bfs(end_index + 1, combination)
                        combination.pop()
        # call the bfs function
        bfs(0, [])
        return result_arr


# -*- coding: utf-8 -*-
'''
Created on 2018年5月8日

@author: WSY
'''

ONLY_MSSP = 'ONLY_MSSP'

ONLY_MSSM = 'ONLY_MSSM'

ONLY_MSSG = 'ONLY_MSSG'

ONLY_MSSM_REASON = '仅运行云签章相关用例'

ONLY_MSSP_REASON = '仅运行云签名相关用例'

ONLY_MSSG_REASON = '仅运行网关相关用例'

runner_tags = []

def set_tags(tags):
    global runner_tags
    runner_tags = tags

def tags_check(tag):
    if tag.upper() in runner_tags:
        return True
    else:
        return False


import goofpy

p = goofpy.Physics(0.0, 0.0, 50.0, 0.2, 127000, 1, 0, 0, 0, 10)
data = []
i = 0
while True:
    data.append(f'"id":"frame{i}","zpos":{p.z},"bounce":{p.b}')
    print(f"Updating physics frame {i}")
    goofpy.updatePhysics()
    i += 1

    if p.z == 0 and p.b == 0:
        data.append(f'"id":"frame{i}","zpos":{p.z},"bounce":{p.b}')
        break

goofpy.savePhysicsToJson(data)


#  A simple Tic-Tac-Toe game
# Players 'X' and 'O' take turn inputing their position on the command line using numbers 1-9
# 1 | 2 | 3
# ---------
# 4 | 5 | 6
# ---------
# 7 | 8 | 9
#

# The Game Board
board = {
    1: ' ', 2: ' ', 3: ' ',
    4: ' ', 5: ' ', 6: ' ',
    7: ' ', 8: ' ', 9: ' '
}

# update the gameboard with the user input
def markBoard(position, mark):

    board[position]= mark.upper()
    return

# print the game board as described at the top of this code skeleton
# Will not be tested in Part 1
def printBoard():

  printboard = ["","","","","","","","",""] #initialize a list with 9 values
  i = 1
  k = 10
  for i in range (1,k):
    if (board[i] == " "):
      printboard[i-1] = str(i)
    elif (board[i] == "X"):
      printboard[i-1] = "X"
    elif (board[i] == "O"):
      printboard[i-1] = "O"

  print (printboard[0]+" | "+printboard[1]+" | "+printboard[2])
  print ("---------")
  print (printboard[3]+" | "+printboard[4]+" | "+printboard[5])
  print ("---------")
  print (printboard[6]+" | "+printboard[7]+" | "+printboard[8])
  print ("---------")

  return

# check for wrong input, this function should return True or False.
# True denoting that the user input is correct
# check for wrong input (user is entering invalid position) or position is out of bound
# another case is that the position is already occupied
def validateMove(position):

    newPos = int(position)
    if newPos >= 1 and newPos <= 9:
        if (board[newPos] == "X" or board[newPos] == "O"):
            print("The position is occupied")
            return False

        else:
            print("Prompt accepted")
            return True

    elif (newPos < 1):
        print("The number is too small, please enter number between     1 to 9")
        return False

    elif (newPos > 9):
        print("The number is too big, please enter number between     1 to 9")
        return False

    else:
        print("Please enter a NUMBER!")
        return False

# list out all the combinations of winning

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

]

# implement a logic to check if the previous winner just win
# This method should return with True or False
def checkWin(player):

  i = 0
  k = len(winCombinations)
  for i in range (0,k):
    if (board[winCombinations[i][0]] == player and
        board[winCombinations[i][1]] == player and
        board[winCombinations[i][2]] == player):
      return True

  return False

#implement a function to check if the game board is already full
# For tic-tac-toe, tie bascially means the whole board is already occupied
# This function should return with boolean
def checkFull():

  i = 1
  k = 10
  for i in range (1,k):
    if board[i] == " ":
      return False

  return True

def currentPlayer(player,input):
  #if player x, then check if he wins, if not, return "0"

  global gameEnded
  gameEnded = False
  proof = False
  if player == 'X':
    positionX = 0
    if proof == False:
      positionX = int(input)
      proof = validateMove(positionX)
      markX = 'X'
      markBoard(positionX, markX)
      printBoard()
      game_win = checkWin(player)
      fullBoard = checkFull()
      # check both for tie and win
      # if win is true, return win condition
      # elif fullboard is true, return tie condition
      if game_win is True:
        gameEnded = True
        return "X",gameEnded

      elif fullBoard is True:
        gameEnded = True
        return "Tie", gameEnded

      return  "O",gameEnded

  elif player == 'O':
    positionO = 0
    while proof == False:
      positionO = int(input)
      proof = validateMove(positionO)
      markO = 'O'
      markBoard(positionO, markO)
      printBoard()
      fullBoard = checkFull()
      game_win = checkWin(player)
      if game_win is True:
        gameEnded = True
        return "O",gameEnded

      elif fullBoard is True:
        gameEnded = True
        return "Tie", gameEnded

      return "X",gameEnded

gameEnded = False
currentTurnPlayer = 'X'

# entry point of the whole program
print('Game started: \n\n' +
    ' 1 | 2 | 3 \n' +
    ' --------- \n' +
    ' 4 | 5 | 6 \n' +
    ' --------- \n' +
    ' 7 | 8 | 9 \n')

# 1. Ask for user input and validate the input
# 2. Update the board
# 3. Check win or tie situation
# 4. Switch User
while not gameEnded:
  move = input(currentTurnPlayer + "'s turn, input: ")
  if move.isdigit() == False:
    print("INSERT NUMBER!")
    continue
  currentTurnPlayer,gameEnded = (currentPlayer(currentTurnPlayer, move))

if currentTurnPlayer == "O" or currentTurnPlayer == "X":
  print(currentTurnPlayer + " win")
elif currentTurnPlayer == "Tie":
  print("It's a Tie")


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

from PIL import Image

class MnistRotDataset(Dataset):
    def __init__(self, mode, transform=None):
        assert mode in ["train", "val", "test"]

        if mode == "train" or mode == "val":
            file = "data/raw/mnist_rotation_new/mnist_all_rotation_normalized_float_train_valid.amat"
        else:
            file = "data/raw/mnist_rotation_new/mnist_all_rotation_normalized_float_test.amat"

        self.transform = transform

        data = np.loadtxt(file, delimiter=" ")

        if mode == "train":
            self.labels = data[:10000, -1].astype(np.int64)
            self.num_samples = len(self.labels)
            self.images = data[:10000, :-1].reshape(-1, 28, 28).astype(np.float32)
        elif mode == "val":
            self.labels = data[10000:, -1].astype(np.int64)
            self.num_samples = len(self.labels)
            self.images = data[10000:, :-1].reshape(-1, 28, 28).astype(np.float32)
        else:
            self.labels = data[:, -1].astype(np.int64)
            self.num_samples = len(self.labels)
            self.images = data[:, :-1].reshape(-1, 28, 28).astype(np.float32)

        self.images = np.pad(self.images, pad_width=((0, 0), (0, 1), (0, 1)), mode="edge")

        assert self.images.shape == (self.labels.shape[0], 29, 29)

    def __getitem__(self, index):
        image, label = self.images[index], self.labels[index]
        image = Image.fromarray(image)
        if self.transform is not None:
            image = self.transform(image)
        return image, label

    def __len__(self):
        return len(self.labels)

class FilteredMNIST(Dataset):
    def __init__(self, mnist_dataset, digit):
        self.mnist_dataset = mnist_dataset
        self.filtered_indices = [i for i, (_, label) in enumerate(self.mnist_dataset) if label == digit]

    def __getitem__(self, index):
        return self.mnist_dataset[self.filtered_indices[index]]

    def __len__(self):
        return len(self.filtered_indices)


from django.conf import settings
from django.conf.urls.defaults import patterns, include, url
from django.contrib import admin

from reviewboard.webapi.resources import root_resource
from reviewboard import initialize

initialize()

handler404 = 'django.views.defaults.page_not_found'
handler500 = 'django.views.defaults.server_error'

# Load in all the models for the admin UI.
if not admin.site._registry:
    admin.autodiscover()

# URLs global to all modes
urlpatterns = patterns('',
    (r'^admin/', include('reviewboard.admin.urls')),
)

# Add static media if running in DEBUG mode
if settings.DEBUG or getattr(settings, 'RUNNING_TEST', False):
    urlpatterns += patterns('django.views.static',
        (r'^media/(?P<path>.*)$', 'serve', {
            'show_indexes': True,
            'document_root': settings.MEDIA_ROOT,
        })
    )

localsite_urlpatterns = patterns('',
    url(r'^$', 'django.views.generic.simple.redirect_to',
        {'url': 'dashboard/'},
        name="root"),

    (r'^api/', include(root_resource.get_url_patterns())),
    (r'^r/', include('reviewboard.reviews.urls')),

    # Dashboard
    url(r'^dashboard/$',
        'reviewboard.reviews.views.dashboard', name="dashboard"),

    # Users
    url(r'^users/$',
        'reviewboard.reviews.views.submitter_list', name="all-users"),
    url(r'^users/(?P<username>[A-Za-z0-9@_\-\.]+)/$',
        'reviewboard.reviews.views.submitter', name="user"),
    url(r'^users/(?P<username>[A-Za-z0-9@_\-\.]+)/infobox/$',
        'reviewboard.reviews.views.user_infobox', name="user-infobox"),

    # Groups
    url(r'^groups/$',
        'reviewboard.reviews.views.group_list', name="all-groups"),
    url(r'^groups/(?P<name>[A-Za-z0-9_-]+)/$',
        'reviewboard.reviews.views.group', name="group"),
    url(r'^groups/(?P<name>[A-Za-z0-9_-]+)/members/$',
        'reviewboard.reviews.views.group_members', name="group_members"),
)

# Main includes
urlpatterns += patterns('',
    (r'^account/', include('reviewboard.accounts.urls')),
    (r'^reports/', include('reviewboard.reports.urls')),

    (r'^s/(?P<local_site_name>[A-Za-z0-9\-_.]+)/',
     include(localsite_urlpatterns)),
)

urlpatterns += localsite_urlpatterns

# django.contrib
urlpatterns += patterns('django.contrib',
    url(r'^account/logout/$', 'auth.views.logout',
        {'next_page': settings.LOGIN_URL}, name="logout")
)


import contextlib
import functools
import inspect
import time
import traceback
import typing
import uuid

from typing_extensions import Self

@typing.runtime_checkable
class ISpan(typing.Protocol):
    def add_context(self, context: dict) -> None:
        ...

    @contextlib.contextmanager
    def trace(
        self,
        name: str,
        context: dict | None = None,
        root_id: str | None = None,
    ) -> typing.Generator[Self, None, None]:
        ...

    def event(
        self,
        name: str,
        context: dict | None = None,
        root_id: str | None = None,
    ) -> None:
        ...

@typing.runtime_checkable
class IPublish(typing.Protocol):
    def publish(self, span: dict) -> None:
        ...

class Span(ISpan):
    __slots__ = ["publisher", "name", "context"]
    publisher: IPublish
    name: str
    context: dict

    def __init__(self, publisher: IPublish, name=None, context=None):
        self.publisher = publisher
        if name is None:
            name = ""
        self.name = name
        if context is None:
            context = {}
        self.context = context

    def add_context(self, context: dict) -> None:
        self.context.update(context)

    @contextlib.contextmanager
    def trace(self, name: str, context: dict | None = None, root_id: str | None = None):
        # Init user context.
        if context is None:
            context = {}
        # Capture filename and lineno of caller.
        filename = context.get("filename")
        lineno = context.get("lineno")
        if not (filename or lineno):
            currentframe = inspect.currentframe()
            if currentframe:
                previous_frame = currentframe.f_back
                while previous_frame and (
                    previous_frame.f_globals.get("__name__") in {"contextlib", __name__}
                ):
                    previous_frame = previous_frame.f_back
                if previous_frame:
                    filename = previous_frame.f_code.co_filename
                    lineno = previous_frame.f_lineno
        # Store name and context.
        existing_name = self.name
        existing_context = self.context
        # Setup IDs.
        trace_id = uuid.uuid4().hex
        parent_id = existing_context.get("trace_id")
        if root_id is None:
            root_id = existing_context.get("root_id", trace_id)
        else:
            # TODO: cleanup, check.
            parent_id = None
        # Setup new context.
        new_context = {"name": name, "root_id": root_id}
        if parent_id is not None:
            new_context["parent_id"] = parent_id
        new_context["trace_id"] = trace_id
        new_context["filename"] = filename
        new_context["lineno"] = lineno
        # Add user context.
        new_context.update(context)
        # Set current cotext.
        new_span = Span(self.publisher, name=name, context=new_context)
        # TODO: issues with this optimization? Async? Multiple routes?
        # self.context = new_context
        # Exec code under trace.
        exc = None
        status = "OK"
        start = time.time()
        try:
            # yield self
            yield new_span
        except Exception as e:
            exc = e
            status = "ERROR"
        end = time.time()
        # Wrap-up.
        duration = end - start
        post_trace = {
            "status": status,
            "start_time": start,
            "end_time": end,
            "duration": duration,
        }
        # Handle exceptions.
        if exc is not None:
            post_trace["exception"] = str(exc)
            post_trace["traceback"] = "".join(traceback.format_exception(exc))
        # Publish.
        new_span.context.update(post_trace)
        new_span.publisher.publish(new_span.context)
        # Restore.
        new_span.name = existing_name
        new_span.context = existing_context
        # Raise.
        if exc is not None:
            raise exc

    def event(
        self, name: str, context: dict | None = None, root_id: str | None = None
    ) -> None:
        with self.trace(name, context, root_id):
            pass

def trace(
    publisher: IPublish,
    name: str,
    context: dict | None = None,
    root_id: str | None = None,
):
    return Span(publisher).trace(name, context, root_id)

def traced(fn=None, span_param="span"):
    def _traced(fn):
        argspec = inspect.getfullargspec(fn)

        @functools.wraps(fn)
        def _inner(*args, **kwargs):
            span_type = None
            if span_param in set(argspec.args):
                arg_idx = {arg: idx for idx, arg in enumerate(argspec.args)}
                if span_param in arg_idx:
                    span_idx = arg_idx[span_param]
                    span = args[span_idx]
                    span_type = "args"
                else:
                    raise ValueError(f"Can't find span {span_param} in passed args!")
            elif span_param in kwargs:
                span = kwargs[span_param]
                span_type = "kwargs"
            else:
                raise ValueError(f"Can't find span {span_param} in args or kwargs.")

            with span.trace(
                f"{fn.__module__}.{fn.__qualname__}",
                {
                    "module": fn.__module__,
                    "function": fn.__qualname__,
                    "filename": fn.__code__.co_filename,
                    "lineno": fn.__code__.co_firstlineno,
                },
            ) as newspan:
                if span_type == "args":
                    args = tuple(
                        newspan if idx == span_idx else arg
                        for idx, arg in enumerate(args)
                    )
                elif span_type == "kwargs":
                    kwargs[span_param] = newspan
                else:
                    raise ValueError(f"Unknown span_type {span_type}.")
                return fn(*args, **kwargs)

        return _inner

    if fn is None:
        return _traced
    return _traced(fn)


from PyQt5.QtWidgets import (QMainWindow, QAction)
from lightype.widgets.testWindow import TestWindow

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("Lightype")
        self.resize(800, 700)
        self.setContentsMargins(0, 0, 0, 0)
        self.layout().setContentsMargins(0, 0, 0, 0)

        testWindow = TestWindow()
        self.setCentralWidget(testWindow)

        self.show()


import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def hartmann(x0, x1, x2):
    n_samples = x0.shape[0]
    alpha = np.array([1.0, 1.2, 3.0, 3.2])
    A = np.array([[3.0, 10, 30],
                  [0.1, 10, 35],
                  [3.0, 10, 30],
                  [0.1, 10, 35]])
    P = np.array([[3689, 1170, 2673],
                  [4699, 4387, 7470],
                  [1091, 8732, 5547],
                  [381, 5743, 8828]]) * 1e-4
    x = np.array([[x0, x1, x2]])
    x = np.transpose(x, [2,0,1])
    x = np.repeat(x, repeats=4, axis=1)
    P = np.repeat(np.array([P]), repeats=n_samples, axis=0)
    exponent = np.einsum("ijk,jk->ij", (x - P) ** 2, A)
    y = -np.einsum("ij,j->i", np.exp(-exponent), alpha)
    return -y

def main(out_dir="./", samples=15, fontsize=12,
         x2_range = [[0.35, 0.4], [0.65, 0.7], [0.9, 0.95]]):
    sublayer = [len(x2_range), 6]

    grad_id = "0903130724"
    grad_x = np.load(os.path.join("../logs/gradient_ascent/", grad_id + "_pred_x.npy"))
    grad_y = np.load(os.path.join("../logs/gradient_ascent/", grad_id + "_pred_y.npy"))
    grad_xy = np.concatenate([grad_x, grad_y], axis=-1)
    coms_id = "0903145437"
    coms_x = np.load(os.path.join("../logs/coms_cleaned/", coms_id + "_pred_x.npy"))
    coms_y = np.load(os.path.join("../logs/coms_cleaned/", coms_id + "_pred_y.npy"))
    coms_xy = np.concatenate([coms_x, coms_y], axis=-1)
    iom_id = "0903132148"
    iom_x = np.load(os.path.join("../logs/iom/", iom_id + "_pred_x.npy"))
    iom_y = np.load(os.path.join("../logs/iom/", iom_id + "_pred_y.npy"))
    iom_xy = np.concatenate([iom_x, iom_y], axis=-1)
    romo_id = "0912043548"
    romo_x = np.load(os.path.join("../logs/romo_ridge/", romo_id + "_pred_x.npy"))
    romo_y = np.load(os.path.join("../logs/romo_ridge/", romo_id + "_pred_y.npy"))
    romo_xy = np.concatenate([romo_x, romo_y], axis=-1)
    rim_id = "0912042643"
    rim_x = np.load(os.path.join("../logs/rim_ridge/", rim_id + "_pred_x.npy"))
    rim_y = np.load(os.path.join("../logs/rim_ridge/", rim_id + "_pred_y.npy"))
    rim_xy = np.concatenate([rim_x, rim_y], axis=-1)
    models = [grad_xy, coms_xy, iom_xy, romo_xy, rim_xy]
    models_name = ["Grad. Ascent", "COMs", "IOM", "ROMO", "REM"]

    x0 = np.linspace(0, 1, samples)
    x1 = np.linspace(0, 1, samples)
    x0, x1 = np.meshgrid(x0, x1)
    np.random.seed(42)
    random = np.random.random(samples * samples)

    fig, axes = plt.subplots(nrows=sublayer[0], ncols=sublayer[1], figsize=(9,4.5))
    for i in range(sublayer[0]):
        for j, pred_xy in enumerate(models):
            tmp = pred_xy[(pred_xy[:,2] > x2_range[i][0]) & (pred_xy[:,2] < x2_range[i][1])]
            df = pd.DataFrame(tmp)
            tmp = df.sort_values([1, 0]).values
            pred_x0 = tmp[:,0].reshape(samples, samples)
            pred_x1 = tmp[:,1].reshape(samples, samples)
            pred_y = tmp[:,-1].reshape(samples, samples)

            ax = axes[i, j]
            if i == 0:
                ax.set_title(models_name[j], fontsize=fontsize + 3)
            if i != sublayer[0] - 1:
                ax.set_xticks([])
            else:
                ax.set_xticks([])
                # ax.set_xticks([0.0, 0.5, 1.0])
                # ax.set_xlabel("x0", fontsize=fontsize + 2)
            if j != 0:
                ax.set_yticks([])
            else:
                ax.set_yticks([])
                # ax.set_yticks([0.0, 0.5, 1.0])
                # ax.set_ylabel("({} < x2 < {})\nx1".format(x2_range[i][0], x2_range[i][1]), fontsize=fontsize + 2)
            ax.tick_params(axis='both', labelsize=fontsize)
            contour = ax.contourf(pred_x0, pred_x1, pred_y, levels=20, cmap="Blues")
            # cbar = fig.colorbar(contour, ax=ax)
            # cbar.ax.tick_params(labelsize=fontsize)
            ax.set_xlim(0, 1)
            ax.set_ylim(0, 1)

    for i in range(sublayer[0]):
        x2 = x2_range[i][0] + random * (x2_range[i][1] - x2_range[i][0])
        y = hartmann(x0.reshape(-1), x1.reshape(-1), x2).reshape(samples, samples)

        ax = axes[i, -1]
        if i == 0:
            ax.set_title("Truth", fontsize=fontsize + 3)
        if i != sublayer[0] - 1:
            ax.set_xticks([])
        else:
            ax.set_xticks([])
            # ax.set_xticks([0.0, 0.5, 1.0])
            # ax.set_xlabel("x0", fontsize=fontsize + 2)
        ax.set_yticks([])
        ax.tick_params(axis='both', labelsize=fontsize)
        contour = ax.contourf(x0, x1, y, levels=20, cmap="Blues")
        # cbar = fig.colorbar(contour, ax=ax)
        # cbar.ax.tick_params(labelsize=fontsize)
        ax.set_xlim(0, 1)
        ax.set_ylim(0, 1)

    figname = os.path.join(out_dir, "manifold.pdf")
    plt.tight_layout(pad=0.4)
    plt.savefig(figname, dpi=1200)

if __name__ == "__main__":
    main(out_dir="./")


# 깊이우선탐색 연습문제2

# loop로 푸는 방법
# 탐색 시작 노드의 인덱스 s
# 정점들의 개수
def DFS(s, N):
    visited = [0] * N
    stck = []
    stck.append(s)
    visited[s] = 1
    sol.append(s)
    while stck:
        for d in range(1, N):
            # 안 가본 & 연결된 노드면
            if not visited[d] and adj[s][d]:
                # 나중에 돌아와서 안 가본 나머지 노드도 가기 위해 push
                stck.append(s)
                visited[d] = 1
                sol.append(d)
                s = d
                break
        # break없이 for문이 끝난 경우에만 작동 == 더 이상 갈 곳이 X
        # 이전 노드로 되돌아가면서 다시 탐색
        else:
            s = stck.pop()

for t in range(int(input())):
    V, E = map(int, input().split())
    # 인접 노드 표시하는 2차원 배열 (딕셔너리로도 가능)
    adj = [[0 for _ in range(V + 1)] for _ in range(V + 1)]
    sol = []
    for _ in range(E):
        n1, n2 = map(int, input().split())
        # 양방향이니까
        adj[n1][n2] = adj[n2][n1] = 1
    DFS(1, V + 1)
    print(f'#{t + 1}', *sol)


import unittest
from unittest import mock

from pyrser import parsing

class TestCallTrue(unittest.TestCase):
    def test_it_calls_its_clause_with_given_args(self):
        parser, clause, args = mock.Mock(), mock.Mock(), (1, 2, 3)
        call = parsing.CallTrue(clause, *args)
        call(parser)
        clause.assert_called_once_with(*args)

    def test_it_returns_true_when_clause_is_true(self):
        parser = mock.Mock()
        clause = mock.Mock(return_value=True)
        call = parsing.CallTrue(clause)
        self.assertTrue(call(parser))

    def test_it_returns_true_when_clause_is_false(self):
        parser = mock.Mock()
        clause = mock.Mock(return_value=False)
        call = parsing.CallTrue(clause)
        self.assertTrue(call(parser))


from typing import List

from django.conf import settings
from django.core.management.color import color_style

from crontab import CronTab, CronItem

class CrontabManager:
    COMMENT_START_WITH = 'task'

    def __init__(self, user='root'):
        """
        user='root' root用户任务
        user=False 系统任务
        user=True 当前用户
        """
        self.user = user
        self.cron = CronTab(user=user)  # /var/spool/cron/root
        self.style = color_style(force_color=True)

    def get_jobs_setting(self):
        jobs_settings = getattr(settings, 'CRONTABJOBS', [])
        if not jobs_settings:
            print(self.style.WARNING('Not set jobs, Can set job by settings.CRONTABJOBS = [(comment, time, command)].'))
            return []

        return jobs_settings

    def build_jobs_from_settings(self):
        tasks = []
        jobs_settings = self.get_jobs_setting()
        for job_set in jobs_settings:
            comment, frequency_time, command_line = job_set
            comment: str
            if not comment.startswith(self.COMMENT_START_WITH):
                print(self.style.WARNING(
                    f'Skip job "{job_set}", The comment of job must be start with "{self.COMMENT_START_WITH}".'))

            # 创建任务
            job = CronItem(command=command_line, comment=comment, user=self.user)
            job.cron = self.cron
            job.enable(enabled=True)
            # 设置任务执行周期
            job.setall(frequency_time)
            if not job.is_valid():
                print(self.style.NOTICE(f'The job "{job_set}" is invalid.'))

            tasks.append(job)

        return tasks

    def add_jobs(self, comment_start_with: str = None):
        jobs = self.build_jobs_from_settings()
        new_add_jobs = []
        with self.cron as cron:
            for job in jobs:
                if comment_start_with and not job.comment.startswith(comment_start_with):
                    continue

                if job not in cron.crons:
                    cron.append(item=job)
                    new_add_jobs.append(job)

        if not new_add_jobs:
            print(self.style.WARNING('Not new job is added.'))
        else:
            print(self.style.SUCCESS('New add jobs:'))
            self.print_jobs(new_add_jobs)

    def remove_jobs(self, comment_start_with: str = None, remove_all=None):
        if remove_all:
            jobs = list(self.cron.crons)
            self.cron.remove_all()
        else:
            jobs = self.find_comment_start_with(start_with=comment_start_with)
            # 清除所有定时任务
            self.cron.remove(*jobs)

        # 写入配置文件
        self.cron.write_to_user(user=self.user)  # 指定用户,删除指定用户下的crontab任务
        print(self.style.SUCCESS('Removed jobs:'))
        self.print_jobs(jobs)

    def show_jobs(self):
        lines = self.cron.render()
        for line in lines.split('\n'):
            if not line or line.startswith('#'):
                print(line)
            else:
                items = line.split('#')
                if len(items) == 2:
                    frequency_time, comment = items
                else:
                    frequency_time = items[0]
                    comment = None

                s = self.style.SUCCESS(frequency_time)
                if comment is not None:
                    s += f' # {comment}'

                print(s)

    def find_comment_start_with(self, start_with: str = None):
        if not start_with:
            start_with = self.COMMENT_START_WITH

        return [job for job in self.cron.crons if job.comment.startswith(start_with)]

    def print_jobs(self, jobs: List[CronItem]):
        for job in jobs:
            line = job.render(specials=True)
            if line and line.startswith('#'):
                print(line)
                continue

            frequency_time = job.slices.render(specials=True)
            command_line = job.command
            comment = job.comment
            print(f"{self.style.SUCCESS(frequency_time)} {self.style.WARNING(command_line)} # {comment}")

    def list_job_settings(self):
        jobs_settings = self.get_jobs_setting()
        print(self.style.WARNING('Tasks list in settings:'))
        for job_set in jobs_settings:
            comment, frequency_time, command_line = job_set
            print(f"{self.style.SUCCESS(frequency_time)} {self.style.WARNING(command_line)} # {comment}")


from dash import html, dcc
import dash
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import pandas as pd
import plotly.express as px
from dash_bootstrap_templates import ThemeSwitchAIO

from app import *
from components import sidebar, dashboardsPrimario, dashboardsSecundario, dashboardsTerciario

# =========  Layout  =========== #
content = html.Div(id="page-content")

app.layout = dbc.Container(children=[
    dbc.Row([
        dbc.Col([
            dcc.Location(id='url'),
            sidebar.layout
        ], sm=2),
        dbc.Col([
            content
        ], md=10)
    ])
], fluid=True,)

@app.callback(Output('page-content', 'children'), [Input('url', 'pathname')])
def render_page(pathname):
    if pathname == '/' or pathname == '/dashboardsPrimario':
        return dashboardsPrimario.layout
    if pathname == '/dashboardsSecundario':
        return dashboardsSecundario.layout
    if pathname == '/dashboardsTerciario':
        return dashboardsTerciario.layout

if __name__ == '__main__':
    app.run_server(debug=True,port=8080)
    #app.run_server(debug=False,port=8080,host='0.0.0.0')


#!/usr/bin/env python3

import sys

candidates = set(['は_は_は_助詞_副助詞_*_*', 'が_が_が_助詞_格助詞_*_*', 'を_を_を_助詞_格助詞_*_*'])

def main():
    infile = sys.argv[1]
    with open(infile) as inf:
        for lineno, line in enumerate(inf):
            line = line.strip()
            commidx = line.find(' #')
            comment = ''
            if commidx != -1:
                comment = line[commidx + 1:]
                line = line[:commidx]
            parts = line.split(' ')

            result = []

            removed = False
            for p in parts:
                if p not in candidates:
                    result.append(p)
                else:
                    removed = True

            if removed:
                print(' '.join(result), f'{comment}-removed-{lineno}')

if __name__ == '__main__':
    main()


import xlsxwriter
import sqlite3
import webbrowser
def gerar_relatorio_equipamento():
    try:
        #Conectando ao banco
        conn = sqlite3.connect('estoque.db')
        cursor = conn.cursor()

        cursor.execute("SELECT equipament_patrymony, equipament_type, equipament_status, equipament_room_code FROM equipamentos WHERE equipament_status2 = 'Ativo'")
        equipamentos = cursor.fetchall()

        # Criando o arquivo
        workbook = xlsxwriter.Workbook('Relatorio_Equipamento.xlsx')
        worksheet = workbook.add_worksheet()

        # cabeçalhos
        header_format = workbook.add_format({'bold': True, 'bg_color': '#cccccc'})
        headers = ['Patrimônio', 'Tipo', 'Status', 'Sala']
        worksheet.write_row('A1', headers, header_format)

        # D cores
        even_row_format = workbook.add_format({'bg_color': '#E2F0D9'})  # Verde claro
        odd_row_format = workbook.add_format({'bg_color': '#C5E0B4'})   # Verde

        # Escrevendo as linhas
        for row_num, equipamento in enumerate(equipamentos, start=1):
            row_format = even_row_format if row_num % 2 == 0 else odd_row_format
            worksheet.write_row('A' + str(row_num + 1), equipamento, row_format)

        worksheet.set_column('A:D', 20)
        worksheet.set_column('B:B', 30)
        workbook.close()

        webbrowser.open('Relatorio_Equipamento.xlsx')
    except sqlite3.Error as err:
        print(f"Erro ao buscar dados no banco de dados: {err}")
    finally:
        if conn:
            conn.close()


import sys
input = sys.stdin.readline

n, m = map(int, input().rstrip().split())

d = {}

for i in range(n):
    a = input().rstrip()
    if len(a) < m:
        continue
    if a in d.keys():
        d[a] += 1
    else:
        d[a] = 1

d_s = sorted(d.items(), key=lambda x : (-x[1], -len(x[0]), x[0]))
for i in d_s:
    print(i[0])


import streamlit as st

from img_classify import classification
from PIL import Image
from image_ocr import get_text

st.sidebar.header("影像處理 APP")
st.sidebar.button("圖片分類", key = 'classification')
st.sidebar.button("圖片 OCR", key = 'ocr')

# if st.button("classification"):

#     st.title('圖像分類 APP')
#     st.header('圖片分類APP')
#     st.text('請上傳圖片進行影像分類')

#     uploaded_file = st.file_uploader("選擇JPG圖片進行上傳", type="jpg")
#     if uploaded_file is not None:
#         image = Image.open(uploaded_file)
#         st.image(image, caption='Uploaded image.', use_column_width=True)
#         st.write("")
#         st.write("分類中...")
#         label = classification(image)

#         st.write("此圖片預測類別為 : {}".format(label))

# elif st.button("ocr"):

st.title('圖片OCR轉文字')
st.header("OCR: Optical Character Recognition")
st.text('請上傳圖片進行OCR')

uploaded_file = st.file_uploader("選擇圖片進行上傳", type=["png", "jpg"], key = "ocr_image_uploader")
if uploaded_file is not None:
        image = Image.open(uploaded_file)
        st.image(image, caption='Uploaded image.', use_column_width=True)
        st.write("")
        st.write("檢測中...")
        text, time_cost, draw_image = get_text(image)

        st.write("總共花費時間: {:.3f}s".format(time_cost))
        st.image(draw_image, caption = "偵測結果")
        st.write("偵測到的文字 : ")
        st.write(text)


import pandas as pd
import pandas_flavor as pf

from functools import partial

from multiprocessing import cpu_count
from concurrent.futures import ProcessPoolExecutor, as_completed

from pytimetk.utils.parallel_helpers import conditional_tqdm, get_threads

from pytimetk.utils.checks import check_dataframe_or_groupby, check_date_column, check_value_column, check_installed

from typing import Optional, Union

try:
    import tsfeatures as tsf
    from tsfeatures import (
        acf_features, arch_stat, crossing_points,
        entropy, flat_spots, heterogeneity,
        holt_parameters, lumpiness, nonlinearity,
        pacf_features, stl_features, stability,
        hw_parameters, unitroot_kpss, unitroot_pp,
        series_length, hurst
    )
    from tsfeatures.tsfeatures import _get_feats
except ImportError:
    pass

dict_freqs = {
    'H': 24, 'D': 1,
    'M': 12, 'Q': 4,
    'W': 1, 'Y': 1
}

@pf.register_dataframe_method
def ts_features(
    data: Union[pd.DataFrame, pd.core.groupby.generic.DataFrameGroupBy],
    date_column: str,
    value_column: str,
    features: Optional[list] = None,
    freq: Optional[str] = None,
    scale: bool = True,
    threads: Optional[int] = 1,
    show_progress: bool = True,
) -> pd.DataFrame:
    '''
    Extracts aggregated time series features from a DataFrame or DataFrameGroupBy object using the `tsfeatures` package.

    Note: Requires the `tsfeatures` package to be installed.

    Parameters
    ----------
    data : pd.DataFrame or pd.core.groupby.generic.DataFrameGroupBy
        The `data` parameter is the input data that can be either a Pandas
        DataFrame or a grouped DataFrame. It contains the time series data that
        you want to extract features from.
    date_column : str
        The `date_column` parameter is the name of the column in the input data
        that contains the dates or timestamps of the time series data.
    value_column : str
        The `value_column` parameter is the name of the column in the DataFrame
        that contains the time series values.
    features : list
        The `features` parameter is a list of functions that represent the time
        series features to be extracted. Each function should take a time series
        as input and return a scalar value as output.

        When `None`, uses the default list of features:
        - acf_features
        - arch_stat
        - crossing_points
        - entropy
        - flat_spots
        - heterogeneity
        - holt_parameters
        - lumpiness
        - nonlinearity
        - pacf_features
        - stl_features
        - stability
        - hw_parameters
        - unitroot_kpss
        - unitroot_pp
        - series_length
        - hurst

    freq : str
        The `freq` parameter specifies the frequency of the time series data.
        It is used to calculate features that are dependent on the frequency,
        such as seasonal features.

        - The frequency can be specified as a string, such as 'D' for daily, 'W'
          for weekly, 'M' for monthly.

        - The frequency can be a numeric value representing the number of
          observations per year, such as 365 for daily, 52 for weekly, 12 for
          monthly.
    scale : bool, optional
        The `scale` parameter in the `ts_features` function determines whether
        or not to scale the extracted features.
        - If `scale` is set to `True`, the features will be scaled using z-score
          normalization.
        - If `scale` is set to `False`, the features will not be scaled.
    threads : Optional[int]
        The `threads` parameter is an optional parameter that specifies the
        number of threads to use for parallel processing.
        - If is `None`, tthe function will use all available threads on the system.
        - If is -1, the function will use all available threads on the system.
    show_progress : bool
        The `show_progress` parameter is a boolean parameter that determines
        whether or not to show a progress bar when extracting features.

    Returns
    -------
    pd.DataFrame
        The function `ts_features` returns a pandas DataFrame containing the
        extracted time series features. If grouped data is provided, the DataFrame
        will contain the grouping columns as well.

    Notes
    -----
    ## Performance

    This function uses parallel processing to speed up computation for large
    datasets with many time series groups:

    Parallel processing has overhead and may not be faster on small datasets.

    To use parallel processing, set `threads = -1` to use all available processors.

    Examples
    --------
    ```{python}
    import pandas as pd
    import pytimetk as tk

    # tsfeatures comes with these features:
    from tsfeatures import (
        acf_features, arch_stat, crossing_points,
        entropy, flat_spots, heterogeneity,
        holt_parameters, lumpiness, nonlinearity,
        pacf_features, stl_features, stability,
        hw_parameters, unitroot_kpss, unitroot_pp,
        series_length, hurst
    )

    df = tk.load_dataset('m4_daily', parse_dates = ['date'])

    # Example 1 - Grouped DataFrame
    # Feature Extraction
    feature_df = (
        df
            .groupby('id')
            .ts_features(
                date_column   = 'date',
                value_column  = 'value',
                features      = [acf_features, hurst],
                freq          = 7,
                threads       = 1,
                show_progress = True
            )
    )
    feature_df
    ```
    '''
    # Checks
    check_installed('tsfeatures')
    check_dataframe_or_groupby(data)
    check_date_column(data, date_column)
    check_value_column(data, value_column)

    # Get threads
    threads = get_threads(threads)

    group_names = None
    if isinstance(data, pd.DataFrame):
        df = data.copy()
        df.sort_values(by=[date_column], inplace=True)
        df['unique_id'] = "X1"
        df = df[['unique_id', date_column, value_column]]
        group_names = ['unique_id']

    if isinstance(data, pd.core.groupby.generic.DataFrameGroupBy):
        group_names = data.grouper.names
        df = data.obj.copy()
        df.sort_values(by=[*group_names, date_column], inplace=True)
        df = df[[*group_names, date_column, value_column]]

    if features is None:
        features = [
            acf_features,
            arch_stat,
            crossing_points,
            entropy,
            flat_spots,
            heterogeneity,
            holt_parameters,
            lumpiness,
            nonlinearity,
            pacf_features,
            stl_features,
            stability,
            hw_parameters,
            unitroot_kpss,
            unitroot_pp,
            series_length,
            hurst
        ]

    # Construct the DataFrame for tsfeatures
    if isinstance(data, pd.DataFrame):
        construct_df = df[group_names]
        construct_df['ds'] = df[date_column]
        construct_df['y'] = df[value_column]
    else: # grouped dataframe
        construct_df = df[group_names]
        for col in group_names:
            construct_df[col] = df[col].astype(str)
        construct_df['unique_id'] = construct_df[group_names].apply(lambda row: '_'.join(row), axis=1)

        group_names_lookup_df = construct_df[[*group_names, 'unique_id']].drop_duplicates().reset_index(drop=True)

        construct_df.drop(columns=group_names, inplace=True)
        construct_df['ds'] = df[date_column]
        construct_df['y'] = df[value_column]

    # Run tsfeatures
    # features_df = tsf.tsfeatures(construct_df, features=features, freq=freq, scale=scale, threads=threads)

    partial_get_feats = partial(
        _get_feats,
        freq=freq,
        scale=scale,
        features=features,
        dict_freqs=dict_freqs
    )

    if isinstance(data, pd.DataFrame):

        name = "X1"
        group = construct_df
        result = partial_get_feats(name, group, features = features)

        # RETURN SINGLE DATA FRAME HERE
        return result

    else: # grouped dataframe

        # Replicate tsfeatures without threads
        # https://github.com/Nixtla/tsfeatures/blob/fe4f6e63b8883f84922354b7a57056cf534aa4ae/tsfeatures/tsfeatures.py#L967

        if threads != 1:

            if threads is None: threads = cpu_count()
            if threads == -1: threads = cpu_count()

            # Switch to concurrent.futures for better performance
            # multiprocessing.Pool is slower than concurrent.futures.ProcessPoolExecutor
            with ProcessPoolExecutor(threads) as executor:

                futures = [executor.submit(partial_get_feats, *args) for args in construct_df.groupby('unique_id')]

                ts_features = []
                for future in conditional_tqdm(as_completed(futures), total=len(futures), desc="TS Featurizing...", display=show_progress):
                    ts_features.append(future.result())

        else:
            # Don't parallel process
            ts_features = []
            for name, group in conditional_tqdm(construct_df.groupby('unique_id'), total=len(construct_df.unique_id.unique()), desc="TS Featurizing...", display=show_progress):
                result = partial_get_feats(name, group, features = features)
                ts_features.append(result)

        # Combine the list to a DataFrame
        ts_features = pd.concat(ts_features).rename_axis('unique_id')
        ts_features = ts_features.reset_index()

        # Finalize id or grouping columns
        ts_features = group_names_lookup_df.merge(ts_features, on='unique_id', how='left')

        # drop unique_id column
        ts_features.drop(columns=['unique_id'], inplace=True)

        return ts_features

# Monkey patch the method to pandas groupby objects
pd.core.groupby.generic.DataFrameGroupBy.ts_features = ts_features


from random import randint
from art import logo

print(logo)
print("Welcome to the Number Guessing Game!")
print("I'm thinking of a number between 1 and 100.")
actual_answer = randint(1, 100)
difficulty = input("Choose a difficulty. Type 'easy' or 'hard': ")
if difficulty == "easy":
    guesses = 10
elif difficulty == "hard":
    guesses = 5

while guesses > 0:
    print(f"You have {guesses} attempts remaining to guess the number.")
    answer = input("Make a guess: ")
    if int(answer) < actual_answer:
        print("Too low.\nGuess again.")
    elif int(answer) > actual_answer:
        print("Too high.\nGuess again.")
    elif int(answer) == actual_answer:
        break
    guesses -= 1

if int(answer) == actual_answer:
    print(f"You got it! The answer was {actual_answer}.")
else:
    print("You've run out of guesses. You lose.")


import base64

from django.core.files.base import ContentFile
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework.relations import PrimaryKeyRelatedField

from recipes.models import (
    IngredientInRecipe,
    Recipe,
    Tag,
    Ingredient,
    User,
    MIN_AMOUNT_INGREDIENTS
)

class Base64ImageField(serializers.ImageField):
    """
    Поле для сериализации картинки.
    """

    def to_internal_value(self, data):
        """
        Метод формирующий отображение картинок.
        """

        if isinstance(data, str) and data.startswith('data:image'):
            format, imgstr = data.split(';base64,')
            ext = format.split('/')[-1]
            data = ContentFile(base64.b64decode(imgstr), name='temp.' + ext)

        return super().to_internal_value(data)

class TagSerializer(serializers.ModelSerializer):
    """
    Сериализатор для тегов.
    """

    class Meta:
        model = Tag
        fields = '__all__'

class CustomUserSerializer(serializers.ModelSerializer):
    """
    Сериализатор для объектов модели User.
    """

    is_subscribed = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = (
            'email',
            'id',
            'username',
            'first_name',
            'last_name',
            'is_subscribed'
        )

    def get_is_subscribed(self, obj):
        """
        Метод формирующий поле is_subscribed.
        """

        user = self.context.get('request').user

        return (
            user.is_authenticated
            and user.follower.filter(author=obj).exists()
        )

class IngredientSerializer(serializers.ModelSerializer):
    """
    Сериализатор для объектов модели Ingredient.
    """

    class Meta:
        model = Ingredient
        fields = (
            'id',
            'name',
            'measurement_unit'
        )

class IngredientsInRecipeReadSerializer(serializers.ModelSerializer):
    """
    Сериализатор объектов модели Ingredient для чтения сериализатора рецептов.
    """

    id = serializers.ReadOnlyField(source='ingredient.id')
    name = serializers.ReadOnlyField(source='ingredient.name')
    measurement_unit = serializers.ReadOnlyField(
        source='ingredient.measurement_unit'
    )

    class Meta:
        model = IngredientInRecipe
        fields = (
            'id',
            'name',
            'measurement_unit',
            'amount'
        )

class IngredientsInRecipeWriteSerializer(serializers.ModelSerializer):
    """
    Сериализатор объектов модели Ingredient для записи сериализатора рецептов.
    """

    id = serializers.IntegerField()

    class Meta:
        model = IngredientInRecipe
        fields = ('id', 'amount')

class RecipeWriteSerializer(serializers.ModelSerializer):
    """
    Сериализатор для записи объектов модели Recipe.
    """

    tags = PrimaryKeyRelatedField(
        queryset=Tag.objects.all(),
        many=True
    )
    ingredients = IngredientsInRecipeWriteSerializer(many=True)
    image = Base64ImageField()

    class Meta:
        model = Recipe
        fields = (
            'ingredients',
            'tags',
            'author',
            'image',
            'name',
            'text',
            'cooking_time'
        )
        read_only_fields = ('author',)

    def validate_ingredients(self, value):
        ingredients = value

        if not ingredients:
            raise ValidationError({
                'ingredients': 'Нужен хотя бы 1 ингредиент'
            })

        ingredients_list = []

        for item in ingredients:
            id_obj = item['id']
            amount = item['amount']
            ingredient = Ingredient.objects.filter(id=id_obj).exists()
            if not ingredient:
                raise ValidationError(
                    {'ingredients': f'Ингредиента с id={id_obj} не существует'}
                )
            if amount < MIN_AMOUNT_INGREDIENTS:
                raise ValidationError(
                    {
                        'ingredients':
                        f'Ингредиентов не должно '
                        f'быть меньше {MIN_AMOUNT_INGREDIENTS}'
                    }
                )
            if id_obj in ingredients_list:
                raise ValidationError({
                    'ingredients': 'Ингредианты не должны повторяться'
                })
            ingredients_list.append(id_obj)

        return value

    def validate_tags(self, value):
        tags = value
        tags_list = []

        if not tags:
            raise ValidationError({
                'tags': 'Нужен хотя бы 1 тэг'
            })

        for item in tags:
            tag = Tag.objects.filter(id=item.id)
            if not tag:
                raise ValidationError(
                    {'tags': f'Тега с id={item} не существует'}
                )
            if item in tags_list:
                raise ValidationError({
                    'ingredients': 'Ингредианты не должны повторяться'
                })
            tags_list.append(item)

        return value

    @staticmethod
    def create_ingredients_through_list(ingredients, recipe):
        IngredientInRecipe.objects.bulk_create(
            [IngredientInRecipe(
                ingredient=Ingredient.objects.get(id=ingredient['id']),
                recipe=recipe,
                amount=ingredient['amount']
            ) for ingredient in ingredients]
        )

    def create(self, validated_data):
        tags = validated_data.pop('tags')
        ingredients = validated_data.pop('ingredients')
        recipe = Recipe.objects.create(**validated_data)
        recipe.tags.set(tags)

        self.create_ingredients_through_list(
            recipe=recipe,
            ingredients=ingredients
        )

        return recipe

    def update(self, instance, validated_data):
        tags = validated_data.pop('tags')
        ingredients = validated_data.pop('ingredients')
        instance = super().update(instance, validated_data)
        instance.tags.clear()
        instance.tags.set(tags)
        instance.ingredients.clear()

        self.create_ingredients_through_list(
            recipe=instance,
            ingredients=ingredients
        )
        instance.save()

        return instance

    def to_representation(self, instance):
        """
        Метод, отвечающий за формат отображение объекта Ingredient.
        """
        request = self.context.get('request')
        return RecipeReadSerializer(
            instance,
            context={'request': request}
        ).data

class RecipeReadSerializer(serializers.ModelSerializer):
    """
    Сериализатор для чтения объектов модели Recipe.
    """

    tags = TagSerializer(many=True, read_only=True)
    ingredients = IngredientsInRecipeReadSerializer(
        many=True,
        source='ingredientinrecipe'
    )
    author = CustomUserSerializer(read_only=True)

    is_favorited = serializers.SerializerMethodField()
    is_in_shopping_cart = serializers.SerializerMethodField()
    image = Base64ImageField()

    class Meta:
        model = Recipe
        fields = (
            'id',
            'tags',
            'author',
            'ingredients',
            'is_favorited',
            'is_in_shopping_cart',
            'name',
            'image',
            'text',
            'cooking_time'
        )

    def _get_is(self, obj, user_related_name):
        """
        Метод формирующий поле is_favorited или is_in_shopping_cart.
        """

        user = self.context.get('request').user

        return (
            user.is_authenticated
            and user_related_name.filter(recipe=obj).exists()
        )

    def get_is_favorited(self, obj):
        """
        Метод формирующий поле is_favorited.
        """

        user = self.context.get('request').user
        return not user.is_authenticated or self._get_is(obj, user.favorites)

    def get_is_in_shopping_cart(self, obj):
        """
        Метод формирующий поле is_in_shopping_cart.
        """

        user = self.context.get('request').user
        return (
            not user.is_authenticated
            or self._get_is(obj, user.shopping_list)
        )

class ShortRecipeSerializer(serializers.ModelSerializer):
    """
    Сокращенная версия сериализатор объектов модели Recipe.
    """

    image = Base64ImageField()

    class Meta:
        model = Recipe
        fields = (
            'id',
            'name',
            'image',
            'cooking_time'
        )

class SubscribeSirializer(serializers.ModelSerializer):
    """
    Сериализатор для предоставления данных по автору.
    """

    recipes = serializers.SerializerMethodField()
    is_subscribed = serializers.SerializerMethodField()
    recipes_count = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = (
            'email',
            'id',
            'username',
            'first_name',
            'last_name',
            'is_subscribed',
            'recipes_count',
            'recipes',
        )

    def get_is_subscribed(self, obj):
        """
        Метод формирующий поле is_subscribed.
        """

        user = self.context.get('request').user

        return (
            user.is_authenticated
            and user.follower.filter(author=obj).exists()
        )

    def get_recipes_count(self, obj):
        """
        Метод формирующий поле recipes_count.
        """

        return obj.recipes.count()

    def get_recipes(self, obj):
        """
        Метод формирующий поле recipes.
        """

        request = self.context.get('request')
        limit = request.query_params.get('recipes_limit')
        recipes = obj.recipes.all()

        if limit:
            limit = int(limit)
            recipes = recipes[:limit]

        serializer = ShortRecipeSerializer(recipes, many=True, read_only=True)

        return serializer.data


alias = "harlericho"
none = None
print(10+1.5)
print(none)

x = 100
# case sensitive
book = "La arquitectura de la felicidad"
Book = "Hello"
_book2 = "libro"
print(book , Book , _book2)

y, _book3 = 100, "I robots"
print(y, _book3)

# Conventions
book_name = "Libro1" # Snake Case
bookName = "Libro2" # Camel Case
BookName = "Libro3" # Pascal Case

# Constantes
# Valores que no cambian
# MAYUSCULA
PI = 3.1416
URL = "https://localhost/d"
MY_NAME = "harlericho"