import sys
import platform
from pathlib import Path
from itertools import *

bindingsOk = Path("./bindings-ok")

class ConstantDesc:

    def __init__(self, name, value):
        self.name = name
        self.value = value

    def save(self, saver):
        saver['name'] = self.name
        saver['value'] = self.value

    @classmethod
    def load(cls, loader):
        return cls(name=loader['name'], value=loader['value'])

class VarDesc:

    def __init__(self, name, type):
        self.name = name
        self.type = type

    def save(self, saver):
        saver['name'] = self.name
        saver['type'] = self.type

    @classmethod
    def load(cls, loader):
        return cls(name=loader['name'], type=loader['type'])

class ArgDesc(VarDesc):

    def __init__(self, name, type, default):
        self.name = name
        self.type = type
        self.default = default

    def save(self, saver):
        saver['name'] = self.name
        saver['type'] = self.type
        if self.default is not None:
            saver['default'] = self.default

    @classmethod
    def load(cls, loader):
        return cls(name=loader['name'], type=loader['type'], default=loader.get('default'))

class FunctionDesc:

    def __init__(self, name, restype, args, docs=None):
        self.name = name
        self.args = args
        self.restype = restype
        self.docs = docs

    def save(self, saver):
        saver['name'] = self.name
        saver['restype'] = self.restype
        saver.save_array('args', self.args)
        saver['docs'] = self.docs

    @classmethod
    def load(cls, loader):
        return cls(name=loader['name'], restype=loader['restype'],
                   args=[ArgDesc.load(l) for l in loader['args']],
                   docs=loader['docs'])

class TypedefDesc:

    kind = 'typedef'

    def __init__(self, name, type):
        self.name = name
        self.type = type

    def save(self, saver):
        saver['name'] = self.name
        saver['kind'] = 'typedef'
        saver['type'] = self.type

    @classmethod
    def load(cls, loader):
        return cls(name=loader['name'], type=loader['type'])

class StructDesc:

    kind = 'struct'

    def __init__(self, name, fields):
        self.name = name
        self.fields = fields

    def save(self, saver):
        saver['name'] = self.name
        saver['kind'] = 'struct'
        saver.save_array('fields', self.fields)

    @classmethod
    def load(cls, loader):
        return cls(name=loader['name'],
                   fields=[VarDesc.load(l) for l in loader['fields']]
                   )
class ApiDesc:

    def __init__(self):
        self.types = collections.OrderedDict()
        self.constants = collections.OrderedDict()
        self.functions = collections.OrderedDict()

import collections

class Saver(collections.OrderedDict):

    def __init__(self):
        pass

    def save_array(self, key, objects):

        result = []
        for obj in objects:
            s = Saver()
            obj.save(s)
            result.append(s)
        self[key] = result

    def add_record(self, key):
        self[key] = Saver()
        return self[key]

    def update_from_dict(self, d):
        for key, value in d.items():
            value.save(self.add_record(key))

def save(api: ApiDesc, file_name):
    import json

    saver = Saver()

    saver.add_record('constants').update_from_dict(api.constants)
    saver.add_record('types').update_from_dict(api.types)
    saver.add_record('functions').update_from_dict(api.functions)
    print(saver)

    json.dump(saver, open(file_name, 'w'), indent=2)

class Loader:

    def __init__(self, d):
        self.d = d

def load(fpath):
    import json

    api = ApiDesc()

    loader = json.load(open(fpath),
                       object_pairs_hook=collections.OrderedDict) # make sure order is always same

    api.constants = collections.OrderedDict((local_name, ConstantDesc.load(data)) for local_name, data in loader['constants'].items())
    api.types = collections.OrderedDict((local_name, {'typedef': TypedefDesc, 'struct': StructDesc}[data['kind']].load(data) ) for local_name, data in loader['types'].items())
    api.functions = collections.OrderedDict((local_name, FunctionDesc.load(data)) for local_name, data in loader['functions'].items())

    return api

def export(header_file, includes, json_file_name, prefixes, castxml, exclude=None, replace=None):
    import xml.etree.ElementTree
    import subprocess

    if bindingsOk.exists():
         bindingsOk.unlink()

    cmd = [castxml,]
    for inc in includes:
        cmd.extend(['-I', inc])
    cmd.extend(['-std=c++11', '-E', '-dD', '-x' , 'c++', header_file, '-o', 'rprapi.pp'])
    subprocess.check_call(cmd)

    cmd = [castxml,]
    for inc in includes:
        cmd.extend(['-I', inc])
    cmd.extend(['-std=c++11', '--castxml-gccxml', '-x', 'c++', header_file, '-o', 'rprapi.xml'])
    subprocess.check_call(cmd)

    t = xml.etree.ElementTree.parse('rprapi.xml')

    root = t.getroot()

    class Type:

        def __init__(self, name):
            self.name = name
            self.depth = None

        def __repr__(self):
            return self.name

        def get_name_for_typedef(self):
            return self.name

        def get_name_for_var_decl(self):
            return self.name

        def generate_cdecl(self):
            return None

        def generate_desc(self):
            return None

        def calculate_depth(self):
            self.depth = 0

    class Function(Type):

        def __init__(self, name, returns, args):
            super().__init__(name)
            self.returns = returns
            self.args = args

        def __repr__(self):
            return 'function:  '+str(types[self.returns])+self.name+str(self.args)

        def get_name_for_typedef(self):
            assert False

        def get_name_for_var_decl(self):
            assert False

        def generate_cdecl(self):
            desc = self.generate_desc()
            return desc.restype + ' ' + desc.name + '('+', '.join(arg.type+' '+arg.name for arg in desc.args)+');'

        def generate_desc(self):
            return FunctionDesc(self.name,
                                types[self.returns].get_name_for_typedef(),
                                [ArgDesc(arg[0], arg[1].get_name_for_typedef(), arg[2]) for arg in self.args])

        def calculate_depth(self):
            self.depth = 0

    class Typedef(Type):

        def __init__(self, name, typedef_type):
            super().__init__(name)
            self.typedef_type = typedef_type

        def __repr__(self):
            return 'typedef '+repr((self.name, types.get(self.typedef_type, self.typedef_type)))

        def get_name_for_typedef(self):
            return self.name

        def get_name_for_var_decl(self):
            return self.name

        def generate_cdecl(self):
            if not self.depth:
                return None
            desc = self.generate_desc()
            return ' '.join(['typedef', desc.type, desc.name]) + ';'

        def generate_desc(self):
            return TypedefDesc(self.name, types[self.typedef_type].get_name_for_typedef())

        def calculate_depth(self):
            if self.depth is None:
                if self.typedef_type in types:
                    anc = types[self.typedef_type]
                    calculate_depth(anc)
                    self.depth = anc.depth + 1
                else:
                    self.depth = 0

    class Pointer(Type):

        def __init__(self, type):
            super().__init__('~~pointer~~')
            self.pointer_type = type

        def __repr__(self):
            return 'pointer to '+repr(types.get(self.pointer_type, self.pointer_type))

        def get_name_for_typedef(self):
            assert self.pointer_type in types
            return types[self.pointer_type].get_name_for_typedef()+'*'

        def get_name_for_var_decl(self):
            assert self.pointer_type in types
            return types[self.pointer_type].get_name_for_typedef()+'*'

        def generate_cdecl(self):
            # assert self.pointer_type in types, self.pointer_type
            #return 'HELLO-generate_cdecl for' + self.pointer_type
            return None

        def calculate_depth(self):
            if self.depth is None:
                assert self.pointer_type
                if self.pointer_type in types:
                    anc = types[self.pointer_type]
                    calculate_depth(anc)
                    self.depth = anc.depth + 1
                else:
                    self.depth = 0

    class Callback(Type):
        def __init__(self, type):
            super().__init__('~~function~~')
            self.function_type = type

        def __repr__(self):
            return 'pointer to function ' + repr(types.get(self.function_type, self.function_type))

        def get_name_for_typedef(self):
            assert self.function_type in types
            ret_type = types[self.function_type].get_name_for_typedef()
            ret_type = ret_type[:-1]
            return ret_type

        def get_name_for_var_decl(self):
            assert self.function_type in types
            return types[self.function_type].get_name_for_typedef()

        def generate_cdecl(self):
            # assert self.pointer_type in types, self.pointer_type
            # return 'HELLO-generate_cdecl for' + self.pointer_type
            return None

        def calculate_depth(self):
            if self.depth is None:
                assert self.function_type
                if self.function_type in types:
                    anc = types[self.function_type]
                    calculate_depth(anc)
                    self.depth = anc.depth + 1
                else:
                    self.depth = 0

    class CvQualifiedType(Type):

        def __init__(self, type, const):
            assert const
            super().__init__('~~cv-qualified~~')
            self.type = type
            self.const = const

        def __repr__(self):
            return ('const ' if self.const else ' ')+repr(types.get(self.type, self.type))

        def get_name_for_typedef(self):
            assert self.type in types
            return types[self.type].get_name_for_typedef()+' const' if self.const else ''

        def get_name_for_var_decl(self):
            return self.get_name_for_typedef()

        def generate_cdecl(self):
            # assert self.pointer_type in types, self.pointer_type
            #return 'HELLO-generate_cdecl for' + self.pointer_type
            return None

        def calculate_depth(self):
            if self.depth is None:
                assert self.type
                if self.type in types:
                    anc = types[self.type]
                    calculate_depth(anc)
                    self.depth = anc.depth + 1
                else:
                    self.depth = 0

    class Struct(Type):

        def __init__(self, name, fields):
            super().__init__(name)
            self.fields = fields

        def __repr__(self):
            return 'struct:'+str((self.name, [repr(members.get(id, id)) for id in self.fields] ))

        def get_name_for_typedef(self):
            # case for "typedef struct {}* typename;" which cffi can't parse
            return 'struct ' + self.name

        def generate_cdecl(self):

            desc = self.generate_desc()

            lines = []
            lines.append(' '.join(['struct', desc.name, '{']))

            for m in desc.members:
                lines.append('    '+m.type+' '+m.name+' hello;')

            lines.append('};')
            return '\n'.join(lines)

        def generate_desc(self):
            return StructDesc(self.name, [VarDesc(members[field][0], members[field][1].get_name_for_var_decl())
                                          for field in self.fields
                                          if field in members])

        def calculate_depth(self):
            if self.depth is not None:
                return

            for field in self.fields:
                if field in members:
                    f = members[field]
                    calculate_depth(f[1])

            self.depth = 1+max((members[field][1].depth for field in self.fields if field in members), default=-1)

    types = {c.get('id'): Type(c.get('name')) for c in root.findall('FundamentalType')}

    for c in root.findall('FunctionType'):
        for arg in c.findall('Argument'):
            types[c.get('id')] = Callback(arg.get('type'))

    for c in root.findall('PointerType'):
        types[c.get('id')] = Pointer(c.get('type'))

    for c in root.findall('CvQualifiedType'):
        types[c.get('id')] = CvQualifiedType(c.get('type'), eval(c.get('const')))

    for c in root.findall('Struct'):
        name = c.get('name')
        if name.startswith("__"):
            continue
        struct_members = c.get('members')
        types[c.get('id')] = Struct(name, struct_members.split() if struct_members else [])

    for c in root.findall('Typedef'):
        name = c.get('name')
        types[c.get('id')] = Typedef(name, c.get('type'))

    def calculate_depth(t):
        t.calculate_depth()

    members = {}

    for c in root.findall('Field'):
        name = c.get('name')
        type_ = c.get('type')
        if type_ not in types:
            continue
        members[c.get('id')] = (name, types[type_])

    # calculate depths of dependencies on other types
    typedefs_sorted = {}

    for t in types.values():
        calculate_depth(t)
        if t.depth not in typedefs_sorted:
            typedefs_sorted[t.depth] = []
        typedefs_sorted[t.depth].append(t)

    functions = []
    for c in root.findall('Function'):
        name = c.get('name')

        for arg in c.findall('Argument'):
            nname = arg.get('name')
            ttype = arg.get('type')
            typename = types[ttype]

            #FunctionDesc(self.name,
            #             types[self.returns].get_name_for_typedef(),
            #             [ArgDesc(arg[0], arg[1].get_name_for_typedef(), arg[2]) for arg in self.args])

        args = [(arg.get('name'), types[arg.get('type')], arg.get('default')) for arg in c.findall('Argument')]

        functions.append(Function(name, c.get('returns'), args))

    api = ApiDesc()
    for i in sorted(typedefs_sorted.keys()):
        for t in sorted(typedefs_sorted[i], key=lambda t: t.name):
            name = t.name
            for prefix in prefixes['type']:
                # ignore name containing any entry from 'exclude' list
                is_excluded = next((True for e in exclude if e in name), False) if exclude else False
                if name.startswith(prefix) and not is_excluded:
                    local_name = name[len(prefix):]
                    api.types[name] = t.generate_desc()

    for t in sorted(functions, key=lambda t: t.name):
        name = t.name
        for prefix in prefixes['function']:
            # ignore name containing any entry from 'exclude' list
            is_excluded = next((True for e in exclude if e in name), False) if exclude else False
            if name.startswith(prefix) and not is_excluded:
                local_name = name[len(prefix):]
                api.functions[name] = t.generate_desc()

    for line in open('rprapi.pp'):
        if line.startswith('#define'):
            tokens = line.split()
            name = tokens[1]
            # ignore name containing any entry from 'exclude' list
            is_excluded = next((True for e in exclude if e in name), False) if exclude else False
            if 'API_ENTRY' not in name and not is_excluded:
                for prefix in prefixes['constant']:
                    if name.startswith(prefix):
                        # replace some bug-producing defines by predefined value
                        if replace and name in replace:
                            value = replace[name]
                        else:
                            value = ' '.join(tokens[2:])

                            # if define points at other prefixed define correct value name by removing prefix
                            value_prefix = next(
                                (p for p in prefixes['constant'] if value.startswith(p)),
                                None)
                            if value_prefix:
                                value = value[len(value_prefix):]

                            local_name = name[len(prefix):]

                        api.constants[name] = ConstantDesc(name, value)

    def parse_multiline_comment(line, lines):
        for line in chain([line], lines):
            yield line
            if '*/' in line:
                return

    def clean_comment_line(line):

        while line and (line[0] in ['\\', '*', '/', ' ', '\t']):
            line = line[1:]

        return line.lstrip()

    def extract_function_comments(lines):
        comment = ''

        for line in lines:
            #print('>>>', line)

            if line.startswith('/*'):
                comment = list(parse_multiline_comment(line, lines))
                continue

            if 'frContextFlushImageCache' in line:
                continue

            if line.startswith('extern RPR_API_ENTRY'):
                # get all lined of function declaration(up to closing bracket)
                l = line
                while ')' not in l:
                    l = next(lines)
                    line += l

                line_cleaned = line.replace('extern RPR_API_ENTRY', '').lstrip()
                restype_and_name, args_rest = line_cleaned.split('(')

                restype, name = restype_and_name.split()

                yield 'function', (name, (restype, tuple(arg.strip() for arg in args_rest.split(')')[0].split(',')), [line_cleaned, comment]))

    for type, (name, sig) in extract_function_comments(open(header_file)):
        if name.startswith('rpr'):
            local_name = name[len('rpr'):]
            api.functions[name].docs = sig[2]

    save(api,json_file_name)

    # If we got this far the current binding should have generated
    bindingsOk.write_text("ok")

