import numpy as np
import dill as pickle

from hic3defdr.util.matrices import select_matrix

class CoreHiC3DeFDR(object):
    """
    Mixin class providing core saving and loading functionality for HiC3DeFDR.
    """
    @property
    def picklefile(self):
        return '%s/pickle' % self.outdir

    @classmethod
    def load(cls, outdir):
        """
        Loads a HiC3DeFDR analysis object from disk.

        It is safe to have multiple instances of the same analysis open at once.

        Parameters
        ----------
        outdir : str
            Folder path to where the HiC3DeFDR was saved.

        Returns
        -------
        HiC3DeFDR
            The loaded object.
        """
        with open('%s/pickle' % outdir, 'rb') as handle:
            return cls(outdir=outdir, **pickle.load(handle))

    def load_bias(self, chrom):
        """
        Loads the bias matrix for one chromosome.

        The rows of the bias matrix correspond to bin indices along the
        chromosome. The columns correspond to the replicates.

        The bias factors for bins that fail ``bias_thresh`` are set to zero.
        This is designed so that all pixels in these bins get dropped during
        union pixel set computation.

        Parameters
        ----------
        chrom : str
            The name of the chromosome to load the bias matrix for.

        Returns
        -------
        np.ndarray
            The bias matrix.
        """
        bias = np.array([np.loadtxt(pattern.replace('<chrom>', chrom))
                         for pattern in self.bias_patterns]).T
        bias[(np.any(bias < self.bias_thresh, axis=1)) |
             (np.any(bias > 1. / self.bias_thresh, axis=1)), :] = 0
        return bias

    def load_data(self, name, chrom=None, idx=None, rep=None, cond=None,
                  coo=False):
        """
        Loads arbitrary data for one chromosome or all chromosomes.

        Parameters
        ----------
        name : str
            The name of the data to load.
        chrom : str, optional
            The name of the chromosome to load data for. Pass None if this data
            is not organized by chromosome. Pass 'all' to load data for all
            chromosomes.
        idx : np.ndarray or tuple of np.ndarray, optional
            Pass a boolean array to load only a subset of the data. Pass a tuple
            of exactly two boolean arrays to chain the indices.
        rep : str, optional
            If the data is a (pixels, reps) rectangular array, pass the name of
            a rep to get a (pixels,) vector of data for just that rep.
        cond : str, optional
            If the data is a (pixels, conds) rectangular array, pass the name of
            a condition to get a (pixels,) vector of data for just that
            condition.
        coo : bool
            Pass True to return a COO-format ``(row, col, data)`` tuple of
            ``np.ndarray``. ``chrom`` cannot be 'all', and ``idx`` must be None
            (this function will handle filtering automatically).

        Returns
        -------
        data or (concatenated_data, offsets) or (row, col, data) : np.ndarray
            The loaded data for one chromosome, or a tuple of the concatenated
            data and an array of offsets per chromosome. ``offsets`` satisfies
            the following properties: ``offsets[0] == 0``,
            ``offsets[-1] == concatenated_data.shape[0]``, and
            ``concatenated_data[offsets[i]:offsets[i+1], :]`` contains the data
            for the ``i``th chromosome. If called with ``coo=True``, this
            function returns a COO-format ``(row, col, data)`` tuple of
            ``np.ndarray``.
        """
        # short-circuit when asking for loop_idx when no loop_patterns exist
        if name == 'loop_idx' and self.loop_patterns is None and idx is None \
                and chrom != 'all':
            disp_idx = np.load_data('disp_idx', chrom)
            return np.ones(disp_idx.sum(), dtype=bool)

        # resolve col_idx
        col_idx = self.design.index.tolist().index(rep) if rep is not None \
            else self.design.columns.tolist().index(cond) if cond is not None \
            else None

        # handle coo
        if coo:
            if chrom == 'all' or idx is not None:
                raise ValueError("cannot pass coo=True with chrom='all' or idx")
            if name in ['row', 'col', 'bias', 'cov_per_bin', 'disp_per_bin']:
                raise ValueError('data with name %s cannot be loaded as COO'
                                 % name)
            if name in ['raw', 'size_factors', 'scaled', 'disp_idx']:
                row = self.load_data('row', chrom)
                col = self.load_data('col', chrom)
            elif name in ['loop_idx', 'disp', 'mu_hat_null', 'mu_hat_alt',
                          'llr', 'pvalues']:
                disp_idx = self.load_data('disp_idx', chrom)
                row = self.load_data('row', chrom, idx=disp_idx)
                col = self.load_data('col', chrom, idx=disp_idx)
            elif name in ['qvalues']:
                disp_idx = self.load_data('disp_idx', chrom)
                loop_idx = self.load_data('loop_idx', chrom)
                row = self.load_data('row', chrom, idx=(disp_idx, loop_idx))
                col = self.load_data('col', chrom, idx=(disp_idx, loop_idx))
            else:
                raise ValueError('data name %s not recognized' % name)
            data = self.load_data(name, chrom)
            if col_idx is not None:
                return row, col, data[:, col_idx]
            return row, col, data

        # index chaining
        if type(idx) == tuple:
            big_idx, small_idx = idx
            big_idx = big_idx.copy()
            big_idx[np.where(big_idx)[0][~small_idx]] = False
            idx = big_idx

        # tackle simple cases first
        if chrom is None:
            fname = '%s/%s.npy' % (self.outdir, name)
        elif chrom != 'all':
            fname = '%s/%s_%s.npy' % (self.outdir, name, chrom)
        else:
            fname = None
        if fname is not None:
            if idx is None:
                data = np.load(fname)
                if col_idx is not None:
                    return data[:, col_idx]
                return data
            else:
                data = np.load(fname, mmap_mode='r')
                if col_idx is not None:
                    return data[idx, col_idx]
                return data[idx]

        # idx is genome-wide, this tracks where we are in idx so that we can
        # find a subset of idx that aligns with the current chrom
        idx_offset = 0

        # list of data arrays per chromosome
        all_data = []

        # running total of the sizes of the elements of all data
        offset = 0

        # saves value of offset after each chrom
        offsets = [0]

        # loop over chroms
        for chrom in self.chroms:
            fname = '%s/%s_%s.npy' % (self.outdir, name, chrom)
            if idx is not None:
                data = np.load(fname, mmap_mode='r')
                full_data_size = data.shape[0]
                data = data[idx[idx_offset:idx_offset+full_data_size]]
                idx_offset += full_data_size
            else:
                data = np.load(fname)
            offset += data.shape[0]
            offsets.append(offset)
            all_data.append(data)
        all_data = np.concatenate(all_data)
        if col_idx is not None:
            return all_data[:, col_idx], np.array(offsets)
        return all_data, np.array(offsets)

    def save_data(self, data, name, chrom=None):
        """
        Saves arbitrary data for one chromosome to disk.

        Parameters
        ----------
        data : np.ndarray
            The data to save.
        name : str
            The name of the data to save.
        chrom : str or np.ndarray, optional
            The name of the chromosome to save data for, or None if this data is
            not organized by chromosome. Pass an np.ndarray of offsets to save
            data for all chromosomes.
        """
        if chrom is None:
            np.save('%s/%s.npy' % (self.outdir, name), data)
        elif isinstance(chrom, np.ndarray):
            for i, c in enumerate(self.chroms):
                self.save_data(data[chrom[i]:chrom[i + 1]], name, c)
        else:
            np.save('%s/%s_%s.npy' % (self.outdir, name, chrom), data)

    def load_disp_fn(self, cond):
        """
        Loads the fitted dispersion function for a specific condition from disk.

        Parameters
        ----------
        cond : str
            The condition to load the dispersion function for.

        Returns
        -------
        function
            Vectorized. Takes in the value of the covariate the dispersion was
            fitted against and returns the appropriate dispersion.
        """
        picklefile = '%s/disp_fn_%s.pickle' % (self.outdir, cond)
        with open(picklefile, 'rb') as handle:
            return pickle.load(handle)

    def save_disp_fn(self, cond, disp_fn):
        """
        Saves the fitted dispersion function for a specific condition and
        chromosome to disk.

        Parameters
        ----------
        cond : str
            The condition to save the dispersion function for.
        disp_fn : function
            The dispersion function to save.
        """
        picklefile = '%s/disp_fn_%s.pickle' % (self.outdir, cond)
        with open(picklefile, 'wb') as handle:
            return pickle.dump(disp_fn, handle, -1)

    def get_matrix(self, name, chrom, row_slice, col_slice, rep=None,
                   cond=None):
        """
        Loads data with ``name`` as a dense matrix specified by ``chrom,
        row_slice, col_slice``.

        Parameters
        ----------
        name : str
            The name (stage) of the data to load. Add a special suffix '_mean'
            to average per-rep stages within condtiions.
        chrom : str
            The chromosome to select data from.
        row_slice, col_slice : slice
            Row and column slice to use, respectively.
        rep, cond : str, optional
            Pass the rep name or condition name if the data specified by
            ``name`` has multiple columns.

        Returns
        -------
        np.ndarray
            The selected dense matrix.
        """
        if name.endswith('_mean'):
            reps = self.design[self.design[cond]].index.tolist()
            return np.mean(
                [self.get_matrix(name.strip('_mean'), chrom, row_slice,
                                 col_slice, rep=r)
                 for r in reps],
                axis=0
            )
        return select_matrix(
            row_slice,
            col_slice,
            *self.load_data(name, chrom, rep=rep, cond=cond, coo=True)
        )


#%%
flower_list = ['gerbera', 'lily', 'rose', 'tulip', 'tulip', 'gerbera']

#%%
unique_flowers = list(set(flower_list))
unique_flowers
# %%
name_list = ['Arie', 'Lily', 'Rose']
age_list  = [20, 30, 40]
# %%
dict(zip(name_list, age_list))
# %%
import requests

# %%
response = requests.get("https://opendata.rdw.nl/resource/m9d7-ebf2.json")
# %%
car_list = response.json()
# %%
import pandas as pd

cars_df = pd.DataFrame(car_list)
# %%


# -*- coding: utf-8 -*-

'''
路由完善：
        修改装饰器路由，由原先的使用正则表达式，改为更为简单的写法
        @r2.route(r'/hello/{name:str}/{age:int}') # 抛去正则表达式，这样写很简单。下面的方式要求框架的使用者熟悉正则。
        @r2.route(r'/hello/(?P<name>\w+)$')
'''
import re
from collections import namedtuple
from webob import Request, Response # webob里封装了Request和Response
from webob.dec import wsgify # webob提供的装饰器，可以将代码大大简化
from webob.exc import HTTPNotFound
#from webob.exc import * # 引入webob所有的Exception

# 这里我们把 str 分成3种：1.str 所有不包含 / 的字符；2.word 字母、数字和下划线；3.any：任意字符
PATTERNS = {
    'str': '[^/].+', # 不包含 /，且至少一个字符
    'word': '\w+',
    'any': '.+', # 任意字符，但是至少包含一个
    'int': '[+-]?\d+', # int类型的正则表达式，可选的+或-号，后面是数字
    'float': '[+-]?\d+\.\d+' # float类型正则表达式
}

CASTS= {
    'str': str,
    'word': str,
    'any': str,
    'int': int,
    'float': float
}

Route = namedtuple('Route', ['pattern', 'methods', 'casts', 'handler'])

