#!/usr/bin/env python3

# class for the extraction of values from simulation output to pandas DataFrame

import pandas as pd
import os as os
import re as re
import glob as glob
import sys as sys
import numpy as np

class extract:
    """
    In the constructor give folder from which to extract
    other arguments are:
    - long cont folder (standard value False)
    - which file to extract (standard is ionicmodel.txt)

    import with:
    from CleftAnalysis import extract

    ------------------------------
    to initiate the class call e.g.
    f = extract.extract(folder_num, subfolder_name, values)
    where:
    folder_num : number of the generated cleftdyn folder
    subfolder_name : string of the possible subfolder. If nothing specified, then no subfolder set
                     numerical values possible: 0 and 1 are special cases defined in determineFolder
    values : name or name snippet of the values to be extracted

    """

    def __init__(self, folder_num, subfolder = False, values = "ionic"):
        self.folder = folder_num
        # setFolder var ensures a folder is not initiated twice
        self.setFolder = False

        self.subfolder = subfolder
        self.determineFolder()

        self.values = values
        self.determineValues()

        self.folderDefinition()
        self.printInfo()
        self.param = self.getParam()
        self.crunumber =  int(self.param["z_discs"][0]*self.param["crus_per_sec_line"][0]**2 -
                              4*self.param["z_discs"][0])

    def read(self):
        var = pd.read_csv(self.folder + self.values, delim_whitespace = True)
        return var

    def readMass(self):
        self.values = "massconversionlog.txt"
        return self.read()

    def readIonic(self):
        self.values = "ionicmodel.txt"
        return self.read()

    def printInfo(self):
        '''
        print info when initiating class
        '''
        print("extraction folder: ", self.folder,
              "\nis it a continuation from long simulations? If yes, which? ", self.subfolder)

    def folderDefinition(self, new_folder = ""):
        '''
        set folder from which to extract data
        Args:
        new_folder: if set can allow changing the actual folder
        '''
        if (not self.setFolder and not self.subfolder):
            self.folder = "../" + str(self.folder) + "/"
            self.setFolder = True
        elif (not self.setFolder and (self.subfolder == True)):
            self.folder = "../long-cont/" + str(self.folder) + "/"
            self.setFolder = True
        elif (not self.setFolder and (type(self.subfolder) == str)):
            self.folder = "../" + self.subfolder + "/" + str(self.folder) + "/"
            self.setFolder = True
        elif (self.setFolder and new_folder):
            print("folder changed to: " + new_folder)
            self.folder = new_folder
        else:
            print("folder already set to: " + self.folder + " or not valid")

    def determineFolder(self):
        ''''
        look for subfolder arg and set it if found
        '''
        if (self.subfolder == 0):
            self.subfolder = False
        elif (self.subfolder == 1):
            self.subfolder = True
        else:
            self.subfolder = self.subfolder

    def getParam(self):
        '''
        get dataframe of parameters from parameter file of cleftdyn (use var names as keys)
        '''
        final_param = pd.DataFrame()
        final_param["params"] = [0]
        param = pd.read_csv(self.folder + "parameters.txt", sep="=", index_col=0).T
        for val in param:
            try:
                final_param[val] = [float(param[val])]
            except TypeError:
                # here some error occurs, to be checked/fixed!
                # print(val)
                pass
            except ValueError:
                pass
            except KeyError:
                pass
        return final_param

    def getParameters(self):
        return self.param

    def getSimulationFolders(self, rootdir = "sampling"):
        """get list of simulation numbers given a root directory where the sims can be found
        needed for analysis of sampling data

        The fct discards all folders in which no maxchanneldata.txt
        file is found (i.e. the simulation did not end yet)

        (this fct is independent of the folder with which the class was initialized)

        """
        sim_dirs = []
        rootdir = "../" + rootdir + "/"
        dirs = os.listdir(rootdir)
        for directory in dirs:
            try:
                val = int(directory)
                # the name trick checks if maxchanneldata.txt is present in the dir,
                # if not it means the sim is not finished yet and it skips it
                name = "{}{}/maxchanneldata.txt".format(rootdir, directory)
                if os.path.exists(name):
                    sim_dirs.append(directory)
                else:
                    continue
                    #sim_dirs.append(directory)
            except ValueError:
                pass
        return sim_dirs

    def crusInfo(self, getRadius = False, getLocations = False, getCRULcation = False):
        '''get total number of RyR and LCCs. Optional radius, channel locations and CRU location

        output are lists of the two channel types optional if
        variables set to True also output CRU radius and channel
        locations (in lists)

        '''
        ryr_numbers = []
        lcc_numbers = []
        radii = []
        ryr_location = []
        lcc_location = []
        for i in range(self.crunumber):
            crufile = open(self.folder + "clefts/cleft" + str(i) + ".log")
            cruinfo = crufile.readline()
            crufile.close()
            cruinfo = cruinfo.strip().replace("  ", " ").split(" ")
            # append number of RyR, LCCs and Radius to list
            ryr_numbers.append(int(cruinfo[cruinfo.index("RyRs") - 1]))
            lcc_numbers.append(int(cruinfo[cruinfo.index("LCCs") - 1]))
            radii.append(float(cruinfo[cruinfo.index("Radius") - 1]))
            # get the locations of the channels only if wished
            if getLocations:
                tmp1, tmp2 = self.__getLocations(ryr_numbers[i], lcc_numbers[i], cruinfo)
                ryr_location.append(tmp1)
                lcc_location.append(tmp2)

        # return different lists according to the wished arguments
        if getRadius and not getLocations:
            return ryr_numbers, lcc_numbers, radii
        elif getLocations and not getRadius:
            return ryr_numbers, lcc_numbers, ryr_location, lcc_location
        elif getRadius and getLocations:
            return ryr_numbers, lcc_numbers, radii, ryr_location, lcc_location
        else:
            return ryr_numbers, lcc_numbers

    def getCRUConcentrations(self, cleftnr):
        """
        get local Ca concentrations for a given CRU in the bulk and in the jSR

        Args:
        - cleftnumber

        Return:
        - numpy arrays with timesteps and bulk/jSR concentrations
        """

        lines, totR, totL = self.__getCleftLogLines(cleftnr)
        times = np.zeros(len(lines))
        bulk_conc = np.zeros(len(lines))
        jsr_conc = np.zeros(len(lines))

        for ind, line in enumerate(lines):
            line_list = line.replace("  ", " ").split(" ")
            times[ind] = line_list[0]
            bulk_conc[ind] = line_list[1]
            jsr_conc[ind] = line_list[2]

        return times, bulk_conc, jsr_conc

    def getCRUFluxes(self, cleftnr):
        """
        get refill and CRU flux for a given CRU number

        Args:
        - cleftnumber

        Return:
        - numpy arrays with timesteps and refill/CRU fluxes
        """

        lines, totR, totL = self.__getCleftLogLines(cleftnr)
        times = np.zeros(len(lines))
        refill_flux = np.zeros(len(lines))
        cru_flux = np.zeros(len(lines))

        for ind, line in enumerate(lines):
            line_list = line.replace("  ", " ").split(" ")
            times[ind] = line_list[0]
            refill_flux[ind] = line_list[3]
            cru_flux[ind] = line_list[4]

        return times, refill_flux, cru_flux

    def __getLocations(self, nryr, nlcc, cru_info_list):
        '''
        To be used only for crusInfo()

        gets x y pairs from first line of the cleft logs

        returns np 2d array of RyR and LCC locations in cleft
        '''
        loc_index = cru_info_list.index("Location")
        cru_info_list = cru_info_list[loc_index + 1:]
        ryr_loc = np.zeros([2, nryr])
        lcc_loc = np.zeros([2, nlcc])

        if ('(' in cru_info_list[0] or '(' in cru_info_list[1]):
            for ind, pair in enumerate(cru_info_list[:nryr]):
                loc = pair[1:-1].split(";")
                ryr_loc[0,ind] = float(loc[0])
                ryr_loc[1,ind] = float(loc[1])
            for ind, pair in enumerate(cru_info_list[nryr: nryr + nlcc]):
                loc = pair[1:-1].split(";")
                lcc_loc[0,ind] = float(loc[0])
                lcc_loc[1,ind] = float(loc[1])
        else:
            import warnings
            warnings.warn("""\nExtracting the Locations 'old' saving style, be AWARE they probably will cause numerical issues, since the output is not consistent.""")

            for ind, num in enumerate(cru_info_list[:nryr-1:2]):
                ryr_loc[0,ind] = float(cru_info_list[ind])
                ryr_loc[1,ind] = float(cru_info_list[ind + 1])

            for ind, num in enumerate(cru_info_list[nryr + 1: nryr + nlcc:2]):
                lcc_loc[0,ind] = float(cru_info_list[ind])
                lcc_loc[1,ind] = float(cru_info_list[ind + 1])
        return ryr_loc, lcc_loc

    def saveCleftPlot(self, mergeOutput = False, overwrite = False):
        """
        Save a plot of each cleft using the channel Locations
        """
        import os
        outputname = self.folder + "clefts/cleftall.pdf"
        if os.path.isfile(outputname) and not overwrite:
            import warnings
            warnings.warn("cleft ouput plots already exist!")
            return None

        import matplotlib.pyplot as plt
        nR, nL, radii, rloc, lloc = self.crusInfo(getRadius=True, getLocations=True)
        savepath = self.folder + "clefts/cleftplot{}.pdf"
        for i in range(self.crunumber):
            rad = radii[i]
            fig, ax = plt.subplots()
            ax.plot(rloc[i][0,], rloc[i][1,], "go", label="{} RyR".format(nR[i]))
            ax.plot(lloc[i][0,], lloc[i][1,], "bo", label="{} LCC".format(nL[i]))
            circ = plt.Circle((0,0), rad, color='k', fill=False)
            ax.add_artist(circ)
            ax.set_xlabel("x [$\mu m$]")
            ax.set_ylabel("y [$\mu m$]")
            ax.set_xlim((-1.5*rad, 1.5*rad))
            ax.set_ylim((-1.5*rad, 1.5*rad))
            ax.legend()
            fig.savefig(savepath.format(i), bbox_inches = "tight")
        if mergeOutput:
            savepath = savepath.format("*")
            print(savepath)
            os.system('pdfunite {} {}clefts/cleftall.pdf'.format(savepath, self.folder))

    def processCRUInfo(self):
        '''
        function that processes and saves Informations of all channels of a sim into a csv file

        Return:
        chInfo_df: pandas DF
        '''

        df = self.getCleftChannelInformation()

        ryrpertime = sum(df["openRyR"])/max(df["time"])
        chInfo_df = pd.DataFrame()
        chInfo_df["openRyR_per_ms"] = [ryrpertime]

        # saving information to file
        outputname = self.folder + "clefts/channelInfo.csv"
        chInfo_df.to_csv(outputname, index=False)

        return chInfo_df

    def getCleftChannelInformation(self):
        '''
        get time, open RyR, open LCC, cleft Location and total channel numbers
        from file in clefts/
        if not existing create it

        - Return:
        pandas DataFrame
        '''

        outputname = self.folder + "clefts/openChannels.csv"
        if (not os.path.exists(outputname)):
            self.saveOpenChannels()

        df = pd.read_csv(outputname, sep=" ")
        df = df.rename(index=str, columns={"Unnamed: 0": "counter0", "Unnamed: 1": "counter1"})

        return df

    def getCleftChannelInformation_fromCSV(self):
        '''
        get time, open RyR, open LCC, cleft Location and total channel numbers
        from files in linescan/
        if not existing create it

        - Return:
        pandas DataFrame
        '''

        outputname = self.folder + "linescan/openChannels_fluo4.csv"
        if (not os.path.exists(outputname)):
            self.saveOpenChannels_fromCSV()

        df = pd.read_csv(outputname, sep=" ")
        df = df.rename(index=str, columns={"Unnamed: 0": "counter0", "Unnamed: 1": "counter1"})

        return df

    def getOpenChannels(self):
        """
        same fct as getCleftChannelInformation
        renaming of fct meaningfull
        """
        return self.getCleftChannelInformation()

    def saveOpenChannels_fromCSV(self, overwrite = False):
        '''
        save time steps, number of open RyR and LCC to file in clefts/ dir

        ATTENTION: works properly only with master branch from (2019/07/09)
        '''

        print("Warning: saving open channels, this might take a while..")
        outputname = self.folder + "linescan/openChannels_fluo4.csv"
        if os.path.isfile(outputname) and not overwrite:
            import warnings
            warnings.warn("cleft ouput for open channels already exists!")
            return None

        cru_info = self.get_linescan_cru_info()
        parameters = self.getParameters()

        cru_info_clean = pd.DataFrame(data=[], index=[], columns=["time","clefts","bulkCa"])

        Fmax = float(parameters['Bspecial_tot'])
        Fmin = 0.0
        Kd = float(parameters['kspecial_minus'])/float(parameters['kspecial_plus'])

        index = 0
        for cru_id in cru_info["cru_id"].unique():
            temp = cru_info[cru_info["cru_id"] == cru_id]# .astype(float)
            #print(cru_id)
            #print(temp["time"].unique())

            for time in temp["time"].unique():
                #range(len(cru_info["time"].unique())):
                #time =  temp["time"].unique()[i]
                temp_time =  temp[ temp["time"] == time].astype(float)

                cru_info_clean.at[index,"time"] = time

                fluo4_conc = np.array(temp_time['fluo4'].astype(float)).max()

                cru_info_clean.at[index,"cyto_ca2+"] = np.array(temp_time['cyto_ca2+'].astype(float)).mean()
                cru_info_clean.at[index,"fluo4"] = np.array(temp_time['fluo4'].astype(float)).mean()

                cru_info_clean.at[index,"bulkCa"] = np.array(temp_time['cyto_ca2+'].astype(float)).mean()
                cru_info_clean.at[index,"openRyR"] = np.array(temp_time['open_ryrs'].astype(int)).max()

                cru_info_clean.at[index,"clefts"] = cru_id

                ca_exp = Kd*(fluo4_conc- Fmin)/(Fmax - fluo4_conc)
                cru_info_clean.at[index,"ca_exp"] = ca_exp

                cru_info_clean.at[index,"xcru"] = np.array(temp_time['cru_x'].astype(float))[0]
                cru_info_clean.at[index,"ycru"] = np.array(temp_time['cru_y'].astype(float))[0]
                cru_info_clean.at[index,"zcru"] = np.array(temp_time['cru_z'].astype(float))[0]

                index += 1

        print("length of cru info: %s" % len(cru_info_clean))

        outfile = open(outputname, 'a')
        cru_info_clean.to_csv(outfile, header=True, sep=" ", index=False)
        outfile.close()

    def saveOpenChannels(self, overwrite = False):
        '''
        save time steps, number of open RyR and LCC to file in clefts/ dir

        ATTENTION: works properly only with not merged cleftdyn branch (addition_CRU_debug_output)
        (2018/10/13)
        where cleft.log output has been changed (num of open channels outputted)
        '''
        print("Warning: saving open channels, this might take a while..")
        outputname = self.folder + "clefts/openChannels.csv"
        if os.path.isfile(outputname) and not overwrite:
            import warnings
            warnings.warn("cleft ouput for open channels already exists!")
            return None

        totDF = pd.DataFrame()
        for i in range(self.crunumber):
            timesteps = []
            openRyR = []
            openLCC = []
            caBulk = []
            cleftname = "cleft" + str(i)
            # get all lines from cleftlogs
            lines, totalRyR, totalLCC, cruloc = self.__getCleftLogLines(i, getCRULocation=True)
            x, y, z = cruloc[0][0], cruloc[0][1], cruloc[0][2]
            #print(lines, totalRyR, totalLCC, cruloc)
            # dirty hack: list starts from 1 since the first time step with time=0 (no dot for float) is not covered by regular expression (CHANGE THIS!)
            for line in lines[1:]:
                nums = re.findall("\d+\.\d+", line)
                timesteps.append(nums[0])
                caBulk.append(nums[1])
                nums = re.findall("\d+", line)
                openRyR.append(int(nums[-2]))
                openLCC.append(int(nums[-1]))

            # create pandas dataframe to save file to csv
            outDF = pd.DataFrame({'clefts': cleftname, 'xcru': x, 'ycru': y, 'zcru': z, 'time': timesteps, 'bulkCa': caBulk, 'openRyR': openRyR, 'openLCC': openLCC, 'totalRyR': totalRyR, 'totalLCC': totalLCC})

            del(timesteps[:], openRyR[:], openRyR[:])
            totDF = pd.concat([totDF, outDF])
        totDF["ratioRyR"] = totDF["openRyR"]/totDF["totalRyR"]
        totDF["ratioLCC"] = totDF["openLCC"]/totDF["totalLCC"]
        outfile = open(outputname, 'a')
        totDF.to_csv(outfile, header=True, sep=" ", index=False)
        outfile.close()

    def __getChannelInformations(self, which="conc", cleftnr=0):
        """
        get Ca concentrations/fluxes at channel mouth from cleft logs given the cleftnumber

        Args:
        - which: determines whether concentrations (conc) or fluxes (flux) are to be determined
        - cleftnumber

        Return:
        - numpy arrays with channel concentrations/fluxes and timesteps
        """
        lines, totR, totL = self.__getCleftLogLines(cleftnr)
        times = np.zeros([1, len(lines)])
        ryr_conflux = np.zeros([len(lines), totR])
        lcc_conflux = np.zeros([len(lines), totL])
        if which == "conc":
            first_channel_ind = 5
        elif which == "flux":
            first_channel_ind = 6
        else:
            print("======== Some error in asked information occured ======== ")
        for ind, line in enumerate(lines):
            line_list = line.replace("  ", " ").split(" ")
            times[:,ind] = line_list[0]
            line_list = line_list[first_channel_ind:]
            ryr_conflux[ind,:] = line_list[1:3*totR:3]
            line_list = line_list[3*totR:]
            lcc_conflux[ind,:] = line_list[1:3*totL:3]

        return times, ryr_conflux, lcc_conflux

    def getChannelConcentrations(self, cleftnr=0):
        """
        get Ca concentrations at channel mouth from cleft logs given the cleftnumber

        Args:
        - cleftnumber

        Return:
        - numpy arrays with channel concentrations and timesteps
        """
        times, ryr_conc, lcc_conc = self.__getChannelInformations("conc", cleftnr=cleftnr)

        return times, ryr_conc, lcc_conc

    def getChannelFluxes(self, cleftnr=0):

        """
        get Ca fluxes at channel mouth from cleft logs given the cleftnumber

        Args:
        - cleftnumber

        Return:
        - numpy arrays with channel fluxes and timesteps
        """
        times, ryr_flux, lcc_flux= self.__getChannelInformations("flux", cleftnr=cleftnr)

        return times, ryr_flux, lcc_flux

    def __getCleftLogLines(self, crunum, getCRULocation = False):
        """
        private fct returning the lines of the cleftlogs and the total number of RyR LCCs
        without the first line
        used by getChannelConcentration() and saveOpenChannels() fcts.
        """
        crufile = open(self.folder + "clefts/cleft" + str(crunum) + ".log")
        lines = [line.rstrip('\n') for line in crufile]
        crufile.close()
        firstline = lines[0].split(" ")
        totalRyR = int(firstline[0])
        totalLCC = int(firstline[2])
        locationCRU = [[float(firstline[6]), float(firstline[7]), float(firstline[8])]]
        del(lines[0])
        if getCRULocation:
            return lines, totalRyR, totalLCC, locationCRU
        else:
            return lines, totalRyR, totalLCC

    def determineValues(self):
        if ((self.values == "ionic") or (self.values == "ionicmodel") or
            (self.values == "ionicmodel.txt") or (self.values == 1) or (self.values == "ion")):
            self.values = "ionicmodel.txt"
        elif ((self.values == "mass") or (self.values == "massconversion") or
              (self.values == "massconversionlog.txt") or (self.values == 0) or
              (self.values == "massconversionlog")):
            self.values = "massconversionlog.txt"
        else:
            print("no considered/implemented value, skip")

    def get_openCRUs(self, year=2018):
        """
        Gets the number of open crus from the outputfile (year is the starting name of the file)
        also gets the according times (works with output that is in simfolder and has the date)

        Output:
        - list of time steps
        - list of open crus
        """
        out_file = self.folder + str(year) + "*"
        out_file = glob.glob(out_file)[0]
        time = []
        crus = []
        # sentence to be matched
        match = " number of open crus: "
        with open(out_file, "r") as fp:
            time_lines = [line for line in fp if match in line]
        for line in time_lines:
            nums = re.findall("\d+", line)
            # the first two ints are the time
            time.append(float(nums[0] + "." + nums[1]))
            # the third int found is the num of open crus
            crus.append(int(nums[2]))
        return time, crus

    def get_linescan_cru_info(self, start_time = -np.infty, end_time = np.infty, min_z = -np.infty, max_z = np.infty):
        '''
            extracts cru_info_rank*.csv files from linescan folder
        '''
        # find files in subfolder

        linescan_folder = self.folder + "linescan/"
        path, dirs, files = next(os.walk(linescan_folder))

        frames_cru_info = []

        for filename in files:

            if filename.find("cru_info") == -1:
                continue

            temp_cru_info = pd.read_csv(linescan_folder + filename)

            #print temp_cru_info
            #
            '''
            z-disc selection
            '''

            temp_cru_info = temp_cru_info[temp_cru_info['cru_z'] >= min_z]
            temp_cru_info = temp_cru_info[temp_cru_info['cru_z'] <= max_z]

            '''
            time selection
            '''

            temp_cru_info = temp_cru_info[temp_cru_info['time'] >= start_time]

            '''
            sort values
            '''

            temp_cru_info = temp_cru_info.sort_values(by=["time", "cru_id"])

            '''
            round values to needed precission
            '''

            temp_cru_info = temp_cru_info.round({'time': 1, 'cru_flux': 2, 'cyto_ca2+': 2, 'cyto_bm': 2, 'cyto_bs':2, 'sarco_ca': 0 , 'fluo4': 2})

            '''
            delete round postion values and delete duplicates to reduce memory cost
            '''
            temp_cru_info = temp_cru_info.drop_duplicates()

            # uncomment the following to see memory usage

            '''
            append to data frame
            '''

            frames_cru_info.append(temp_cru_info)

        cru_info_all = pd.concat(frames_cru_info)

        cru_info_all = cru_info_all.sort_values(by=["time", "cru_id"])

        return cru_info_all