def eval_constant(s):
    if s.endswith(('U', 'u')):
        s = s[:-1]

    try:
        return eval(s)

    except NameError:
        return s

def get_rpr_sdk(base=Path()):
    p = base / ".sdk/rpr"
    return {
        'inc': p / "inc",
        'bin': p / "bin",
        'lib': p / "lib" if platform.system() == 'Windows' else None,
        'hipbin': p / "hipbin",
    }

def get_rif_sdk(base=Path()):
    p = base / ".sdk/rif"
    return {
        'inc': p / "inc",
        'bin': p / "bin",
        'lib': p / "lib" if platform.system() == 'Windows' else None
    }

if __name__=='__main__':
    #change paths according to your developer environment:
    #castxml = r'C:\Development\tools\castxml\bin\castxml'

    castxml = sys.argv[1]

    rpr_sdk = get_rpr_sdk()
    rif_sdk = get_rif_sdk()

    # RPR
    rpr_wrap_h = 'src/bindings/pyrpr/rprwrap.h'
    rpr_includes = [str(rpr_sdk['inc'])]
    rpr_wrap_json = 'src/bindings/pyrpr/src/pyrprwrapapi.json'

    # ImageProcessing
    rif_wrap_h = 'src/bindings/pyrpr/imagefilterswrap.h'
    rif_wrap_json = 'src/bindings/pyrpr/src/pyrprimagefiltersapi.json'
    rif_includes = [*rpr_includes, str(rif_sdk['inc'])]

    export(
        rpr_wrap_h, rpr_includes, rpr_wrap_json,
        {
            'type': ['rpr_', '_rpr'],
            'function': ['rpr',],
            'constant': ['RPR_',]
        },
        castxml,
        exclude=['RPR_CONTEXT_FLUSH_FRAMEBUFFERS_FUNC_NAME',
                 'RPR_SHAPE_SET_LIGHTMAP_CHART_INDEX_FUNC_NAME',
                 'RPR_MESH_UPDATE_FUNC_NAME',
                 'RPR_SHAPE_SET_TRANSFORM_BATCH_FUNC_NAME',
                 'rprDirectionalLightSetRasterShadowSplits',
                 'rprContextCreateMeshInstanceWithUniqueAttributes',
                 'RPR_CONTEXT_CREATE_MESH_EDITABLE_FUNC_NAME',
                 'rprContextCreateCompressedImage_func',
                 'rpr_compressed_format',
                 'rpr_comressed_image_desc',
                 'RPR_CONTEXT_CREATE_COMPRESSED_IMAGE',
                 'rpr_framebuffer_type',
                 'RPR_UV_CAMERA_SET_CHART_INDEX_FUNC_NAME',
                 'RPR_CONTEXT_CREATE_FRAMEBUFFER_TYPED_FUNC_NAME',
                 'RPR_MATERIAL_SET_INPUT_BY_S_KEY_FUNC_NAME',
                 'RPR_MATERIALX_SET_FILE_FUNC_NAME',
                 'RPR_MATERIALX_SET_FILE_AS_BUFFER_FUNC_NAME',
                 'rpr_vector_component_type',
                 'rpr_format_ext',
                 'RPR_CONTEXT_CREATE_IMAGE_FROM_EXTERNAL_HANDLE',
                 'rprSetLogFunction',
                 'RPR_GET_SUPPORTED_DEVICES_FUNC_NAME'
                 ]
    )

    export(
        rif_wrap_h, rif_includes, rif_wrap_json,
        {
            'type': ['rif_', '_rif'],
            'function': ['rif'],
            'constant': ['RIF_', 'VERSION_', 'COMMIT_'],
        },
        castxml,
        exclude=['RIF_DEPRECATED', 'RIF_MAKE_VERSION', 'RIF_API_VERSION', 'VERSION_BUILD',
                 'RIF_STRINGIFY2(s)', 'RIF_STRINGIFY(s)',
                 'rif_logger_desc', 'rifLoggerAttach', 'rifGetModelMemorySize']
    )

    # export(rpr_header_gltf, includes_gltf, json_file_name_gltf,
    #        {
    #            'type': ['rprgltf_'],
    #            'function': ['rprExport', 'rprImport', 'rprGLTF'],
    #            'constant': []
    #        },
    #        castxml)


from MyFunctions import *
import tensorflow as tf
import numpy as np
from tensorflow.keras import layers

class CNNModel:
    def __init__(self, num_classes=10, input_shape=(28, 28, 1)):
        self.num_classes = num_classes
        self.input_shape = input_shape

    def create_cnn_model(self):
        model = tf.keras.Sequential(
            [
                tf.keras.Input(shape=self.input_shape),
                layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
                layers.MaxPooling2D(pool_size=(2, 2)),
                layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
                layers.MaxPooling2D(pool_size=(2, 2)),
                layers.Flatten(),
                layers.Dropout(0.5),
                layers.Dense(self.num_classes, activation="softmax"),
            ]
        )
        return model

def my_CNN( X_tr, X_ts, T_train, T_test):
    num_classes = 10
    # input_shape = (28, 28, 1)
    rows, cols, depth = (32, 32, 1)
    input_shape = (rows, cols, 1)

    X_tr = X_tr.T
    X_ts = X_ts.T
    X_tr = X_tr.reshape(X_tr.shape[0], rows, cols)
    X_ts = X_ts.reshape(X_ts.shape[0], rows, cols)

    X_tr = np.expand_dims(X_tr, -1)
    X_ts = np.expand_dims(X_ts, -1)

    model = CNNModel(num_classes, input_shape).create_cnn_model()
    # model.summary()

    batch_size = 32
    epochs = 10

    model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
    model.fit(X_tr, tf.transpose(T_train), epochs=epochs, batch_size=batch_size, verbose=1)

    t_hat = model.predict(X_tr).T
    t_hat_test = model.predict(X_ts).T

    return compute_nme(t_hat,T_train), compute_nme(t_hat_test,T_test), compute_mse(t_hat,T_train), compute_mse(t_hat_test,T_test), calculate_accuracy(t_hat,T_train), calculate_accuracy(t_hat_test,T_test)


from dask import delayed
from dask.diagnostics import Profiler, ResourceProfiler, CacheProfiler,\
    visualize, ProgressBar
import dask

class ForLoop:
    def __init__(self, inputs, func, merge_func=None, **kwargs):
        results = []
        for data in inputs:
            result = func(data, **kwargs)
            results.append(result)
        if merge_func is not None:
            self._result = merge_func(results, **kwargs)
        else:
            self._result = results

    def compute(self, **kwargs):
        with Profiler() as prof, ResourceProfiler(dt=0.25) as rprof, CacheProfiler() as cprof:
            self._computed_result = dask.compute(self._result, **kwargs)[0]
            self._prof = prof
            self._rprof = rprof
            self._cprof = cprof

    def show_profiling(self, output_filepath=None):
        visualize([self._prof, self._rprof, self._cprof],
                  file_path=output_filepath)

    def show_workflow(self, output_filepath=None):
        dask.visualize(self._result, filename=output_filepath)

    def get_result(self):
        return self._computed_result


#!/usr/bin/env python
# Tai Sakuma <sakuma@fnal.gov>
import ROOT
import sys
import json

ROOT.gROOT.SetBatch(1)