class Router:
    def __init__(self, prefix='', domain=None):
        self.routes = []
        self.domain = domain
        self.prefix = prefix

    def _route(self, rule, methods, handler):
        pattern, casts = self._rule_parse(rule)
        self.routes.append(Route(pattern, methods, casts, handler))

    def _rule_parse(self, rule):
        pattern = []
        spec = []
        casts = {}
        is_spec = False

        # @r2.route('/hello/{name}/{age:int}') # /hello/(?P<name>[^/]+)/(?P<age>[+-]?\d+)$
        for c in rule:
            if c == '{' and not is_spec:
                is_spec = True # 开始spec字段
            elif c == '}' and is_spec:
                is_spec = False # 结束spec字段
                # TODO process spec
                name, p, c = self._spec_parse(''.join(spec))
                spec = []
                pattern.append(p)
                casts[name] = c
            elif is_spec:
                spec.append(c)
            else:
                pattern.append(c)

        return '{}$'.format(''.join(pattern)), casts

    def _spec_parse(self, src):
        tmp = src.split(':')  # spec= age:int
        if len(tmp) > 2:
            raise Exception('error pattern')
        name = tmp[0]
        type = 'str'  # type默认为str类型的
        if len(tmp) == 2:
            type = tmp[1]
        pattern = '(?P<{}>{})'.format(name, PATTERNS[type])
        return name, pattern, CASTS[type]

    # def route(self, pattern, methods=None):
    #     if methods is None:
    #         methods = ('GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTION')
    #
    #     def dec(fn): # fn就是传递进来的handler
    #         self._route(pattern, methods, fn)
    #         return fn # 这里不需要执行fn，原样返回就行了
    #
    #     return dec
    def route(self, rule, methods=None):
        if methods is None:
            methods = ('GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTION')

        def dec(fn): # fn就是传递进来的handler
            self._route(rule, methods, fn)
            def wrap(*args, **kwargs):
                return fn # 这里不需要执行fn，原样返回就行了
            return wrap

        return dec

    def _domian_match(self, request):
        return self.domain is None or re.match(self.domain, request.host)

    def _prefix_match(self, request):
        return request.path.startswith(self.prefix)

    def match(self, request):
        if self._domian_match(request) and self._prefix_match(request):
            for route in self.routes:
                if request.method in route.methods:
                    m = re.match(route.pattern, request.path.replace(self.prefix, '', 1))
                    if m:
                        request.args = {}
                        for k, v in m.groupdict().items():
                            request.args[k] = route.casts[k](v)
                        return route.handler

class Application:
    def __init__(self, **options): # options这里作为全局的设置，传递给views
        self.routers = []
        self.options = options

    def add_router(self, router):
        self.routers.append(router)

    @wsgify
    def __call__(self, request):
        for router in self.routers:
            handler = router.match(request)
            if handler:
                return handler(self, request)
        raise HTTPNotFound(detail='no handler match')

# 上面都是框架代码，下面是业务代码
from webob.exc import HTTPTemporaryRedirect
from html import escape

r1 = Router()
r2 = Router('/r2') # 前缀r2，127.0.0.1:3000/r2/hello/jkzhao
r3 = Router(domain='jinzhi.wisedu.com') # 需要修改hosts文件，配置ip地址和这个主机名相对应。但是改完之后，所有的就得用域名的方式访问

@r3.route('/')
def main(app, request):
    # return Response('this is man page')
    raise HTTPTemporaryRedirect(location='/r2/hello/jkzhao/26') # 302临时跳转,webob内部实现了

@r2.route('/hello/{name}/{age:int}') # 抛去正则表达式，这样写很简单，不写类型就是string。下面的方式要求框架的使用者熟悉正则。
# @r2.route(r'/hello/(?P<name>\w+)$') # 传递方式变为 127.0.0.1:3000/hello/jkzhao 这样就可以通过path来传递参数了
def hello(app, request):
    print(request.args['age'])
    print(type(request.args['age']))
    body = 'hello {}'.format(escape(request.args.get('name')))
    return Response(body)

@r1.route('/favicon.ico')
def favicon(app, request):
    with open('./favicon.ico', 'rb') as f:
        response = Response(body=f.read(), content_type='image/x-icon')
        return response

if __name__ == '__main__':
    from wsgiref.simple_server import make_server # 是不是单线程要看容器，这就是个单线程容器

    app = Application()
    app.add_router(r1)
    app.add_router(r2)
    app.add_router(r3)

    server = make_server('0.0.0.0', 3000, app) # 创建一个容器
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        server.shutdown()


import fractions
from Crypto.Util.number import GCD
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