# Copyright (C) 2018 GuQiangJs.
# Licensed under Apache License 2.0 <see LICENSE file>

import time

import pandas as pd

__all__ = ['get_szse_symbols']

# http://www.szse.cn/szseWeb/ShowReport.szse?SHOWTYPE=xlsx&CATALOGID=1110&tab1PAGENO=1&ENCODE=1&TABKEY=tab1  全部
# http://www.szse.cn/szseWeb/ShowReport.szse?SHOWTYPE=xlsx&CATALOGID=1110&tab1PAGENO=1&ENCODE=1&TABKEY=tab2  A股
# http://www.szse.cn/szseWeb/ShowReport.szse?SHOWTYPE=xlsx&CATALOGID=1110&tab5PAGENO=1&ENCODE=1&TABKEY=tab5  中小板
# http://www.szse.cn/szseWeb/ShowReport.szse?SHOWTYPE=xlsx&CATALOGID=1110&tab6PAGENO=1&ENCODE=1&TABKEY=tab6  创业板

_ticker_cache = None

def get_szse_symbols(kind: str = '2', retry_count=3, timeout=30, pause=None):
    """获取最新的深圳证券交易所交易的 股票 名称数据

    数据来源：http://www.szse.cn/main/marketdata/jypz/colist/

    Args:
        kind: 分类。

            * 2: A股(A股中包含所有的中小板、创业板数据)
            * 5: 中小板
            * 6: 创业板

        retry_count: 重试次数
        timeout: 超时时间
        pause:

    Returns:
        ``pandas.DataFrame``:

    Examples:
        .. code-block:: python

            >>> from finance_datareader_py.szse import get_szse_symbols

            >>> print(get_szse_symbols().tail())

                  symbol   name
            2101  300743   天地数码
            2102  300745   欣锐科技
            2103  300746   汉嘉设计
            2104  300747   锐科激光
            2105  300750   宁德时代
    """
    global _ticker_cache
    if timeout < 0:
        raise ValueError(
            'timeout must be >= 0, not {timeout}'.format(timeout=timeout))

    if pause is None:
        pause = timeout / 3
    elif pause < 0:
        raise ValueError('pause must be >= 0, not {pause}'.format(pause=pause))

    if _ticker_cache is None or kind not in _ticker_cache:
        if _ticker_cache is None:
            _ticker_cache = {}
        while retry_count > 0:
            try:
                _ticker_cache[kind] = _download_szse_symbols(kind)
                retry_count = -1
            except Exception:
                # retry on any exception
                if retry_count <= 0:
                    raise
                else:
                    retry_count -= 1
                    time.sleep(pause)

    return _ticker_cache[kind]