##____________________________________________________________________________||
def noEvents(inputPathList):
    if len(inputPathList) == 0: return True
    for inputPath in inputPathList:
        if getNEvents(inputPath) > 0: return False
    return True

##____________________________________________________________________________||
def getNEvents(inputPath):
    file = ROOT.TFile.Open(inputPath)
    events = file.Get('Events')
    return events.GetEntries()

##____________________________________________________________________________||
class PrintFileNameIfChange(object):
    def __init__(self, verbose = True):
        self.fileName = ""
        self.verbose = verbose

    def __call__(self, event):
        if self.fileName is not event._filenames[event.fileIndex()]:
            self.fileName = event._filenames[event.fileIndex()]
            if not self.verbose: return
            print >> sys.stderr, self.fileName

##____________________________________________________________________________||
class LuminosityBlockCertification(object):
    def __init__(self, jsonPath):
        self.json = json.load(open(jsonPath)) if jsonPath else None

    def __call__(self, event):
        if self.json is None: return True
        run = event.eventAuxiliary().run()
        lumi = event.eventAuxiliary().luminosityBlock()
        if str(run) not in self.json: return False
        if any([(l1 <= lumi <= l2) for (l1, l2) in self.json[str(run)]]): return True
        return False

##____________________________________________________________________________||
def mkInputPathList(inputPath, inputPathListFile):
    if inputPath:
        return [inputPath]
    elif inputPathListFile:
        return [l for l in open(inputPathListFile).read().splitlines()]
    else:
        return [ ]

##____________________________________________________________________________||
def loadLibraries():
    argv_org = list(sys.argv)
    sys.argv = [e for e in sys.argv if e != '-h']
    ROOT.gSystem.Load("libFWCoreFWLite")
    ROOT.AutoLibraryLoader.enable()
    ROOT.gSystem.Load("libDataFormatsFWLite")
    ROOT.gSystem.Load("libDataFormatsPatCandidates")
    sys.argv = argv_org

##____________________________________________________________________________||
if __name__ == '__main__':
    pass


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

df_adm = pd.read_csv('/Users/KexinHuang/Downloads/ADMISSIONS.csv')
df_adm.ADMITTIME = pd.to_datetime(df_adm.ADMITTIME, format = '%Y-%m-%d %H:%M:%S', errors = 'coerce')
df_adm.DISCHTIME = pd.to_datetime(df_adm.DISCHTIME, format = '%Y-%m-%d %H:%M:%S', errors = 'coerce')
df_adm.DEATHTIME = pd.to_datetime(df_adm.DEATHTIME, format = '%Y-%m-%d %H:%M:%S', errors = 'coerce')

df_adm = df_adm.sort_values(['SUBJECT_ID','ADMITTIME'])
df_adm = df_adm.reset_index(drop = True)
df_adm['NEXT_ADMITTIME'] = df_adm.groupby('SUBJECT_ID').ADMITTIME.shift(-1)
df_adm['NEXT_ADMISSION_TYPE'] = df_adm.groupby('SUBJECT_ID').ADMISSION_TYPE.shift(-1)

rows = df_adm.NEXT_ADMISSION_TYPE == 'ELECTIVE'
df_adm.loc[rows,'NEXT_ADMITTIME'] = pd.NaT
df_adm.loc[rows,'NEXT_ADMISSION_TYPE'] = np.NaN

df_adm = df_adm.sort_values(['SUBJECT_ID','ADMITTIME'])

#When we filter out the "ELECTIVE", we need to correct the next admit time for these admissions since there might be 'emergency' next admit after "ELECTIVE"
df_adm[['NEXT_ADMITTIME','NEXT_ADMISSION_TYPE']] = df_adm.groupby(['SUBJECT_ID'])[['NEXT_ADMITTIME','NEXT_ADMISSION_TYPE']].fillna(method = 'bfill')
df_adm['DAYS_NEXT_ADMIT']=  (df_adm.NEXT_ADMITTIME - df_adm.DISCHTIME).dt.total_seconds()/(24*60*60)
df_adm['OUTPUT_LABEL'] = (df_adm.DAYS_NEXT_ADMIT < 30).astype('int')
### filter out newborn and death
df_adm = df_adm[df_adm['ADMISSION_TYPE']!='NEWBORN']
df_adm = df_adm[df_adm.DEATHTIME.isnull()]
df_adm['DURATION'] = (df_adm['DISCHTIME']-df_adm['ADMITTIME']).dt.total_seconds()/(24*60*60)

df_notes = pd.read_csv('/Users/KexinHuang/Downloads/NOTEEVENTS.csv')
df_notes = df_notes.sort_values(by=['SUBJECT_ID','HADM_ID','CHARTDATE'])
df_adm_notes = pd.merge(df_adm[['SUBJECT_ID','HADM_ID','ADMITTIME','DISCHTIME','DAYS_NEXT_ADMIT','NEXT_ADMITTIME','ADMISSION_TYPE','DEATHTIME','OUTPUT_LABEL','DURATION']],
                        df_notes[['SUBJECT_ID','HADM_ID','CHARTDATE','TEXT','CATEGORY']],
                        on = ['SUBJECT_ID','HADM_ID'],
                        how = 'left')

df_adm_notes.ADMITTIME_C = df_adm_notes.ADMITTIME.apply(lambda x: str(x).split(' ')[0])
df_adm_notes['ADMITTIME_C'] = pd.to_datetime(df_adm_notes.ADMITTIME_C, format = '%Y-%m-%d', errors = 'coerce')
df_adm_notes['CHARTDATE'] = pd.to_datetime(df_adm_notes.CHARTDATE, format = '%Y-%m-%d', errors = 'coerce')

### If Discharge Summary
df_discharge = df_adm_notes[df_adm_notes['CATEGORY'] == 'Discharge summary']
# multiple discharge summary for one admission -> after examination -> replicated summary -> replace with the last one
df_discharge = (df_discharge.groupby(['SUBJECT_ID','HADM_ID']).nth(-1)).reset_index()
df_discharge=df_discharge[df_discharge['TEXT'].notnull()]

### If Less than n days on admission notes (Early notes)
def less_n_days_data (df_adm_notes, n):

    df_less_n = df_adm_notes[((df_adm_notes['CHARTDATE']-df_adm_notes['ADMITTIME_C']).dt.total_seconds()/(24*60*60))<n]
    df_less_n=df_less_n[df_less_n['TEXT'].notnull()]
    #concatenate first
    df_concat = pd.DataFrame(df_less_n.groupby('HADM_ID')['TEXT'].apply(lambda x: "%s" % ' '.join(x))).reset_index()
    df_concat['OUTPUT_LABEL'] = df_concat['HADM_ID'].apply(lambda x: df_less_n[df_less_n['HADM_ID']==x].OUTPUT_LABEL.values[0])

    return df_concat

df_less_2 = less_n_days_data(df_adm_notes, 2)
df_less_3 = less_n_days_data(df_adm_notes, 3)

import re
def preprocess1(x):
    y=re.sub('\\[(.*?)\\]','',x) #remove de-identified brackets
    y=re.sub('[0-9]+\.','',y) #remove 1.2. since the segmenter segments based on this
    y=re.sub('dr\.','doctor',y)
    y=re.sub('m\.d\.','md',y)
    y=re.sub('admission date:','',y)
    y=re.sub('discharge date:','',y)
    y=re.sub('--|__|==','',y)
    return y

def preprocessing(df_less_n):
    df_less_n['TEXT']=df_less_n['TEXT'].fillna(' ')
    df_less_n['TEXT']=df_less_n['TEXT'].str.replace('\n',' ')
    df_less_n['TEXT']=df_less_n['TEXT'].str.replace('\r',' ')
    df_less_n['TEXT']=df_less_n['TEXT'].apply(str.strip)
    df_less_n['TEXT']=df_less_n['TEXT'].str.lower()

    df_less_n['TEXT']=df_less_n['TEXT'].apply(lambda x: preprocess1(x))

    #to get 318 words chunks for readmission tasks
    from tqdm import tqdm
    df_len = len(df_less_n)
    want=pd.DataFrame({'ID':[],'TEXT':[],'Label':[]})
    for i in tqdm(range(df_len)):
        x=df_less_n.TEXT.iloc[i].split()
        n=int(len(x)/318)
        for j in range(n):
            want=want.append({'TEXT':' '.join(x[j*318:(j+1)*318]),'Label':df_less_n.OUTPUT_LABEL.iloc[i],'ID':df_less_n.HADM_ID.iloc[i]},ignore_index=True)
        if len(x)%318>10:
            want=want.append({'TEXT':' '.join(x[-(len(x)%318):]),'Label':df_less_n.OUTPUT_LABEL.iloc[i],'ID':df_less_n.HADM_ID.iloc[i]},ignore_index=True)

    return want

df_discharge = preprocessing(df_discharge)
df_less_2 = preprocessing(df_less_2)
df_less_3 = preprocessing(df_less_3)

### An example to get the train/test/split with random state:
### note that we divide on patient admission level and share among experiments, instead of notes level.
### This way, since our methods run on the same set of admissions, we can see the
### progression of readmission scores.

readmit_ID = df_adm[df_adm.OUTPUT_LABEL == 1].HADM_ID
not_readmit_ID = df_adm[df_adm.OUTPUT_LABEL == 0].HADM_ID
#subsampling to get the balanced pos/neg numbers of patients for each dataset
not_readmit_ID_use = not_readmit_ID.sample(n=len(readmit_ID), random_state=1)
id_val_test_t=readmit_ID.sample(frac=0.2,random_state=1)
id_val_test_f=not_readmit_ID_use.sample(frac=0.2,random_state=1)

id_train_t = readmit_ID.drop(id_val_test_t.index)
id_train_f = not_readmit_ID_use.drop(id_val_test_f.index)

id_val_t=id_val_test_t.sample(frac=0.5,random_state=1)
id_test_t=id_val_test_t.drop(id_val_t.index)

id_val_f=id_val_test_f.sample(frac=0.5,random_state=1)
id_test_f=id_val_test_f.drop(id_val_f.index)

# test if there is overlap between train and test, should return "array([], dtype=int64)"
(pd.Index(id_test_t).intersection(pd.Index(id_train_t))).values

id_test = pd.concat([id_test_t, id_test_f])
test_id_label = pd.DataFrame(data = list(zip(id_test, [1]*len(id_test_t)+[0]*len(id_test_f))), columns = ['id','label'])

id_val = pd.concat([id_val_t, id_val_f])
val_id_label = pd.DataFrame(data = list(zip(id_val, [1]*len(id_val_t)+[0]*len(id_val_f))), columns = ['id','label'])

id_train = pd.concat([id_train_t, id_train_f])
train_id_label = pd.DataFrame(data = list(zip(id_train, [1]*len(id_train_t)+[0]*len(id_train_f))), columns = ['id','label'])

#get discharge train/val/test

discharge_train = df_discharge[df_discharge.ID.isin(train_id_label.id)]
discharge_val = df_discharge[df_discharge.ID.isin(val_id_label.id)]
discharge_test = df_discharge[df_discharge.ID.isin(test_id_label.id)]

# subsampling for training....since we obtain training on patient admission level so now we have same number of pos/neg readmission
# but each admission is associated with different length of notes and we train on each chunks of notes, not on the admission, we need
# to balance the pos/neg chunks on training set. (val and test set are fine) Usually, positive admissions have longer notes, so we need
# find some negative chunks of notes from not_readmit_ID that we haven't used yet