def continued_fraction_expansion(e, n):
    cf_expansion = []
    while n:
        cf_expansion.append(e // n)
        e, n = n, e % n
    return cf_expansion

def convergents(cf_expansion):
    convergents_list = []
    numerator, denominator = 0, 1
    for x in cf_expansion:
        numerator, denominator = denominator, x * denominator + numerator
        convergents_list.append((numerator, denominator))
    return convergents_list

def wiener_attack(public_key):
    n, e = public_key

    cf_expansion = continued_fraction_expansion(e, n)
    convergent_list = convergents(cf_expansion)

    for k, d in convergent_list:
        if k == 0:
            continue

        # Calculate phi and ensure it's a positive integer
        phi = (e * d - 1) // k
        if phi <= 0 or (e * d - 1) % k != 0:
            continue

        # Calculate possible factors of n using phi
        x = pow(phi - n - 1, 2) - 4 * n
        if x < 0:
            continue

        root_x = int(x**0.5)
        if root_x * root_x != x:
            continue

        p, q = (phi - n - 1 + root_x) // 2, (phi - n - 1 - root_x) // 2
        if p * q == n and GCD(e, phi) == 1:
            return d

    return None

def rsa_differential_attack_wiener(public_key, ciphertexts):
    n, e = public_key

    # Attempt to recover the private key (d) using Wiener's attack
    d = wiener_attack(public_key)
    if d is None:
        # Unable to recover the private key using Wiener's attack
        return []

    # Decrypt the ciphertexts using the private key (d)
    possible_plaintexts = []
    for ct in ciphertexts:
        pt = pow(ct, d, n)
        possible_plaintexts.append(pt)

    return possible_plaintexts

# Generate RSA key pair with small d
key = RSA.generate(1024)
n, e = key.n, key.e
d = key.d

print("Public key (n, e):", (n, e))
print("Private key (d):", d)

# Encrypt messages using the public key
plaintexts = [b'Hello, world!', b'Secure communication']
cipher = PKCS1_OAEP.new(key.publickey())
ciphertexts = [cipher.encrypt(pt) for pt in plaintexts]
print("Ciphertexts:", ciphertexts)

# Perform the Wiener attack
possible_plaintexts = rsa_differential_attack_wiener((n, e), ciphertexts)
print("Possible plaintexts (as integers):", possible_plaintexts)

# Convert the integers back to bytes
possible_plaintexts_bytes = [pt.to_bytes((pt.bit_length() + 7) // 8, byteorder='big') for pt in possible_plaintexts]
print("Possible plaintexts (as bytes):", possible_plaintexts_bytes)


from project3.eulerstep import eulerstep as estep
from project3.TRstep import TRstep
from mpl_toolkits import mplot3d
import numpy as np
import scipy.sparse as sp
import matplotlib.pyplot as plt

N = 30  # interior position points
dx = 1/(N+1)  # distance between grid points
M = 186  # time points  (186 to examine cfl)
tend = 0.1
dt = tend/M  # distance between time points
xx = np.linspace(0, 1, N+2)
tt = np.linspace(0, tend, M+1)  # VARFÖR inte +2 här?

T, X = np.meshgrid(tt, xx)

# CREATE TOEPLITZ MATRIX
k = np.array([np.ones(N - 1), -2 * np.ones(N), np.ones(N - 1)])
offset = [-1, 0, 1]
Tdx = 1/dx**2 * sp.diags(k, offset).toarray()

# SOLVE THE PDE
solmat = np.zeros((N, M+1))  # initiate matrix containing the solution of PDE
gx = 10*(0.5 - abs(xx[1:-1] - 0.5))  # u(0,x) = gx (initial value)
solmat[:, 0] = gx
uold = gx

for i in range(M):
    # unew = estep(Tdx, uold, dt)  # task 1.1
    unew = TRstep(Tdx, uold, dt)  # task 1.2  # STÄMMER DENNA PLOTTEN?
    # print(unew)
    # print(unew[0])
    # print(unew.shape)
    solmat[:, i+1] = unew
    uold = unew

solmat = np.insert(solmat, [0, len(solmat)], np.zeros(M+1), 0)  # insert boundary conditions
# print(solmat)

# PLOT
fig = plt.figure(1)
ax = plt.axes(projection='3d')
ax.plot_surface(X, T, solmat, cmap='jet')  # https://medium.com/@yzhong.cs/beyond-data-scientist-3d-plots-in-python-with-examples-2a8bd7aa654b
ax.set_title('task11')
plt.show()

cfl = dt/dx**2
print(cfl)  # 0.5166..


import torch

class TextClassificationDataset:
    def __init__(self, data, tokenizer, config):
        self.data = data
        self.tokenizer = tokenizer
        self.config = config
        self.text_column = self.config.text_column
        self.target_column = self.config.target_column

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

    def __getitem__(self, item):
        text = str(self.data[item][self.text_column])
        target = self.data[item][self.target_column]
        target = int(target)
        inputs = self.tokenizer(
            text,
            max_length=self.config.max_seq_length,
            padding="max_length",
            truncation=True,
        )

        ids = inputs["input_ids"]
        mask = inputs["attention_mask"]

        if "token_type_ids" in inputs:
            token_type_ids = inputs["token_type_ids"]
        else:
            token_type_ids = None

        if token_type_ids is not None:
            return {
                "input_ids": torch.tensor(ids, dtype=torch.long),
                "attention_mask": torch.tensor(mask, dtype=torch.long),
                "token_type_ids": torch.tensor(token_type_ids, dtype=torch.long),
                "labels": torch.tensor(target, dtype=torch.long),
            }
        return {
            "input_ids": torch.tensor(ids, dtype=torch.long),
            "attention_mask": torch.tensor(mask, dtype=torch.long),
            "labels": torch.tensor(target, dtype=torch.long),
        }


from setuptools import find_packages
from setuptools import setup

package_name = 'jetbot_move'

setup(
    name=package_name,
    version='0.14.0',
    packages=find_packages(exclude=['test']),
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
        ('share/' + package_name + '/demo_routines', ['demo_routines/autumn.json']),
        ('share/' + package_name + '/launch',
         ['launch/circle.launch.py', 'launch/dance.launch.py']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    author='Jeremy Wallace',
    author_email='jeremygw@amazon.com',
    maintainer='Jeremy Wallace',
    maintainer_email='jeremygw@amazon.com',
    keywords=['ROS'],
    classifiers=[
        'Intended Audience :: Developers',
        'License :: OSI Approved :: Apache Software License',
        'Programming Language :: Python',
        'Topic :: Software Development',
    ],
    description=(
        'Move operations for the Jetbot'
    ),
    license='Apache License, Version 2.0',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            'circle = jetbot_move.circle:main',
            'dance = jetbot_move.dance:main'
        ],
    },
)


import socket
import requests

headers = {
'Host':'10.10.11.12',
'Connection':'keep-alive',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
'Content-Type':'application/x-www-form-urlencoded',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language':'zh-CN,zh;q=0.8'
}

data = {
'loginType':'',
'auth_type':'0',
'isBindMac':'0',
'pageid':'1',
'templatetype':'3',
'listbindmac':'0',
'isRemind':'0',
'loginTimes':'',
'groupId':'',
'userId':'这里输入账号',
'passwd':'这里输入密码'
}
# gethostbyname 返回的是 主机名 的IPv4 的地址格式，如果传入的参数是IPv4 的地址格式，则返回值跟参数一样，
# 这个函数不支持IPv6 的域名解析
localIP = socket.gethostbyname(socket.gethostname())
#gethostbyname_ex()它能够返回 一个三元组 （原始主机名，域名列表，IP地址列表），这个函数不支持IPv6的域名解析
#参数传入域名
ipList = socket.gethostbyname_ex(socket.gethostname())
ip = ipList[2][0]

url = 'http://10.10.11.12/portal.do?wlanuserip='+ ip +'&wlanacname=XF_BRAS&mac=eb:57:14:ac:00:00&vlan=0&rand=d2c08f2fd07e2'

p = requests.post(url,headers=headers,data=data)
r = requests.get('https://www.baidu.com')
if r.status_code == 200:
    print("登陆成功")
else:
    print("登陆失败")


import numpy as np
from ..fileio import FileIO as psopen
from ...common import pandas
#import pysal_examples
from ... import examples as pysal_examples
import unittest as ut

PANDAS_EXTINCT = pandas is None

class Test_Table(ut.TestCase):
    def setUp(self):
        self.filehandler = psopen(pysal_examples.get_path('columbus.dbf'))
        self.df = self.filehandler.to_df()
        self.filehandler.seek(0)
        self.shapefile = psopen(pysal_examples.get_path('columbus.shp'))
        self.csvhandler = psopen(pysal_examples.get_path('usjoin.csv'))
        self.csv_df = self.csvhandler.to_df()
        self.csvhandler.seek(0)

    @ut.skipIf(PANDAS_EXTINCT, 'missing pandas')
    def test_to_df(self):
        for column in self.csv_df.columns:
            if column.lower() == 'name':
                continue
            np.testing.assert_allclose(self.csvhandler.by_col(column),
                                       self.csv_df[column].values)
        for column in self.df.columns:
            if column == 'geometry':
                continue
            np.testing.assert_allclose(self.filehandler.by_col(column),
                                       self.df[column])


import random
import pygame

from settings import *
from tile import Tile
from player import Player
from debug import debug
from support import *
from weapon import Weapon

class Level:
    def __init__(self):

        # Get the display surface.
        self.player = None
        self.display_surface = pygame.display.get_surface()

        # Sprite group setup.
        self.visible_sprites = YSortCameraGroup()
        self.obstacle_sprites = pygame.sprite.Group()

        # Attack sprites.
        # Stores the current weapon used for attacking.
        self.current_attack = None

        # Sprite setup
        self.create_map()

    def create_map(self):
        # dict of the different layouts of the map.
        layouts = {
            "boundary": import_csv_layout("map/map_FloorBlocks.csv"),
            "grass": import_csv_layout("map/map_Grass.csv"),
            "object": import_csv_layout("map/map_Objects.csv")
        }

        # Importing all the graphics for objects.
        graphics = {
            "grass": import_folder("graphics/grass"),
            "objects": import_folder("graphics/objects")
        }

        # Loop over dictionary containing the layouts of image.
        for style, layout in layouts.items():
            # Loop over layout for columns & rows.
            for row_index, row in enumerate(layout):
                for col_index, col in enumerate(row):
                    # Avoid boundaries being placed in incorrect areas.
                    if col != "-1":
                        # Set spacing between each index according to the tile size.
                        x = col_index * TILE_SIZE
                        y = row_index * TILE_SIZE
                        if style == "boundary":
                            Tile((x, y), [self.obstacle_sprites], "invisible")

                        if style == "grass":
                            # Get random grass image.
                            random_grass_image = random.choice(graphics["grass"])
                            # Create a grass tile.
                            Tile((x, y), [self.visible_sprites, self.obstacle_sprites], "grass", random_grass_image)

                        if style == "object":
                            # Create an object tile.
                            surf = graphics["objects"][int(col)]
                            Tile((x, y), [self.visible_sprites, self.obstacle_sprites], "object", surf)

        # Place the player in towards the middle of the screen on the path.
        self.player = Player((2000, 1430), [self.visible_sprites], self.obstacle_sprites, self.create_attack,
                             self.destroy_attack)

    # Bring weapon to the level class to interact with objects.
    def create_attack(self):
        self.current_attack = Weapon(self.player, [self.visible_sprites])

    # Destroys the attack image on screen & sets current_attack back to none.
    def destroy_attack(self):
        if self.current_attack:
            self.current_attack.kill()
        self.current_attack = None

    # Runs the level class.
    def run(self):
        # update & draw the game.
        self.visible_sprites.custom_draw(self.player)
        self.visible_sprites.update()
        debug(self.player.status)

class YSortCameraGroup(pygame.sprite.Group):
    def __init__(self):
        super().__init__()
        self.display_surface = pygame.display.get_surface()

        # Get half the width & height of the display surface.
        self.half_width = self.display_surface.get_size()[0] // 2
        self.half_height = self.display_surface.get_size()[1] // 2

        # Vector to help offset the camera according to player position.
        self.offset = pygame.math.Vector2()

        # Creating the floor surface & rectangle to be below everything.
        self.floor_surf = pygame.image.load("graphics/tilemap/ground.png").convert()
        self.floor_rect = self.floor_surf.get_rect(topleft=(0, 0))

    def custom_draw(self, player):
        # Getting the offset.
        self.offset.x = player.rect.centerx - self.half_width
        self.offset.y = player.rect.centery - self.half_height

        # Draw the floor.
        floor_offset_position = self.floor_rect.topleft - self.offset
        self.display_surface.blit(self.floor_surf, floor_offset_position)

        """
        Sort the sprites so the player appears behind it with a greater y position
        & in front of obstacles with a lesser y position.
        """
        for sprite in sorted(self.sprites(), key=lambda sprite: sprite.rect.centery):
            # Setting the offset position to the top left according to values in offset vector.
            offset_position = sprite.rect.topleft - self.offset
            self.display_surface.blit(sprite.image, offset_position)


"""
CH14. 49_Minimum_Height_Trees.py
"""
import collections
from gc import collect
import heapq
import functools
import itertools
import re
import sys
import math
import bisect

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

def toTree(list):
    size = len(list)
    idx = 1

    if size == 0:
        return None

    def recursive(i):
        if i > size or list[i-1] is None:
            return None
        node = TreeNode(list[i-1])
        node.left = recursive(i*2)
        node.right = recursive(i*2+1)
        return node
    return recursive(idx)

def printTree(root):
    if root is None:
        print('Tree is Empty')

    q = collections.deque([root])

    while q:
        for _ in range(len(q)):
            cur = q.popleft()
            if cur.left:
                q.append(cur.left)
            if cur.right:
                q.append(cur.right)
            print(cur.val, end = ' ')
        print()

# 입력 1
n1 = 4
edges1 = [[1, 0], [1, 2], [1, 3]]
# 출력 1
output1 = [1]

# 입력 2
n2 = 6
edges2 = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
# 출력 2
output2 = [3, 4]

# 입력 3
n3 = 9
edges3 = [[1, 3], [2, 3], [3, 4], [3, 5], [4, 6], [6, 10], [5, 7], [5, 8], [8, 9]]
# 출력 3
output3 = [3]

# --------------------------------------------------
def findMinHeightTrees(n, edges):
    if n <= 1:
        return [0]

    graph = collections.defaultdict(list)
    for i, j in edges:
        graph[i].append(j)
        graph[j].append(i)

    leaves = []
    for i in range(n + 1):
        if len(graph[i]) == 1:
            leaves.append(i)

    while n > 2:
        n -= len(leaves)
        new_leaves = []
        for leaf in leaves:
            neighbor = graph[leaf].pop()
            graph[neighbor].remove(leaf)

            if len(graph[neighbor]) == 1:
                new_leaves.append(neighbor)

        leaves = new_leaves

    return leaves

print(findMinHeightTrees(n1, edges1))
print(findMinHeightTrees(n1, edges1) == output1)
print(findMinHeightTrees(n2, edges2))
print(findMinHeightTrees(n2, edges2) == output2)
print(findMinHeightTrees(n3, edges3))
print(findMinHeightTrees(n3, edges3) == output3)

# --------------------------------------------------


# pylint: disable=unused-argument, arguments-differ
"""Celery tasks for the Amazon Product Advertising API"""
import logging

from celery import chord
from celery.signals import celeryd_after_setup
from celery.task import (
    PeriodicTask,
    Task,
)
from celery.task.control import (
    inspect,
    revoke,
)

from collections import (
    Counter,
    namedtuple,
)

from datetime import (
    datetime,
    timedelta,
)

from django.db.models import (
    Min,
    Q,
)
from django.utils import timezone

# from django.utils.translation import ugettext

from price_monitor import app_settings
from price_monitor.models import (
    Price,
    Product,
    Subscription,
)
from price_monitor.product_advertising_api.api import ProductAdvertisingAPI
from price_monitor.utils import (
    chunk_list,
    send_mail,
)

from smtplib import SMTPServerDisconnected

logger = logging.getLogger('price_monitor.product_advertising_api')

@celeryd_after_setup.connect
def celeryd_after_setup(*args, **kwargs):
    """
    Called after the worker instances are set up.

    Starts the StartupTask to get the whole synchronization started.
    """
    StartupTask().apply_async(countdown=5)

class StartupTask(Task):

    """The task for getting the machinery up and running. As we do not use celery beat, we have to start somewhere."""

    ignore_result = True

    def run(self):
        logger.info('StartupTask was called')

        # that's better than an simple tuple
        task_repr = namedtuple('TaskRepresentation', 'id, name')

        # fetch all currently queued task, map them to the TaskRepresentation tuple
        scheduled_tasks = [task_repr(x['request']['id'], x['request']['name']) for x in list(inspect().scheduled().values())[0]]

        # count how many FindProductsToSynchronizeTask are scheduled
        count = dict(Counter([x.name for x in scheduled_tasks]).most_common())

        # check if the FindProductsToSynchronizeTask is in and how often
        if count and FindProductsToSynchronizeTask.name in count:
            c = count[FindProductsToSynchronizeTask.name]
        else:
            c = 0

        # if the task is not scheduled, do so
        if c == 0:
            logger.info('no FindProductsToSynchronizeTask is scheduled, now scheduling it')
            FindProductsToSynchronizeTask().apply_async(countdown=5)

        # put out logging info if the task is already scheduled
        if c == 1:
            logger.info('FindProductsToSynchronizeTask is already scheduled, skipping additional run')

        # if the task is there more than once, remove it
        # this has the potential to remove ALL scheduled FindProductsToSynchronizeTasks if the timing is "bad"
        # however, the JumpStartTask will re-schedule the task if this happens (a workaround for a workaround - bad design by me btw.)
        if c > 1:
            logger.info('FindProductsToSynchronizeTask is already scheduled %d times, revoking %d', c, c - 1)

            # revoke c-1 tasks - that means the task still stays in schedule but is removed and not executed when execution time is reached
            for t in scheduled_tasks[1:]:
                logger.info('revoking FindProductsToSynchronizeTask with id %s', t.id)
                revoke(t.id)

class JumpStartTask(PeriodicTask):

    """
    Task providing jump start to the FindProductsToSynchronizeTask.

    It can happen that the FindProductsToSynchronizeTask does not reschedule itself. I don't know why. We do a workaround with this periodic tasks providing a
    jumper cable to reschedule the task by queuing the StartupTask.
    """

    run_every = timedelta(minutes=60)

    def run(self):
        """
        Does no more that to call the StartupTask in 5 seconds.

        :return: always True
        """
        logger.info('JumpStartTask was called')
        StartupTask().apply_async(countdown=5)
        return True

class FindProductsToSynchronizeTask(Task):

    """The tasks that finds the products that shall be updated through the api."""

    def run(self):
        """
        Fetches the products to update via api. Queues a SynchronizeProductsTask and calls a new instance of itself after all
        tasks are done. If no products found for update, sleeps until the next update time is reached.

        :return: the result is always true
        :rtype: bool
        """
        logger.info('FindProductsToSynchronizeTask was called')

        # get all products that shall be updated
        products = self.__get_products_to_sync()

        if products:
            # chunk the products into 10 products each
            products_chunked = list(chunk_list(list(products), 10))

            logger.info('Starting chord for synchronization of %d products in %d chunks', len(products), len(products_chunked))

            # after all single product synchronize tasks are done recall the FindProductsToSynchronizeTask. That is because we do not know how long it takes to
            # synchronize the products and there can be new ones meanwhile. If the newly called task finds no products, it will handle the new callback to the
            # correct time.
            chord(
                SynchronizeProductsTask().s([product.asin for product in product_list]) for product_list in products_chunked
            )(
                FindProductsToSynchronizeTask().si()
            )
        else:
            logger.info('No products found to update now')
            # One might think this may interfere with newly created products and their synchronization if they are added before the
            # FindProductsToSynchronizeTask is called again, but it doesn't. The new product is updated on creation and the next synchronization is always
            # after the next task call.
            oldest_synchronization = Product.objects.filter(subscription__isnull=False, status__in=[0, 1]).aggregate(
                Min('date_last_synced')
            )['date_last_synced__min'] or datetime.now()
            next_synchronization = oldest_synchronization + timedelta(minutes=app_settings.PRICE_MONITOR_AMAZON_PRODUCT_REFRESH_THRESHOLD_MINUTES)
            logger.info('Eta for next FindProductsToSynchronizeTask run is %s', next_synchronization)
            FindProductsToSynchronizeTask().apply_async(eta=next_synchronization)

        return True

    def __get_products_to_sync(self):
        """
        Returns the products to synchronize.

        These are newly created products with status "0" or products that are older than settings.PRICE_MONITOR_AMAZON_PRODUCT_REFRESH_THRESHOLD_MINUTES.
        :return: list of products
        :rtype: django.db.models.query.QuerySet
        """
        # prefer already synced products over newly created
        return Product.objects.select_related().filter(
            subscription__isnull=False,
            date_last_synced__lte=(timezone.now() - timedelta(minutes=app_settings.PRICE_MONITOR_AMAZON_PRODUCT_REFRESH_THRESHOLD_MINUTES)),
            # issue #21 don't sync products that are  not existent
            status__in=[0, 1]
        )

class SynchronizeProductsTask(Task):

    """Task for synchronizing a single product."""

    # limit to one task per second, limited by Amazon API
    rate_limit = '1/s'

    # if we use the product instances instead of asins we get an EncodeError(RuntimeError('maximum recursion depth exceeded',),) resulting in a
    # billiard.exceptions.WorkerLostError:
    def run(self, asin_list):
        """
        Called by celery if task is being delayed.

        :param asin_list: list of asins of the products to be sycnhronized with Amazon
        :type  asin_list: list
        """
        products = dict()
        # fetch the product instances
        for asin in asin_list:
            try:
                # do select_related for price values for reducing db queries
                product = Product.objects.select_related('highest_price', 'lowest_price', 'current_price').get(asin=asin)
            except Product.DoesNotExist:
                logger.error('Product with ASIN %s could not be found.', asin)
                continue

            products[asin] = product

        if not products:
            logger.error('For the given ASINs %s no products where found!', ','.join(asin_list))
            return True

        logger.info('Synchronizing products with ItemIds %s', ', '.join(products.keys()))

        # query Amazon and iterate over results to update values
        for asin, amazon_data in ProductAdvertisingAPI().item_lookup(item_ids=list(products.keys())).items():
            self.__sync_product(products[asin], amazon_data)

        return True

    def __sync_product(self, product, amazon_data):
        """
        Synchronizes the given price_monitor.model.Product with the Amazon data.
        :param product: the product to update
        :type product: price_monitor.models.Product
        :param amazon_data: the date from the amazon api
        :type amazon_data: dict
        """
        now = timezone.now()

        # create the price
        price = Price.objects.create(
            value=amazon_data['price'] if 'price' in amazon_data else None,
            currency=amazon_data['currency'] if 'currency' in amazon_data else None,
            date_seen=now,
            product=product,
        )

        product.current_price = price

        if product.lowest_price is None or (price.value is not None and price.value <= product.lowest_price.value):
            product.lowest_price = price

        if product.highest_price is None or (price.value is not None and price.value >= product.highest_price.value):
            product.highest_price = price

        # remove the elements that are not a field in Product model
        if 'price' in amazon_data:
            amazon_data.pop('price')
        if 'currency' in amazon_data:
            amazon_data.pop('currency')

        # update and save the product
        product.__dict__.update(amazon_data)
        product.status = 1
        product.date_last_synced = now
        product.save()

        if price.value is not None:
            # get all subscriptions of product that are subscribed to the current price or a higher one and
            # whose owners have not been notified about that particular subscription price since before
            # settings.PRICE_MONITOR_SUBSCRIPTION_RENOTIFICATION_MINUTES.
            for sub in Subscription.objects.filter(
                Q(
                    product=product,
                    price_limit__gte=price.value,
                    date_last_notification__lte=(timezone.now() - timedelta(minutes=app_settings.PRICE_MONITOR_SUBSCRIPTION_RENOTIFICATION_MINUTES))
                ) | Q(
                    product=product,
                    price_limit__gte=price.value,
                    date_last_notification__isnull=True
                )
            ):
                # FIXME: how to handle failed notifications?
                NotifySubscriberTask().apply_async((product.pk, price.pk, sub.pk), countdown=5)

class NotifySubscriberTask(Task):

    """Task for notifying a single user about a product that has reached the desired price."""

    def run(self, product_pk, price_pk, subscription_pk, **kwargs):
        """
        Sends an email to the subscriber.

        :param product_pk: the id of product to notify about
        :type product_pk: int
        :param price_pk: the id of current price of the product
        :type price_pk: int
        :param subscription_pk: the id of Subscription class connecting subscriber and product
        :type subscription_pk: int
        """
        try:
            product = Product.objects.get(pk=product_pk)
        except Product.DoesNotExist:
            logger.error('Product with PK %d could not be found.', product_pk)
            return False

        try:
            price = Price.objects.get(pk=price_pk)
        except Price.DoesNotExist:
            logger.error('Price with PK %d could not be found.', price_pk)
            return False

        try:
            subscription = Subscription.objects.get(pk=subscription_pk)
        except Subscription.DoesNotExist:
            logger.error('Subscription with PK %d could not be found.', subscription_pk)
            return False

        logger.info('Trying to send notification email to %s...', subscription.email_notification.email)
        try:
            send_mail(product, subscription, price, self.get_audience_rating_info(product))
        except SMTPServerDisconnected:
            logger.exception('SMTP server was disconnected.')
        else:
            logger.info('Notification email to %s was sent!', subscription.email_notification.email)
            subscription.date_last_notification = timezone.now()
            subscription.save()
            return True

        return False

    # TODO move to Product
    def get_audience_rating_info(self, product):
        """
        Checks, if the product matches specific audience rating and includes additional information.

        If the region is DE and the product is a FSK 18 one, additionally get all other FSK 18 products and put them into a mailable list.
        see https://github.com/ponyriders/django-amazon-price-monitor/issues/92

        As we do not currently have any use cases that could be generalized to something using the audience rating this is a country specific implementation.
        :param product: the product to check
        :type product:  price_monitor.models.Product
        :return: an additional mail text or empty string if product and installation do not match prerequisites.
        :rtype: str
        """
        # age_identifiers = ['Freigegeben ab 18 Jahren', 'Ages 18 and over']
        # if app_settings.PRICE_MONITOR_AMAZON_PRODUCT_API_REGION == 'DE' and product.audience_rating in age_identifiers:
        #     # mail text
        #     mail_text = ''
        #
        #     # fetch all other products with FSK 18
        #     for p in Product.objects.filter(audience_rating__in=age_identifiers).exclude(pk=product.pk).order_by('current_price'):
        #         mail_text += '{title:s}\n'.format(title=p.get_title())
        #         mail_text += '{price:0.2f} {currency:s} ({price_date:s})\n'.format(
        #             price=p.current_price.value,
        #             currency=p.current_price.currency,
        #             price_date=p.current_price.date_seen.strftime('%b %d, %Y %H:%M %p %Z'),
        #         )
        #         mail_text += '{offer_url:s}\n'.format(offer_url=p.offer_url)
        #         mail_text += '{product_detail_url:s}\n\n'.format(product_detail_url=product.get_detail_url())
        #
        #     # prepend introduction if there were results
        #     if mail_text:
        #         mail_text = '\n{intro:s}\n\n'.format(
        #             intro=ugettext('As this is a FSK 18 article, here are your other subscribed FSK 18 articles:')
        #         ) + mail_text
        #
        #     # return
        #     return mail_text
        return ''


import os
import sys
import time
from datetime import datetime
import numpy as np
import atomize.general_modules.general_functions as general
import atomize.device_modules.Termodat_11M6 as td

if len(sys.argv) > 1:
    test_flag = sys.argv[1]
else:
    test_flag = 'None'

tdat11m6 = td.Termodat_11M6()
timenow = str(datetime.now().strftime("%d-%m-%Y_%H-%M-%S"))
path_to_file = os.path.join('D:/Melnikov/', str(timenow) + '_Column_heating_test' + '.csv')

# Event handling flags
flag1 = 0
flag2 = 0

xs = []
ys1 = []
ys2 = []
ys3 = []
ys4 = []

tdat11m6.tc_setpoint('1','623.1')
tdat11m6.tc_setpoint('2','623.1')
tdat11m6.tc_setpoint('3','623.1')
tdat11m6.tc_setpoint('4','623.1')

# Parameters
heat_time = 3600 # in seconds

# Main loop
for i in range(36000):

    # for heating the indicated amount of time
    now = round(time.time())

    xs = np.append(xs, i)
    temp1 = tdat11m6.tc_temperature('1') - 273.1
    temp2 = tdat11m6.tc_temperature('2') - 273.1
    temp3 = tdat11m6.tc_temperature('3') - 273.1
    temp4 = tdat11m6.tc_temperature('4') - 273.1

    ys1 = np.append(ys1, temp1)
    ys2 = np.append(ys2, temp2)
    ys3 = np.append(ys3, temp3)
    ys4 = np.append(ys4, temp4)

    general.plot_1d('Plot 1', xs, ys1, label='ch1')
    general.plot_1d('Plot 2', xs, ys2, label='ch2')
    general.plot_1d('Plot 3', xs, ys3, label='ch3')
    general.plot_1d('Plot 4', xs, ys4, label='ch4')

    if flag1 == 0 and (temp1 > 350 or temp2 > 350 or temp3 > 350 or temp4 > 350):
        temp_reached = round(time.time())
        flag1 = 1
        general.message('Target temperature has been reached')

    if flag2 == 0 and flag1 == 0:
        pass
    elif flag2 == 0 and flag1 == 1:
        if abs(now - temp_reached) > heat_time:
            flag2 = 1
            tdat11m6.tc_setpoint('1','253')
            tdat11m6.tc_setpoint('2','253')
            tdat11m6.tc_setpoint('3','253')
            tdat11m6.tc_setpoint('4','253')
            general.message('Heating is OFF')
    else:
        pass

    if test_flag != 'test':

        head = '' # set empty header
        if not os.path.isfile(path_to_file): # checks if the file exists
            head = 'Time step: ' + '1 s\n'+ \
            'Ch1 - Ch2 - Ch3 - Ch4 (deg. Celcius):'  # if it doesn't then add the header
        file_save = open(path_to_file, 'a')

        np.savetxt(file_save, np.c_[xs[i], ys1[i], ys2[i], ys3[i], ys4[i]], fmt='%.1f', delimiter=',', \
            newline='\n', footer='', header=head, comments='# ', encoding=None)

        file_save.close()

    elif test_flag == 'test':
        pass

    general.wait('1 s')


import os
import time
from prometheus_client import start_http_server, Gauge, Histogram, Counter
import requests
import logging

logger=logging.getLogger()
logging.basicConfig(level=logging.DEBUG)

_INF = float("inf")

class AppMetrics:
    def __init__(self, app_port=8000, polling_interval_seconds=5):
        self.app_port = app_port
        self.polling_interval_seconds = polling_interval_seconds

        # Prometheus metrics to collect
        self.total_requests = Counter("total_request","Total request")
        self.total_succ_requests = Counter("total_succ_request", "Total successful request")
        self.total_fail_requests = Counter("app_total_fail_request","Total failed request")
        self.time_dur = Histogram('python_request_duration_seconds', 'Histogram for the duration in seconds.', buckets=(1, 2, 5, 6, 10, _INF))

        self.total_number_per_label =  {
            'airplane': Counter("total_airplane_requests", "Total airplane requests"),
            'automobile': Counter("total_automobile_request", "Total automobile requests"),
            'bird': Counter("total_bird_requests", "Total bird requests"),
            'cat':Counter("total_cat_requests", "Total cat requests"),
            'deer':Counter("total_deer_requests", "Total deer requests"),
            'dog':Counter("total_dog_requests", "Total dog requests"),
            'frog':Counter("total_frog_requests", "Total frog requests"),
            'horse':Counter("total_horse_requests", "Total horse requests"),
            'ship':Counter("total_ship_requests", "Total ship requests"),
            'truck':Counter("total_truck_requests", "Total truck requests")
            }

        self.total_acc_per_label =  {
            'airplane': Gauge("total_airplane_acc", "total airplane accuracy"),
            'automobile': Gauge("total_automobile_acc", "total automobile accuracy"),
            'bird': Gauge("total_bird_acc", "total bird accuracy"),
            'cat':Gauge("total_cat_acc", "total cat accuracy"),
            'deer':Gauge("total_deer_acc", "total deer accuracy"),
            'dog':Gauge("total_dog_acc", "total dog accuracy"),
            'frog':Gauge("total_frog_acc", "total frog accuracy"),
            'horse':Gauge("total_horse_acc", "total horse accuracy"),
            'ship':Gauge("total_ship_acc", "total ship accuracy"),
            'truck':Gauge("total_truck_acc", "total truck accuracy")
            }

        self.average_acc = Gauge("average_acc", "Average accuracy for all labels")

    def run_metrics_loop(self):
        while True:
            self.fetch()
            time.sleep(self.polling_interval_seconds)

    def fetch(self):
        # Fetch raw status data from the application
        status_data = None
        try:
            headers = {'Accept': 'application/json'}
            resp = requests.get(url=f"http://localhost:{self.app_port}/metric", headers=headers)
            status_data = resp.json()
        except Exception as e:
            print(e)
        if status_data is not None:
            # logger.info(status_data)
            # Update Prometheus metrics with application metrics
            self.total_requests.inc(status_data['suc_requests'] + status_data['failed_requests'])
            self.total_succ_requests.inc(status_data['suc_requests'])
            self.total_fail_requests.inc(status_data['failed_requests'])

            for item, accuracy in status_data['acc_per_label'].items():
                for acc in accuracy:
                    self.total_acc_per_label[item].set(acc)

            for item, num in status_data['num_labels'].items():
                self.total_number_per_label[item].inc(num)

            for dur in status_data['time_dur']:
                self.time_dur.observe(dur)

def main():

    polling_interval_seconds = int(os.getenv("POLLING_INTERVAL_SECONDS", "5"))
    app_port = int(os.getenv("APP_PORT", "8000"))
    exporter_port = int(os.getenv("EXPORTER_PORT", "9877"))
    logger.info(f"exporter started on port 9877")

    app_metrics = AppMetrics(
        app_port=app_port,
        polling_interval_seconds=polling_interval_seconds
    )
    start_http_server(exporter_port)
    app_metrics.run_metrics_loop()

if __name__ == "__main__":
    main()


# -*- coding: utf-8 -*-
import scrapy
from yun_shang_wang.items import YunShangWangItem
import re

class YswSpider(scrapy.Spider):
    name = 'ysw'
    allowed_domains = ['www.ynshangji.com',
                       'ynshangji.com'
                       ]
    start_urls = ['http://www.ynshangji.com/']
    # start_urls = ['http://13281188246.ynshangji.com/liuyan/']

    '''
    http://shunda03.ynshangji.com/liuyan/
    http://zhisheng123.ynshangji.com/liuyan/
    ttp://13281188246.ynshangji.com/liuyan/

    '''

    def parse(self, response):
        # 大分类
        class_list = response.xpath('//ul[@class="m_zl"]//li//a')
        print('----- len(class_list)', len(class_list))
        if class_list != []:
            for min_class in class_list:
                p_d_url = min_class.xpath('./@href')
                if p_d_url != []:
                    page_data_url = p_d_url.extract()[0]
                    yield scrapy.Request(url=page_data_url, callback=self.parse_page_data)

    def parse_page_data(self, response):
        # 页面上列表  翻页
        print('***** ',response.url)
        data_list = response.xpath('//div[@class="s-list s-pro-list"]/ul//li')
        n_url = response.xpath('//div[@class="paging mb30"]/a[last()]/@href')
        print('**** len(data_list) = ', len(data_list))
        if data_list != []:
            for data_info in data_list:
                d_url = data_info.xpath('.//div[@class="company"]/a[2]/@href')
                if d_url != []:
                    data_url = d_url.extract()[0] + '/liuyan/'
                    yield scrapy.Request(url=data_url, callback=self.parse_data, meta={'info_url':data_url})

        # 翻页
        if n_url != []:
            next_url = 'http://www.ynshangji.com' + n_url.extract()[0]
            print('next_url = ', next_url)
            yield scrapy.Request(url=next_url, callback=self.parse_page_data)

    def parse_data(self, response):
        # 详细信息
        print('+++++ ', response.url)
        data_info = response.xpath('//table[@class="bgcolor3"]//tr')
        print('++++++++ ', len(data_info))
        # print('+++ ', response.body.decode('gbk'), '+++')

        item = YunShangWangItem()
        # 爬取对应官网名称(siteName) 例： 阿里巴巴商友圈
        item['siteName'] = '云商网'
        # 爬取对应官网链接(webLinks) 例： https://club.1688.com/
        item['webLinks'] = 'http://www.ynshangji.com/'
        # 对应详情页链接(detailLink)：  	https://qiye.gongchang.com/hongyipu/contact/
        item['detailLink'] = response.meta['info_url']
        data_list = response.xpath('//table[@id="viewAttribute"]//tr')
        # 企业名称:(companyName)			中国科学器材有限公司
        item['companyName'] = ''
        companyName = response.xpath('//table[@class="bgcolor3"]//tr[1]/td[2]/text()').extract()
        print('companyName = ', companyName)
        if companyName == []:
            companyName = response.xpath('//div[@id="bodyleft"]//li[1]/text()').extract()
            if companyName != []:
                item['companyName'] = companyName[0].replace('\xa0', '').replace('\n', '').replace('\t', '').replace('\r', '')
        else:
            item['companyName'] = companyName[0].replace('\xa0', '').replace('\n', '').replace('\t', '').replace('\r', '')

        # print('************ ', item['companyName'])
        # 企业英文名：(companyEnglishName)			China National Scientific Instruments and Materials Co., Ltd
        item['companyEnglishName'] = ''
        # 注册类型：(registrationType)		供应商
        item['registrationType'] = ''
        # 企业性质：(companyType)			国有绝对控股企业
        item['companyType'] = ''
        # 成立时间:(establishedTime)   		2015-07-22
        item['establishedTime'] = ''
        # 营业执照号:(businessLicenseNo)			91331102350072370U
        item['businessLicenseNo'] = ''
        # 经营模式：(businessModel)			贸易型
        item['businessModel'] = ''
        # 注册资本：(registeredCapital)			400000.000000 万元
        item['registeredCapital'] = ''
        # 雇员人数：(employee)			301-500 人
        item['employee'] = ''
        # 联 系 人：(contact)			雷靖行
        item['contact'] = ''
        contact = response.xpath('//table[@class="bgcolor3"]//tr[1]/td[4]/text()').extract()
        if contact == []:
            contact = response.xpath('//div[@id="bodyleft"]//li[3]/text()').extract()
            if contact != []:
                item['contact'] = contact[0].replace(' ', '').replace(':', '').replace('：', '').replace('\n', '').replace('\t', '').replace('\r', '').replace('联系人', '')
        else:
            item['contact'] = contact[0].replace('\xa0', '').replace('\n', '').replace('\t', '').replace('\r', '')
        # 手机号码：(phoneNumber)			18117451540
        item['phoneNumber'] = ''
        phoneNumber = response.xpath('//table[@class="bgcolor3"]//tr[2]/td[4]/text()').extract()
        if phoneNumber == []:
            phoneNumber = response.xpath('//div[@id="bodyleft"]//li[5]/text()').extract()
            if phoneNumber != []:
                item['phoneNumber'] = phoneNumber[0].replace(' ', '').replace(':', '').replace('：', '').replace('\n', '').replace('\t', '').replace('\r', '').replace('手机', '')
        else:
            item['phoneNumber'] = phoneNumber[0].replace(' ', '').replace('\n', '').replace('\t', '').replace('\r', '')
        # 联系电话：(telephone)			0755-00000000
        item['telephone'] = ''
        telephone = response.xpath('//table[@class="bgcolor3"]//tr[2]/td[2]/text()').extract()
        if telephone == []:
            telephone = response.xpath('//div[@id="bodyleft"]//li[4]/text()').extract()
            if telephone != []:
                item['telephone'] = telephone[0].replace(' ', '').replace(':', '').replace('：', '').replace('\n', '').replace('\t', '').replace('\r','').replace('电话', '')
        else:
            item['telephone'] = telephone[0].replace('\xa0', '').replace('\n', '').replace('\t', '').replace('\r','')
        # 公司传真：(companyFax)			0755-00000000
        item['companyFax'] = ''
        # E-MAIL  : (Email)  		18641572818@163.com
        item['Email'] = ''
        Email = response.xpath('//table[@class="bgcolor3"]//tr[3]/td[4]/text()').extract()
        if Email != []:
            if '系统已隐藏' not in Email[0]:
                item['Email'] = Email[0].replace('\n', '').replace('\t', '').replace('\r','')

        # Q Q号 码：(qq)   		282278944
        item['qq'] = ''
        qq = response.xpath('//table[@class="bgcolor3"]//tr[4]/td[4]/a/@href').extract()
        if qq == []:
            qq = response.xpath('//table[@class="bgcolor3"]//tr[4]/td[4]/a/img/@src').extract()
            if qq != []:
                item['qq'] = qq[0].replace('\n', '').replace('\t', '').replace('\r', '').replace(':', ':').replace('：', ':').split(':')[2]
        else:
            item['qq'] = re.findall(r'uin=(.*?)&Site', qq[0].replace('\xa0', '').replace('\n', '').replace('\t', '').replace('\r', ''), re.DOTALL)[0]
        # 微信： (wechat)  		mdjx6673
        item['wechat'] = ''
        # 邮政编码：	(postcode)		210000
        item['postcode'] = ''
        # 客服旺旺：	(angelBeauty)		**********
        item['angelBeauty'] = ''
        # 主营产品：(mainProducts)			理化分析仪器、光学仪器、电子仪器及配件、生物技术及生物工程设备、计算机及附属设备
        item['mainProducts'] = ''
        # 企业地址：(businessAddress)			北京市朝阳区太阳宫中路19号院1号楼4层
        item['businessAddress'] = ''
        businessAddress = response.xpath('//table[@class="bgcolor3"]//tr[3]/td[2]/text()').extract()
        if businessAddress == []:
            businessAddress = response.xpath('//div[@id="bodyleft"]//li[6]/text()').extract()
            if businessAddress != []:
                item['businessAddress'] = businessAddress[0].replace(' ', '').replace(':', '').replace('：', '').replace('\xa0', '').replace('\n', '').replace('\t','').replace('\r', '').replace('地址', '')
        else:
            item['businessAddress'] = businessAddress[0].replace('\xa0', '').replace('\n', '').replace('\t','').replace('\r', '')
        # 企业网址：(Website)			www.csimc.com.cn
        item['Website'] = ''
        Website = response.xpath('//table[@class="bgcolor3"]//tr[5]/td[2]/a/@href').extract()
        if Website == []:
            pass
        else:
            item['Website'] = Website[0].replace('\xa0', '').replace('\n', '').replace('\t', '').replace('\r', '')
        print('item = ', item)
        # if item['phoneNumber'] != '':
        yield item


import html
from typing import TYPE_CHECKING, Union

from prompt_toolkit import Application, HTML
from prompt_toolkit.data_structures import Point
from prompt_toolkit.layout.controls import FormattedTextControl

from ..data.table import Table
from ..data.type import TablePromptDict, TablePromptList

if TYPE_CHECKING:  # pragma: no cover
    from pandas import DataFrame

class TablePrompt(Application):

    def __init__(
        self,
        question: str,
        data: Union["DataFrame", TablePromptDict, TablePromptList],
        *args,
        **kwargs,
    ):
        super().__init__(*args, **kwargs)

        # get prompt content box
        self.prompt_content: FormattedTextControl = self.layout.container.get_children()[0].content  # type: ignore

        # save question
        self.question = question

        # process data
        self.table = Table(data)

        # set cursor
        self.prompt_content.get_cursor_position = lambda: Point(
            self.table.get_current_cursor_position()[0],
            self.table.get_current_cursor_position()[1] + 1,  # add 1 offset for height of question
        )

    def update(self):
        """update prompt content"""
        content = f'[<question_mark>?</question_mark>] <question>{self.question}</question>:\n'

        # append table
        content += html.escape(
            self.table.get_table_as_str()
        )  # escaping is needed so formatting from PromptToolkit won't destroy the whole table

        self.prompt_content.text = HTML(content)

    def prompt(self) -> Union["DataFrame", TablePromptDict, None]:
        """start the application, returns the return value"""
        self.update()
        out: Union["DataFrame", TablePromptDict, None] = self.run()

        return out

    def on_up(self):
        """when up is pressed, the cell one above will be selected"""
        self.table.on_up()

        self.update()

    def on_down(self):
        """when down is pressed, the cell one below will be selected"""
        self.table.on_down()

        self.update()

    def on_left(self):
        """when left is pressed, the cell one to the left will be selected"""
        self.table.on_left()

        self.update()

    def on_right(self):
        """when left is pressed, the cell one to the right will be selected"""
        self.table.on_right()

        self.update()

    def on_key(self, key_sequence: list[str]):
        """when a key is pressed, the key will be added to the current cells content"""
        key = key_sequence[0]
        self.table.add_key(key)

        self.update()

    def on_backspace(self):
        """when backspace is pressed, the last char will be removed from the current cells content"""
        self.table.del_key()

        self.update()

    def on_enter(self):
        # return the modified table
        self.exit(result=self.table.data.get_data())


import networkx as nx
import time
import numpy as np
import heapq
import network_process as ns
import TARank as AUC
import matplotlib.pyplot as plt
import math

'''
选择候选节点集
'''
'''
创新：1.初始化节点排序是整个图的节点排序 而不是社区内的节点排序 这使得在社区内部也考虑了网络全局信息
    2.在进行候选节点选择时，由于初始化BGN是反向地加入节点，首先加入的是网络中最不重要的节点，所以在遍历一部分最不重要的节点后，
    剩余节点满足候选节点的数量要求后，直接将剩余节点加入候选节点集，不用再计算其加入网络的最大连通分量的大小，减小其时间复杂度的同时提高准确率。
'''

def sortNode(G):
    '''
    按度从大到小排序
    '''
    matG = []
    nodeG = nx.nodes(G)
    # print(nodeG)
    matG.append(nodeG)  # 加入节点列表
    degreeG = list(dict(nx.degree(G)).values())
    # print(degreeG)
    matG.append(degreeG)  # 加入度列表
    # print(matG) #1127, 1128, 1129, 1130, 1131, 1132, 1133, 0)), dict_values([38, 30, 22, 10, 21, 26, 8,
    matG = np.array(matG)
    result = matG.T[np.lexsort(-matG)].T  # 按最后一行的顺序逆序  # 按度从大到小排序
    # x.T 将x 转置   a.T[np.lexsort(a)].T按最后一行顺序排序
    # np.lexsort((b,a)) # Sort by a, then by b
    li = result[0]  # 返回与度从大到小的节点序号
    return li

def greedHeap(G, vrank, c_size):  # vrank节点排序序列  #
    '''

    :param G:
    :param vrank:
    :param c_size: 想要选取的候选节点数量  则进行Heap_BGN的节点有 len(G)-c_size
    :return:
    '''
    heap = []
    len_G = len(G)
    S = []  # 集合S存放每次选择的节点
    # !!!!!!!! 不是顺序递增 就用字典来存储
    # cost = [1]*len_G  # 加入节点之后的R值（鲁棒性值）
    cost = {node: 1 for node in G.nodes()}  # 节点的R值（鲁棒性值）
    # is_update = np.zeros(len_G)  #已更新为1

    is_update = {node: 0 for node in G.nodes()}  # 记录是否被更新

    # print('社区内节点：', G.nodes())

    # Cluster = [set()] * len_G  # 用以记录每一个集团的成员节点
    # Cluster = {node: set() for node in G.nodes()}
    Cluster = {i: set() for i in range(len_G)}

    # NodeCluster = [0]*len_G #记录每一个节点所属集团的ID
    NodeCluster = {node: 0 for node in G.nodes()}  # 记录每一个节点所属集团的ID

    newClusterId = 1
    maxcluster = 1  # 最大连通分量的大小
    sumcluster = 0
    '''
    for i in range(len_G):
        heapq.heappush(heap,(cost[i],i,vrank[i]))#建堆
    '''
    i = 0
    for node in G.nodes():
        heapq.heappush(heap, (cost[node], i, vrank[i]))  # 根据初始化排序 去构建堆
        i += 1
    # print '建堆完成'
    print(heap)
    while len(heap) > c_size:
        v = heapq.heappop(heap)  # 从堆中删除元素，返回值是堆中最小的元素
        nodev = v[2]  # 弹出被选择的节点
        # print('被弹出节点：',nodev)
        if is_update[nodev] == 1:
            NodeCluster, Cluster, newClusterId, maxcluster = chooseV(nodev, G, NodeCluster, Cluster, newClusterId,
                                                                     maxcluster)
            sumcluster = sumcluster + maxcluster
            S.append(nodev)
            is_update = {node: 0 for node in G.nodes()}  # 选完一个节点后更新状态为未更新
        else:  # 如果没有更新则更新
            cost[nodev] = updateCost(nodev, G, NodeCluster, cost, Cluster, maxcluster)  # 更新节点的cost
            is_update[nodev] = 1  # 标记为已更新
            heapq.heappush(heap, (cost[nodev], v[1], nodev))  # 放入堆
    rnum = (sumcluster - len_G) / len_G / len_G
    # print (rnum)
    # print(S)
    S = set(G.nodes) - set(S)  # 求剩下的相对重要的节点
    return S

def updateCost(nodev, G, NodeCluster, cost, Cluster, maxcluster):  # 更新节点的cost       计算最大连通分量的大小
    ci = set()  # 记录nodev可能连接的集团的ID集合
    for vj in nx.all_neighbors(G, nodev):
        if NodeCluster[vj] != 0:  # vj已属于某个集团
            ci.add(NodeCluster[vj])
    sumc = 1
    for name in ci:
        sumc = sumc + len(Cluster[name])
    if sumc < maxcluster:
        sumc = maxcluster
    cost[nodev] = sumc
    return cost[nodev]

def chooseV(nodev, G, NodeCluster, Cluster, newClusterId, maxcluster):  # 选择该节点:创建新集团 or 合并集团    维持派系
    ci = set()  # 记录vi可能连接的集团的ID集合
    for vj in nx.all_neighbors(G, nodev):
        if NodeCluster[vj] != 0:  # vj已属于某个集团
            ci.add(NodeCluster[vj])
    if len(ci) == 0:  # 即新加入的节点为孤立节点
        NodeCluster[nodev] = newClusterId  # 分配给新的集团
        Cluster[newClusterId] = set()  # 新集团
        Cluster[newClusterId].add(nodev)  # 将vi加入
        newClusterId = newClusterId + 1
    else:  # 加入的节点不是孤立节点
        minci = min(ci)  # 记录Ci中编号最小的集团ID，记为minci
        NodeCluster[nodev] = minci  # 节点vi所属集团的ID minci
        Cluster[minci].add(nodev)  # 将节点vi加入到编号为minci的集团中
        # 将Ci中所有集团的成员节点都合并，均放入minci中
        for name in ci:
            if name != minci:
                for nod in Cluster[name]:
                    NodeCluster[nod] = minci  # 修改集团索引
                    Cluster[minci].add(nod)
        if len(Cluster[minci]) > maxcluster:
            maxcluster = len(Cluster[minci])  # 最大连通分量的大小
    return NodeCluster, Cluster, newClusterId, maxcluster

'''  选择一部分节点 一部分不重要的节点'''
def imp_BGN(G,rank_dg,rank_ks,seed_size): # seed_size选择的种子节点数量
    eplision=0.1  # 控制参数
    len_G = len(G)
    S = []  # 集合S存放每次选择的节点
    G_R=G.copy()
    # !!!!!!!! 不是顺序递增 就用字典来存储
    cost = {node: 1 for node in G.nodes()}  # 节点的R值（鲁棒性值）thtea
    deg_ks={node:eplision*(rank_dg[node]+rank_ks[node]) for node in G.nodes()}  # 辅助判断  保证辅助判断小于1
    # is_affected={node:0 for node in G.nodes()}  # 初始化所有节点未被影响

    # is_update = {node: 0 for node in G.nodes()}  # 记录是否被更新

    # print('社区内节点：', G.nodes())

    # Cluster = [set()] * len_G  # 用以记录每一个集团的成员节点  # 错误用法,因为用*的话，赋予统一空间，修改时会修改所有!!!!  应该用列表生成器
    # Cluster={node:set() for node in G.nodes()}

    Cluster = {i: set() for i in range(len_G)}

    NodeCluster = {node: 0 for node in G.nodes()}  # 记录每一个节点所属集团的ID

    newClusterId = 1
    maxcluster = 1  # 最大连通分量的大小
    while len(G_R)>seed_size:
        for node in G_R.nodes():  # 对于即将要加入图的节点计算其鲁棒性值，选其鲁棒性值最小的  # ！！！！！修改不是所有节点都进行更新操作 受影响的节点才进行更新
            cost[node] = updateCost(node, G, NodeCluster, cost, Cluster, maxcluster)+deg_ks[node]  # 更新节点的cost
        # thtea=sorted(cost.items(),key=lambda x:x[1],reverse=True) #从大到小排列
        # node_min=thtea[0][0]
        node_min=min(cost.items(),key=lambda x:x[1])[0] # 取节点
        NodeCluster, Cluster, newClusterId, maxcluster = chooseV(node_min, G, NodeCluster, Cluster, newClusterId,maxcluster)  # 即添加节点
        # 添加节点需要计算哪些节点受到影响
        S.append(node_min)
        G_R.remove_node(node_min)
        cost.pop(node_min)
    S = list(set(G.nodes) - set(S))  # 剩余的节点就是相对重要的节点   大量节省了时间
    return S

def imp_BGN_BFS(G,auc,eplision,seed_size): # auc 分数进行辅助判断  seed_size 选择的种子节点数量  eplision 区分参数 对于不同的网络有不同的值
    # eplision=0.01  # 控制参数  根据网络变化
    # eplision=0.0001   # for email
    len_G = len(G)
    S = []  # 集合S存放每次选择的节点
    G_R=G.copy()
    # !!!!!!!! 不是顺序递增 就用字典来存储
    cost = {node: 1 for node in G.nodes()}  # 节点的R值（鲁棒性值）thtea

    Cluster = {i: set() for i in range(len_G)}
    NodeCluster = {node: 0 for node in G.nodes()}  # 记录每一个节点所属集团的ID

    newClusterId = 1
    maxcluster = 1  # 最大连通分量的大小
    # sumcluster = 0
    while len(G_R)>seed_size:
        for node in G_R.nodes():  # 对于即将要加入图的节点计算其鲁棒性值，选其鲁棒性值最小的  # ！！！！！修改不是所有节点都进行更新操作 受影响的节点才进行更新
            cost[node] = updateCost(node, G, NodeCluster, cost, Cluster, maxcluster)*(1+eplision*auc[node])  # 更新节点的cost
        # thtea=sorted(cost.items(),key=lambda x:x[1],reverse=True) #从大到小排列
        # node_min=thtea[0][0]
        node_min=min(cost.items(),key=lambda x:x[1])[0] # 取节点
        NodeCluster, Cluster, newClusterId, maxcluster = chooseV(node_min, G, NodeCluster, Cluster, newClusterId,maxcluster)  # 即添加节点
        # 添加节点需要计算哪些节点受到影响
        S.append(node_min)
        G_R.remove_node(node_min)
        cost.pop(node_min)
    S = list(set(G.nodes) - set(S))  # 剩余的节点就是相对重要的节点   大量节省了时间
    return S

def calcNode_E1(G,v): # 邻居节点的度的熵
    result = 0
    degree1 = 0
    for u in list(G.neighbors(v)):  # 求节点v的邻居节点的度之和
        degree1 += G.degree(u)

    for u in list(G.neighbors(v)):
        result += G.degree(u) / degree1 * math.log(G.degree(u) / degree1)
    return -1 * result

def calcNode_E2(G): # 用度计算
    all_degree = nx.number_of_edges(G) * 2  # 网络中所有节点度之和 边2的数量*2
    # node's information pi
    node_information={}
    for node in G.nodes():
        node_information[node]=0
        for u in nx.neighbors(G,node):
            node_information[node]+=-(G.degree(u)/all_degree)*math.log(G.degree(u)/all_degree)
    return node_information

def get_seeds_by_HeapBGN(g, com_nodes,init_rank,seed_candidate):
    '''
    根据传入的参数选择备选节点加入备选节点库  在每个社区中选择
    :param g: 整体的社交网络
    :param com_nodes: 当前社区
    inin_rank：初始化排序
    :return:
    注意：测试初始化排序是社区内部的还是整个图的 是整个图的还是只是社区内部的？？？
    '''

    seed = []  # 返回选取的高影响力种子节点
    initrank_c=[] # 社区内部的初始化排序
    # 根据节点获取图的子图 社区
    community_graph = nx.subgraph(g, com_nodes)
    # nx.draw(community_graph, with_labels=True)
    # plt.show()

    node_c=community_graph.nodes()
    # 找到社区内部对应的初始化排序
    for i in range(len(init_rank)):
        if init_rank[i] in node_c:
            initrank_c.append(init_rank[i])

    # size_g = len(community_graph)  # 计算社区大小
    # ！！！！计算需要多少节点传入候选节点=======公式==== 0.5*size_g  相对于每个社区大小选取
    # initial-BGN  在每个社区中进行 然后截取部分节点
    # !!!!! 因为最先选择的节点是最不重要的节点 节点需要反转  所以只对部分节点进行HeapBGN操作 剩下的直接传入候选节点集 不用再对剩下的重要节点排序
    # seed_len = 0.6 * size_g
    # initrank = list(sortNode(community_graph))  # 初始化排序   社区内部
    # initrank.reverse()  # 度从小到大的编号

    print('初始化排序：', initrank_c)
    seed = greedHeap(community_graph, initrank_c, seed_candidate)  # 在每个社区中
    return list(seed)

def get_seeds_by_impBGN(g, com_nodes,rank1,rank2,seed_candidate):  # 在社区内部执行改进的BGN
    '''

    :param g:
    :param com_nodes: 社区内的节点集
    :param rank1:
    :param rank2:
    :param seed_candidate: 候选种子节点
    :return:
    '''
    # 根据节点获取图的子图 社区
    community_graph = nx.subgraph(g, com_nodes)
    # size_g = len(community_graph)  # 计算社区大小
    # ！！！！计算需要多少节点传入候选节点=======公式==== 0.5*size_g  相对于每个社区大小选取
    # initial-BGN  在每个社区中进行 然后截取部分节点
    # !!!!! 因为最先选择的节点是最不重要的节点 节点需要反转  所以只对部分节点进行HeapBGN操作 剩下的直接传入候选节点集 不用再对剩下的重要节点排序
    # seed_candicate = 0.6 * size_g
    seed=imp_BGN(community_graph,rank1,rank2,seed_candidate)
    return seed

'''  选择一部分节点 一部分不重要的节点'''

def get_seeds_by_impBGNBFS(g, com_nodes,auc,eplision,seed_candidate): # auc 分数进行辅助判断  eplision 区分参数
    # 根据节点获取图的子图 社区
    community_graph = nx.subgraph(g, com_nodes)
    # size_g = len(community_graph)  # 计算社区大小
    # ！！！！计算需要多少节点传入候选节点=======公式==== 0.5*size_g  相对于每个社区大小选取
    # initial-BGN  在每个社区中进行 然后截取部分节点
    # !!!!! 因为最先选择的节点是最不重要的节点 节点需要反转  所以只对部分节点进行HeapBGN操作 剩下的直接传入候选节点集 不用再对剩下的重要节点排序
    # seed_candicate = 0.6 * size_g
    seed = imp_BGN_BFS(community_graph,auc,eplision,seed_candidate)
    return seed

if __name__ == '__main__':
    # 输入图
    # G = nx.karate_club_graph()
    eplision=0.1
    G=nx.read_edgelist('data/karate_edges.txt',nodetype=int)
    com_lists = ns.get_community(G)  # 获得社区列表
    print(com_lists)
    print(com_lists[0])
    start_time = time.process_time()
    # 传入整个图的初始化排序
    init_rank_G=list(sortNode(G))
    init_rank_G.reverse()
    com_seed = get_seeds_by_HeapBGN(G, com_lists[0],init_rank_G,3)
    end_time = time.process_time()
    print('-----------------------')
    print('HeapBGN候选节点degree:',com_seed)  # 选出的候选节点集
    print('运行时间：', end_time - start_time)

    print('------------------------')

    node_ks = nx.core_number(G)
    node_ks_min = min(node_ks.items(), key=lambda x: x[1])[1]
    node_ks_max = max(node_ks.items(), key=lambda x: x[1])[1]
    # node_ks=sorted(node_ks.items(),key=lambda x:x[1],reverse=True)

    print('--------求节点的熵1-邻居节点------------')
    node_information1 = {node: calcNode_E1(G, node) for node in G.nodes()}
    node_inf_min = min(node_information1.items(), key=lambda x: x[1])[1]
    node_inf_max = max(node_information1.items(), key=lambda x: x[1])[1]
    print('节点熵：', node_information1)
    # 归一化

    # 对k-shell 值归一化  不用排序
    print('节点k-shell:',node_ks)
    for node in node_ks:  # 遍历字典键
        node_ks[node] = float(node_ks[node] - node_ks_min) / (node_ks_max - node_ks_min)
    print('归一化节点k-shell:',node_ks)

    print('--------对节点熵1进行归一化------------')
    for node in node_information1:  # 遍历字典键
        node_information1[node] = float(node_information1[node] - node_inf_min) / (node_inf_max - node_inf_min)
    print(node_information1)

    print('初始化排序：')

    init_rank={node: eplision*(node_information1[node]+node_ks[node]) for node in G.nodes()}
    init_rank=sorted(init_rank.items(),key=lambda x:x[1])   # 从小到大排序
    print(init_rank)
    # print(init_rank[0])
    initrank=[]
    for node,score in init_rank: # 初始化排序 从小到大的节点列表
        initrank.append(node)
    print('初始化排序结果',initrank)

    seed_imp= get_seeds_by_impBGN(G,com_lists[0],node_information1,node_ks,3)
    seed_imp_heap=get_seeds_by_HeapBGN(G,com_lists[0],initrank,3)
    print('改进熵度BGN候选节点：',seed_imp)
    print('改进熵度Heap-BGN候选节点：',seed_imp_heap)

    auc_score = AUC.process(G)
    print('AUC分数：', auc_score)
    auc_min = min(auc_score.items(), key=lambda x: x[1])[1]
    auc_max = max(auc_score.items(), key=lambda x: x[1])[1]
    # 进行归一化
    print('---------------归一化AUC分数-----------')
    for node in auc_score:  # 遍历字典键
        auc_score[node] = float(auc_score[node] - auc_min) / (auc_max - auc_min)
    print(auc_score)

    seed_impBGNAUC=get_seeds_by_impBGNBFS(G,com_lists[0],auc_score,0.01,3)
    print('改进BGNAUC候选节点：',seed_impBGNAUC)


# -*- coding: utf-8 -*-

import pandas as pd
import statsmodels.api as sm
import pylab as pl
import numpy as np
from sklearn.metrics import roc_curve, auc

df = pd.read_csv("titanic_all_numeric.csv")

df.columns
df.head()
df.dtypes
#df = df.drop(['age_was_missing'], axis=1)

y = df['survived']

y

X = df.drop(['survived'], axis =1)

df.dtypes

X.columns
y

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

from sklearn.linear_model import LogisticRegression

logreg = LogisticRegression()

# fit the model with data
logreg.fit(X_train,y_train)

#
y_pred=logreg.predict(X_test)
y_pred
y_test

from sklearn import metrics
cnf_matrix = metrics.confusion_matrix(y_test, y_pred)
cnf_matrix

TP = cnf_matrix[0,0]
TN = cnf_matrix[1,1]

FP = cnf_matrix[1,0]
FN=cnf_matrix[0,1]

(TP+TN)/ (TP+TN+FP+FN)

'''
print("Accuracy:",metrics.accuracy_score(y_test, y_pred))

y_test = [1,1,1,1,1,1,1,1,0,0]
y_pred = [1,1,1,1,1,1,1,1,1,1]
y_test = [0,0,0,0,0,0,0,0,0,0]
'''

print("Accuracy:",metrics.accuracy_score(y_test, y_pred))

print("Precision:",metrics.precision_score(y_test, y_pred))
print("Recall:",metrics.recall_score(y_test, y_pred))

y_pred_proba = logreg.predict_proba(X_test)[::,1]
y_pred_proba
y_pred_proba.shape

fpr, tpr, _ = metrics.roc_curve(y_test, y_pred_proba)

fpr
tpr

auc = metrics.roc_auc_score(y_test, y_pred_proba)
auc

#together

plt.plot(fpr,tpr,label="data 1, auc="+str(auc))
plt.legend(loc=4)
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic')
plt.legend(loc="lower right")
plt.show();

import math

ls= list(range(-16,16))
ls

y=[]
for x in ls:
    y.append((1)/(1+math.exp(-x)))

y

import matplotlib.pyplot as plt
plt.scatter(ls,y)


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

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

class Solution:
    def upsideDownBinaryTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        def dfs(node):
            res = node
            l = node.left
            if l:
                res = dfs(l)
                l.left = node.right
                l.right = node
            return res

        if not root:
            return None
        res = dfs(root)
        root.left = root.right = None
        return res


# -*- coding:utf8 -*-
import os
from PIL import Image
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data

import numpy as np

source_image_dir = 'image'
source_image_size = 16
target_image_size = 28

source_image = []
source_file_list = os.listdir(source_image_dir)
source_file_list.sort()

for file in source_file_list:
    if not file.find('png') == -1:
        im = np.array(Image.open(os.path.join(source_image_dir, file)).convert('L'), dtype=np.int16)
        source_image.append(im)
mnist = input_data.read_data_sets("image")
target_image = mnist.train.images[:2000]
target_image = np.reshape(target_image, [target_image.shape[0], 28, 28])
target_image_label = mnist.train.labels[:2000]

# 卷积自编码器
learn_rate = 5
loop_num = 100

inputs = tf.placeholder(tf.float32, (1, source_image_size, source_image_size, 1), name='image_input')
targets = tf.placeholder(tf.float32, (target_image_size, target_image_size), name='image_output')
# 解码

# 扩张成28*28
unpool = tf.image.resize_images(inputs, size=(target_image_size, target_image_size),
                                method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)
# 反卷积，得到５个反卷积图像
conv = tf.layers.conv2d_transpose(inputs=unpool, filters=10, kernel_size=(3, 3), strides=1, padding='same',
                                  activation=tf.nn.sigmoid)
conv = conv[0]
# conv1 1x28x28x5
W_image = tf.Variable(initial_value=tf.random_normal(conv.shape), dtype=tf.float32)
W_merge = tf.ones(shape=[conv.shape[0], conv.shape[2], 1])
V_merge = tf.random_normal(shape=[int(conv.shape[0]), int(conv.shape[1]), ])
conv = tf.multiply(W_image, conv)
conv = tf.matmul(conv, W_merge)
conv = tf.reshape(conv, [conv.shape[0], conv.shape[1]])

out = tf.layers.dense(inputs=conv, units=conv.shape[0])
out = tf.sigmoid(out) * 255

loss = tf.losses.mean_squared_error(predictions=out, labels=targets)
tran_op = tf.train.AdadeltaOptimizer(learn_rate).minimize(loss)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    # tf.train.Saver().restore(sess, "./model_save")

    print('working...')
    for i in range(loop_num):
        for t_i, target_im in zip(target_image_label, target_image):
            feed = {inputs: np.reshape(source_image[t_i], [1, source_image_size, source_image_size, 1]),
                    targets: target_im}
            sess.run(tran_op, feed_dict=feed)
        loss_ = sess.run(loss, feed_dict=feed)
        tf.train.Saver().save(sess, "./model_save")
        print('step %d, loss=%f' % (i, loss_))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from enum import Enum
from hpc_ds_types import *
from hpc_ds_desc import HPCDatastoreDescription
from hpc_ds_dsclient import DatasetServerClient
from hpc_ds_reg_client import RegisterServiceClient
from time import time
import requests

class HPCDatastoreRepository(object):
	"""HPC Datastore Repository representation"""

	data_headers = {
		"json": { "Content-Type": "application/json" },
		"string": { "Content-Type": "text/plain; charset=utf-8" }
	}

	def __init__(self, server_url, dataset_path=None, credentials=None):
		"""Set up base URL of the repository to use
		:type dataset_path: str
		:param dataset_path: Identity of the datastore (UUID)

		:type server_url: str
		:param server_url: DataStore server URL, defaults to localhost:9080

		:type credentials: object
		:param credentials: Future access credentials, set to None for now
		"""
		self.server_url = server_url
		self.dataset_path = dataset_path
		self.credentials = credentials

	def assert_dataset_ready(self, dataset_path):
		if dataset_path is None:
			raise InvalidDatasetException(
			"No dataset path has been specified, repository cannot be accessed")

	def get_base_url(self, use_dataset=True):
		"""Returns full datastore URL"""
		retval = self.server_url + DS_PATH
		if use_dataset:
			self.assert_dataset_ready(self.dataset_path)
			retval += '/' + self.dataset_path
		return retval

	def create(self, datastore_description):
		"""Create repository and record the server URL"""
#		print("Request URL: %s" % self.get_base_url(False))
		desc = requests.post(self.get_base_url(False),
								data=datastore_description.to_json(),
								headers=self.data_headers["json"])

		if desc is not None and int(desc.status_code / 100) == 2:
			self.dataset_path = desc.text
		else:
			raise HPCRepositoryAccessException(
			"Dataset has not been created, HTTP error %i" % (desc.status_code))
		return None

	def retrieve(self):
		"""Load repository data"""
		desc = requests.get(self.get_base_url())
		if desc is not None and int(desc.status_code / 100) == 2:
			return desc.json()
		else:
			raise HPCRepositoryAccessException(
			"Dataset %s has not been found, HTTP error %i"
				% (self.dataset_path, desc.status_code))
		return None

	def delete(self, deleted_dataset_path): # =self.dataset_path):
		# Argument forced to rather not to prevent deleting used datasets
		self.assert_dataset_ready(deleted_dataset_path)
		desc = requests.delete(self.get_base_url(False) + '/' + deleted_dataset_path)
		if desc is not None and int(desc.status_code / 100) == 2:
			if deleted_dataset_path == self.dataset_path: self.dataset_path = None
			return True
		elif desc.status_code == 404:
			if deleted_dataset_path == self.dataset_path: self.dataset_path = None
#			return False
#		else:
#			raise HPCRepositoryAccessException(
#				"Dataset %s has not been deleted, HTTP error %i"
#				% (deleted_dataset_path, desc.status_code))
		return False

	def get_common_metadata(self):
		"""Get N5 metadata from repository"""
		self.assert_dataset_ready(self.dataset_path)
		result = requests.get(self.get_base_url() + "/common-metadata")
		if result is not None and int(result.status_code / 100) == 2:
			return result.text

	def set_common_metadata(self, metadata):
		"""Set N5 metadata to repository"""
		self.assert_dataset_ready(self.dataset_path)
		result = requests.post(self.get_base_url() + "/common-metadata",
								data=str(metadata),
								headers=self.data_headers["string"])
		return result is not None and int(result.status_code / 100) == 2

	def add_channels(self, count):
		"""Add extra channels"""
		self.assert_dataset_ready(self.dataset_path)
		result = requests.post(self.get_base_url() + "/channels",
								data=str(count),
								headers=self.data_headers["json"])
		return result is not None and int(result.status_code / 100) == 2

	def rebuild(self, resolutions=[Point3D(1,1,1)]):
		"""Rebuilds data for specified resolutions from base data"""
		self.assert_dataset_ready(self.dataset_path)
		res_url = Point3D(1,1,1).to_ds_url_part() # From doc, otherwise ""
		for resolution in resolutions:
			res_url += Point3D.to_ds_url_part(resolution)
		result = requests.get(self.get_base_url() + res_url + "/rebuild")
		return result is not None and int(result.status_code / 100) == 2

class HPCDatastoreClient(object):
	"""HPC Datastore client implementation in Python 3"""

	def __init__(self, server_url="http://localhost:9080", dataset_path=None,
					access_regime = DatastoreAccess.READ, credentials=None):
		"""Initializes the Data Store connection

		:type dataset_path: str
		:param dataset_path: Identity of the datastore (UUID)

		:type access_regime: DatasetAccess
		:param access_regime: Access regime to the datastore - R/W/RW

		:type server_url: str
		:param server_url: DataStore server URL, defaults to localhost and port 9080

		:type credentials: object
		:param credentials: Future access credentials, set to None for now
		"""

		self.access_regime = access_regime
		self.credentials = credentials
		self.ds_description = None
		#self.server_url = server_url
		self.repository = HPCDatastoreRepository(server_url, dataset_path,
							credentials)

		#Running Data Store servers
		self.ds_servers = dict()

	def load_description(self):
		json_objects=self.repository.retrieve()
		#print(json_objects)
		self.ds_description = HPCDatastoreDescription(json_objects=json_objects)

	def start_dataset_server(self, resolution, access_regime=None,
									version="latest", timeout=15000):
		"""Open dataset server for limited time to work with slices and
		returns object which is representing it

		:type resolutions: ``Point3D``
		:param server_url: (X,Y,Z) tuple representing the resolution levels
		       from HPCDatastoreDescription on individual axes

		:type access_regime: DatastoreAccess
		:param access_regime: Access regime to the datastore - R/W/RW.
				None will result in the default access regime being used.

		:type version: str
		:param version: Name of the version (may be number, latest, ...)

		:type timeout: int
		:param timeout: Timeout of Service Client instance in ms

		:rtype: ``DatasetServerClient``
		:return: A new or already running instance of ``DatasetServerClient``
		"""
		if access_regime is None:
			access_regime = self.access_regime

		if self.ds_description is None:
			self.load_description()

		ds_regserv = RegisterServiceClient(self.repository.get_base_url(),
					access_regime, resolution, version, timeout,
					self.credentials)

		ds_id=ds_regserv.to_url()
		if ds_id in self.ds_servers \
		  and (self.ds_servers[ds_id].expires is None \
				or self.ds_servers[ds_id].expires > time()):
			ds_regserv = self.ds_servers[ds_id]
		else:
			ds_regserv.start()
			self.ds_servers[ds_id] = ds_regserv
			ds_regserv.client.voxel_type = self.ds_description.voxelType

		return ds_regserv.client

	def __str__(self):
		out_s = ""
		for k in self.__dict__:
			out_s += "%s: %s\n" % (k,self.__dict__[k])
		return out_s


import numpy as np
from pysrvf.main_mean import get_data_mean
import time
# from scipy.io import savemat

### ----- 1d examples ----- ###
# Bumps
# Shape is (N x T)
# Xdata = np.load('../data/1d/two_bumps.npy')
# qmean, pmean, pmean_scaled, reformatted_Xdatam _ = get_data_mean(Xdata)

### ----- 2d examples ----- ###
# Dog curves
# Shape is (N x n x T)
Xdata = np.load('../data/3d/sine_curves.npy')
qmean, pmean, pmean_scaled, reformatted_Xdata, qarr, alpha_t_arr = get_data_mean(Xdata)

# 2d parametric curves
# Shape is (n x T x N)
# Xdata = np.load('../data/2d/misc.npy')
# t = time.time()
# # do stuff
# qmean, pmean, pmean_scaled, reformatted_Xdata, _ = get_data_mean(Xdata, subject_first = False)
# print(time.time() - t)

### ----- 3d examples ----- ###
# Xdata = np.load('../data/3d/sine_curves.npy')
# qmean, pmean, pmean_scaled, reformatted_Xdata, _ = get_data_mean(Xdata)

### Plot data and mean ###
import matplotlib.pyplot as plt
N, n, T = np.shape(reformatted_Xdata)

if n == 1:
	for c in reformatted_Xdata:
		plt.plot(range(T), c[0,:], alpha = 0.25)
	plt.plot(range(T), pmean_scaled[0,:], 'k--')
elif n == 2:
	for c in reformatted_Xdata:
		plt.plot(c[0,:], c[1,:], alpha = 0.4)
elif n == 3:
	from mpl_toolkits.mplot3d import Axes3D
	fig = plt.figure()
	ax = fig.add_subplot(111, projection='3d')
	for c in reformatted_Xdata:
		ax.plot(c[0,:], c[1,:], c[2,:], alpha = 0.4)
	ax.plot(pmean_scaled[0,:], pmean_scaled[1,:], pmean_scaled[2,:], 'k--')

plt.show()


import json
import random
def zero():
    puti = "D:\\нейронка\\pamiati\\"
    t = 100
    k = 0
    p = 0
    mas = []
    for j in range(49):
        j = str(j)
        hp = json.load(open(puti + j + 'hp.txt', 'r'))
        json.dump(0, open(puti + j + 'str.txt', 'w', encoding="UTF-8"))
        if hp > 0:
            mas.append(j)
            json.dump(100, open(puti + j + 'hp.txt', 'w', encoding="UTF-8"))
    mos = json.load(open(puti + str(mas[len(mas)-1]) + '.txt', 'r'))
    x = random.randint(1, 5)
    for j in range(x):
        r = random.randint(0, 58)
        mos[r]=random.randint(0, 44)
    for j in range(49):
        j = str(j)
        hp = json.load(open(puti + j + 'hp.txt', 'r'))
        if hp <= 0:
            json.dump(100, open(puti + j + 'hp.txt', 'w', encoding="UTF-8"))
            cikl = json.load(open(puti + mas[k] + '.txt', 'r'))
            #print(k)
            json.dump(cikl, open(puti + j + '.txt', 'w', encoding="UTF-8"))
            if p == 6:
                k+=1
                p=0
            p+=1

нейронка/zero.py