def _download_szse_symbols(kind: str):
    url = r'http://www.szse.cn/szseWeb/ShowReport.szse?SHOWTYPE=xlsx&CATALOGID=1110&tab{0}PAGENO=1&ENCODE=1&TABKEY=tab{0}'.format(
        kind)
    df = pd.read_excel(url, convert_float=False, dtype=object)
    df = df[['公司代码', '公司简称']]
    df.rename(columns={'公司代码': 'symbol', '公司简称': 'name'}, inplace=True)
    # df.set_index("symbol", inplace=True)
    return df


# -*- coding: utf-8 -*-
"""
Created on Thu Apr  7 12:00:30 2022

@author: solis
"""
# import littleLogging as logging
import csv

class Change_format():

    def __init__(self, org, dst, first_col, npuntos, step):
        """
        Reads some data from a csv file org and write them in another format

        Parameters
        ----------
        org : str
            csv input file
        dst : str
            csv output file
        first_col : int
            first col to read in org
        npuntos : int
            # points to read.
        step : int
            # columns for each point.

        Returns
        -------
        None.

        """
        self.org = org
        self.dst = dst
        self.step = step
        self.npuntos = npuntos
        self.first_col = first_col

    def chg_format(self, stop_at_line = -1):
        """
        Read csv file org and write data in another format (piezometric data)

        Parameters
        ----------
        stop_at_line : int
            execution stops after #line in self.org =stop_at_line
            If you want to read all the lines keep the default value
            first line is 0, not 1
            line 0 gets station codes
            line 1 gets headers
            line 2 gets first line of data

        Returns
        -------
        None.

        """
        header_col1 = 'id'
        with open(self.org) as fi, open(self.dst, mode='w', newline='') as fo:
            reader = csv.reader(fi, delimiter=";")
            writer = csv.writer(fo, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
            for nrow, row in enumerate(reader):
                print(nrow)
                c1 = self.first_col
                c2 = c1 + self.step
                if nrow == 0:
                    ids = []
                    for item in range(self.npuntos):
                        ids.append(row[0].split(',')[c1:c2][0])
                        c1 = c2
                        c2 += self.step
                elif nrow == 1:
                    writer.writerow([header_col1,] + row[0].split(',')[c1:c2])
                else:
                    for i in range(self.npuntos):
                        cells = [ids[i],] + row[0].split(',')[c1:c2]
                        if cells[1].strip() == '' or ''.join(cells[2:]) == '':
                            c1 = c2
                            c2 += self.step
                            continue
                        tdate1 = cells[1].split('/')
                        cells[1] = f'{tdate1[1]}/{tdate1[0]}/{tdate1[2]}'
                        writer.writerow(cells)
                        # print(ids[i], row[c1:c2])
                        c1 = c2
                        c2 += self.step
                    if nrow == stop_at_line:
                         break


# -*- coding: utf-8 -*-
"""
Created on Wed Aug 25 09:28:40 2021

@author:
    Aaron Fox
    Centre for Sport Research
    Deakin University
    aaron.f@deakin.edu.au

    Quick script to combine the season win-loss and coach datasets together

"""

# %% Import packages

import pandas as pd

# %% Combine datasets

#Import season win-loss
winLoss = pd.read_csv('seasonWinLossSummaries.csv')

#Import coach dataset
coachData = pd.read_csv('coachSummaries.csv')

#Import premiership dataset
premiershipData = pd.read_csv('premiershipSummaries.csv')

#Loop through season data and identify coach and premiership status
coachList = []
minorPremierList = []
runnerUpList = []
premierList = []
competitionList = []
for ii in range(len(winLoss)):

    #Get current team and year
    team = winLoss['team'][ii]
    year = winLoss['year'][ii]

    #Get coach from dataset
    coach = coachData.loc[(coachData['team'] == team) &
                          (coachData['year'] == year),['coach']].reset_index(
                              drop = True)['coach'][0]

    #Append to list
    coachList.append(coach)

    #Get premiership/runner-up status
    #Premiers
    if premiershipData.loc[premiershipData['year'] == year,['premiers']].reset_index(
            drop = True)['premiers'][0] == team:
        premierList.append('Yes')
    else:
        premierList.append('No')
    #Minor premiers
    if premiershipData.loc[premiershipData['year'] == year,['minorPremiers']].reset_index(
            drop = True)['minorPremiers'][0] == team:
        minorPremierList.append('Yes')
    else:
        minorPremierList.append('No')
    #Runner Up
    if premiershipData.loc[premiershipData['year'] == year,['runnerUp']].reset_index(
            drop = True)['runnerUp'][0] == team:
        runnerUpList.append('Yes')
    else:
        runnerUpList.append('No')

    #Set competition
    competitionList.append(premiershipData.loc[premiershipData['year'] == year, ['competition']].reset_index(
        drop = True)['competition'][0])

#Add new variables to win loss dataframe
winLoss['coach'] = coachList
winLoss['minorPremiership'] = minorPremierList
winLoss['premiership'] = premierList
winLoss['runnerUp'] = runnerUpList
winLoss['competition'] = competitionList

#Save dataset
winLoss.to_csv('resultsFromTheTimeMachine.csv', index = False)

# %% ----- End of combineDatasets.py -----


#!/usr/bin/env python
import pickle
import ursgal
import sys
import re
import os
from collections import defaultdict as ddict
from urllib.parse import unquote
import pprint
import re
import json

regexs_for_non_standard_mgfs = {
    "cz": re.compile(
        r"""
        msmsid:F(?P<spec_id>[0-9]*),
        quan:(?P<quant>[0-9]*),
        start:(?P<rt_start_in_seconds>\d*\.\d+|\d+),
        end:(?P<rt_end_in_seconds>\d*\.\d+|\d+),
        survey:S(?P<survey>[0-9]*),
        parent:(?P<precursor_mz>\d*\.\d+|\d+),
    """,
        re.VERBOSE,
    )
}

def add_mascot_to_ursgal_history(file):
    """Add Mascot to history.

    Args:
        mapped_csv_search_results (str): Path to mapped search results.
    """
    mapped_json = "{0}.u.json".format(file)
    iinfo, oinfo, params, history = json.load(open(mapped_json))
    mascot_missing = True
    for entry in history["history"]:
        engine_type = entry["META_INFO"].get("engine_type", {})
        is_search_engine = engine_type.get("protein_database_search_engine", False)
        if is_search_engine and "mascot" in entry["engine"]:
            mascot_missing = False

    if mascot_missing:
        history["history"].insert(
            0,
            {
                "META_INFO": {
                    "engine_type": {
                        "protein_database_search_engine": True,
                        "by Hand": True,
                    }
                },
                "engine": "mascot_x_x_x",
            },
        )
        with open(mapped_json, "w") as d:
            json.dump([iinfo, oinfo, params, history], d)

def write_ursgal_pkl_from_mascot_dat(mascot_data_file):
    """
    Write ursgal pickle from mascot dat files

    Args:
        mascot_data_file (str): Path to mascot dat file for pickle generation.

    Returns:
        str: Path to the generated pickle file.
    """
    # rt_regex = re.compile(r'^.*rt\:(?P<rt>\d+\.\d+),.*')

    pattern = re.compile(
        r'Content-Type: application/x-Mascot; name="(?P<section>[a-z0-9]*)"'
    )

    mascot_dat_base = os.path.basename(mascot_data_file)
    pkl_path = os.path.join(os.path.dirname(mascot_data_file), f"_ursgal_lookup.pkl")

    sections = ddict(list)
    current_section = None
    with open(mascot_data_file) as mascot_file:
        for line in mascot_file:
            if line.strip() == "":
                continue
            match = pattern.match(line)
            if match is not None:
                current_section = match.group("section")
            else:
                sections[current_section].append(line.strip())

    for f in sections["parameters"]:
        if f.startswith("FILE"):
            full_fname = f.split("=")[1]

            fname = os.path.splitext(os.path.basename(full_fname))[0]
            break
    dat_basename, ext = os.path.splitext(mascot_dat_base)

    if os.path.exists(pkl_path):
        t = pickle.load(open(pkl_path, "rb"))
    else:
        t = {}
    if fname not in t:
        t.update(
            {
                fname: {
                    "rt_2_scan": {},
                    "scan_2_rt": {},
                    "unit": "seconds",
                    "scan_2_mz": {},
                }
            }
        )

    query_dict = {}
    for entry in sections:
        if entry is not None:
            if entry.startswith("query"):
                for key in sections[entry]:
                    if "=" in key:
                        k, v = key.split("=")
                        query_dict[k] = v
                title = query_dict["title"]
                try:
                    path, spec_id, spec_id, charge = title.split(".")
                except:
                    path = os.path.basename(fname)
                    unqstring = unquote(title)
                    charge = int(query_dict["charge"].replace("+", ""))
                    for _id, pattern in regexs_for_non_standard_mgfs.items():
                        m = pattern.match(unqstring)
                        if m is not None:
                            spec_id = int(m.group("spec_id"))

                            query_dict["rtinseconds"] = float(
                                m.group("rt_start_in_seconds")
                            )
                            query_dict["precursor_mz"] = m.group("precursor_mz")
                            break

                rt = query_dict["rtinseconds"]
                t[fname]["rt_2_scan"][float(rt)] = int(spec_id)
                t[fname]["scan_2_rt"][int(spec_id)] = float(rt)
                t[fname]["scan_2_mz"][int(spec_id)] = float(query_dict["precursor_mz"])
    with open(pkl_path, "wb") as pkl:
        pickle.dump(t, pkl)
    return pkl_path

def main(input_file, database):
    """
    Usage:

    ./unify_mascot_dat.py <mascot dat file> <database>

    Note:
        Modifications are hard coded so please adjust accordingly
    """
    uc = ursgal.UController()
    uc.params["database"] = database
    uc.params["modifications"] = [
        "C,fix,any,Carbamidomethyl",
        "*,opt,Prot-N-term,Acetyl",
        "M,opt,any,Oxidation",
        "*,opt,N-term,TMT6plex",
        "K,fix,any,TMT6plex",
    ]
    uc.params["csv_filter_rules"] = [
        ["Sequence", "contains_not", "X"],
        # ['PEP', 'lte', 0.01],
    ]
    uc.params["decoy_tag"] = "###REV###"
    uc.scan_rt_lookup_path = write_ursgal_pkl_from_mascot_dat(input_file)
    converted_unfiltered = uc.execute_unode(input_file, engine="mascot_dat2csv")
    converted = uc.execute_misc_engine(
        input_file=converted_unfiltered, engine="filter_csv"
    )
    mapped = uc.map_peptides_to_fasta(converted)
    add_mascot_to_ursgal_history(mapped)
    unified = uc.unify_csv(mapped)
    print(unified)

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print(main.__doc__)
    else:
        main(sys.argv[1], sys.argv[2])


from pyatlan.cache.custom_metadata_cache import CustomMetadataCache
from pyatlan.cache.enum_cache import EnumCache
from pyatlan.client.atlan import AtlanClient
from pyatlan.error import NotFoundError
from pyatlan.model.assets import Badge
from pyatlan.model.enums import (
    AtlanCustomAttributePrimitiveType,
    BadgeComparisonOperator,
    BadgeConditionColor,
)
from pyatlan.model.structs import BadgeCondition
from pyatlan.model.typedef import AttributeDef, CustomMetadataDef, EnumDef
from pyatlan.utils import get_logger

ENUM_NAME = "QDRating"
CUSTOM_METADATA_NAME = "Quality Data"

client = AtlanClient()
logger = get_logger(level="INFO")

def create_custom_metadata_options():
    """
    Create custom metadata options (enumeration), if it does not yet exist.
    """
    if EnumCache.get_by_name(ENUM_NAME):
        logger.info(f"{ENUM_NAME} enumeration has already been created.")
        return

    enum_def = EnumDef.create(name=ENUM_NAME, values=["Poor", "OK", "Great"])
    response = client.create_typedef(enum_def)
    assert response  # noqa: S101
    logger.info(f"{ENUM_NAME} enumeration created.")

def create_custom_metadata_structure():
    """
    Create a logo-branded custom metadata structure, if it does not yet exist.
    """
    try:
        CustomMetadataCache.get_id_for_name(CUSTOM_METADATA_NAME)
        logger.info(
            f"{CUSTOM_METADATA_NAME} custom metadata structure has "
            f"already been created."
        )
    except NotFoundError:
        cm_def = CustomMetadataDef.create(display_name=CUSTOM_METADATA_NAME)
        cm_def.attribute_defs = [
            AttributeDef.create(
                display_name="Rating",
                attribute_type=AtlanCustomAttributePrimitiveType.OPTIONS,
                options_name=ENUM_NAME,
            ),
            AttributeDef.create(
                display_name="Passed count",
                attribute_type=AtlanCustomAttributePrimitiveType.INTEGER,
            ),
            AttributeDef.create(
                display_name="Failed count",
                attribute_type=AtlanCustomAttributePrimitiveType.INTEGER,
            ),
            AttributeDef.create(
                display_name="Detailed reports",
                attribute_type=AtlanCustomAttributePrimitiveType.URL,
                multi_valued=True,
            ),
        ]
        cm_def.options = CustomMetadataDef.Options.with_logo_from_url(
            url="http://assets.atlan.com/assets/atlan-a-logo-blue-background.png"
        )
        result = client.create_typedef(cm_def)
        assert result  # noqa: S101
        logger.info(f"{CUSTOM_METADATA_NAME} custom metadata structure created.")

def create_badge():
    """
    Create a badge for the enumerated values of the "Rating" attribute in the
    custom metadata structure.
    """
    badge = Badge.create(
        name="Rating",
        cm_name=CUSTOM_METADATA_NAME,
        cm_attribute="Rating",
        badge_conditions=[
            BadgeCondition.create(
                badge_condition_operator=BadgeComparisonOperator.EQ,
                badge_condition_value='"Great"',
                badge_condition_colorhex=BadgeConditionColor.GREEN,
            ),
            BadgeCondition.create(
                badge_condition_operator=BadgeComparisonOperator.EQ,
                badge_condition_value='"OK"',
                badge_condition_colorhex=BadgeConditionColor.YELLOW,
            ),
            BadgeCondition.create(
                badge_condition_operator=BadgeComparisonOperator.EQ,
                badge_condition_value='"Poor"',
                badge_condition_colorhex=BadgeConditionColor.RED,
            ),
        ],
    )
    badge.user_description = "Overall quality rating for the asset."
    response = client.upsert(badge)
    assert response.assets_created(asset_type=Badge)  # noqa: S101
    logger.info(f"Badge for {CUSTOM_METADATA_NAME}:Rating created / updated.")

def main():
    create_custom_metadata_options()
    create_custom_metadata_structure()
    create_badge()

if __name__ == "__main__":
    main()


import unittest
from capstone import *
from capstone.arm64 import *

class ARM64BRAARegAccessTest(unittest.TestCase):

    # These instructions should all have all their register operands being READ.
    # https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/BRAA--BRAAZ--BRAB--BRABZ--Branch-to-Register--with-pointer-authentication-
    PATTERNS = [
        ("5F 08 1F D6", "braaz x2"),
        ("11 0A 1F D7", "braa x16, x17"),
        ("1F 0C 1F D6", "brabz x0"),
        ("11 0E 1F D7", "brab x16, x17"),
        ]

    def setUp(self):
        self.insts = []
        self.cs = Cs(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN)
        self.cs.detail = True

        for pattern, asm in self.PATTERNS:
            # Disassemble the instruction. Any error here means Capstone doesn't handle the instruction (maybe the wrong branch)
            inst = next(self.cs.disasm(bytes.fromhex(pattern), 0))

            expected_regs_read = list(map(lambda r: r.strip(', '), asm.split()[1:]))
            expected_regs_written = [] # nothing written
            expected_regs = [expected_regs_read, expected_regs_written]

            self.insts.append((inst, asm, expected_regs))

    def test_regs_access(self):
        """Check that the `regs_access` API provides correct data"""

        for inst, asm, expected_regs in self.insts:

            # Check that the instruction writes the first register operand and reads the second
            for i, decoded_regs in enumerate(map(lambda l: list(map(self.cs.reg_name, l)), inst.regs_access())):
                self.assertEqual(decoded_regs, expected_regs[i], "%s has %r %s registers instead of %r" % (asm, decoded_regs, ["read", "written"][i], expected_regs[i]))

    def test_operands(self):
        """Check that the `operands` API provides correct data"""
        for inst, asm, expected_regs in self.insts:
            ops = inst.operands

            expected_regs_read, expected_regs_written = expected_regs
            self.assertEqual(len(expected_regs_written), 0)
            #print("Ensuring %s has the following read registers: %r" % (asm, expected_regs_read))
            self.assertEqual(len(ops), len(expected_regs_read))

            for i, op in enumerate(ops):
                self.assertEqual(op.type, CS_OP_REG, "%s has operand %d with invalid type" % (asm, i))
                self.assertEqual(op.access, CS_AC_READ, "%s has operand %d with invalid access" % (asm, i))

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


import json
from flask import Flask, render_template, request
app = Flask(__name__)

with open('data/movie5000.json') as f:
    mv = json.load(f)
with open('data/movie50000.json') as f:
    mv2 = json.load(f)

actors_movies = {}
movies_actors = {}
movies = {}
genres = {}
year = {}

def preprocess(data, actors_movies, movies_actors):
    for k, v in data.items():
        if k not in actors_movies.keys():
            actors_movies[k] = []
        for item in v:
            # actors_movies
            if item['title'] not in actors_movies[k]:
                actors_movies[k].append(item['title'])

            # movies_actors
            if item['title'] not in movies_actors.keys():
                movies_actors[item['title']] = [k]
            elif item['title'] in movies_actors[item['title']]:
                continue
            else:
                movies_actors[item['title']].append(k)

            # genres
            for genre in item['genres']:
                if genre not in genres.keys():
                    genres[genre] = [item['title']]
                else:
                    genres[genre].append(item['title'])
            # year
            if item['release_date'][:4] not in year.keys():
                year[item['release_date'][:4]] = [item['title']]
            else:
                year[item['release_date'][:4]].append(item['title'])
            # movies
            if item['title'] not in movies.keys():
                movies[item['title']] = {'vote_count': item['vote_count'], 'vote_avg': item['vote_avg'],
                                         'release_date': item['release_date'], 'poster_path': item['poster_path'],
                                         'genres': item['genres'], 'characters': [k]}
            else:
                if k not in movies[item['title']]['characters']:
                    movies[item['title']]['characters'].append(k)

preprocess(mv, actors_movies, movies_actors)
preprocess(mv2, actors_movies, movies_actors)
del year['2030']
del year['2028']
del year['2026']
del year['2024']
del year['2023']
del year['2022']

class Vertex:
    def __init__(self, key):
        self.id = key
        self.connectedTo = {}  # empty dictionary

    def addNeighbor(self, nbr, weight=0):
        self.connectedTo[nbr] = weight

    def getId(self):
        return self.id

    def getConnection(self):
        return self.connectedTo.keys()

class Graph:
    def __init__(self):
        self.verList = {}
        self.numVertices = 0

    def addVertex(self, key):
        self.numVertices += 1
        newVertex = Vertex(key)
        self.verList[key] = newVertex
        return newVertex

    def addEdge(self, f, t, weight=0):
        if f not in self.verList:
            nv = self.addVertex(f)
        if t not in self.verList:
            nv = self.addVertex(t)
        self.verList[f].addNeighbor(self.verList[t], weight)

def Backtrace(dic, start, end):
    res = [end]
    while 1:
        if start == end:
            break
        for k, v in dic.items():
            for i in v:
                if i == end:
                    res.append(k)
                    end = k
                    break
    return res

graph = Graph()
for actor in actors_movies.keys():
    graph.addVertex("A-"+actor)
for movie in movies_actors.keys():
    graph.addVertex("M-"+movie)

for k, v in movies_actors.items():
    for item in v:
        graph.addEdge("M-"+k, "A-"+item, 1)
        graph.addEdge("A-"+item,"M-"+k,1)

@app.route('/')
def KBGame():
    return render_template('game.jinja')

@app.route('/game/result', methods=['POST'])
def KBGame_result():
    backtrace={}
    def BFS(s, goal):
        s="A-"+s
        goal = "A-"+goal
        start = s
        visited = {}
        for key in graph.verList.keys():
            visited[key] = False
        queue = []
        queue.append(s)
        visited[s] = True

        while queue:
            s = queue.pop(0)
            for i in graph.verList[s].getConnection():
                if visited[i.getId()] == False:
                    if s not in backtrace.keys():
                        backtrace[s] = [i.getId()]
                    else:
                        backtrace[s].append(i.getId())
                    queue.append(i.getId())
                    visited[i.getId()] = True
                if i == graph.verList[goal]:
                    return Backtrace(backtrace, start, goal)
    actor1 = request.form['actor1']
    actor2 = request.form['actor2']
    noactor1 = ""
    noactor2 =""
    if "A-"+actor1 not in graph.verList:
        noactor1 = 'There is no result for ' + actor1
    if "A-"+actor2 not in graph.verList:
        noactor2 = 'There is no result for ' + actor2
    if len(noactor1)!=0 or len(noactor2)!=0:
        return render_template('game-result.jinja', noactor1=noactor1, noactor2=noactor2)

    result = BFS(actor2, actor1)

    return render_template('game-result.jinja', actor1=actor1, actor2=actor2, result=result)

@app.route('/popular')
def popular():
    return render_template('popular.jinja',)

@app.route('/popular/result', methods=['POST'])
def popular_res():
    def BFS_all(s):
        s="A-"+s
        if s not in graph.verList.keys():
            return []
        visited = {}
        for key in graph.verList.keys():
            visited[key] = False
        queue = []

        queue.append(s)
        visited[s] = True

        result={}
        inner = []
        count = 0.5
        while queue:
            s = queue.pop(0)

            for i in graph.verList[s].getConnection():

                if visited[i.getId()] == False:

                    inner.append(i.getId())
                    visited[i.getId()] = True

            if len(queue) == 0:
                result[count]=inner
                count+=0.5
                queue+=inner
                inner = []
            if count == 7.5:
                break
        return result

    actor = request.form['actor']
    all_degree = BFS_all(actor)
    if len(all_degree)==0:
        r = "No Search. Please enter again."
        return render_template('popular-result.jinja', nosearch=r)
    star = len(actors_movies[actor])

    score = []
    for i in range(1, 8):
        try:
            if all_degree[i]:
                score.append(len(all_degree[i]))
        except:
            score.append(0)

    if len(score)==5:
        score.append(0)
    if len(score)==6:
        score.append(0)

    popular_score = (1*score[0]+2*score[1]+3*score[2]+4*score[3]+5*score[4]+6*score[5] +
                     7*score[6])/(score[0]+score[1]+score[2]+score[3]+score[4]+score[5]+score[6])

    return render_template('popular-result.jinja', actor=actor, popular=round(popular_score,2), score=score, star=star)

@app.route('/recommend')
def recommend_page():
    all_genre = list(genres.keys())

    all_year = list(sorted(year.keys()))
    all_year.reverse()

    return render_template('recommend.jinja',all_genre=all_genre, all_year = all_year)

@app.route('/recommend/result', methods=['POST'])
def recommend_res():
    def Diff(li1, li2):
        return list(set(li1) - set(li2)) + list(set(li2) - set(li1))
    def listToString(s):
        str1 = " "
        separator = ', '
        return (separator.join(s))
    actor=request.form['actor']
    genre = request.form['genre']
    from_year = request.form['from_year']
    to_year = request.form['to_year']

    def recommend(genre, actor=None, from_year=None, to_year=None):
        movie = []
        delete = []
        if genre == 'Science':
            genre = 'Science Fiction'
        if genre == 'TV':
            genre=='TV Movie'
        movie = genres[genre]
        for m in movie:
            if actor:
                if actor not in movies_actors[m]:
                    delete.append(m)
            if from_year:
                if movies[m]['release_date'][:4] < from_year:
                    delete.append(m)
            if to_year:
                if movies[m]['release_date'][:4] >to_year:
                    delete.append(m)
            if movies[m]['vote_count']<1000:
                delete.append(m)
        result = Diff(movie, delete)
        sorting = {}
        for res in result:
            sorting[res] = movies[res]['vote_avg']
        sorting = dict(sorted(sorting.items(), key=lambda item: item[1], reverse=True))
        top20 = {}
        count=1
        for item in list(sorting.keys()):
            if item not in top20.keys():
                top20[item]=movies[item]

            count+=1
            if count==20:break

        return top20

    result= recommend(genre, actor=actor,from_year=from_year, to_year=to_year)

    title=[]
    for k in result.keys():
        title.append(k)
    vote_count = []
    vote_avg =[]
    year_list = []
    photo=[]
    genres_list=[]
    for item in result.values():
        vote_count.append(item['vote_count'])
        vote_avg.append(item['vote_avg'])
        year_list.append(item['release_date'][:4])
        photo.append(item['poster_path'])
        genres_list.append(item['genres'])
    r = []
    for i in range(len(title)):
        r.append([title[i],year_list[i],vote_count[i],vote_avg[i],genres_list[i],\
          'https://image.tmdb.org/t/p/w500/'+photo[i]])
    if len(r) == 0:
        r = "No Search. Please enter again."
        return render_template('recommend-result.jinja', nosearch = r)

    return render_template('recommend-result.jinja', result = r)

@app.route('/contact')
def contact():
    return render_template('contact.html')

if __name__ == '__main__':
    app.run(debug=True)


import sys
sys.setrecursionlimit(9**9)
input=sys.stdin.readline
p,n=map(int,input().split())
*l,=map(int,input().split())
tree=4*p*[0]
def build(s,e,i):
    if s==e:
        tree[i]=l[s]
        return tree[i]
    m=(s+e)//2
    tree[i]=build(s,m,2*i)+build(m+1,e,2*i+1)
    return tree[i]
build(0,len(l)-1,1)
def get_sum(s,e,i,f,t):
    if e<f or t<s:
        return 0
    if f<=s and e<=t:
        return tree[i]
    m=(s+e)//2
    return get_sum(s,m,2*i,f,t)+get_sum(m+1,e,2*i+1,f,t)
def update(s,e,i,w,v):
    if w<s or w>e:
        return
    tree[i]+=v
    if s-e:
        m=(s+e)//2
        update(s,m,2*i,w,v)
        update(m+1,e,2*i+1,w,v)

while n:
    p,q,r,s=map(int,input().split())
    print(get_sum(0,len(l)-1,1,min(p,q)-1,max(p,q)-1))
    update(0,len(l)-1,1,r-1,s-l[r-1])
    l[r-1]=s
    n-=1


# pip install paho-mqtt
# https://test.mosquitto.org/ssl/mosquitto.org.crt

import os, sys, time, ssl
from os.path import join
from datetime import datetime
import paho.mqtt.publish as publish
import paho.mqtt.client as mqtt

DIR  = os.path.dirname(os.path.realpath(__file__))
HOST = "test.mosquitto.org"
PORT = 8883

TLS = {
    'ca_certs' : join(DIR, "mosquitto.org.crt"),
    'tls_version' : ssl.PROTOCOL_TLSv1_2
}

print ("---BEGIN---")
publish.single( 'wizio',
    payload = "Hello world:" + str(datetime.now()),
    hostname = HOST, port = PORT,
    protocol  = mqtt.MQTTv311,
    client_id = "CLIENT_ID_" + str( time.time() ),
    tls = TLS
)
print ("----END----")


#

import pybullet as p
import time

p.connect(p.GUI)

p.setAdditionalSearchPath("../URDF_model")

p.createCollisionShape(p.GEOM_PLANE)
p.createMultiBody(0, 0)

# sphereRadius = 0.05
# colSphereId = p.createCollisionShape(p.GEOM_SPHERE, radius=sphereRadius)
# colBoxId = p.createCollisionShape(p.GEOM_BOX,
#                                   halfExtents=[sphereRadius, sphereRadius, sphereRadius])

# mass = 1
# visualShapeId = -1

cubeStartPos = [0,0,1]
cubeStartOrientation = p.getQuaternionFromEuler([0,0,0])
boxId = p.loadURDF("single_body.urdf",cubeStartPos, cubeStartOrientation)

# link_Masses = [1]
# linkCollisionShapeIndices = [colBoxId]
# linkVisualShapeIndices = [-1]
# linkPositions = [[0, 0, 0.11]]
# linkOrientations = [[0, 0, 0, 1]]
# linkInertialFramePositions = [[0, 0, 0]]
# linkInertialFrameOrientations = [[0, 0, 0, 1]]
# indices = [0]
# jointTypes = [p.JOINT_REVOLUTE]
# axis = [[0, 0, 1]]

# basePosition = [0,0,0.5]
# baseOrientation = [0, 0, 0, 1]

# sphereUid = p.createMultiBody(mass, colSphereId, visualShapeId, basePosition,
#                                       baseOrientation)
# p.changeDynamics(sphereUid,
#                        -1,
#                        spinningFriction=0.001,
#                        rollingFriction=0.001,
#                        linearDamping=0.0)

p.setGravity(0, 0, -10)
p.setRealTimeSimulation(1)

# p.getNumJoints(sphereUid)
# for i in range(p.getNumJoints(sphereUid)):
#   p.getJointInfo(sphereUid, i)

for i in range (10000):
    p.stepSimulation()
    time.sleep(1./240.)
# cubePos, cubeOrn = p.getBasePositionAndOrientation(boxId)
# print(cubePos,cubeOrn)
p.disconnect()


import pytest
import sqlite3

from ..src import initialization
from ..src import db as data

from .test_database.fixtures import TEST_DB_CONN_STRING, drop_it_all_sql

@pytest.fixture
def test_db_teardown():
    """
    A fixture to tear down the test database which must necessarily
    be created in order to test the cold start functionality.
    """
    # No set up; yield immediately to the test
    yield

    # Spin up a connection and execute the drop_it_all
    # script from the test_database package on the
    # designated test database file.
    conn = sqlite3.connect(TEST_DB_CONN_STRING)
    cursor = conn.cursor()
    cursor.executescript(drop_it_all_sql)
    conn.commit()
    conn.close()

class TestInitialization:
    def test_cold_start(self, test_db_teardown):
        # Run the cold start script
        initialization.execute_cold_start(TEST_DB_CONN_STRING)

        # Get a connection to the provided test DB
        conn = sqlite3.connect(TEST_DB_CONN_STRING)

        # Assure each of the tables exists and is non-empty
        assert data.wars.select_latest_war(conn) is not None

        assert len(data.maps.select_latest_maps(conn)) > 0
        maps: initialization.Map = data.maps.select_latest_maps(conn)[0]

        assert len(data.labels.select_latest_labels_for_map(maps[0], conn)) > 0
        assert len(data.icons.get_latest_icons_for_map(maps[0], conn)) > 0


#!/usr/bin/env python
import os, inspect, os.path as path, shutil
import distutils.dir_util as dirutil

Import('build')

env = build.env.Clone();
env.Append(CPPDEFINES = ('TITANIUM_GROWL_API_EXPORT', 1))
env.Append(CPPPATH = ['#kroll'])

build.add_thirdparty(env, 'poco')
sources = Glob('*.cpp')

if build.is_osx():
	cwd = build.cwd()
	env.Append(FRAMEWORKPATH = [cwd + '/Resources/osx'])
	env.Append(CPPPATH = [cwd + '/Resources/osx/Growl.framework/Headers'])
	env.Append(FRAMEWORKS = ['Cocoa', 'Growl'])
	env.Append(LIBS = ['kroll','dl'])
	sources += Glob(build.os + '/*.mm')
	sources += Glob('%s/*.cpp' % build.os)

elif build.is_win32():
	env.Append(LIBS = ['user32', 'shell32', 'advapi32'])
	sources += Glob('%s/*.cpp' % build.os)

elif build.is_linux():
	sources += Glob('libnotify/*.cpp')
	env.ParseConfig('pkg-config --cflags --libs libnotify')

m = build.add_module('ti.Growl', env=env)
t = env.SharedLibrary(target = m.build_dir + '/tigrowlmodule', source=sources)
build.mark_build_target(t)


"""
Linked List Cycle II
"""

# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def getCycleStart(self, head: ListNode) -> ListNode:
        fast, slow = head, head

        while fast is not None and fast.next is not None:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                return slow

        return None

    def detectCycle(self, head: ListNode) -> ListNode:
        if head is None or head.next is None:
            return None
        cycle_start = self.getCycleStart(head)

        if cycle_start is None:
            return None

        while head != cycle_start:
            head = head.next
            cycle_start = cycle_start.next

        return head


from page_scripts import helpers, food_page
from pages import PAGES_TO_SCRAPE
from wikipedia import wiki_http as http
import models
import pages

# logic to scrape a page with a table of foods
def scrape():
    categories = []
    for category in PAGES_TO_SCRAPE.get('table_categories'):

        page_url = f'{pages.WIKI_BASE}{category[1]}'

        categories.append(models.WikiCategory(
            category[0],
            helpers.scape_description(page_url),
            page_url,
            [],
            scrape_page(page_url, category[2])
        ))

    return categories

def scrape_page(page_url, column):
    ''' scrapes pages with the structure:
        1) h2 = name
        2) p = description
        3) table = list
    '''
    soup = http.request(page_url)

    # each table is a category
    tables = soup.select(':not(.navbox) > table')
    return [models.WikiCategory(
        category_name(table),
        category_description(table),
        page_url,
        category_foods(table, column)
    ) for table in tables]

def category_name(table):
    # scrapes the preceeding H2 text as the category name
    helpers.remove_superscripts(table)

    for sibling in table.previous_siblings:
        if sibling.name == 'h2':
            return helpers.scrub_string(sibling.text)

def category_foods(table, column=1):
    # gets the food names and links to dedicated pages,
    # ultimately scraping the description

    foods = []
    for anchor in [row.select_one(f'td:nth-child({column}) a') for row in table.select('tbody tr')]:
        if anchor and 'redlink=1' not in anchor["href"]:
            foods.append(food_page.create_food_from_anchor(anchor))

    return foods

def category_description(table):
    # scrapes the preceeding paragraph as a description of the category
    helpers.remove_superscripts(table)

    for sibling in table.previous_siblings:
        if sibling.name == 'p':
            return helpers.scrub_string(sibling.text)


from django.http import Http404, HttpResponse
from django.core import serializers
from django.views.decorators.csrf import csrf_exempt
from news.models import News
from .models import likes, dislikes, comment as commentTable
import json
from users.models import userExtraField

def add_like(request):
    if request.user.is_authenticated:

        news_id = request.GET.get('articale_id')
        news_is = News.objects.get(id = news_id)
        try:
            like_obj = likes.objects.get(for_news = news_is)
        except likes.DoesNotExist:
            like_obj = likes(for_news=news_is)
            like_obj.save()

        like_obj.like_by.add(request.user)
        like_obj.save()
        data = {
            'total' : like_obj.like_by.all().exclude(id = news_is.created_by.id).count()
        }
        return HttpResponse(json.dumps(data))

    else:
        raise Http404()

def remove_like(request):
    if request.user.is_authenticated:

        news_id = request.GET.get('articale_id')
        news_is = News.objects.get(id = news_id)
        like_obj = likes.objects.get(for_news = news_is)
        like_obj.like_by.remove(request.user)
        like_obj.save()
        data = {
            'total' : like_obj.like_by.all().exclude(id = news_is.created_by.id).count()
        }
        return HttpResponse(json.dumps(data))

    else:
        raise Http404()

def add_dislike(request):
    if request.user.is_authenticated:

        news_id = request.GET.get('articale_id')
        news_is = News.objects.get(id = news_id)
        try:
            dislike_obj = dislikes.objects.get(for_news = news_is)
        except dislikes.DoesNotExist:
            dislike_obj = dislikes(for_news=news_is)
            dislike_obj.save()

        dislike_obj.dislike_by.add(request.user)
        dislike_obj.save()
        data = {
            'total' : dislike_obj.dislike_by.all().exclude(id = news_is.created_by.id).count()
        }
        return HttpResponse(json.dumps(data))

    else:
        raise Http404()

def remove_dislike(request):
    if request.user.is_authenticated:

        news_id = request.GET.get('articale_id')
        news_is = News.objects.get(id = news_id)
        like_obj = dislikes.objects.get(for_news = news_is)
        like_obj.dislike_by.remove(request.user)
        like_obj.save()
        data = {
            'total' : like_obj.dislike_by.all().exclude(id = news_is.created_by.id).count()
        }
        return HttpResponse(json.dumps(data))

    else:
        raise Http404()

@csrf_exempt
def add_comment(request):
    if request.user.is_authenticated:
        if request.method == 'POST':
            article = request.POST['articale_id']
            message = request.POST['message']
            news = News.objects.get(id=article)
            extra= userExtraField.objects.get(user=request.user)
            comments = commentTable(comment_for = news, commented_by=request.user, message=message)
            comments.save()
            data = {'data': serializers.serialize('json', [comments, ])}
            if extra.profile_pic:
                data['profile_pic'] = extra.profile_pic.url
            else:
                data['profile_pic'] = '/static/icon/default-avatar.png'
            return HttpResponse(json.dumps(data))

    raise Http404()

def get_comment(request):
    news_id = request.GET.get('article_id')
    news_is = News.objects.get(id=news_id)
    main_comment = commentTable.objects.filter(comment_for=news_is, parent=None).order_by('-created_at')
    child_comment = commentTable.objects.filter(comment_for=news_is).exclude(parent=None).order_by('-created_at')
    main_comments = []
    child_comments = []
    for comment in main_comment:
        extra = userExtraField.objects.get(user=comment.commented_by)
        obj = {
            'username': comment.commented_by.username,
            'message': comment.message,
            'parent': comment.parent,
            'pk': comment.id,
            # 'created_at': comment.created_at
        }
        if extra.profile_pic:
            obj['profile_pic'] = extra.profile_pic.url
        else:
            obj['profile_pic'] = '/static/icon/default-avatar.png'

        main_comments.append(obj)

    for comment in child_comment:
        extra = userExtraField.objects.get(user=comment.commented_by)
        obj = {
            'username': comment.commented_by.username,
            'message': comment.message,
            'parent': comment.parent.id,
            'pk': comment.id,
            # 'created_at': comment.created_at
        }
        if extra.profile_pic:
            obj['profile_pic'] = extra.profile_pic.url
        else:
            obj['profile_pic'] = '/static/icon/default-avatar.png'

        child_comments.append(obj)
    data = {
        'main_comment': main_comments,
        'child_comment': child_comments
    }
    return HttpResponse(json.dumps(data))

@csrf_exempt
def add_reply(request):
    if request.user.is_authenticated:
        if request.method == 'POST':
            news_is = News.objects.get(id = request.POST['articale_id'])
            messages = request.POST['message']
            parent_comment = commentTable.objects.get(id=request.POST['parent'])
            comments = commentTable(comment_for=news_is, commented_by=request.user, message=messages, parent=parent_comment)
            comments.save()
            data = serializers.serialize('json', [comments, ])
            return HttpResponse(json.dumps(data))

    raise Http404()

@csrf_exempt
def edit_reply(request):
    if request.method == 'POST':
        comments = commentTable.objects.get(id = request.POST['comment_id'])
        messages = request.POST['message']
        comments.message = messages
        comments.save()
        data = serializers.serialize('json', [comments, ])
        return HttpResponse(json.dumps(data))

@csrf_exempt
def delete_reply(request, id):
    if request.user.is_authenticated:
        try:
            comments = commentTable.objects.get(id = id)
            comments.delete()
            return HttpResponse('done')
        except commentTable.DoesNotExist:
            raise Http404
    else:
        return HttpResponse('Unauthorized', status=401)


def find_simple_del(n):
    numbers = list(range(2, n + 1))
    for number in numbers:
        if number != 0:
            for candidate in range(2 * number, n+1, number):
                numbers[candidate-2] = 0
    return (list(filter(lambda x: x != 0, numbers)))

mass = find_simple_del(5_000_000)

MaxD = 0  # макс кол-во делителей
for i in range(20000, 1, -1):
    k = 0  # текущ счетчик делителей
    for j in range(len(mass)):
        if i % mass[j] == 0:
            k += 1
    if k >= MaxD:
        MaxD = k
        x = i
print(x, MaxD)


import firebase_admin
from firebase_admin import credentials, firestore
import datetime
root_collection = 'active-hosts'
##### IMPORTANT WRITE ALL OF THIS INTO A CLASS!!!!

class firebase_dns:
    def __init__(self):
        cred = credentials.Certificate('./serviceAccountKey.json')
        firebase_admin.initialize_app(cred)
        self.db = firestore.client()

    def write_data_db(self,host_ip , queried_domain  , data : dict):
        self.db.collection(root_collection).document(host_ip).collection(queried_domain).add(data)

    def get_all_dns_by_host_ip(self,host_ip):
        doc_ref = self.db.collection(root_collection).document(host_ip)
        dns_data_snapshot = doc_ref.get()
        if dns_data_snapshot.exists:
            dns_data = dns_data_snapshot.to_dict()
            print(dns_data)

        for key in dns_data:
            for queried_domain in dns_data[key]:
               self.get_queried_domain_by_host( host_ip , queried_domain)
    def get_queried_domain_by_host(self,host_ip,queried_domain):
        doc_ref = self.db.collection(root_collection).document(host_ip).collection(queried_domain)
        dns_data_snapshot = doc_ref.get()  # this is duplicate code , refactor
        # returns documents , and we print them
        for snapshot in dns_data_snapshot:
            dns_data = snapshot.to_dict()
            print(dns_data)

    def get_all_dns(self):
        pass

#get_queried_domain_by_host('127.0.0.1','google.com')
#get_all_dns_by_host_ip('127.0.0.1')


import json
import time

from platformio.cache import ContentCache
from platformio.compat import aio_create_task
from platformio.home.rpc.handlers.base import BaseRPCHandler
from platformio.home.rpc.handlers.os import OSRPC

class MiscRPC(BaseRPCHandler):
    async def load_latest_tweets(self, data_url):
        cache_key = ContentCache.key_from_args(data_url, "tweets")
        cache_valid = "180d"
        with ContentCache() as cc:
            cache_data = cc.get(cache_key)
            if cache_data:
                cache_data = json.loads(cache_data)
                # automatically update cache in background every 12 hours
                if cache_data["time"] < (time.time() - (3600 * 12)):
                    aio_create_task(
                        self._preload_latest_tweets(data_url, cache_key, cache_valid)
                    )
                return cache_data["result"]

        return await self._preload_latest_tweets(data_url, cache_key, cache_valid)

    @staticmethod
    async def _preload_latest_tweets(data_url, cache_key, cache_valid):
        result = json.loads((await OSRPC.fetch_content(data_url)))
        with ContentCache() as cc:
            cc.set(
                cache_key,
                json.dumps({"time": int(time.time()), "result": result}),
                cache_valid,
            )
        return result


import logging
from io import BytesIO

import numpy as np
from scipy.io import wavfile
from voxpopuli import Voice, PhonemeList
from voxpopuli.phonemes import Phoneme

from cock_music_smart_music import get_random_progression_freqs
from tools.audio import to_f32_16k, to_wav_bytes, mix_tracks
from tools.melody import get_trinote_progression_freqs
from tools.player import AudioPlayer

TEMPO = 50
BEATS_PER_MEASURE = 4
CHORDS_PROGRESSION = ["Am2", "Dm2", "Am2", "E2"]
LOOPS_COUNT = 40

BEATS_TRACK_FILE = None
BEATS_TRACK_FILE = "tools/data/beats/tight_beat.wav"
BEATS_TRACK_BEAT_COUNT = 16

if __name__ == "__main__":
    logging.getLogger().setLevel(logging.INFO)

    if BEATS_TRACK_FILE is None:
        beat_duration = 60 / TEMPO
    else:
        rate, beats_track = wavfile.read(BEATS_TRACK_FILE)
        beat_duration = len(beats_track) / (rate * BEATS_TRACK_BEAT_COUNT)
        beats_track_looped = np.tile(beats_track,
                                     LOOPS_COUNT * BEATS_PER_MEASURE * len(CHORDS_PROGRESSION) // BEATS_TRACK_BEAT_COUNT)

    logging.info("Beat time : %dms" % (beat_duration * 1000))
    logging.info("Measure time : %dms" % (beat_duration * 1000 * 4))

    # prog_freqs = get_trinote_progression_freqs(CHORDS_PROGRESSION, BEATS_PER_MEASURE)
    # logging.info("First freq progression: \n %s" % (str(prog_freqs)))
    track_freqs = []
    for _ in range(LOOPS_COUNT):
        track_freqs += get_trinote_progression_freqs(CHORDS_PROGRESSION, BEATS_PER_MEASURE)
        # track_freqs += get_random_progression_freqs(CHORDS_PROGRESSION)

    progression_phonems = PhonemeList([])
    for freq in track_freqs:
        progression_phonems.append(
            Phoneme("o", int(beat_duration * 1000), [(0,freq), (100,freq)])
        )
    logging.info("Rendering audio")

    voice = Voice(lang="fr", voice_id=4)
    wav = voice.to_audio(progression_phonems)
    if BEATS_TRACK_FILE is not None:
        rate, wave_array = to_f32_16k(wav)
        mixed_tracks = mix_tracks(beats_track_looped * 0.5, wave_array * 0.7, align="left")
        wav = to_wav_bytes(mixed_tracks, 16000)
    player = AudioPlayer()
    with open("/tmp/gros_beat.wav", "wb") as wavfile:
        wavfile.write(wav)
    player.set_file(BytesIO(wav))
    player.play()
    player.close()


from django.contrib import messages
from django.contrib.auth.mixins import AccessMixin
from django.core.cache import cache
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.db import models
from django.db.models import ProtectedError
from django.http import JsonResponse, HttpRequest
from django.urls import reverse_lazy
from django.views.generic.detail import SingleObjectTemplateResponseMixin
from django.views.generic.edit import ModelFormMixin, ProcessFormView

from utilities.methods import get_model_foreignkey_fields, \
    get_model_manytomany_fields, render_pdf
from utilities.views_helper_methods import create_form, update_form, \
    search_query

class CRUDView(
    SingleObjectTemplateResponseMixin,
    ModelFormMixin,
    ProcessFormView,
    AccessMixin
):
    """
    CRUD View provide create update delete functionality from on view
    """
    submit = True
    assign_shop = True
    has_update_url = False
    pdf_response = False
    pdf_template = None
    pdf_file_name = None
    paginated_by = 10
    queryset = None

    def get_success_url(self):
        if self.success_url:
            return self.success_url
        return reverse_lazy(
            self.model._meta.app_label + ':' + self.model._meta.model_name
        )

    def get_cache_key(self):
        return '%s-queryset-%s' % (self.model._meta.model_name,
                                   self.request.user.id)

    def get_permission_denied_message(self):
        """
        Override this method to override
        the permission_denied_message attribute.
        """
        messages.error(self.request, self.permission_denied_message)
        return self.permission_denied_message

    def dispatch(self, request, *args, **kwargs):
        """
        :return: view after checking all required permission
        """
        if not request.user.is_authenticated:
            return self.handle_no_permission()
        if not self.is_permitted(request, 'view'):
            return self.handle_no_permission()
        return super().dispatch(request, *args, **kwargs)

    def has_shop(self):
        return self.request.user.staff_shop_id is not None

    def is_permitted(self, request: HttpRequest, permission_type: str):
        if request.user.is_active and request.user.is_superuser:
            return True

        permission = '{0}.{1}_{2}'.format(
            str(self.model._meta.app_label),
            permission_type,
            str(self.model._meta.model_name)
        )
        if request.user.has_perm(permission):
            return True
        self.permission_denied_message = \
            "You have no {0} permission..!".format(
                permission_type
            )
        return False

    def get_object(self, queryset=None):
        try:
            return super(CRUDView, self).get_object(queryset)
        except AttributeError:
            return None

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        if self.pdf_response:
            if self.pdf_template is None or self.pdf_file_name is None:
                raise ValueError('PDF File Name And Template Name Must Be Set')
            return render_pdf(
                request=request,
                template=self.pdf_template,
                context=self.get_context_data(),
                file_name=self.pdf_file_name
            )
        if request.GET.get('page'):
            return super(CRUDView, self).get(request, *args, **kwargs)
        if request.is_ajax():

            if 'update' in request.path:
                if self.object and self.is_permitted(
                        request,
                        'change'
                ):  # if has permission to change object then render form

                    return JsonResponse(
                        data={'html_form': update_form(self, request)}
                    )

            if self.is_permitted(
                    request,
                    'add'
            ):  # if has permission to add object then render form

                return JsonResponse(
                    data={'html_form': create_form(self, request)}
                )

            return JsonResponse(
                data={'error': 'Error Permission Denied For You'})

        return super(CRUDView, self).get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()

        if 'confirm_delete' in request.POST:
            if self.is_permitted(request, 'delete'):
                name = self.object
                try:
                    self.object.delete()
                    messages.success(
                        self.request, str(
                            self.model._meta.verbose_name
                        ).capitalize() + ' ' + str(
                            name) + ' Delete Successfully'
                    )
                    cache.delete(self.get_cache_key())
                    return JsonResponse({'msg': "Deleted Successfully"})
                except ProtectedError:
                    return JsonResponse(
                        {'error': "Can\'t Delete It has some depended data"}
                    )

            self.permission_denied_message = "You have no delete permission..!"
            return JsonResponse({'error': self.permission_denied_message})

        if self.object and self.is_permitted(
                request,
                'change'
        ) or self.is_permitted(
            request, 'add'
        ):
            return super(CRUDView, self).post(request, *args, **kwargs)
        self.permission_denied_message = \
            "You have no create or add permission..!"
        return self.handle_no_permission()

    def form_valid(self, form):
        cache.delete(self.get_cache_key())
        if self.object:
            form = self.get_form()
            messages.success(self.request,
                             f'{self.object} Update Successfully')
        else:
            form.instance.creator = self.request.user
            if self.assign_shop:
                form.instance.shop_id = self.request.user.staff_shop_id
            messages.success(
                self.request,
                f'{self.model._meta.verbose_name} Created Successfully'
            )

        return super().form_valid(form)

    def get_queryset(self):
        queryset = cache.get(self.get_cache_key())
        if queryset:
            return self.get_filtered_queryset(queryset)
        if self.queryset:
            queryset = self.queryset
        else:
            queryset = self.model.objects.select_related(
                *get_model_foreignkey_fields(self.model)
            ).prefetch_related(
                *get_model_manytomany_fields(self.model)
            ).all()
        cache.set(self.get_cache_key(), queryset, 600)
        return self.get_filtered_queryset(queryset.order_by('updated'))

    def paginated_list(self, object_list):
        page = self.request.GET.get('page', 1)
        paginator = Paginator(object_list, self.paginated_by)
        try:
            objects = paginator.page(page)
        except PageNotAnInteger:
            objects = paginator.page(1)
        except EmptyPage:
            objects = paginator.page(paginator.num_pages)
        return objects

    def get_filtered_queryset(self, queryset):
        filter_dict = {}
        search_value = None
        fields = []
        for field in queryset.model._meta.get_fields():
            if isinstance(field, models.ForeignKey):
                fields.append(field.name + '_id')
            else:
                fields.append(field.name)

        for key, value in dict(self.request.GET).items():
            if key == 'search':
                search_value = self.request.GET.get(key)
                continue
            if key == 'page':
                continue
            if self.request.GET.get(key) != '' and key in fields:
                filter_dict[key] = self.request.GET.get(key)
        object_list = queryset.filter(**filter_dict)
        if search_value:
            object_list = search_query(self, search_value, object_list)
        if self.assign_shop:
            object_list = object_list.filter(shop=self.request.user.staff_shop)
        return object_list

    def get_paginated_list(self):
        object_list = self.get_queryset()
        return self.paginated_list(object_list)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['page_title'] = self.model._meta.verbose_name
        context['app_label'] = self.model._meta.app_label
        context['object_list'] = self.get_paginated_list()
        context['total_found'] = self.get_queryset().count()
        context['permitted_for_delete'] = self.is_permitted(
            request=self.request, permission_type='delete')
        context['permitted_for_view'] = self.is_permitted(
            request=self.request,
            permission_type='view'
        )
        context['permitted_for_change'] = self.is_permitted(
            request=self.request,
            permission_type='change'
        ) and self.has_shop()
        context['permitted_for_add'] = self.is_permitted(
            request=self.request,
            permission_type='add'
        ) and self.has_shop()
        if self.submit:  # if true add submit button html snippets in context
            context['submit'] = \
                '<input type="submit" name="submit" ' \
                'value="Save" class="btn btn-primary float-right mb-2"' \
                ' id="submit-id-submit">'
        try:
            context['url_params'] = '?' + \
                                    self.request.get_full_path().split('?')[
                                        1] + '&page='
        except IndexError:
            context['url_params'] = '?page='
        return context

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['request'] = self.request
        return kwargs


import numpy as np

import fetricks as ft
import numpy as np
import dolfin as df
import pygmsh

code_gmsh = """
p12 = newp;
Point(p12) = {0.0, 0.0, 0.0};
p13 = newp;
Point(p13) = {20.0, 0.0, 0.0};
p14 = newp;
Point(p14) = {20.0, 50.0, 0.0};
p15 = newp;
Point(p15) = {0.0, 50.0, 0.0};
l12 = newl;
Line(l12) = {p12, p13};
l13 = newl;
Line(l13) = {p13, p14};
l14 = newl;
Line(l14) = {p14, p15};
l15 = newl;
Line(l15) = {p15, p12};
ll3 = newll;
Line Loop(ll3) = {l12, l13, l14, l15};
s3 = news;
Plane Surface(s3) = {ll3};
Transfinite Line {l12} = 5;
Transfinite Line {l13} = 10;
Transfinite Line {l14} = 5;
Transfinite Line {l15} = 10;
Physical Surface(0) = {s3};
Physical Line(1) = {l12};
Physical Line(2) = {l14};
"""

class Bar(ft.Gmsh):
    def __init__(self, meshname, h, l, Ntransfinite = []):
        super().__init__(meshname)

        self.rec = self.add_rectangle(0.0, l, 0.0, h, 0.0, make_surface= False)

        self.s = self.add_plane_surface(self.rec.line_loop)

        for i, N in enumerate(Ntransfinite):
            self.set_transfinite_lines([self.rec.lines[i]], N)

        self.physicalNaming()

    def physicalNaming(self):
        self.add_physical(self.s, 0)
        self.add_physical(self.rec.lines[0], 1) # bottom
        self.add_physical(self.rec.lines[2], 2) # top

if __name__ == '__main__':
    h = 50.0;
    l = 20.0;
    r = 2.0;

    Nbottom = 5
    Ntop = 5
    Nleft = 10
    Nright = 10

    # From raw code Gmsh (non parametrised, but easily done)
    gmsh_mesh = ft.Gmsh("bar.xdmf")
    gmsh_mesh.add_raw_code(code_gmsh)

    gmsh_mesh.generate()
    #gmsh_mesh.writeMSH() # automatically generate mesh object
    gmsh_mesh.write("fenics", optimize_storage = True)

    mesh = ft.Mesh("bar.xdmf")

    assert np.allclose(df.assemble( df.Constant(1.0)*mesh.ds(1)), l)
    assert np.allclose(df.assemble( df.Constant(1.0)*mesh.ds(2)), l)
    assert np.allclose(df.assemble( df.Constant(1.0)*mesh.dx(0)), l*h)

    # From the class
    gmsh_mesh = Bar("bar.xdmf", h, l, Ntransfinite = [Nbottom, Nright, Ntop, Nleft])
    gmsh_mesh.generate()
    # gmsh_mesh.writeMSH() # automatically generate mesh object
    gmsh_mesh.write("fenics", optimize_storage = False)

    mesh = ft.Mesh("bar.xdmf")

    assert np.allclose(df.assemble( df.Constant(1.0)*mesh.ds(1)), l)
    assert np.allclose(df.assemble( df.Constant(1.0)*mesh.ds(2)), l)
    assert np.allclose(df.assemble( df.Constant(1.0)*mesh.dx(0)), l*h)

    # From the class
    gmsh_mesh = Bar("bar.xdmf", h, l, Ntransfinite = [Nbottom, Nright, Ntop, Nleft])
    gmsh_mesh.generate()
    # gmsh_mesh.writeMSH() # automatically generate mesh object
    gmsh_mesh.write("fenics", optimize_storage = True)

    mesh = ft.Mesh("bar.xdmf")

    assert np.allclose(df.assemble( df.Constant(1.0)*mesh.ds(1)), l)
    assert np.allclose(df.assemble( df.Constant(1.0)*mesh.ds(2)), l)
    assert np.allclose(df.assemble( df.Constant(1.0)*mesh.dx(0)), l*h)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Building Web Maps using Folium"""

from __future__ import (division, absolute_import, print_function,
                        unicode_literals)

import os
import pandas as pd
import folium
from folium.plugins import MarkerCluster

# Get File Directory
WORK_DIR = os.path.dirname((os.path.realpath(__file__)))

# Loading the json data as python dictionary
DATA = pd.read_csv(WORK_DIR + "/data/Volcanoes_USA.txt")
LAT = DATA['LAT']
LON = DATA['LON']
ELEVATION = DATA['ELEV']

# Function to change colors
def color_change(elev):
    """Change Color depending on Mountain Elevation"""

    if elev < 1000:
        return 'green'
    if 1000 <= elev < 3000:
        return 'orange'
    return 'red'

# Create base map
MAP = folium.Map(
    location=[37.296933, -121.9574983],
    zoom_start=5,
    tiles="CartoDB dark_matter")

# Create Cluster
MARKER_CLUSTER = MarkerCluster().add_to(MAP)

# Plot Markers
for LAT, LON, ELEVATION in zip(LAT, LON, ELEVATION):
    folium.CircleMarker(
        location=[LAT, LON],
        radius=9,
        popup=str(ELEVATION) + " m",
        fill_color=color_change(ELEVATION),
        color="gray",
        fill_opacity=0.9).add_to(MARKER_CLUSTER)

# ave the map
MAP.save("map.html")


# Python Program to display the powers of 2 using anonymous function

# Take number of terms from user
terms = int(input("How many terms? "))

# use anonymous function
result = list(map(lambda x: 2 ** x, range(terms)))

# display the result
for i in range(terms):
   print("2 raised to power",i,"is",result[i])


# Module imports
import requests
import os
import sys
import pandas as pd

# Retrieve ID and TOKEN from environment variables
## (Set with $ export NAME=VALUE)
ID = os.getenv('ID')
TOKEN = os.environ.get('TOKEN')

# Retrieve Twitter data for a given username (30 days by default)
def get_socialblade_data(user):
    twit_user = user
    client_id = ID
    token = TOKEN

    query_url = f'https://matrix.sbapis.com/b/twitter/statistics?query={twit_user}&clientid={client_id}&token={token}'
    x = requests.get(query_url)

    if x.status_code==200:
        print(f"Got data for {user}")
        resp = x.json()
        # call process_response() function on data object
        processed_data = process_response(resp)
        return processed_data
    else:
        print(f"Query for [{user}] returned status {x.status_code}")
        exit()

# Use pandas to format response object into dataframe
## (Subroutine of get_socialblade_data)
def process_response(resp):
    user_data = resp['data']['id']
    df = pd.DataFrame(resp['data']['daily']).sort_values(by='date').copy()

    df['username'] = user_data['username']
    df['display_name'] = user_data['display_name']

    # reorganize columns
    df = df[['username','display_name','date', 'followers', 'following', 'tweets']]

    # calculate follower change
    df['change'] = df.followers.diff()
    df['percent_change'] = df.followers.pct_change()
    print(f"Compiled data for {user_data['username']}")
    return df

# Save dataframe to CSV in a given directory (e.g. political alignment)
def write_to_csv(df, directory, username):
    if not os.path.exists(directory):
        os.makedirs(directory)
        print(f"Created directory {directory}")

    df.to_csv(f'{directory}/{username}.csv', index=False)
    print(f'Saved {username} to csv.')

# Main function - requests data from socialblade, writes to CSV
## Takes second argument
def save_follow_data(user, alignment):
    df = get_socialblade_data(user)
    write_to_csv(df, alignment, user)

# Run function if called from command line
## (Requires 2 arguments: handle and category/directory)
if __name__ == "__main__":
    handle = sys.argv[1]
    category = sys.argv[2]
    save_follow_data(handle, category)


# -*- coding:utf-8 -*-
'''
https://www.nowcoder.com/practice/345e2ed5f81d4017bbb8cc6055b0b711?tpId=117&&tqId=37751&&companyId=665&rp=1&ru=/company/home/code/665&qru=/ta/job-code-high/question-ranking

题目描述
给出一个有n个元素的数组S，S中是否有元素a,b,c满足a+b+c=0？找出数组S中所有满足条件的三元组。
注意：
三元组（a、b、c）中的元素必须按非降序排列。（即a≤b≤c）
解集中不能包含重复的三元组。
例如，给定的数组 S = {-10 0 10 20 -10 -40},解集为(-10, 0, 10) (-10, -10, 20)

示例1
输入
复制
[-2,0,1,1,2]
返回值
复制
[[-2,0,2],[-2,1,1]]

'''
class Solution:
    def threeSum(self , numbers ):
        nums = sorted(numbers)
        def findTwoNum(index1, index2, target):
            res = []
            idx1, idx2 = index1, index2
            while idx1 < idx2:
                currentSum = nums[idx1] + nums[idx2]
                if currentSum == target: ## curSum 刚好, 是最好的.
                    res.append([nums[idx1], nums[idx2]])
                    tmp = idx1
                    while idx1 < len(nums) and nums[idx1] == nums[tmp]: idx1 += 1
                    tmp = idx2
                    while idx2 >= 0 and nums[idx2] == nums[tmp]: idx2 -= 1
                elif currentSum < target: ## 如果cursum太小
                    tmp = idx1
                    while idx1 < len(nums) and nums[idx1] == nums[tmp]: idx1 += 1
                else: ## curSum太大怎么办?
                    tmp = idx2
                    while idx2 >= 0 and nums[idx2] == nums[tmp]: idx2 -= 1
            return res
        # write code here
        res = []
        index = 0
        while index < len(nums) - 2: ## 不要遍历到最后一个元素, 遍历到倒数第三个就够了.
            laterParts = findTwoNum(index1 = index + 1, index2 = len(nums) - 1, target = 0 - nums[index])
            if len(laterParts) == 0: ## 后续部分找不到目标值target
                pass
            else: ## 找到了的话, 就好了.
                for laterPart in laterParts:
                    laterPart.insert(0, nums[index])
                    res.append(laterPart)
            ## 下面两行是为了找没出现过的数字.
            tmp = index
            while index < len(nums) and nums[index] == nums[tmp]: index += 1
        return res

NC54-数组中相加和为0的三元组-中等.py