df = pd.concat([not_readmit_ID_use, not_readmit_ID])
df = df.drop_duplicates(keep=False)
#check to see if there are overlaps
(pd.Index(df).intersection(pd.Index(not_readmit_ID_use))).values

# for this set of split with random_state=1, we find we need 400 more negative training samples
not_readmit_ID_more = df.sample(n=400, random_state=1)
discharge_train_snippets = pd.concat([df_discharge[df_discharge.ID.isin(not_readmit_ID_more)], discharge_train])

#shuffle
discharge_train_snippets = discharge_train_snippets.sample(frac=1, random_state=1).reset_index(drop=True)

#check if balanced
discharge_train_snippets.Label.value_counts()

discharge_train_snippets.to_csv('./discharge/train.csv')
discharge_val.to_csv('./discharge/val.csv')
discharge_test.to_csv('./discharge/test.csv')

### for Early notes experiment: we only need to find training set for 3 days, then we can test
### both 3 days and 2 days. Since we split the data on patient level and experiments share admissions
### in order to see the progression, the 2 days training dataset is a subset of 3 days training set.
### So we only train 3 days and we can test/val on both 2 & 3days or any time smaller than 3 days. This means
### if we train on a dataset with all the notes in n days, we can predict readmissions smaller than n days.

#for 3 days note, similar to discharge

early_train = df_less_3[df_less_3.ID.isin(train_id_label.id)]
not_readmit_ID_more = df.sample(n=500, random_state=1)
early_train_snippets = pd.concat([df_less_3[df_less_3.ID.isin(not_readmit_ID_more)], early_train])
#shuffle
early_train_snippets = early_train_snippets.sample(frac=1, random_state=1).reset_index(drop=True)
early_train_snippets.to_csv('./3days/train.csv')

early_val = df_less_3[df_less_3.ID.isin(val_id_label.id)]
early_val.to_csv('./3days/val.csv')

# we want to test on admissions that are not discharged already. So for less than 3 days of notes experiment,
# we filter out admissions discharged within 3 days
actionable_ID_3days = df_adm[df_adm['DURATION'] >= 3].HADM_ID
test_actionable_id_label = test_id_label[test_id_label.id.isin(actionable_ID_3days)]
early_test = df_less_3[df_less_3.ID.isin(test_actionable_id_label.id)]

early_test.to_csv('./3days/test.csv')

#for 2 days notes, we only obtain test set. Since the model parameters are tuned on the val set of 3 days

actionable_ID_2days = df_adm[df_adm['DURATION'] >= 2].HADM_ID

test_actionable_id_label_2days = test_id_label[test_id_label.id.isin(actionable_ID_2days)]

early_test_2days = df_less_2[df_less_2.ID.isin(test_actionable_id_label_2days.id)]

early_test_2days.to_csv('./2days/test.csv')


"""
Plotting support using bokeh & Jupyter
"""
from bokeh.models import GMapOptions
from bokeh.plotting import gmap, GMap
from geopy import Point
from geopy.distance import distance
import math
import os
import pandas
from typing import Sequence, Tuple, Union

from missilemap import Sighting

def render_path(figure: GMap, path: Sequence[Union[Point, Tuple[float, float]]], line_color='blue', line_width=2, line_alpha=0.8):
    """
    Render specified path on the map chart

    :param figure: GMap object
    :param path: sequence of points to render
    :param line_color: line color (default: blue)
    :param line_width: line width (default: 2.0)
    :param line_alpha: line alpha controlling transparency (default: 0.8)
    """
    x_start = []
    y_start = []
    x_end = []
    y_end = []

    for s, e in zip(path[:-1], path[1:]):
        x_start.append(s[1])
        y_start.append(s[0])
        x_end.append(e[1])
        y_end.append(e[0])

    figure.segment(x0=x_start, y0=y_start, x1=x_end, y1=y_end, line_color=line_color, line_width=line_width, line_alpha=line_alpha)

def render(location, zoom=6, plot_width=1400, plot_height=800, api_key: str = None, title=None,
           sightings: Sequence[Sighting] = None, sighting_size=10,
           paths: Sequence[Sequence[Tuple[float, float]]] = None
           ) -> GMap:
    """
    Render a map with sightings.

    :param location: (latitude, longitude) pair
    :param zoom: map zoom factor. zoom=6 is approximately whole of Ukraine, zoom=10 is around a city
    :param plot_width: (optional) plot width in pixels
    :param plot_height: (optional) plot height in pixels
    :param api_key: Google Maps API key with JavaScript support enabled
    :param title: (optional) figure title
    :param sightings: (optional) list of sightings to display
    :param sighting_size: (optional) circle size for sightings in pixels (default: 10)
    :param paths: (optional) list of paths where each path is a sequence of points [(latitude, longitude), ...]

    :return: bokeh.Figure
    """
    if api_key is None:
        if 'MAPS_API_KEY' not in os.environ:
            raise Exception("MAPS_API_KEY environment variable must be defined or api_key= explicitly specified")
        api_key = os.environ['MAPS_API_KEY']

    gmap_options = GMapOptions(lat=location[0], lng=location[1], map_type='roadmap', zoom=zoom)
    figure = gmap(api_key, gmap_options, title=title, width=plot_width, height=plot_height)

    if sightings is not None and len(sightings):
        # render sighting points:
        figure.circle(
            x=[s.longitude for s in sightings],
            y=[s.latitude for s in sightings],
            size=sighting_size, fill_color="red", fill_alpha=0.7, line_color=None)

        arrows = []
        for s in sightings:
            head = distance(kilometers=2).destination((s.latitude, s.longitude),
                                                      bearing=math.degrees(s.bearing if s.bearing > 0 else s.bearing + 2 * math.pi))
            arrows.append({
                'x_start': s.longitude,
                'y_start': s.latitude,
                'x_end': head[1],
                'y_end': head[0]
            })

            # render arrows (NOTE: adding Arrow did not work for some reason)
            # for arrow in arrows:
            #     p.add_layout(Arrow(
            #         x_start=arrow['x_start'],
            #         start_units='data', end_units='data',
            #         y_start=arrow['y_start'],
            #         x_end=arrow['x_end'],
            #         y_end=arrow['y_end'],
            #         line_color='red',
            #         line_width=2
            #     ))

        arrows = pandas.DataFrame(arrows)
        figure.segment(
            x0=arrows['x_start'].values,
            y0=arrows['y_start'].values,
            x1=arrows['x_end'].values,
            y1=arrows['y_end'].values,
            line_color='red',
            line_width=1
        )

    if paths is not None and len(paths):
        # render specified paths as segments
        for path in paths:
            render_path(figure, path)

    return figure


import select, socket, sys,queue
HOST = ''
PORT = 7000

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('# Socket created')

# Create socket on port
try:
    server.bind((HOST, PORT))
except socket.error as msg:
    print('# Bind failed. ')
    sys.exit()

print('# Socket bind complete')

# Start listening on socket
server.listen(10)
print('# Socket now listening')
inputs = [server]
outputs = []
message_queues = {}

while inputs:
    readable, writable, exceptional = select.select(
        inputs, outputs, inputs)
    for s in readable:
        if s is server:
            connection, client_address = s.accept()
            connection.setblocking(0)
            inputs.append(connection)
            message_queues[connection] = queue.Queue()
        else:
            data = s.recv(1024)
            if data:
                message_queues[s].put(data)
                if s not in outputs:
                    outputs.append(s)
            else:
                if s in outputs:
                    outputs.remove(s)
                inputs.remove(s)
                s.close()
                del message_queues[s]

    for s in writable:
        try:
            next_msg = message_queues[s].get_nowait()
        except queue.Empty:
            outputs.remove(s)
        else:
            s.send(next_msg)

    for s in exceptional:
        inputs.remove(s)
        if s in outputs:
            outputs.remove(s)
        s.close()
        del message_queues[s]


'''
Created on 6 de ago de 2016

@author: yago
'''
n = int(input("Digite um nuemro: "))
cont, soma = 2, 1
if 0 <  n < 0:
    while cont < n:
        if n % cont == 0:
            soma += cont
            cont += 1
            if soma == n:
                print ("O número", n, "é perfeito")
            else:
                print ("O número", n, "não é perfeito")

else :
    print("digite um numero maior que 0")


import sys
input=sys.stdin.readline
n=int(input())
ls=list()
stack=list()
answer=list()
idx=1
for _ in range(n):
    num=int(input())
    while idx<=num:
        stack.append(idx)
        answer.append('+')
        idx+=1
    if stack[-1]==num:
        stack.pop()
        answer.append('-')
if stack:
    print("NO")
else:
    for i in answer:
        print(i)


import FWCore.ParameterSet.Config as cms

externalLHEProducer = cms.EDProducer("ExternalLHEProducer",
    #args = cms.vstring('/cvmfs/cms.cern.ch/phys_generator/gridpacks/slc7_amd64_gcc700/13TeV/powhegV2/ttH_inclusive_hdamp_NNPDF31_13TeV_M125/ttH_inclusive_hdamp_NNPDF31_13TeV_M125.tgz'),
    args = cms.vstring('/afs/cern.ch/user/m/moameen/public/gridpacks/ttH_PowhegP8/ttH_slc7_amd64_gcc10_CMSSW_12_4_8_tt_H.tgz'),
    nEvents = cms.untracked.uint32(5000),
    numberOfParameters = cms.uint32(1),
    outputFile = cms.string('cmsgrid_final.lhe'),
    scriptName = cms.FileInPath('GeneratorInterface/LHEInterface/data/run_generic_tarball_cvmfs.sh')
)

#Link to datacards:
# For Run-2 https://github.com/cms-sw/genproductions/blob/0a0040eb78ea5cafe8287837d333869e2a676d3d/bin/Powheg/production/2017/13TeV/Higgs/ttH_inclusive_hdamp_NNPDF31_13TeV_M125/ttH_inclusive_hdamp_NNPDF31_13TeV_M125.input
# For Run-3: https://github.com/cms-sw/genproductions/blob/master/bin/Powheg/production/Run3/13p6TeV/Higgs/ttH_inclusive_hdamp_NNPDF31_13p6TeV_M125/ttH_inclusive_hdamp_NNPDF31_13p6TeV_M125.input

from Configuration.Generator.Pythia8CommonSettings_cfi import *
from Configuration.Generator.MCTunesRun3ECM13p6TeV.PythiaCP5Settings_cfi import *
from Configuration.Generator.Pythia8PowhegEmissionVetoSettings_cfi import *
from Configuration.Generator.PSweightsPythia.PythiaPSweightsSettings_cfi import *

generator = cms.EDFilter("Pythia8ConcurrentHadronizerFilter",
                         maxEventsToPrint = cms.untracked.int32(1),
                         pythiaPylistVerbosity = cms.untracked.int32(1),
                         filterEfficiency = cms.untracked.double(1.0),
                         pythiaHepMCVerbosity = cms.untracked.bool(False),
                         comEnergy = cms.double(13600.),
                         PythiaParameters = cms.PSet(
        pythia8CommonSettingsBlock,
        pythia8CP5SettingsBlock,
        pythia8PowhegEmissionVetoSettingsBlock,
        pythia8PSweightsSettingsBlock,
        processParameters = cms.vstring(
            'POWHEG:nFinal = 3',   ## Number of final state particles
                                   ## (BEFORE THE DECAYS) in the LHE
                                   ## other than emitted extra parton
            '23:mMin = 0.05',
	    	'24:mMin = 0.05',
            '25:m0 = 125.0',
            '25:onMode = on',
			'25:offIfAny = 5 -5' #with previous line: decays to all, except bb pair
          ),
        parameterSets = cms.vstring('pythia8CommonSettings',
                                    'pythia8CP5Settings',
				    'pythia8PowhegEmissionVetoSettings',
                    		    'pythia8PSweightsSettings',
                                    'processParameters'
                                    )
        )
 )

ProductionFilterSequence = cms.Sequence(generator)


import csv, json

INPUT_FILE = 'testing/input.csv'
OUTPUT_FILE = 'testing/output.csv'

def import_urls():
    urls = []
    with open(INPUT_FILE, 'r') as csv_file:
        csv_reader = csv.reader(csv_file)
        for row in csv_reader:
            urls.append(row[0])
    assert urls, 'No urls found in ' + INPUT_FILE
    return urls

def export_results(output):
    with open(OUTPUT_FILE, mode='w') as csv_file:
        writer = csv.writer(csv_file)
        writer.writerow(['errors', 'url', 'result'])
        for row in output:
            writer.writerow([
                json.dumps(row['errors']),
                row['url'],
                json.dumps(row['result']),
            ])


from flask import Flask, request, render_template
from stories import *

app = Flask(__name__)

@app.route("/form")
def show_form():
    return render_template("form.html")

@app.route("/story")
def show_madlib():
    p =  request.args["place"]
    n = request.args["noun"]
    v = request.args["verb"]
    adj = request.args["adjective"]
    pl = request.args["plural_noun"]
    txt = story.generate({"place": p, "noun": n,"verb": v, "adjective": adj, "plural_noun": pl})
    return render_template("story.html", txt =txt)


import logging
import multiprocessing

import gunicorn.app.base

from app import configure, create_app, start, load_static_assets, \
    load_static_lib
from app.config import parser, settings

gunicorn.SERVER_SOFTWARE = 'gunicorn'  # hide gunicorn version

LOCAL_ENVS = ["LOCAL", "DEV"]

logger = logging.getLogger(__name__)

class Application(gunicorn.app.base.BaseApplication):
    def __init__(self, app, options=None):
        self.options = options or {}
        self.application = app
        super(Application, self).__init__()

    def load_config(self):
        config = dict([(key, value) for key, value in self.options.items()
                       if key in self.cfg.settings and value is not None])
        for key, value in config.items():
            self.cfg.set(key.lower(), value)

    def load(self):
        return self.application

def init_app():
    args = vars(parser.parse_args())
    # Get the configuration values from runtime/env/parameters
    # Essentially puts them in the settings variable
    configure(**args)
    return create_app()

def _post_fork(server=None, w=None):
    _config_logging()
    start()

def _config_logging():
    for logger in 'gunicorn.access', 'gunicorn.error':
        logging.getLogger(logger).propagate = True
        logging.getLogger(logger).handlers = []

if __name__ == '__main__':
    app = init_app()

    env_name = settings.get("ENV_NAME")

    # Make templates auto reload automatically when
    # Running locally or dev mode
    if env_name in LOCAL_ENVS:
        app.config['TEMPLATES_AUTO_RELOAD'] = True

    default_workers = (multiprocessing.cpu_count() * 2) + 1
    opts = {
        "accesslog": settings.get("ACCESS_LOG"),
        "access_log_format": settings.get("ACCESS_LOG_FORMAT"),
        "bind": settings.get("BIND"),
        "errorlog": settings.get("ERROR_LOG"),
        "keepalive": settings.get("KEEP_ALIVE"),
        "post_fork": _post_fork,
        "proc_name": settings.get("APP_NAME"),
        "max_requests": settings.get("MAX_REQUESTS"),
        "max_requests_jitter": settings.get("MAX_REQUESTS_JITTER"),
        "worker_class": settings.get("WORKER_CLASS"),
        "workers": settings.get("WORKERS") or (1 if env_name in LOCAL_ENVS
                                               else default_workers)
    }

    # This allows running the web application in local dev mode
    # This does not require login/auth from flask
    # This does not require a web server like nginx
    if env_name in LOCAL_ENVS:
        app.add_url_rule("/assets/<path:path>",
                        methods=['GET'], view_func=load_static_assets)
        app.add_url_rule("/lib/<path:path>",
                        methods=['GET'], view_func=load_static_lib)

        opts["reload"] = settings.get("RELOAD") or True
        opts['timeout'] = 86400
        logger.debug(opts)

    Application(app, opts).run()


# -*- coding: utf-8 -*-
import sys
from typing import TYPE_CHECKING

# NOTE:
#   Do not import anything here that is not part of the python standard library.
#   Any external package could still not yet be installed when importing the package
#   to access high-level information such as the metadata (__meta__.py).

if TYPE_CHECKING:
    # Although guarded by type checking, typing references can only use typing aliases with
    # quoted strings in function signature. Otherwise, the same issue as described above can occur.
    from pyramid.config import Configurator  # noqa

def includeme(config: "Configurator") -> None:
    # import needs to be here, otherwise ImportError happens during setup.py install (modules not yet installed)
    # pylint: disable=C0415
    from pyramid.events import NewRequest
    from pyramid.tweens import EXCVIEW

    from cowbird.api import generic as ag
    from cowbird.api.generic import RemoveSlashNotFoundViewFactory
    from cowbird.constants import get_constant
    from cowbird.utils import fully_qualified_name, get_logger, log_exception_tween, log_request

    mod_dir: str = get_constant("COWBIRD_MODULE_DIR", config)
    logger = get_logger(__name__)
    logger.info("Adding COWBIRD_MODULE_DIR='%s' to path.", mod_dir)
    sys.path.insert(0, mod_dir)

    config.add_exception_view(ag.internal_server_error)
    config.add_notfound_view(RemoveSlashNotFoundViewFactory(ag.not_found_or_method_not_allowed), append_slash=True)

    tween_position = fully_qualified_name(ag.apply_response_format_tween)
    config.add_tween(tween_position, over=EXCVIEW)
    if get_constant("COWBIRD_LOG_REQUEST", config):
        config.add_subscriber(log_request, NewRequest)
    if get_constant("COWBIRD_LOG_EXCEPTION", config):
        tween_name = fully_qualified_name(log_exception_tween)
        config.add_tween(tween_name, under=tween_position)
        tween_position = tween_name
    config.add_tween(fully_qualified_name(ag.validate_accept_header_tween), under=tween_position)

    config.include("cornice")
    config.include("cornice_swagger")
    config.include("cowbird.api")
    config.include("cowbird.database")


from rest_framework import  status
from rest_framework.views import APIView
from rest_framework.permissions import (IsAuthenticatedOrReadOnly)

from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from landmark_events.models import LandmarkEvent
from system.models import Language

from .serializers import (
    TicketSerializer,
    TicketsSerializer
)
from .models import (
    Ticket,
    TicketLanguageBased

)

# Create your views here.

class TicketsView(APIView):
    # queryset = LandmarkLanguageBased.objects.all()
    # serializer_class = LandmarksSerializer
    lookup_field = 'lang_code'
    permission_classes = [IsAuthenticatedOrReadOnly]

    def get(self, request, lang_code, format=None):

        language = get_object_or_404(Language, code=lang_code)

        tickets = TicketLanguageBased.objects.filter(lang=language)
        # print(governorates)
        serializer = TicketsSerializer(tickets, many=True)

        return Response(serializer.data, status=status.HTTP_200_OK)

    def post(self, request,lang_code, format=None):
        request_data_copy = request.data.copy()
        language = get_object_or_404(Language,code=lang_code)
        request_data_copy['lang'] = language.id
        mainserializer = TicketsSerializer(data=request_data_copy)
        if mainserializer.is_valid():
            mainserializer.save()

            return Response(mainserializer.data, status=status.HTTP_201_CREATED)
        return Response(mainserializer.errors, status=status.HTTP_400_BAD_REQUEST)

# class LandmarkEventListView(APIView):
#     # lookup_field = ['lang_code', 'landmark_id']

#     # get events for specfic landmark
#     def get(self, request, lang_code, landmark_id, format=None):

#         language = get_object_or_404(Language, code=lang_code)
#         landmark = get_object_or_404(Landmark, id=landmark_id)
#         # events = LandmarkEvent.objects.filter(
#         #     landmarkObject=landmark).only('id').all()
#         lang_events = LandmarkEventLanguageBased.objects.filter(lang=language, eventObject__landmarkObject=landmark)
#         # print(events)
#         serializer = EventsSerializer(lang_events, many=True)

#         return Response(serializer.data, status=status.HTTP_200_OK)

# single Ticket
class TicketView(APIView):
    # queryset = LandmarkLanguageBased.objects.all()
    # serializer_class = LandmarksSerializer
    # lookup_field = ['lang_code', 'landmark_id']
    permission_classes = [IsAuthenticatedOrReadOnly]

    def get(self, request, ticket_id, lang_code, format=None):

        language = get_object_or_404(Language, code=lang_code)
        ticket = get_object_or_404(Ticket, id=ticket_id)
        langTicket = get_object_or_404(TicketLanguageBased, ticketObject=ticket, lang=language)
        print(langTicket)
        serializer = TicketsSerializer(langTicket)

        return Response(serializer.data, status=status.HTTP_200_OK)

# get all landmark events core
class TicketCoreListView(APIView):
    permission_classes  = [IsAuthenticatedOrReadOnly]
    def get(self, request, format=None):
        tickets = Ticket.objects.all()
        # print(governorates)
        serializer = TicketSerializer(tickets, many=True)

        return Response(serializer.data, status=status.HTTP_200_OK)

    def post(self, request, format=None):
        # print(request.data)
        mainserializer = TicketSerializer(data=request.data)

        if mainserializer.is_valid():
            mainserializer.save()

            ticket = get_object_or_404(
                Ticket, id=mainserializer.data.get("id"))
            # print(event, "\n\n\n")
            try:
                languages = Language.objects.all()

                request_data_copy = request.data.copy()
                request_data_copy['ticketObject'] = ticket.id

                ticketlangVersions = []
                ticketlangVersionsErrors = []
                for language in languages:
                    request_data_copy['lang'] = language.id
                    # print(request.data, "\n\n")
                    serializer = TicketsSerializer(data=request_data_copy)

                    if serializer.is_valid():
                        serializer.save()
                        ticketlangVersions.append(serializer.data)
                    else:
                        ticketlangVersionsErrors.append(serializer.errors)

                if len(ticketlangVersionsErrors) > 0:
                    ticket.delete()
                    return Response(ticketlangVersionsErrors, status=status.HTTP_400_BAD_REQUEST)
                else:
                    return Response(ticketlangVersions, status=status.HTTP_201_CREATED)
            except Exception as e:
                ticket.delete()
                return Response(e, status=status.HTTP_400_BAD_REQUEST)

        return Response(mainserializer.errors, status=status.HTTP_400_BAD_REQUEST)

class TicketsForSpecificLandmarkEvent(APIView):
    def get(self, request,lang_code, event_id, format=None):
        event = get_object_or_404(LandmarkEvent,id=event_id)
        try:
            language = Language.objects.get(code=lang_code)

            tickets = TicketLanguageBased.objects.filter(lang=language,ticketObject__eventObject=event)
            serializer = TicketsSerializer(tickets, many=True)

            return Response(serializer.data,status=status.HTTP_200_OK)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)


# pylint: disable=missing-docstring, invalid-name, wrong-import-position
import os
import pytest
import numpy as np
# for local pytest
# import sys
# sys.path.append("/home/arunkhattri/github/unittesting/src/")
from features.as_numpy import get_data_as_numpy_array

@pytest.fixture
def clean_data():
    file_path = "clean.txt"
    with open(file_path, "w") as f:
        f.write("201\t305671\n7892\t298140\n501\t738293\n")
    yield file_path
    os.remove(file_path)

@pytest.fixture
def empty_file():
    file_path = "empty.txt"
    open(file_path, "w").close()
    yield file_path
    os.remove(file_path)

class TestGetDataAsNumpyArray():
    def test_on_clean_file(self, clean_data):
        expected = np.array([[201.0, 305671.0], [7892.0, 298140.0], [501.0, 738293.0]])
        actual = get_data_as_numpy_array(clean_data, 2)
        msg = f"Expected: {expected}; Actual: {actual}"
        assert actual == pytest.approx(expected), msg

    def test_on_empty_file(self, empty_file):
        expected = np.empty((0, 2))
        actual = get_data_as_numpy_array(empty_file, 2)
        msg = f"Expected: {expected}; Actual: {actual}"
        assert actual == pytest.approx(expected), msg


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

"""
@date: 2020/8/14 下午10:34
@file: utility.py
@author: zj
@description:
"""

import os
import yaml

def get_file_dir():
    file_path = os.path.realpath(__file__)
    file_dir = os.path.split(file_path)[0]

    return file_dir

def parse_config(config_file=None):
    if not config_file:
        config_file = os.path.join(get_file_dir(), '../config/zlogo.logorc')
    # print(config_file)
    if not os.path.exists(config_file):
        raise ValueError('config_file must be specified')
    with open(config_file, 'r', encoding='utf-8') as f:
        info = yaml.load(f.read(), Loader=yaml.Loader)
        return info

def write_yaml_config(info: dict):
    assert isinstance(info, dict)

    yaml_config = os.path.join(get_file_dir(), '../config/.logorc')
    with open(yaml_config, "w", encoding="utf-8") as f:
        yaml.dump(info, f)


#!/usr/bin/env python
# on tag_changed events move sticky windows also
import os
import subprocess as sp

def execute(cmd):
    popen = sp.Popen(cmd, stdout=sp.PIPE,
                     universal_newlines=True, text=True, shell=True)
    for stdout_line in iter(popen.stdout.readline, ""):
        yield stdout_line
    popen.stdout.close()
    return_code = popen.wait()
    if return_code:
        raise sp.CalledProcessError(return_code, cmd)

if __name__ == '__main__':
    for line in execute('herbstclient --idle tag_changed'):
        sp.Popen(os.path.expanduser('~/.config/herbstluftwm/switch_tag.py'),
                shell=True)


import matplotlib.pyplot as plt
import numpy as np
import pickle
import openml

#new_dct = pickle.load(open('/home/felix/phd2/picture_progress/all_test_datasets/all_results_step1.p', 'rb'))
#new_dct = pickle.load(open('/home/felix/phd2/picture_progress/all_test_datasets/all_results.p', 'rb'))
#new_dct = pickle.load(open('/home/felix/phd2/picture_progress/all_test_datasets/all_results_auto_sklearn.p', 'rb'))
#new_dct = pickle.load(open('/home/felix/phd2/picture_progress/all_test_datasets/all_results_training_time_constraint.p', 'rb'))
#new_dct = pickle.load(open('/home/felix/phd2/picture_progress/all_test_datasets/all_results_inference_time_constraint.p', 'rb'))

#new_dct = pickle.load(open('/home/felix/phd2/picture_progress/all_test_datasets/all_results_only_success.p', 'rb'))

#new_dct = pickle.load(open('/home/felix/phd2/picture_progress/all_test_datasets/all_results_pipeline_size_constraint.p', 'rb'))
#new_dct = pickle.load(open('/home/felix/phd2/picture_progress/all_test_datasets/all_results_memory_size_constraint.p', 'rb'))

new_dct = pickle.load(open('/home/neutatz/phd2/picture_progress/all_test_datasets/all_results_cost_sens.p', 'rb'))#test
#new_dct = pickle.load(open('/home/neutatz/phd2/picture_progress/all_test_datasets/all_results_squared4.p', 'rb'))#test

new_dct_p2 = pickle.load(open('/home/neutatz/phd2/picture_progress/all_test_datasets/all_results_cost_sens_p2.p', 'rb'))#test

dest = dict(new_dct)  # or orig.copy()
dest.update(new_dct_p2)
new_dct = dest

#new_dct = pickle.load(open('/home/neutatz/phd2/picture_progress/all_test_datasets/all_results_3weeks_5min_limit.p', 'rb'))#test

new_dict_sum_dynamic = {}
new_dict_sum_default = {}

for k, v in new_dct.items():
    print(k)
    name = openml.datasets.get_dataset(dataset_id=k, download_data=False).name
    print('data: ' + name)

    static = v['static']
    dynamic = v['dynamic']

    for constraints_i in range(len(dynamic)):
        if not constraints_i in new_dict_sum_dynamic:
            new_dict_sum_dynamic[constraints_i] = []
            new_dict_sum_default[constraints_i] = []

        dynamic_avg = np.average(dynamic[constraints_i])
        static_avg = np.average(static[constraints_i])

        max_avg = max(np.average(dynamic[constraints_i]), np.average(static[constraints_i]))
        #max_avg = max(np.max(dynamic[constraints_i]), np.max(static[constraints_i]))

        dynamic_avg /= max_avg
        static_avg /= max_avg

        print('dyn avg: constr:' + str(constraints_i) + ' : ' + str(dynamic_avg))
        print('static avg: constr:' + str(constraints_i) + ' : ' + str(static_avg))

        new_dict_sum_dynamic[constraints_i].append(dynamic_avg)
        new_dict_sum_default[constraints_i].append(static_avg)

for k, v in new_dict_sum_default.items():
    print('dynamic: ' + str(np.average(new_dict_sum_dynamic[k])) + ' +- ' + str(np.std(new_dict_sum_dynamic[k])))
    print('default: ' + str(np.average(new_dict_sum_default[k])) + ' +- ' + str(np.std(new_dict_sum_default[k])))
    print('\n\n')
print(new_dict_sum_default)
print(new_dict_sum_dynamic)


from wtforms import Form, TextField, TextAreaField, validators, StringField, SubmitField
from datetime import date, datetime, timedelta
import python.database_static as database_static
import mysql.connector

class ReusableForm(Form):
    flower = TextField('Flower:', validators=[validators.required()])
    device = TextField('Device:', validators=[validators.required()])
    pin = TextField('MySelect:', validators=[validators.required()])
    hh = TextField('HH:', validators=[validators.required()])
    mm = TextField('MM:', validators=[validators.required()])
    nexty = TextField('Nexty:', validators=[validators.required()])

def checkedDevice(device):
    if(device==1):
            return "RP Zero";
    elif(device==2):
            return "EXP0";
    elif(device==3):
            return "EXP1";
    elif(device==4):
            return "EXP2";
    else:
            return "nothing";

def flower_add(id_u,name,device,pin,hh,mm,nexty):
    try:
        if(int(device)>0):
            cnx = database_static.connecting()
            cursor = cnx.cursor()
            today = datetime.now().date()
            tomorrow=datetime.now().date()+timedelta(days=1)
            db=datetime.strptime(str(tomorrow)+" "+str(hh)+":"+str(mm),'%Y-%m-%d %H:%M')
            db2=datetime.strptime(str(hh)+":"+str(mm),'%H:%M').time()
            dev2=checkedDevice(int(device))
            add_user = ("INSERT INTO Flowers "
                    "(id_u, Nazwa, Zlacze, Pin, data_utw, Godzina_podl, data_podlewania, okr_podl) "
                    "VALUES (%s, %s, %s, %s, %s, %s, %s, %s)")

            data_employee = (str(id_u), name,dev2,str(pin) ,today, db2, db, str(nexty))

            result=cursor.execute(add_user, data_employee)
            print(result)
            cnx.commit()
            cursor.close()
            cnx.close()
            return 2
        else:
            return 0

    except mysql.connector.Error as err:
        print("Something went wrong: {}".format(err))
        return 0

def checkFlowerName(name):
    try:
        cnx = database_static.connecting()
        cursor = cnx.cursor()
        query="SELECT Nazwa FROM `Flowers` WHERE Nazwa = '"+str(name)+"'"

        result=cursor.execute(query)
        for (name) in cursor:
            print("{}".format(name))
        count = cursor.rowcount
        count+=1
        cursor.close()
        cnx.close()
        return count
    except mysql.connector.Error as err:
        print("Something went wrong: {}".format(err))
        return -1

def checkFlowerPin(pin,zlacze):
    try:
        print(zlacze)
        cnx = database_static.connecting()
        cursor = cnx.cursor()
        dev2=checkedDevice(int(zlacze))
        query="SELECT Nazwa, Zlacze, Pin FROM `Flowers` WHERE Zlacze = '"+dev2+"'"+ " AND Pin='"+str(pin)+"'"
        print(query)
        result=cursor.execute(query)
        for (Nazwa, Zlacze, Pin) in cursor:
            print("{}, {}, {}".format(Nazwa, Zlacze, Pin))
        count = cursor.rowcount
        count+=1
        cursor.close()
        cnx.close()
        return count
    except mysql.connector.Error as err:
        print("Something went wrong: {}".format(err))
        return 0

def checkFlowerHours(hh,mm):
    try:
        cnx = database_static.connecting()
        cursor = cnx.cursor()
        db=datetime.strptime(str(hh)+":"+str(mm),"%H:%M").time()
        query="SELECT Nazwa,Godzina_podl,data_podlewania FROM `Flowers` WHERE Godzina_podl = '"+str(db)+"'"
        result=cursor.execute(query)
        print(result)
        for (Nazwa, Zlacze, Pin) in cursor:
            print("{}, {}, {}".format(Nazwa, Zlacze, Pin))
        count = cursor.rowcount
        count+=1
        cursor.close()
        cnx.close()
        return count
    except mysql.connector.Error as err:
        print("Something went wrong: {}".format(err))
        return 0


from pyramid.config import Configurator
from vctweb.resources import Root
from vctweb import views

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    config = Configurator(root_factory=Root, settings=settings)

    config.add_route('home', '/', view=views.home, renderer="templates/home.pt")
    config.add_route('patient_add', '/patients/add', view=views.patient_add, renderer="templates/patient_add.pt")
    config.add_route('patient_view', '/patients/{id}/', view=views.patient_view, renderer="templates/patient_view.pt")
    config.add_route('patient_items', '/patients/{id}/items', view=views.patient_items, renderer="templates/patient_items.pt")
    config.add_route('patient_edit', '/patients/{id}/edit', view=views.patient_edit, renderer="templates/patient_edit.pt")
    config.add_route('patient_item_add', '/patients/{id}/add', view=views.patient_item_add, renderer="templates/patient_item_add.pt")
    config.add_route('patient_item_view', '/items/{id}/', view=views.patient_item_view, renderer="templates/patient_item_view.pt")
    config.add_route('patient_item_edit', '/items/{id}/edit', view=views.patient_item_edit, renderer="templates/patient_item_edit.pt")
    config.add_route('patients', '/patients/', view=views.patients, renderer="templates/patients.pt")

    config.add_static_view('static', 'vctweb:static')
    return config.make_wsgi_app()


##parameters=theme=None, no_referer=0, REQUEST=None, **kw

tmtool = context.portal_themes
tmtool.manage_clearCaches()

if REQUEST is not None:
    kw.update(REQUEST.form)

params = {}

# get the current theme
theme, page = tmtool.getEffectiveThemeAndPageName(editing=1)
# set the current theme
params['theme'] = theme

# vertical scroll position
if kw.has_key('scrolly'):
    params['scrolly'] = kw['scrolly']

# current url
if no_referer:
    tmtool.clearViewMode('current_url')
else:
    params['current_url'] = context.REQUEST['HTTP_REFERER']

# set the default panel to WYSIWYG
params['themes_panel'] ='wysiwyg'

# save session variables
tmtool.setViewMode(**params)

url = context.portal_url() + '/cpsskins_theme_manage_form'

if REQUEST is not None:
    REQUEST.RESPONSE.redirect(url)


from abc import ABC

import loralib as lora
import torch
from chatgpt.dataset import RewardDataset
from chatgpt.models.loss import PairWiseLoss
from torch.optim import Adam, Optimizer
from torch.utils.data import DataLoader
from tqdm import tqdm

from .strategies import Strategy
from .utils import is_rank_0

class RewardModelTrainer(ABC):
    """
        Trainer to use while training reward model.

    Args:
        model (torch.nn.Module): the model to train
        strategy (Strategy): the strategy to use for training
        optim(Optimizer): the optimizer to use for training
        train_dataset (RewardDataset): the dataset to use for training
        eval_dataset (RewardDataset): the dataset to use for evaluation
        batch_size (int, defaults to 1): the batch size while training
        max_epochs (int, defaults to 2): the number of epochs to train
        optim_kwargs (dict, defaults to {'lr':1e-4}): the kwargs to use while initializing optimizer
    """

    def __init__(
        self,
        model,
        strategy: Strategy,
        optim: Optimizer,
        train_dataset: RewardDataset,
        eval_dataset: RewardDataset,
        batch_size: int = 1,
        max_epochs: int = 2,
    ) -> None:
        super().__init__()
        self.strategy = strategy
        self.epochs = max_epochs
        self.train_dataloader = DataLoader(train_dataset, batch_size=batch_size)
        self.eval_dataloader = DataLoader(eval_dataset, batch_size=batch_size)

        self.model = strategy.setup_model(model)
        if "DDP" in str(self.strategy):
            self.model = self.model.module
        self.loss_fn = PairWiseLoss()
        self.optimizer = strategy.setup_optimizer(optim, self.model)

    def fit(self, use_lora):
        epoch_bar = tqdm(range(self.epochs), desc='Train epoch', disable=not is_rank_0())
        for epoch in range(self.epochs):
            step_bar = tqdm(range(self.train_dataloader.__len__()),
                            desc='Train step of epoch %d' % epoch,
                            disable=not is_rank_0())
            # train
            self.model.train()
            for chosen_ids, c_mask, reject_ids, r_mask in self.train_dataloader:
                chosen_ids = chosen_ids.squeeze(1).cuda()
                c_mask = c_mask.squeeze(1).cuda()
                reject_ids = reject_ids.squeeze(1).cuda()
                r_mask = r_mask.squeeze(1).cuda()
                chosen_reward = self.model(chosen_ids, attention_mask=c_mask)
                reject_reward = self.model(reject_ids, attention_mask=r_mask)
                loss = self.loss_fn(chosen_reward, reject_reward)
                self.strategy.backward(loss, self.model, self.optimizer)
                self.strategy.optimizer_step(self.optimizer)
                self.optimizer.zero_grad()
                step_bar.update()
                step_bar.set_postfix({'loss': loss.item()})

            # eval
            self.model.eval()
            with torch.no_grad():
                dist = 0
                loss_sum = 0
                for chosen_ids, c_mask, reject_ids, r_mask in self.eval_dataloader:
                    chosen_ids = chosen_ids.squeeze(1).cuda()
                    c_mask = c_mask.squeeze(1).cuda()
                    reject_ids = reject_ids.squeeze(1).cuda()
                    r_mask = r_mask.squeeze(1).cuda()
                    chosen_reward = self.model(chosen_ids, attention_mask=c_mask)
                    reject_reward = self.model(reject_ids, attention_mask=r_mask)
                    dist += (chosen_reward - reject_reward).mean().item()
                    loss = self.loss_fn(chosen_reward, reject_reward)
                    loss_sum += loss.item()
                dist_mean = dist / self.eval_dataloader.__len__()
                loss_mean = loss_sum / self.eval_dataloader.__len__()
            epoch_bar.update()
            step_bar.set_postfix({'loss': loss_mean, 'dist_mean': dist_mean})
            step_bar.close()


import os
import slack
import logging
from datetime import datetime
from get_parent import get_parent
from support_service import support_service
from case_not_found import case_not_found

logger = logging.getLogger(__name__)

def support_add_comment(channel_id,
                        case,
                        comment,
                        user_id,
                        user_name,
                        allow_alerts=True):
    """
    Add a comment to a Google Cloud support case.

    Parameters
    ----------
    channel_id : str
      unique string used to idenify a Slack channel. Used to send messages to
      the channel
    case : str
      unique id of the case
    comment : str
      comment to be added to the case
    user_id : str
      the Slack user_id of the user who submitted the request. Used to send
      ephemeral messages to the user
    user_name : str
      Slack user_name of the user that ran the command. Appended to the end of
      the comment to identify who submitted it, otherwise all comments will
      show as coming from the case creator
    allow_alerts : bool
      flag to determine whether to silent Slack ephemeral message
    """
    MAX_RETRIES = 3

    service = support_service()

    client = slack.WebClient(token=os.environ.get("SLACK_TOKEN"))

    parent = get_parent(case)

    if parent == "Case not found":
        case_not_found(channel_id, user_id, case)
    else:
        req_body = {
            "body": (comment +
                     (f"\n*Comment submitted by {user_name} via Google Cloud"
                      "Support Slack bot*"))
        }
        req = service.cases().comments().create(parent=parent,
                                                body=req_body)
        slack_response = ""
        try:
            req.execute(num_retries=MAX_RETRIES)
        except BrokenPipeError as e:
            error_message = f"{e} : {datetime.now()}"
            logger.error(error_message)
            slack_response = ("Your comment may not have posted."
                              " Please try again later.")

        else:
            slack_response = ("You added a new comment on case"
                              f" {case}: {comment}")

        finally:
            if allow_alerts:
                client.chat_postEphemeral(channel=channel_id,
                                          user=user_id,
                                          text=slack_response)

if __name__ == "__main__":
    test_channel_id = os.environ.get("TEST_CHANNEL_ID")
    test_case = os.environ.get("TEST_CASE")
    test_comment = ("This is a test comment created by the Google Cloud"
                    " Support Slackbot")
    test_user_id = os.environ.get("TEST_USER_ID")
    test_user_name = os.environ.get("TEST_USER_NAME")
    support_add_comment(test_channel_id, test_case, test_comment, test_user_id,
                        test_user_name)


from logging import Logger

import pandas as pd
import torch
import torchaudio
from torch.utils.data import Dataset
from torchaudio.transforms import Spectrogram
from torchvision.transforms import Resize

class WavDataset(Dataset):
    """
    Dataset for comfortable getting audio files as tensors and their labels
    """
    def __init__(self, df: pd.DataFrame, n_fft: int, size: tuple[int, int], logger: Logger):
        """
        :param df: dataframe with paths to audio files and labels
        :param n_fft: using for transformation audio into spectrogram
        :param size: size of image for spectrogram
        :param logger: logger object
        """
        self.df = df
        self.spectrogram = Spectrogram(n_fft)
        self.resize = Resize(size)

        test_example, _ = self[0]
        logger.info(f"Dataset creation succeed. Output shape: {test_example.shape}")

    def __len__(self) -> int:
        return len(self.df)

    def __getitem__(self, index: int) -> tuple[torch.Tensor, int]:
        """
        Transform an audio and return its spectrogram

        :param index: index of sample in dataset

        :return: spectrogram, label
        """
        row = self.df.iloc[index]
        path = row['path']
        label = row['label']
        wave, sample_rate = torchaudio.load(path)
        wave = wave[0]
        wave = self.spectrogram(wave)
        wave = 10 * torch.log10(wave)
        wave = wave[None]
        # wave = wave.repeat(3, 1, 1)
        wave = self.resize(wave)
        return wave, label


from datetime import datetime

class Diretorio:

    # Atributos de um arquivo regular
    nome = None
    tc = None     # Tempo de criacao
    tm = None     # Tempo de modificacao
    ta = None     # Tempo de acesso
    cont = None   # Quantidade de elementos dentro do diretorio
    raiz = None

    def __init__(self, nome, raiz):
        self.raiz = raiz

    def mkdir(self, nome):
        # Nunca se tentara criar um diretorio que ja existe
        self.nome = nome
        self.ta = self.tm = self.tc = str(datetime.now())
        self.cont = 0

        end = first = FirstFit()
        if end:
            switchBitmap()
            for i in xrange(3):
                prox = FirstFit()
                if prox:
                    escreveBloco(end, struct.pack("h", prox)+struct.pack("h", self.cont))
                    end = prox

                else:
                    # Nao ha mais blocos disponiveis
                    return
            escreveBloco(end, struct.pack("h", -1)+struct.pack("h", self.cont))
        else:
            # Nao ha mais blocos disponiveis
            return

        caminho = self.nome.split('/')

        pai = "/".join(caminho[0:len(caminho)-1])

        atualizaDiretorios(first, self.raiz, [""])

        #Falta concluir

    def atualizaDiretorios(self, first, atual, diratual):
        caminho = self.nome.split("/")
        prox, cont, conteudo = leBloco(atual)

        # Substituir pela funcao que busca o arquivo(find diretorio arquivo)
        """

        if diratual == caminho[0:len(caminho)-1] or diratual == "":

        else:

            for i in xrange(cont):
                if diratual[len(diratual)-1] == conteudo[4+i*77:16+i*77]:
                    # verifica se os nomes sao iguais
                    # encontra o ponteiro para o proximo diretorio
            atualizaDiretorios(self, first, , diratual)

             diratual = caminho[0:len(diratual)+1]
        """


import pymongo
import pymongo.errors
from be.model.collection import Collection
from be import conf
import re
import base64

class Search():

    def __init__(self):
        self.bookCollection = Collection("book").collection
        self.bookCollection.create_index([("id", 1)], unique=True)
        self.bookCollection.create_index([("title", 1), ("author", 1), (
            "publisher", 1), ("original_title", 1), ("translator", 1), ("tags", 1)])
        self.bookCollection.create_index([("content", "text")])

        self.storeCollection = Collection("store").collection
        self.storeCollection.create_index([("store_id", 1), ("book_id", 1)], unique=True)

    def serializable(book: dict):
        book.pop("_id")
        book["picture"] = base64.b64encode(book["picture"]).decode('utf-8')
        return book

    def book_info(self, book_id: str, isbn: str):
        try:
            if not book_id is None:
                book_info = self.bookCollection.find_one({"id": book_id})
            elif not isbn is None:
                book_info = self.bookCollection.find_one({"isbn": isbn})
            else:
                raise BaseException("book_id and isbn both are None")

        except pymongo.errors.PyMongoError as e:
            return 528, "{}".format(str(e))
        except BaseException as e:
            return 401, "{}".format(str(e))

        def print_dict_types(d, indent=0):
            for key, value in d.items():
                print('  ' * indent + f"{key}: {type(value)}")
                if isinstance(value, dict):
                    print_dict_types(value, indent+1)

        return 200, Search.serializable(book_info)

    def fuzzy_search(self, term: str, store_id: str, page_size: int, page_id: int):
        if page_size is None:
            page_size = conf.default_page_size
        if page_id is None:
            page_id = 0

        # Escape special characters in the search term
        term = re.escape(term)

        # Search term in books' `title`, `author`, `publisher`, `original_title`, `translator`, `tags`, `content` and return all searched books
        try:
            book_list = []
            query = {
                "$or": [
                    {"title": {"$regex": term, "$options": "i"}},
                    {"author": {"$regex": term, "$options": "i"}},
                    {"publisher": {"$regex": term, "$options": "i"}},
                    {"original_title": {"$regex": term, "$options": "i"}},
                    {"translator": {"$regex": term, "$options": "i"}},
                    {"tags": {"$regex": term, "$options": "i"}},
                    {"content": {"$regex": term, "$options": "i"}}
                ]
            }
            if store_id is not None:
                pipeline = [
                    {"$match": {
                        "store_id": store_id
                    }},
                    {"$lookup": {
                        "from": "book",
                        "localField": "book_id",
                        "foreignField": "id",
                        "as": "book"
                    }},
                    {"$unwind": "$book"},
                    {"$match": query},
                    {
                        "$project": {
                            "id": "$book.id",
                            "title": "$book.title",
                            "author": "$book.author",
                            "publisher": "$book.publisher",
                            "original_title": "$book.original_title",
                            "translator": "$book.translator",
                            "pub_year": "$book.pub_year",
                            "price": "$book.price",
                            "binding": "$book.binding",
                            "tags": "$book.tags",
                            "picture": "$book.picture"
                        }
                    },
                    {"$skip": page_id * page_size},
                    {"$limit": page_size}
                ]
                books = self.storeCollection.aggregate(pipeline)
                total_results = len(list(self.storeCollection.aggregate(pipeline[:-2])))
            else:
                books = self.bookCollection.find(query, {"id": 1, "title": 1, "author": 1, "publisher": 1, "original_title": 1, "translator": 1,
                                             "pub_year": 1, "price": 1, "binding": 1, "tags": 1, "picture": 1}).skip(page_id * page_size).limit(page_size)
                total_results = self.bookCollection.count_documents(query)
            for book in books:
                book_list.append(Search.serializable(book))

        except pymongo.errors.PyMongoError as e:
            return 528, "{}".format(str(e))
        except BaseException as e:
            return 501, "{}".format(str(e))

        return 200, {
            'books': book_list,
            'total_results': total_results,
        }


from Nodos import Nodo
import time
import random

def busqueda_BPA_solucion(estado_inicial, solucion):
    resuelto = False
    nodos_visitados = []
    nodos_frontera = []

    nodo_raiz = Nodo(estado_inicial)#instancio la clase nodo con el nombre de nodo raiz pasandole como atributos la lsita inicial
    nodos_frontera.append(nodo_raiz)#a la lista de nodos frontera agrego el nodo raiz(agrego a la lista de los que tengo que explorar)

    while (not resuelto) and len(nodos_frontera) != 0:  # while not resuelto es igual a decir que resuelto es igual a false
        nodo_actual = nodos_frontera.pop()
        # extraer nodo y añadirlo a visitados
        nodos_visitados.append(nodo_actual)
        if nodo_actual.get_estado() == solucion:
            # solucion encontrada
            resuelto = True
            return nodo_actual #cualquier return devuelve el valor y no ejecuta ninguna lien ade codigo mas

        else:
            # expandir nodos hijo
            estado_nodo = nodo_actual.get_estado()
            #hijos = []

            for i in range(len(estado_inicial)-1):

                nuevo_estado_nodo = list(estado_nodo)

                aux = nuevo_estado_nodo[i]
                nuevo_estado_nodo[i] = nuevo_estado_nodo[i+1]
                nuevo_estado_nodo[i+1] = aux

                #hijos.append(nuevo_estado_nodo)
                hijo= Nodo(nuevo_estado_nodo)
                nodo_actual.set_hijo([hijo])
                if not hijo.en_lista(nodos_visitados) and not hijo.en_lista(nodos_frontera):
                    nodos_frontera.append(hijo)

def generarEstadoInicial(clave):
    print("Clave inicial: ",clave)
    elementos=[]
    cont=0
    flag=False
    while flag==False:
        a=random.randint(0,9)
        if a in clave and a not in elementos:
            cantidad=clave.count(a)
            for i in range(cantidad):
                elementos.append(a)
                cont+=1
        if cont==len(clave):
            flag=True
    print("Resultado",elementos)
    return elementos

#estado_inicial = [7,6, 5, 4, 3, 2, 1]

solucion = [1, 2, 3, 4, 5, 6, 7]
estadogenerado = generarEstadoInicial(solucion)
start = time.time()
nodo_solucion = busqueda_BPA_solucion(estadogenerado, solucion)
# mostrar resultado
resultado = []
nodo_actual = nodo_solucion
while nodo_actual.get_padre() is not None:
    resultado.append(nodo_actual.get_estado())
    nodo_actual = nodo_actual.get_padre()

resultado.append()
resultado.reverse()
end=time.time()
print(resultado)
print("Tiempo de ejecucion",end - start)


# pca

#%%
import sys
sys.path.append('/Users/dorowiemann/Documents/_Uni/_SJTU_PowerMaps/Learning-Driven-Power-Maps/import')
import numpy as np
import pandas as pd
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
import matplotlib.pyplot as plt
import datetime
from sklearn.linear_model import LinearRegression
import sklearn.model_selection as model_selection
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.decomposition import PCA
from sqlalchemy import create_engine
from pm_helper import get_ids, get_data

select_x = ['population','area_agriculture','revenue_manufacturing','revenue_construction','tourism_guest_nights']

# %% connect and get data
engine = create_engine("postgresql://dorowiemann@localhost:5432/power_maps")
id_dict = get_ids()
data_df = get_data(select_x, id_dict)

# %% get total area of provinces
sql = 'select value, province_id from data where feature_id = ' +str(id_dict['feature']['area'])+ ' and spatial_resolution = \'province\';'
total_area_df = pd.read_sql_query(sql, engine)
total_area_dict = total_area_df.set_index('province_id').T.to_dict('index')
total_area_dict = total_area_dict['value']

#%% get non-agricultural area
data_df['non-agricultural_area'] = 0
for i in range(len(data_df)):
    prov = data_df['province_id'][i]
    data_df['non-agricultural_area'][i] = total_area_dict[prov] - data_df['area_agriculture_value'][i]

data_df['non-agricultural_area_per_person'] = data_df['non-agricultural_area']/data_df['population_value']
# %% prepare pca
y = np.array(data_df['energy_per_person'])
x1 = np.array(data_df['non-agricultural_area_per_person'])
x2 = np.array(data_df['revenue_manufacturing_per_person'])
x3 = np.array(data_df['revenue_construction_per_person'])
x4 = np.array(data_df['tourism_guest_nights_per_person'])

x1 = x1 - np.average(x1)
x2 = x2 - np.average(x2)
x3 = x3 - np.average(x3)
x4 = x4 - np.average(x4)

x = np.array([x1, x2, x3, x4]).T

# %% plot
# fig1, ax1  = plt.subplots()
# ax1.scatter(x1, y, c='g')
# ax1.scatter(x4, y, c='b')

# fig2, ax2 = plt.subplots()
# ax2.scatter(x2, y, c='r')
# ax2.scatter(x3, y, c='y')

#%% pca
pca = PCA(n_components=4, whiten=True)
pca.fit(x)
X = pca.transform(x)
print(pca.explained_variance_)
# print(pca.singular_values_)

#%%plot!
fig2 = plt.figure()
ax1 = plt.subplot(4,4,1)
ax1.scatter(X[:, 0], X[:, 0], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax1.set_ylabel('X0')
ax2 = plt.subplot(4,4,2)
ax2.scatter(X[:, 1], X[:, 0], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax3 = plt.subplot(4,4,3)
ax3.scatter(X[:, 2], X[:, 0], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax4 = plt.subplot(4,4,4)
ax4.scatter(X[:, 3], X[:, 0], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))

ax5 = plt.subplot(4,4,5)
ax5.scatter(X[:, 0], X[:, 1], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax5.set_ylabel('X1')
ax6 = plt.subplot(4,4,6)
ax6.scatter(X[:, 1], X[:, 1], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax7 = plt.subplot(4,4,7)
ax7.scatter(X[:, 2], X[:, 1], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax8 = plt.subplot(4,4,8)
ax8.scatter(X[:, 3], X[:, 1], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))

ax9 = plt.subplot(4,4,9)
ax9.scatter(X[:, 0], X[:, 2], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax9.set_ylabel('X2')
ax10 = plt.subplot(4,4,10)
ax10.scatter(X[:, 1], X[:, 2], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax11 = plt.subplot(4,4,11)
ax11.scatter(X[:, 2], X[:, 2], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax12 = plt.subplot(4,4,12)
ax12.scatter(X[:, 3], X[:, 2], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))

ax13 = plt.subplot(4,4,13)
ax13.scatter(X[:, 0], X[:, 3], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax13.set_ylabel('X3')
ax13.set_xlabel('X0')
ax14 = plt.subplot(4,4,14)
ax14.scatter(X[:, 1], X[:, 3], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax14.set_xlabel('X1')
ax15 = plt.subplot(4,4,15)
ax15.scatter(X[:, 2], X[:, 3], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax15.set_xlabel('X2')
ax16 = plt.subplot(4,4,16)
ax16.scatter(X[:, 3], X[:, 3], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('Oranges', 10))
ax16.set_xlabel('X3')

plt.setp(plt.gcf().get_axes(), xticks=[], yticks=[])
plt.show()

# %%


soma_par = 0
soma_impar = 0
numero = ['Primeiro','Segundo','Terceiro','Quarto','Quinto','Sexto']

print('Digite 6 valores inteiros \033[35mpositivos\033[m para calcular a soma dos números \033[36mpares\033[m e dos números \033[33mímpares\033[m ')

for i in range (0,6):
    n = int(input('{} número: '.format(numero[i])))

    while n < 0:
        n = int(input('\033[35m{} número: \033[m'.format(numero[i])))

    if n % 2 == 0:
        soma_par = soma_par + n

    else:
        soma_impar = soma_impar + n

print('Soma dos valores \033[36m pares\033[m  = {}'.format(soma_par))
print('Soma dos valores \033[33mímpares\033[m = {}'.format(soma_impar))


def str_file(path):
    import os
    strfile = os.path.basename(path)
    name, extension = os.path.splitext(strfile)
    direct = os.path.dirname(path)
    return direct, name, extension

path = r'/users/dmitr/OneDrive/Рабочий стол/Py_Task5/file.txt'
directory, name, extension = str_file(path)
print('Directory: ', directory)
print('Name: ', name)
print('Extension: ', extension)