from __future__ import absolute_import
from __future__ import print_function

import pyspark
import h5py
import json
from keras.optimizers import serialize as serialize_optimizer
from keras.models import load_model

from .utils import lp_to_simple_rdd
from .utils import model_to_dict
from .mllib import to_matrix, from_matrix, to_vector, from_vector
from .optimizers import SGD
from .worker import AsynchronousSparkWorker, SparkWorker
from .parameter import HttpServer, SocketServer
from .parameter import HttpClient, SocketClient

class SparkModel(object):

    def __init__(self, model, mode='asynchronous', frequency='epoch',  parameter_server_mode='http', num_workers=None,
                 elephas_optimizer=None, custom_objects=None, batch_size=32, *args, **kwargs):
        """SparkModel

        Base class for distributed training on RDDs. Spark model takes a Keras
        model as master network, an optimization scheme, a parallelisation mode
        and an averaging frequency.

        :param model: Compiled Keras model
        :param mode: String, choose from `asynchronous`, `synchronous` and `hogwild`
        :param frequency: String, either `epoch` or `batch`
        :param parameter_server_mode: String, either `http` or `socket`
        :param num_workers: int, number of workers used for training (defaults to None)
        :param elephas_optimizer: Elephas optimizer
        :param custom_objects: Keras custom objects
        """

        self._master_network = model
        if not hasattr(model, "loss"):
            raise Exception(
                "Compile your Keras model before initializing an Elephas model with it")
        metrics = model.metrics
        loss = model.loss
        optimizer = serialize_optimizer(model.optimizer)

        if custom_objects is None:
            custom_objects = {}
        if metrics is None:
            metrics = ["accuracy"]
        if elephas_optimizer is None:
            self.optimizer = SGD()
        else:
            self.optimizer = elephas_optimizer
        self.mode = mode
        self.frequency = frequency
        self.num_workers = num_workers
        self.weights = self._master_network.get_weights()
        self.pickled_weights = None
        self.master_optimizer = optimizer
        self.master_loss = loss
        self.master_metrics = metrics
        self.custom_objects = custom_objects
        self.parameter_server_mode = parameter_server_mode
        self.batch_size = batch_size
        self.kwargs = kwargs

        self.serialized_model = model_to_dict(self.master_network)
        # TODO only set this for async/hogwild mode
        if self.parameter_server_mode == 'http':
            self.parameter_server = HttpServer(
                self.serialized_model, self.optimizer, self.mode)
            self.client = HttpClient()
        elif self.parameter_server_mode == 'socket':
            self.parameter_server = SocketServer(self.serialized_model)
            self.client = SocketClient()
        else:
            raise ValueError("Parameter server mode has to be either `http` or `socket`, "
                             "got {}".format(self.parameter_server_mode))

    @staticmethod
    def get_train_config(epochs, batch_size, verbose, validation_split):
        return {'epochs': epochs,
                'batch_size': batch_size,
                'verbose': verbose,
                'validation_split': validation_split}

    def get_config(self):
        base_config = {
            'parameter_server_mode': self.parameter_server_mode,
            'elephas_optimizer': self.optimizer.get_config(),
            'mode': self.mode,
            'frequency': self.frequency,
            'num_workers': self.num_workers,
            'batch_size': self.batch_size}
        config = base_config.copy()
        config.update(self.kwargs)
        return config

    def save(self, file_name):
        model = self.master_network
        model.save(file_name)
        f = h5py.File(file_name, mode='a')

        f.attrs['distributed_config'] = json.dumps({
            'class_name': self.__class__.__name__,
            'config': self.get_config()
        }).encode('utf8')

        f.flush()
        f.close()

    @property
    def master_network(self):
        return self._master_network

    @master_network.setter
    def master_network(self, network):
        self._master_network = network

    def start_server(self):
        self.parameter_server.start()

    def stop_server(self):
        self.parameter_server.stop()

    def predict(self, data):
        """Get prediction probabilities for a numpy array of features
        """
        return self.master_network.predict(data)

    def predict_classes(self, data):
        """ Predict classes for a numpy array of features
        """
        return self.master_network.predict_classes(data)

    def fit(self, rdd, epochs=10, batch_size=32,
            verbose=0, validation_split=0.1):
        """
        Train an elephas model on an RDD. The Keras model configuration as specified
        in the elephas model is sent to Spark workers, abd each worker will be trained
        on their data partition.

        :param rdd: RDD with features and labels
        :param epochs: number of epochs used for training
        :param batch_size: batch size used for training
        :param verbose: logging verbosity level (0, 1 or 2)
        :param validation_split: percentage of data set aside for validation
        """
        if self.num_workers:
            rdd = rdd.repartition(self.num_workers)

        if self.mode in ['asynchronous', 'synchronous', 'hogwild']:
            self._fit(rdd, epochs, batch_size, verbose, validation_split)
        else:
            raise ValueError(
                "Choose from one of the modes: asynchronous, synchronous or hogwild")

    def _fit(self, rdd, epochs, batch_size, verbose, validation_split):
        """Protected train method to make wrapping of modes easier
        """
        self.master_network.compile(optimizer=self.master_optimizer,
                                    loss=self.master_loss,
                                    metrics=self.master_metrics)
        if self.mode in ['asynchronous', 'hogwild']:
            self.start_server()
        train_config = self.get_train_config(
            epochs, batch_size, verbose, validation_split)
        mode = self.parameter_server_mode
        freq = self.frequency
        optimizer = self.master_optimizer
        loss = self.master_loss
        metrics = self.master_metrics
        custom = self.custom_objects

        yaml = self.master_network.to_yaml()
        init = self.master_network.get_weights()
        parameters = rdd.context.broadcast(init)

        if self.mode in ['asynchronous', 'hogwild']:
            worker = AsynchronousSparkWorker(
                yaml, parameters, mode, train_config, freq, optimizer, loss, metrics, custom)
            rdd.mapPartitions(worker.train).collect()
            new_parameters = self.client.get_parameters()
        elif self.mode == 'synchronous':

            worker = SparkWorker(yaml, parameters, train_config,
                                 optimizer, loss, metrics, custom)
            deltas = rdd.mapPartitions(worker.train).collect()
            new_parameters = self.master_network.get_weights()
            for delta in deltas:
                def base_constraint(a): return a
                constraints = [base_constraint for _ in self.weights]
                new_parameters = self.optimizer.get_updates(
                    self.weights, constraints, delta)
        else:
            raise ValueError("Unsupported mode {}".format(self.mode))
        self.master_network.set_weights(new_parameters)
        if self.mode in ['asynchronous', 'hogwild']:
            self.stop_server()

def load_spark_model(file_name):
    model = load_model(file_name)
    f = h5py.File(file_name, mode='r')

    elephas_conf = json.loads(f.attrs.get('distributed_config'))
    class_name = elephas_conf.get('class_name')
    config = elephas_conf.get('config')
    if class_name == "SparkModel":
        return SparkModel(model=model, **config)
    elif class_name == "SparkMLlibModel":
        return SparkMLlibModel(model=model, **config)

class SparkMLlibModel(SparkModel):

    def __init__(self, model, mode='asynchronous', frequency='epoch', parameter_server_mode='http',
                 num_workers=4, elephas_optimizer=None, custom_objects=None, batch_size=32, *args, **kwargs):
        """SparkMLlibModel

        The Spark MLlib model takes RDDs of LabeledPoints for training.

        :param model: Compiled Keras model
        :param mode: String, choose from `asynchronous`, `synchronous` and `hogwild`
        :param frequency: String, either `epoch` or `batch`
        :param parameter_server_mode: String, either `http` or `socket`
        :param num_workers: int, number of workers used for training (defaults to None)
        :param elephas_optimizer: Elephas optimizer
        :param custom_objects: Keras custom objects
        """
        SparkModel.__init__(self, model=model, mode=mode, frequency=frequency,
                            parameter_server_mode=parameter_server_mode, num_workers=num_workers,
                            elephas_optimizer=elephas_optimizer, custom_objects=custom_objects,
                            batch_size=batch_size, *args, **kwargs)

    def fit(self, labeled_points, epochs=10, batch_size=32, verbose=0, validation_split=0.1,
            categorical=False, nb_classes=None):
        """Train an elephas model on an RDD of LabeledPoints
        """
        rdd = lp_to_simple_rdd(labeled_points, categorical, nb_classes)
        rdd = rdd.repartition(self.num_workers)
        self._fit(rdd=rdd, epochs=epochs, batch_size=batch_size,
                  verbose=verbose, validation_split=validation_split)

    def predict(self, mllib_data):
        """Predict probabilities for an RDD of features
        """
        if isinstance(mllib_data, pyspark.mllib.linalg.Matrix):
            return to_matrix(self.master_network.predict(from_matrix(mllib_data)))
        elif isinstance(mllib_data, pyspark.mllib.linalg.Vector):
            return to_vector(self.master_network.predict(from_vector(mllib_data)))
        else:
            raise ValueError(
                'Provide either an MLLib matrix or vector, got {}'.format(mllib_data.__name__))


#!/usr/bin/env python

from distutils.core import setup

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

setup(name='panasonic-comfort-cloud-mqtt',
    version='0.5.0',
    description='Home-Assistant MQTT bridge for Panasonic Comfort Cloud ',
    long_description=long_description,
    long_description_content_type="text/markdown",
    author='Santtu Järvi',
    author_email='slvwolf@finfur.net',
    keywords='home automation panasonic climate mqtt hass',
    url='https://github.com/slvwolf/panasonic-comfort-cloud-mqtt',
    classifiers=[
       'Topic :: Home Automation',
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
    ],
    packages=['pcfmqtt'],
    license='MIT',
    install_requires=['pcomfortcloud>=0.0.22', 'paho-mqtt>=1.6.1'],
)


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

import tkinter as tk
from typing import List

from ParseError import ParseError
from geometry_syntax import GeometrySyntax
from oval_parameters import OvalParameters
from preview import Preview

class Application(tk.Frame):
    _syntax_error_tag = "syntax_error"

    def __init__(self, master, title: str):
        super().__init__(master)
        self._master = master

        self.grid(sticky="NEWS")
        self.columnconfigure(0, weight=1, uniform="app_column")
        self.columnconfigure(1, weight=1, uniform="app_column")
        self.rowconfigure(0, weight=1)

        self.winfo_toplevel().title(title)
        self._create_widgets()
        self._bind_event_handlers()

    def _create_widgets(self):
        editor_frame = tk.LabelFrame(self, text="Editor")
        editor_frame.grid(row=0, column=0, sticky="NEWS")
        editor_frame.columnconfigure(0, weight=1)
        editor_frame.rowconfigure(0, weight=1)

        preview_frame = tk.LabelFrame(self, text="Preview")
        preview_frame.grid(row=0, column=1, sticky="NEWS")
        preview_frame.columnconfigure(0, weight=1)
        preview_frame.rowconfigure(0, weight=1)

        self.__text_field = tk.Text(
            editor_frame,
            undo=True,
            wrap=tk.WORD,
            font="fixed",
        )
        self.__text_field.grid(sticky="NEWS")
        self.__text_field.tag_config(
            self._syntax_error_tag, background="red", foreground="white"
        )

        self.__preview = Preview(
            preview_frame, self._on_new_figure_created, self._on_figure_updated
        )

    def _bind_event_handlers(self):
        self.__text_field.bind("<Leave>", lambda _: self._on_update_text())
        self.__text_field.bind("<FocusOut>", lambda _: self._on_update_text())
        self.__text_field.bind("<Key-Return>", lambda _: self._on_update_text())

    def _on_update_text(self):
        self._remove_syntax_errors()
        text = self.__text_field.get("1.0", tk.END)
        figures, errs = GeometrySyntax.parse(text)
        failed_line_no = self.__preview.draw_figures(figures)
        errs += list(map(lambda l: ParseError(line=l), failed_line_no))
        self._display_errors(errs)

    def _display_errors(self, errors: List[ParseError]):
        self._remove_syntax_errors()
        for err in errors:
            self.__text_field.tag_add(
                self._syntax_error_tag,
                f"{err.line}.0",
                f"{err.line}.0 + 1l - 1c",
            )

    def _remove_syntax_errors(self):
        x = self.__text_field.tag_ranges(self._syntax_error_tag)
        for start, end in zip(x[::2], x[1::2]):
            self.__text_field.tag_remove(self._syntax_error_tag, start, end)

    def _on_new_figure_created(self, params: OvalParameters):
        new_text = GeometrySyntax.serialize([params])
        line_count = self._count_lines()
        if (
            len(self.__text_field.get(f"{line_count}.0", f"{line_count}.0 + 1l - 1c"))
            > 0
        ):
            new_text = "\n" + new_text
        self.__text_field.insert(tk.END, new_text)
        self._on_update_text()

    def _on_figure_updated(self, params: OvalParameters):
        new_text = GeometrySyntax.serialize([params])
        edited_line = params.id
        line_count = self._count_lines()
        if line_count >= edited_line:
            start = f"{edited_line}.0"
            end = f"{edited_line}.0 + 1l - 1c"
            self.__text_field.delete(start, end)
            self.__text_field.insert(start, new_text)
            self._on_update_text()

    def _count_lines(self) -> int:
        return int(self.__text_field.index(tk.END + "-1c").split(".")[0])

    def _on_exit(self):
        self._master.destroy()


#author: Samet Kalkan

import numpy as np
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dropout, Dense
from keras.utils import np_utils
from keras.callbacks import ModelCheckpoint
from keras import regularizers
from keras import backend as K
np.random.seed(0)

train_data = np.load("/home/baker/Desktop/BDD100K/bdd_digitalize/100/7.17/train_data_i.npy")
train_label = np.load("/home/baker/Desktop/BDD100K/bdd_digitalize/100/7.17/train_label_i.npy")

#train_data=train_data[:60000]
#train_label=train_label[:60000]

size = train_data.shape[1]

# normalization
train_data = train_data / 255.0

train_data = train_data.reshape(train_data.shape[0], size, size, 3)

# number of class
num_classes = 7

# for example if label is 4 converts it [0,0,0,0,1]
train_label = np_utils.to_categorical(train_label, num_classes)

val_data=train_data[60000:]
val_label=train_label[60000:]
train_data=train_data[:60000]
train_label=train_label[:60000]

def mycrossentropy(y_true, y_pred, e=0.1):
    return (1-e)*K.categorical_crossentropy(y_true,y_pred) + e*K.categorical_crossentropy(K.ones_like(y_pred)/num_classes, y_pred)

model = Sequential()

#convolutional layer with 5x5 32 filters and with relu activation function
#input_shape: shape of the each data
#kernel_size: size of the filter
#strides: default (1,1)
#activation: activation function such as "relu","sigmoid"

model.add(Conv2D(32, kernel_size=(2,2),input_shape=(size, size, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

for i in range(4):
    model.add(Conv2D(32, kernel_size=(2,2), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, kernel_size=(1,1), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())

# beginning of fully connected neural network.
model.add(Dense(100, activation='relu'))
model.add(Dropout(0.5))
# Add fully connected layer with a softmax activation function
model.add(Dense(num_classes, activation='softmax'))

# Compile neural network
model.compile(loss=mycrossentropy, # self_Cross-entropy
                optimizer='adam', # Root Mean Square Propagation
                metrics=['accuracy']) # Accuracy performance metric

checkpointer = ModelCheckpoint(filepath='modelsCNN/size100/7.17_i_1.h5', verbose=1, save_best_only=True)

# begin train the data
history = model.fit(train_data, # train data
            train_label, # label
            validation_data=[val_data,val_label],
            epochs=40, # Number of epochs
            verbose=1,
            batch_size=256,
            callbacks=[checkpointer]
            )

#model.save("modelsCNN/size100/7.17.h5",overwrite=True)


import tempfile
import subprocess
import os
import yaml
import codecs
import logging

class FileService(object):
    METAPATH_KEY = "_metapath"

    def __init__(self, logger=None):
        self.logger = logger or logging.getLogger(__name__)

    def edit_temp_file(self, initial_text):
        """Edits a temp file in a subprocess"""
        with tempfile.NamedTemporaryFile(suffix=".tmp") as tfile:
            tfile.write(initial_text)
            tfile.flush()
            self.logger.info("Starting text editor (vim) as a subprocess")
            subprocess.call(["vim", '+set backupcopy=yes', tfile.name])
            self.logger.info("Text editor closed")
            tfile.seek(0)
            ret_bytes = tfile.read().rstrip()
            ret = codecs.decode(ret_bytes, "UTF-8")
            return ret

    def read_line(self, path, line_no):
        current_line = 0
        with open(path, "r") as fs:
            for line in fs:
                current_line += 1
                if current_line == line_no:
                    return line.strip()
        return None

    def get_metapath(self, path):
        metafile_ext = ".yaml"
        directory, fname = os.path.split(path)
        fname_no_ext, ext = os.path.splitext(fname)
        if ext == metafile_ext:
            raise FileServiceException("Can't get a metafile for files using the {} extension"
                                       .format(metafile_ext))
        return os.path.join(directory, fname_no_ext + metafile_ext)

    def get_metafile(self, path):
        """Returns the metafile for this file, or a new one"""
        self.logger.debug("Fetching metafile at {}".format(path))
        metapath = self.get_metapath(path)
        try:
            with open(metapath) as fs:
                metafile = yaml.load(fs)
        except FileNotFoundError:
            metafile = {"path": path, "lines": dict()}

        # Add a path to the object, which should not be serialized
        metafile[self.METAPATH_KEY] = metapath
        return metafile

    def save_metafile(self, metafile):
        self.logger.debug("Saving metafile")
        metapath = metafile[self.METAPATH_KEY]
        with open(metapath, "w") as fs:
            # HACK:
            del metafile[self.METAPATH_KEY]
            yaml.dump(metafile, fs, default_flow_style=False)
            metafile[self.METAPATH_KEY] = metapath

class FileServiceException(Exception):
    """Generic exception involving the file service"""
    pass


# coding: utf-8
"""
该文件主要是对数据进行预处理，将评分数据按照8：2分为训练数据与测试数据
"""
import pandas as pd
import csv
import os

#将文件中的数据按照userId进行排序，如果userId相同则按照timestamp进行排序
origin_f = open('data/ratings.csv','rt',encoding='utf-8',errors="ignore")
new_f= open('data/ratings_sort.csv','wt',encoding='utf-8',errors="ignore",newline="")
reader=csv.reader(origin_f)
writer=csv.writer(new_f)
sortedlist=sorted(reader,key=lambda x:(x[0],x[3]),reverse=True)
print(sortedlist.__len__())
i=0
for row in sortedlist:
    if i==0:
        # 添加表头
        writer.writerow(('userId','movieId','rating','timestamp'))
    if(i==(sortedlist.__len__()-1)):
        continue
    writer.writerow(row)
    i=i+1
origin_f.close()
new_f.close()

#增加last_movie字段
csvfile1=open('data/ratings_sort.csv','rt')
reader=csv.DictReader(csvfile1)
rows=[row for row in reader]
# print(rows[0].get("userId"))
i=0
csvfile2=open('data/ratings_sort.csv','rt')
reader=csv.DictReader(csvfile2)
rating_addLastMovie=open('data/rating_addLastMovie.csv','wt',encoding='utf-8',errors="ignore",newline="")
writer=csv.writer(rating_addLastMovie)
for row in reader:
    # 添加用户看得上一部电影
    if i<(rows.__len__()-1) and rows[i].get("userId")==rows[i+1].get("userId"):
        row["last_movie"]=rows[i+1].get("movieId")
    else:
        row["last_movie"]=0
    # print(row.values())
    if i==0:
        writer.writerow(('userId', 'movieId', 'rating', 'timestamp','last_movie'))
    writer.writerow(row.values())
    i=i+1
csvfile1.close()
csvfile2.close()
rating_addLastMovie.close()

# 删除文件中的表头
origin_f = open('data/rating_addLastMovie.csv','rt',encoding='utf-8',errors="ignore")
new_f = open('data/ratingsNoHead.csv','wt+',encoding='utf-8',errors="ignore",newline="")
reader = csv.reader(origin_f)
writer = csv.writer(new_f)
i=0
for i,row in enumerate(reader):
    if i>1:
        writer.writerow(row)
origin_f.close()
new_f.close()

#将数据按照8:2的比例进行划分得到训练数据集与测试数据集
df = pd.read_csv('data/ratingsNoHead.csv', encoding='utf-8')
# df.drop_duplicates(keep='first', inplace=True)  # 去重，只保留第一次出现的样本
# print(df)
df = df.sample(frac=1.0)  # 全部打乱
cut_idx = int(round(0.2 * df.shape[0]))
df_test, df_train = df.iloc[:cut_idx], df.iloc[cut_idx:]
# 打印数据集中的数据记录数
print(df.shape,df_test.shape,df_train.shape)
# print(df_train)
# 将数据记录存储到csv文件中
# 存储训练数据集
df_train=pd.DataFrame(df_train)
df_train.to_csv('data/ratings_train_tmp.csv',index=False)
# 由于一些不知道为什么的原因，使用pandas读取得到的数据多了一行，在存储时也会将这一行存储起来，所以应该删除这一行（如果有时间在查一查看能不能解决这个问题）
origin_f = open('data/ratings_train_tmp.csv','rt',encoding='utf-8',errors="ignore")
new_f = open('data/ratings_train.csv','wt+',encoding='utf-8',errors="ignore",newline="")     #必须加上newline=""否则会多出空白行
reader = csv.reader(origin_f)
writer = csv.writer(new_f)
for i,row in enumerate(reader):
    if i>0:
        writer.writerow(row)
origin_f.close()
new_f.close()
os.remove('data/ratings_train_tmp.csv')
# 存储测试数据集
df_test=pd.DataFrame(df_test)
df_test.to_csv('data/ratings_test_tmp.csv',index=False)
origin_f = open('data/ratings_test_tmp.csv','rt',encoding='utf-8',errors="ignore")
new_f = open('data/ratings_test.csv','wt+',encoding='utf-8',errors="ignore",newline="")
reader = csv.reader(origin_f)
writer = csv.writer(new_f)
for i,row in enumerate(reader):
    if i>0:
        writer.writerow(row)
origin_f.close()
new_f.close()
os.remove('data/ratings_test_tmp.csv')


from collections import deque
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
graph = [[]*(n+1) for _ in range(n+1)]
visited = [False] * (n+1)

for _ in range(m):
    a, b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a)
cnt = 0

def bfs(v):
    queue = deque([v])
    visited[v] = True
    while queue:
        a = queue.popleft()
        for i in graph[a]:
            if not visited[i]:
                queue.append(i)
                visited[i] = True

for i in range(1, n+1):
    if visited[i] == False:
        bfs(i)
        cnt+=1
print(cnt)

# from collections import deque
# n, m = map(int, input().split())

# graph = [[] for _ in range(n+1)]
# visited = [False] * (n+1)

# for _ in range(m):
#     a, b = map(int, input().split())
#     graph[a].append(b)
#     graph[b].append(a)

# def bfs(start):
#     visited[start] = True
#     queue = deque()
#     queue.append(start)

#     while queue:
#         a = queue.popleft()
#         for i in graph[a]:
#             if not visited[i]:
#                 visited[i] = True
#                 queue.append(i)

# cnt = 0
# for i in range(1, n+1):
#     if not visited[i]:
#         bfs(i)
#         cnt += 1
# print(cnt)


# -*- coding: utf-8 -*-
"""
This model takes the winemag data & filters on the north_america and europe continents.
After cleaning and prepping the date,
we run two bayesian hierarchical models (one for each continent) on the data using variational inference & pymc3
"""
import pandas as pd
import numpy as np
import pymc3 as pm
import seaborn as sns
from sklearn.model_selection import train_test_split
import theano
from sklearn.metrics import classification_report

# Use Feature Engineering file to clean data beforehand
from FE import FE

wine = pd.read_csv('winemag-data-130k-v2.csv')
wine_clean = FE(wine)

# For reproducibility
SEED = 20200514

# %% Data cleaning/prep

# Clone initial data sets for cleaning
NA = wine_clean.copy().query('continent == "north_america"')
EU = wine_clean.copy().query('continent == "europe"')

# Convert province to codes to be used in hierarchical priors
province_dict = wine_clean.set_index('province').to_dict()['continent']

NA_dict = np.asarray([i for i,j in province_dict.items() if j == "north_america"])
NA_lookup = dict(zip(NA_dict, range(len(NA_dict))))
NA['province'] = NA.province.replace(NA_lookup).values

EU_dict = np.asarray([i for i,j in province_dict.items() if j == "europe"])
EU_lookup = dict(zip(EU_dict, range(len(EU_dict))))
EU['province'] = EU.province.replace(EU_lookup).values

# Set Other & Nan Values to 0
NA_province = NA['province'] = NA['province'].replace(to_replace={np.nan :0}).astype(int).values
EU_province = NA['province'] = NA['province'].replace(to_replace={np.nan :0}).astype(int).values

NA_unique = NA['province'].unique()
EU_unique = EU['province'].unique()

cont_vars = ['price']
cat_vars = ['year','color']
hierarchical = 'province'
pred = 'points'

NA_data = NA.copy()
EU_data = EU.copy()

# List of variables to be used in regression
colList = cont_vars + cat_vars + [hierarchical] + [pred]

# Drop where we don't have region data
regression_NA = NA_data.query('country.notnull() & price.notnull()' , engine='python')[colList]
regression_EU = EU_data.query('country.notnull() & price.notnull()' , engine='python')[colList]

# Break out categorical & one-hot encode
NA_regression_categorical = pd.get_dummies(regression_NA[cat_vars])
EU_regression_categorical = pd.get_dummies(regression_EU[cat_vars])

# Scale Price Logarithmically & scale
NA_X_mean = np.log(regression_NA[cont_vars]).mean()
NA_X_std = np.log(regression_NA[cont_vars]).std()
NA_regression_continuous = ((np.log(regression_NA[cont_vars]) - NA_X_mean)/NA_X_std)

EU_X_mean = np.log(regression_EU[cont_vars]).mean()
EU_X_std = np.log(regression_EU[cont_vars]).std()
EU_regression_continuous = ((np.log(regression_EU[cont_vars]) - EU_X_mean)/EU_X_std)

NA_X = pd.concat([NA_regression_categorical, NA_regression_continuous, regression_NA[hierarchical]], axis=1)
EU_X = pd.concat([EU_regression_categorical, EU_regression_continuous, regression_EU[hierarchical]], axis=1)

# Scale Y
NA_Y_mean = regression_NA[pred].mean()
NA_Y_std = regression_NA[pred].std()
NA_Y = (regression_NA[pred] - NA_Y_mean)/NA_Y_std

# Scale Y
EU_Y_mean = regression_EU[pred].mean()
EU_Y_std = regression_EU[pred].std()
EU_Y = (regression_EU[pred] - EU_Y_mean)/EU_Y_std

# Split out a train/test set
NA_X_train, NA_X_test, NA_y_train, NA_y_test = train_test_split(NA_X, NA_Y, random_state=SEED, test_size = 0.20)
EU_X_train, EU_X_test, EU_y_train, EU_y_test = train_test_split(EU_X, EU_Y, random_state=SEED, test_size = 0.20)

NA_train_cat = NA_X_train.drop(cont_vars + [hierarchical], axis=1)
EU_train_cat = EU_X_train.drop(cont_vars + [hierarchical], axis=1)

# Set up shape of continents priors
NA_len = len(NA_unique)+1
EU_len = len(EU_unique)+1

# Set up tensors for train/test data
NA_y_tensor = theano.shared(NA_y_train.values.astype('float64'))
NA_x_cont_tensor = theano.shared(NA_X_train[cont_vars].values.astype('float64'))
NA_x_cat_tensor = theano.shared(NA_X_train.drop(cont_vars + [hierarchical], axis=1).values.astype('float64'))
NA_x_province_tensor = theano.shared(NA_X_train['province'].values.astype('int64'))

EU_y_tensor = theano.shared(EU_y_train.values.astype('float64'))
EU_x_cont_tensor = theano.shared(EU_X_train[cont_vars].values.astype('float64'))
EU_x_cat_tensor = theano.shared(EU_X_train.drop(cont_vars + [hierarchical], axis=1).values.astype('float64'))
EU_x_province_tensor = theano.shared(EU_X_train['province'].values.astype('int64'))

# %% Bayesian Linear Regression models
with pm.Model() as NA_model:
    # Hyperpriors
    mu_a = pm.Normal('mu_a',mu=0,sd=1e5)
    sigma_a = pm.HalfCauchy('sigma_a',5)

    # Hierarcical intercept
    a = pm.Normal('a', mu=mu_a, sd=sigma_a, shape=NA_len)

    # Regular intercept
    zbetaj_cont = pm.Normal('zbetaj_cont', mu=0, sd=2)
    zbetaj_cat = pm.Beta('zbetaj_cat', alpha = 1, beta = 1, shape=NA_train_cat.shape[1])

    zmu =  a[NA_x_province_tensor] + pm.math.dot(zbetaj_cont, NA_x_cont_tensor.T) + pm.math.dot(zbetaj_cat, NA_x_cat_tensor.T)

    sigma = pm.HalfCauchy('sigma', beta=10, testval=1.)

    likelihood = pm.Normal('likelihood', mu=zmu, sigma=sigma, observed=NA_y_tensor)

with pm.Model() as EU_model:
    # Hyperpriors
    mu_a = pm.Normal('mu_a',mu=0,sd=1e5)
    sigma_a = pm.HalfCauchy('sigma_a',5)

    # Hierarcical intercept
    a = pm.Normal('a', mu=mu_a, sd=sigma_a, shape=EU_len)

    # Regular intercept
    zbetaj_cont = pm.Normal('zbetaj_cont', mu=0, sd=2)
    zbetaj_cat = pm.Beta('zbetaj_cat', alpha = 1, beta = 1, shape=EU_train_cat.shape[1])

    zmu =  a[EU_x_province_tensor] + pm.math.dot(zbetaj_cont, EU_x_cont_tensor.T) + pm.math.dot(zbetaj_cat, EU_x_cat_tensor.T)

    sigma = pm.HalfCauchy('sigma', beta=10, testval=1.)

    likelihood = pm.Normal('likelihood', mu=zmu, sigma=sigma, observed=EU_y_tensor)

with NA_model:
     NA_advi_fit = pm.fit(n=15000, method = pm.ADVI())

with EU_model:
     EU_advi_fit = pm.fit(n=15000, method = pm.ADVI())
# %% Plot Elbo Results

# plot the ELBO over time

NA_advi_elbo = pd.DataFrame(
    {'ELBO': -NA_advi_fit.hist,
     'n': np.arange(NA_advi_fit.hist.shape[0])})

_ = sns.lineplot(y='ELBO', x='n', data=NA_advi_elbo)

EU_advi_elbo = pd.DataFrame(
    {'ELBO': -EU_advi_fit.hist,
     'n': np.arange(EU_advi_fit.hist.shape[0])})

_ = sns.lineplot(y='ELBO', x='n', data=EU_advi_elbo)

# %% Run data on test split

# Sample to look at regression fit
NA_advi_trace = NA_advi_fit.sample(10000)
EU_advi_trace = EU_advi_fit.sample(10000)

# Switch tensor to test data
NA_y_tensor.set_value(NA_y_test)
NA_x_cont_tensor.set_value(NA_X_test[cont_vars].values)
NA_x_cat_tensor.set_value(NA_X_test.drop(cont_vars + [hierarchical], axis=1).values)
NA_x_province_tensor.set_value(NA_X_test['province'].values)

EU_y_tensor.set_value(EU_y_test)
EU_x_cont_tensor.set_value(EU_X_test[cont_vars].values)
EU_x_cat_tensor.set_value(EU_X_test.drop(cont_vars + [hierarchical], axis=1).values)
EU_x_province_tensor.set_value(EU_X_test['province'].values)

# Generate predictions for test set
NA_advi_posterior_pred = pm.sample_posterior_predictive(NA_advi_trace, 1000, NA_model)
NA_advi_predictions = np.mean(NA_advi_posterior_pred['likelihood'], axis=0)

EU_advi_posterior_pred = pm.sample_posterior_predictive(EU_advi_trace, 1000, EU_model)
EU_advi_predictions = np.mean(EU_advi_posterior_pred['likelihood'], axis=0)

# %% Convert back to original scale & plot results
NA_advi_predictions_orig = NA_advi_predictions*NA_Y_std + NA_Y_mean
NA_y_test_orig = NA_y_test*NA_Y_std + NA_Y_mean

EU_advi_predictions_orig = EU_advi_predictions*EU_Y_std + EU_Y_mean
EU_y_test_orig = EU_y_test*EU_Y_std + EU_Y_mean

NA_prediction_data = pd.DataFrame(
    {'ADVI': NA_advi_predictions_orig[0],
     'actual': NA_y_test_orig,
     'error_ADVI': NA_advi_predictions_orig[0] - NA_y_test_orig})

EU_prediction_data = pd.DataFrame(
    {'ADVI': EU_advi_predictions_orig[0],
     'actual': EU_y_test_orig,
     'error_ADVI': EU_advi_predictions_orig[0] - EU_y_test_orig})

final_prediction_data = pd.concat([NA_prediction_data, EU_prediction_data], axis=0)

# Calculate RMSE
RMSE = np.sqrt(np.mean(final_prediction_data.error_ADVI ** 2))
print(f'RMSE for ADVI predictions = {RMSE:.3f}')

_ = sns.lmplot(y='ADVI', x='actual', data=final_prediction_data,
               line_kws={'color': 'red', 'alpha': 0.5})

class_grid = final_prediction_data.copy()
class_grid['cat_actual'] = np.where(class_grid['actual'] < 86, "BottomTier",
                                      np.where(class_grid['actual'] < 93, "MiddleTier","TopTier"))
class_grid['cat_predicted'] = np.where(class_grid['ADVI'] < 86, "BottomTier",
                                      np.where(class_grid['ADVI'] < 93, "MiddleTier","TopTier"))

print(classification_report(class_grid['cat_actual'],class_grid['cat_predicted'],target_names=['TopTier','MiddleTier','BottomTier']))

pm.model_to_graphviz(NA_model)

# %%


from matplotlib import pyplot as plt
from PIL import Image

img = Image.open("original.jpg")

img2 = Image.open("broken1.png").convert(img.mode)

img2 = img2.resize(img.size)

img3 = Image.blend(img,img2,0.35)

plt.figure(num='BROKEN LENS Failure')
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img3),plt.title('Broken Lens')
plt.xticks([]), plt.yticks([])
plt.show()


# coding=utf-8
__author__ = '01053185'
"""
该代码实现功能：
1.测试集 与 学习集合的划分
2.测试集的输入文件构造
3.构造学习集的输入文件
"""
import os
import random

class StepOne():
    def __init__(self):
        self.data_dir_in = 'E:\\gitshell\\tianchi2'  # 输入文件夹
        self.data_dir_out = 'E:\\gitshell\\tianchi3'  # 输出文件夹

    # 搭配关系重新表示
    def my_ShangPinGuanLian(self):
        # 两个ID， id1 原文件中表示所在行编号  id2 表示以;分割所在的顺序号
        # 所以 id1相同 id2不同 表示配对商品
        path = os.path.join(self.data_dir_in, "dim_fashion_matchsets.txt")
        opath = os.path.join(self.data_dir_out, "dim_fashion_matchsets2.txt")
        read_stream = open(path, 'r')
        write_stream = open(opath, 'w')
        for line in read_stream:
            aaa = line.rstrip().split(' ')
            key = int(aaa[0])
            item_list = aaa[1].rstrip().split(';')
            for i in xrange(0, len(item_list)):
                temp_str = str(key) + '\t' + str(i) + '\t'
                item_list2 = item_list[i].split(',')
                for temp_item in item_list2:
                    write_stream.writelines(temp_str + temp_item + '\n')
        read_stream.close()
        write_stream.close()

    def data_partition(self, file1="dim_fashion_matchsets2.txt"):
        # 以0.03的概率随机抽取测试样本
        read_stream = open(os.path.join(self.data_dir_out, file1), 'r')
        learn_set_stream = open(os.path.join(self.data_dir_out, 'learn_set.txt'), 'w')
        test_set_stream = open(os.path.join(self.data_dir_out, 'test_set.txt'), 'w')
        random.seed("I LOVE U")
        for line in read_stream:
            if random.random() < 0.03:
                test_set_stream.write(line)
            else:
                learn_set_stream.write(line)
        test_set_stream.close()
        learn_set_stream.close()

    # 词组搭配的学习文本构建
    def data_partition2(self, file1="wordstr_wordstr0.txt"):
        read_stream = open(os.path.join(self.data_dir_in, file1), 'r')  # 需要分割的文件
        test_set_stream = open(os.path.join(self.data_dir_out, 'test_set.txt'), 'r')  # 需要过滤掉的测试集合文件
        learn_set_stream = open(os.path.join(self.data_dir_out, 'learn_wordstr_wordstr0.txt'), 'w')  # 目标结果文件
        test_dic = {}
        for line in test_set_stream:
            my_line = line.rstrip().split('\t')
            test_dic[int(my_line[-1])] = 1  # 最后一个为商品id
        test_set_stream.close()
        for line in read_stream:
            my_line = line.rstrip('\r').rstrip('\n').split('\t')
            if test_dic.get(int(my_line[0]), 0)+test_dic.get(int(my_line[1]), 0) == 0:  # 都不在测试集中
                learn_set_stream.write(my_line[4]+'\t'+my_line[5]+'\t1\n')
        read_stream.close()
        learn_set_stream.close()

    #  构造需要测试集的商品对应用户输入文件
    def file_to_test(self):
        test_set_stream = open(os.path.join(self.data_dir_out, 'test_set.txt'), 'r')  # 需要过滤掉的测试集合文件
        test_dic ={}
        for line in test_set_stream:
            my_line = line.rstrip().split('\t')
            test_dic[int(my_line[-1])] = 1  # 最后一个为商品id
        test_set_stream.close()
        # 过滤用户购买历史
        bought_history = open(os.path.join(self.data_dir_in, "user_bought_history1.txt"),'r')
        item_user = []
        for line in bought_history:
            my_line = line.strip().split(',')
            if 0 != test_dic.get(int(my_line[1]), 0):
                item_user.append((my_line[1], my_line[0]))
        bought_history.close()
        item_user = sorted(item_user, key=lambda x:x[0])
        test_file = open(os.path.join(self.data_dir_out, "test_file.txt"), 'w')
        for x in item_user:
            test_file.write(x[0]+'\t'+x[1]+'\n')
        test_file.close()

if __name__ == "__main__":
    a = StepOne()
    a.my_ShangPinGuanLian()
    a.data_partition()
    a.data_partition2()
    a.file_to_test()


#!/usr/bin/env python3
"""
cron: 0 40 22 * * *
new Env('明日天气');
"""
import sys
import requests
import json
import time
from bs4 import BeautifulSoup
import os, re

# 获取WxPusher appToken  WxPusher_appToken
if "WxPusher_appToken" in os.environ:
    if len(os.environ["WxPusher_appToken"]) > 1:
        WxPusher_appToken = os.environ["WxPusher_appToken"]
else:
    print('未配置环境变量 WxPusher_appToken')
    sys.exit()

# 获取WxPusher uid  WxPusher_uids ','分隔
if "WxPusher_uids" in os.environ:
    if len(os.environ["WxPusher_uids"]) > 1:
        WxPusher_uids = os.environ["WxPusher_uids"].split(',')
else:
    print('未配置环境变量 WxPusher_uids')
    sys.exit()

def get_weather_data(city_id):
    """
    获取当前到次日凌晨的每小时气温和未来5天的每天最低气温
    """
    head = {
        "referer": "http://m.weather.com.cn/",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44 "
    }
    timestamp = str(int(time.time())) + '761'
    url = r'https://d1.weather.com.cn/wap_40d/{}.html?_={}'.format(city_id, timestamp)
    print('正在请求天气信息...')
    r = requests.get(url, headers=head)
    if r.status_code != 200:
        print('status code:', r.status_code)
        return False

    r.encoding = r.apparent_encoding
    html = r.text.split(';')  # html[0]为40天预报  html[2]为48小时预报

    weather40 = html[0][html[0].find('['):]
    tomorrow = {}
    i = 0
    for day in json.loads(weather40):
        if int(day['009']) < int(time.strftime('%Y%m%d')):
            continue  # 009是日期，如果日期小于今天则舍去
        if int(day['009']) == int(time.strftime('%Y%m%d')):
            i = i + 1
            continue
        if i == 1:
            tomorrow = day
            i = i + 1
        else:
            break
    return tomorrow

def analyse_weather(tomorrow):
    """
    分析气温变化，判断要不要发送消息提醒，如果不需要提醒，返回空字符串
    :param tomorrow: 明天天气信息
    :return: 返回发送消息提醒的文本内容
    """

    message = ''

    moji_url = 'https://tianqi.moji.com/weather/china/henan/anyang'

    headers = {
        'Host': 'tianqi.moji.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
    }

    r = requests.get(moji_url, headers=headers)
    r.encoding = "utf-8"
    soup = BeautifulSoup(r.text, 'lxml')
    today_temp = soup.select('body > div:nth-child(5) > div.left > div.forecast.clearfix > ul:nth-child(2) > '
                             'li:nth-child(3)')[0].text.replace(" ", "").replace("°", "")
    today_min_temp, today_max_temp = today_temp.split('/')
    tomorrow_temp = soup.select('body > div:nth-child(5) > div.left > div.forecast.clearfix > ul:nth-child(3) > '
                                'li:nth-child(3)')[0].text.replace(" ", "")
    tomorrow_min_temp, tomorrow_max_temp = tomorrow_temp.replace("°", "").split('/')
    tomorrow_weather = soup.select('body > div:nth-child(5) > div.left > div.forecast.clearfix > ul:nth-child(3) > '
                                   'li:nth-child(2)')[0].text.strip()

    # 明日天气
    today_avg_temp = (int(today_min_temp) + int(today_max_temp)) / 2
    tomorrow_avg_temp = (int(tomorrow_min_temp) + int(tomorrow_max_temp)) / 2
    diff = today_avg_temp - tomorrow_avg_temp
    print(diff)
    if diff > 5:
        message += '明日降温,平均温度下降{}℃\n'.format(diff)
    elif diff < -5:
        message += '明日升温,平均温度上升{}℃\n'.format(diff)
    year, month, days = time.strftime('%Y-%m-%d', time.strptime(tomorrow['009'], '%Y%m%d')).split('-')
    message += '明 日: {}年{}月{}日 {}\n'.format(year, month, days, tomorrow['016'])
    message += '天 气: {}\n'.format(tomorrow_weather)
    message += '温 度: {}\n'.format(tomorrow_temp)
    message += '农 历: {}\n'.format(tomorrow['010'])
    if tomorrow['017'] != '':
        message += '节 日: {}\n'.format(tomorrow['017'])
    if tomorrow['018'] != '':
        message += '节 气: {}\n'.format(tomorrow['018'])
    return message

def send_reminder(message):

    url = 'http://wxpusher.zjiecode.com/api/send/message'

    headers = {
        'Content-Type': 'application/json'
    }

    data = {
        'appToken': WxPusher_appToken,
        'content': message,
        # 'summary': '消息摘要', # 消息摘要，显示在微信聊天页面或者模版消息卡片上，限制长度100，可以不传，不传默认截取content前面的内容。
        'contentType': 1,  # 内容类型 1表示文字 2表示html(只发送body标签内部的数据即可，不包括body标签) 3表示markdown
        # 'topicIds': [], # 发送目标的topicId，是一个数组！！！，也就是群发，使用uids单发的时候， 可以不传。
        # 'uids': ['', '']  # 发送目标的UID，是一个数组。注意uids和topicIds可以同时填写，也可以只填写一个。
        'uids':WxPusher_uids
        # 'url': "" # 原文链接，可选参数
    }

    if not message:
        print('气温变化适宜，不用发送消息提醒')
        return
    r = requests.post(headers=headers, url=url, data=json.dumps(data))
    if r.status_code == 200:
        print('发送提醒成功,message:')
        print(message)
    else:
        print('发送提醒失败，status_code:', r.status_code)

if __name__ == '__main__':
    cityID = '101180201'  # 安阳
    assert cityID

    time5 = time24 = time5_2 = time24_2 = 0
    print('现在是{}'.format(time.strftime('%Y-%m-%d %H:%M')))
    tomorrow = get_weather_data(cityID)
    assert tomorrow
    message = analyse_weather(tomorrow)
    assert message
    send_reminder(message)


"""
Get Options Action for App ID
"""
from urllib.parse import urlencode

from api.api_samples.python_client.ext import requests
from common.methods import set_progress
from itsm.servicenow.models import ServiceNowITSM
import json

def get_options_list(field, **kwargs):
    options = [('', '--- Select an App ID ---')]
    snowitsm = ServiceNowITSM.objects.first()
    wrapper = snowitsm.get_api_wrapper()
    base_url = wrapper.service_now_instance_url.replace("/login.do", "")
    req_for_data = lookup_ci(table_name='cmdb_ci_appl',
                             base_url=base_url,
                             conn=snowitsm,
                             sysparm_fields=[
                                 'name',
                                 'u_application_id',
                                 'u_systemid',
                                 'install_status',
                                 'owned_by',
                                 'support_group',
                                 'u_priority',
                                 'version',
                                 'operational_status',
                                 'sys_created_on',
                             ]
                             )
    response_json = json.loads(req_for_data)
    results = response_json["result"]
    for result in results:
        if result["support_group"]:
            support_group = result["support_group"]["display_value"]
            result["support_group"] = support_group
        if result["owned_by"]:
            support_group = result["owned_by"]["display_value"]
            result["owned_by"] = support_group
        options.append((json.dumps(result), result["name"]))
    return options

def lookup_ci(table_name=None, base_url=None, conn=None,
              sysparm_fields: list = None, url=None):
    if not url:
        query = ''
        if sysparm_fields:
            query = urlencode({'sysparm_display_value': 'true',
                               'sysparm_fields': ",".join(sysparm_fields)})

        url = base_url + f"/api/now/table/{table_name}?{query}"

    response = requests.get(
        url=url,
        auth=(conn.service_account, conn.password),
        headers={
            "Content-Type": "application/json",
            "Accept": "application/json"
        },
        timeout=5.0
    )

    return response.content


# Copyright (C) 2020 Claudio Marques - All Rights Reserved
from enum import Enum

class Lists(Enum):
    VOWEL = 'aeiou'
    CONSOANT = "bcdfghjklmnpqrstvwxyz"
    NUMERIC = "0123456789"
    SPECIALCHAR = "!\"#|\\$%&/()=?«»´`*+ºª^~;,-_@£€{[]}'"

class DatesEnum(Enum):
    SemDados = 0
    UmMes = 1
    SeisMeses = 2
    UmAno = 3
    MaisDeUmAno = 4

class HttpResponseEnum(Enum):
    SemDados = 0
    Codigos100 = 1
    Codigos200 = 2
    Codigos300 = 3
    Codigos400 = 4
    Codigos500 = 5


from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse
from wmh_server.models import LocationData as lc
from django.views.decorators.csrf import csrf_exempt
import json
import datetime as dt
from django.conf import settings

def index(request):
    res = "Base Path:{}. This is a site of 'WalkMeHome' Project. The site is under construction!".format(settings.BASE_DIR)
    return HttpResponse(res)

@csrf_exempt
def send_loc(request):
    try:
        if (request.method == 'POST') \
                and ('email' in request.POST) \
                and ('loc_date' in request.POST) \
                and ('LAT' in request.POST) \
                and ('LON' in request.POST):
            loc_date_str = request.POST['loc_date']
            loc_date = dt.datetime.strptime(loc_date_str,"%d.%m.%Y %H:%M:%S")
            loc = lc(email=request.POST['email'], loc_date=loc_date, LON=float(request.POST['LON']), LAT=float(request.POST['LAT']))
            loc.save()
            res = "0"
        else:
            res = "Ошибка"
    except NameError:
        res = "Ошибка"

    return HttpResponse(res)

@csrf_exempt
def send_track(request):
    try:
        if (request.method == 'POST'):
            json_data = request.read()
            # json_data contains the data uploaded in request
            data = json.loads(json_data)
            for rec in data:
                loc_date_str = rec['loc_date']
                loc_date = dt.datetime.strptime(loc_date_str,"%d.%m.%Y %H:%M:%S")
                loc = lc(email=rec['email'], loc_date=loc_date, LON=float(rec['LON']), LAT=float(rec['LAT']))
                loc.save()
            res = "0"
        else:
            res = "Ошибка"
    except NameError:
        res = "Ошибка"

    return HttpResponse(res)

@csrf_exempt
def get_last_location(request):
    if (request.method == 'GET') and ('email' in request.GET):
        locations = lc.objects.filter(email=request.GET['email'])
        if locations.count()>0:
            sortlocations = locations.order_by("-loc_date")
            last_record = sortlocations[0]
            loc_date_str = last_record.loc_date.strftime("%d.%m.%Y %H:%M:%S")
            last_location = dict(email=last_record.email, loc_date=loc_date_str,
                                 LAT=last_record.LAT,
                                 LON=last_record.LON)

            res = json.dumps(last_location)
        else:
            res = 'Нет данных'
    else:
        res = 'Ошибка'
    return HttpResponse(res)


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import pywt
from sklearn.cluster import KMeans
from sklearn.cluster import AgglomerativeClustering
import random
from scipy.spatial import distance
import math
from typing import Union

DataSources = Union[str,pd.Series,np.ndarray]

class TemplateError():
    pass

class DWTTemplate():

    def __init__(self, template: np.ndarray, idxs = (0,0), start_level = 4):
        self.__level = start_level
        self.template = template
        self.template_norm = template/np.sum(template)
        self.idxs = idxs
        self.strart_level = start_level
        coeffs = pywt.wavedec(self.template_norm, 'haar', level = start_level)
        self.ca, self.cd = coeffs[0],coeffs[1:]

    def down(self)->None:
        """
        Reduces the wavelet transform level of the Series Piece.
        """
        self.__level -= 1
        if self.__level == 0:
            raise TemplateError("The wavelet transform is too low. The level cannot be lower than 1.")
        coeffs = pywt.wavedec(self.template_norm, 'haar', level = self.__level)
        self.ca, self.cd = coeffs[0],coeffs[1:]

class DWTTemplates():

    def __init__(self, series:DataSources, start_level = 4, pattern_len = 120,
                 t_count = 10000, temp_type = 'shuffle', acceleration = True):
        self.series = self.__init_series(series)

        self.current_level = start_level
        self.all_patters = False
        self.__ixs = None
        self._templates =  None
        self._acceleration = acceleration
#         self._templates = self.__init_templates(temp_type, start_level, pattern_len, t_count)

    def set_options(self, start_level = 4, pattern_len = 120, t_count = 10000, temp_type = 'shuffle'):
        self._templates = self.__init_templates(temp_type, start_level, pattern_len, t_count)

    def __init_series(self,series:DataSources)->np.ndarray:
        if isinstance(series, str):
            return pd.read_csv(series)
        if isinstance(series,  pd.Series):
            return series.values
        if isinstance(series,  np.ndarray):
            return series
        return None

    def __init_templates(self, temp_type:str, start_level:int, pattern_len:int, t_count = None)->np.ndarray:
        """
        Split time series to Series Pieces.
        """
        piece_len = pattern_len
        slices = []
        ixs = []
        ixs = np.asarray(list(range(0,len(self.series)- piece_len)))
        if temp_type == 'shuffle':
            np.random.shuffle(ixs)
            self.__ixs = ixs[:t_count]
        elif temp_type == 'half_step':
            step = pattern_len//2
            self.__ixs = ixs[::step]
        elif temp_type == 'third_step':
            step = pattern_len//3
            self.__ixs = ixs[::step]
        for i in range(0, len(self.series)- pattern_len):
            part = self.series[i:i+pattern_len]
            part = DWTTemplate(part, start_level = start_level, idxs = (i, i+pattern_len))
            slices.append(part)
        slices = np.asarray(slices)
        return slices

    @property
    def cur_templates(self):
        """
        List all pieces of temporary data in a -Template- format.
        """
        return self._templates[self.__ixs]

    @property
    def templates(self):
        """
        List of all aggregated pieces of temporary format np.ndarray data.
        """
        itemplates = []
        if self.all_patters == False:
            T = self._templates[self.__ixs]
        else:
            T = self._templates
        for t in T:
            itemplates.append(t.ca)
        return  np.asarray(itemplates)

    @property
    def original_templates(self):
        """
        List of all original pieces of temporary format np.ndarray data.
        """
        itemplates = []
        if self.all_patters == False:
            T = self._templates[self.__ixs]
        else:
            T = self._templates
        for t in T:
            itemplates.append(t.template_norm)
        return  np.asarray(itemplates)

    def down(self):
        if self._acceleration == True:
            for i in self.__ixs:
                    self._templates[i].down()
        else:
            for i,t in enumerate(self._templates):
                    self._templates[i].down()
        return

if __name__ == "__main__":
    data = pd.read_csv("data.csv", skiprows = 5, header = None, sep="\s+")
    train_data = data[4]
    templates = DWTTemplates(train_data, pattern_len = 96, start_level = 4)
    t = templates.templates
    to = templates.original_templates

#    n_clusters = 30
#    kmeans = KMeans(n_clusters=120)
#    y_kmeans = kmeans.fit_predict(t)
#
#    mask = np.where(y_kmeans == 5)[0][:-1]
#    t1 = t[mask]
#    to1 = to[mask]
#    sqeres_plot(t1, size = (4,4))
#    sqeres_plot(to1, size = (4,4))


# Sytulacja rzutu dwoma kośćmi.

from die import Die
from plotly.graph_objs import Bar, Layout
from plotly import offline

die_1 = Die()
die_2 = Die(10)

results = [die_1.roll()+die_2.roll() for roll_num in range(50_000)]

max_result = die_1.num_sides + die_2.num_sides
frequencies = [results.count(value) for value in range(2, max_result+1)]

x_values = list(range(2, max_result+1))
data = [Bar(x=x_values, y=frequencies)]

x_axis_config = {'title': 'Wynik', 'dtick': 1} # dtick : 1 -> nakazanie dodawania podpisu do każdego słupka
y_axis_config = {'title': 'Częstotliwośc występowania wartości'}
my_layout = Layout(title='Wynik rzucania kośćmi D6 i D10 pięćdziesiąt tysięcy razy',
                   xaxis=x_axis_config, yaxis=y_axis_config)
offline.plot({'data':data, 'layout': my_layout}, filename='d6_d10.html')


# -*- coding: utf-8 -*-
"""
Course: CS 4365/5354 [Computer Vision]
Author: Jose Perez [ID: 80473954]
Assignment: Lab 1
Instructor: Olac Fuentes
Last Modification: September 2, 2016 by Jose Perez
"""
from timeit import default_timer as timer
from PIL import Image
from numpy import *

# Page 42-43, exercise 5
# Gradient direction and magnitude
# Detect lines in an image
# Estimate extent of the lines and parameters
# Plot lines overlaid on the image
def problem1_exercise5(filename, threshold=50):
    im = array(Image.open(filename).convert('L'))
    background = Image.open(filename).convert('RGBA')

    # Begin calculation
    start_time = timer()

    # Sobel
    imx_sobel = zeros(im.shape)
    filters.prewitt(im, 1, imx_sobel)

    imy_sobel = zeros(im.shape)
    filters.prewitt(im, 0, imy_sobel)

    magnitude = sqrt(imx_sobel**2 + imy_sobel**2)

    # Filter (AKA set a threshold)
    low_values = magnitude < threshold
    high_values = magnitude >= threshold
    magnitude[low_values] = 255 # White for values below threshold
    magnitude[high_values] = 0 # Black for values above threshold

    magnitude_color = Image.fromarray(magnitude).convert('RGBA')
    magnitude_color_arr = array(magnitude_color)
    red, green, blue, alpha = magnitude_color_arr.T

    black_areas = (red == 0) & (blue == 0) & (green == 0)
    white_areas = (red == 255) & (blue == 255) & (green == 255)
    magnitude_color_arr[:,:,:][black_areas.T] = (255, 0, 0, 255) # Convert black to red for outline
    magnitude_color_arr[:,:,:][white_areas.T] = (0, 0, 255, 0) # Make white transparent

    # Overlay over the original image in color
    overlay = Image.fromarray(magnitude_color_arr)
    background.paste(overlay, None, overlay)

    # End calculation
    end_time = timer()
    print('[Problem 1 - Exercise 5] Duration: ' + str(end_time - start_time))

    imshow(background)


import time
import csv

import osm_bot_abstraction_layer.osm_bot_abstraction_layer as osm_bot_abstraction_layer
import osmapi

def is_imprecise_ukrainian_name(name_uk, name):
    if name_uk in ["шкільний комплекс", "професійна школа"]:
        return True
    if name_uk == "Загальноосвітній ліцей" and name.lower() != "liceum ogólnokształcące":
        return True
    if name_uk == "Початкова школа" and name.lower() != "szkoła podstawowa":
        return True
    return False

def main(make_edits):
    report_of_problems = ""
    for file in ["szkoły.csv", 'wioski_przygraniczne.csv', 'urzędy_wojewódzkie.csv', 'miasta.csv']: #'lotniska.csv']: #'krew.csv', 'szpitale.csv', 'pks.csv', 'community_centre.csv', 'miasta.csv']: # 'social_facility_second.csv' 'stacje_kolejowe.csv
        report_of_problems += "\n------\n" + file + "\n"
        changeset = None
        show_overpass_query(file)

        names_uk = []
        names_ru = []
        with open(file, newline='') as csvfile:
            spamreader = csv.reader(csvfile, delimiter=',', quotechar='"')
            row_index = 0
            for row in spamreader:
                if row_index == 0:
                    matcher = build_id_to_index_number(row)
                else:
                    name_uk = None
                    name_ru = None
                    name = row[matcher.get("name")]
                    if matcher.get("name:uk") != None:
                        name_uk = row[matcher.get("name:uk")].replace(" (місто)", "") # drop "(city) explanation"
                    if matcher.get("name:ru") != None:
                        name_ru = row[matcher.get("name:ru")].replace(" (Польша)", "") # drop "(city) explanation"
                    if name_ru in names_ru and name_ru != None:
                        print("REPEATING", name_ru)
                    if name_uk in names_uk and name_uk != None:
                        if is_imprecise_ukrainian_name(name_uk, name) == False:
                            print("REPEATING", name_uk, "FOR", name)
                    if name_ru != None:
                        names_ru.append(name_ru)
                    if name_uk != None:
                        names_uk.append(name_uk)
                row_index += 1
        with open(file, newline='') as csvfile:
            print("aaa")
            spamreader = csv.reader(csvfile, delimiter=',', quotechar='"')
            row_index = 0
            matcher = None
            for row in spamreader:
                if row_index == 0:
                    matcher = build_id_to_index_number(row)
                else:
                    osm_element_type = row[matcher["id"]].split("/")[0]
                    osm_element_id = row[matcher["id"]].split("/")[1]
                    name = row[matcher["name"]]
                    name_ru = None
                    if matcher.get("name:ru") != None:
                        name_ru = row[matcher.get("name:ru")].replace(" (Польша)", "") # drop "(city) explanation"
                    name_uk = None
                    if matcher.get("name:uk") != None:
                        name_uk = row[matcher.get("name:uk")].replace(" (місто)", "") # drop "(city) explanation"
                    if name_uk in ["Сувчина" # https://www.openstreetmap.org/node/31948375
                        "Стубно", # https://www.openstreetmap.org/node/31948515
                        "Клецко", # https://www.openstreetmap.org/node/563338229
                        ]:
                        name_uk = None

                    if is_imprecise_ukrainian_name(name_uk, name):
                        error = "SKIPPING IMPRECISE NAME ( " + link + " )!\n"
                        if name_uk != None:
                            error += "Provided Ukrainian name:\n" + name_uk.strip() + "\n"
                        else:
                            error += "No provided Ukrainian name"
                        if name_ru:
                            error += "Provided Russian name:\n" + name_ru.strip() + "\n"
                        else:
                            error += "No provided Russian name"
                        report_of_problems += error
                        print(error + "\n")
                        name_uk = None
                    element = osm_bot_abstraction_layer.get_data(osm_element_id, osm_element_type)
                    if element == None:
                        error = "NO ELEMENT AT ALL ( " + link + " )!\n"
                        report_of_problems += error
                        print(error + "\n")
                        skip_edit = True
                        continue # no need to check anything else
                    if "tag" not in element:
                        error = "NO TAGS AT ALL ( " + link + " )!\n"
                        report_of_problems += error
                        print(error + "\n")
                        skip_edit = True
                        continue # no need to check anything else
                    tags = element["tag"]

                    skip_edit = False
                    link = "https://www.openstreetmap.org/" + osm_element_type + "/" + osm_element_id
                    if "name" not in tags:
                        error = "NAME MISSING ( " + link + " )!\n"
                        if name_uk != None:
                            error += "Provided Ukrainian name:\n" + name_uk.strip() + "\n"
                        else:
                            error += "No provided Ukrainian name"
                        if name_ru:
                            error += "Provided Russian name:\n" + name_ru.strip() + "\n"
                        else:
                            error += "No provided Russian name"
                        report_of_problems += error
                        print(error + "\n")
                        skip_edit = True
                    elif name != tags["name"]:
                        expanded_name = tags["name"]
                        if "RCKiK" in tags["name"]:
                            expanded_name = expanded_name.replace("RCKiK", "Regionalne Centrum Krwiodawstwa i Krwiolecznictwa")
                            expanded_name = expanded_name.replace("TO", "Oddział Terenowy")
                            expanded_name = expanded_name.replace("OT", "Oddział Terenowy")
                        if "WCKiK" in tags["name"]:
                            expanded_name = expanded_name.replace("WCKiK", "Wojskowe Centrum Krwiodawstwa i Krwiolecznictwa")

                        if name != expanded_name:
                            error = "NAME MISMATCH ( " + link + " )!\n"
                            error += "Being translated:\n" + name + "\n"
                            error += "In OSM:\n" + tags["name"] + "\n"
                            error += "expanded_name:\n" + expanded_name + "\n"
                            if name_uk != None:
                                error += "Provided Ukrainian name:\n" + name_uk.strip() + "\n"
                            else:
                                error += "No provided Ukrainian name"
                            if name_ru:
                                error += "Provided Russian name:\n" + name_ru.strip() + "\n"
                            else:
                                error += "No provided Russian name"

                            report_of_problems += error
                            print(error + "\n")
                            skip_edit = True
                    if name_uk != None:
                        if "name:uk" in tags and name_uk.strip() != tags["name:uk"].strip():
                            error = "UKRAINIAN NAME MISMATCH ( " + link + " )!\n"
                            error += "Provided:\n" + name_uk.strip() + "\n"
                            error += "In OSM:\n" + tags["name:uk"].strip() + "\n"
                            error += "Translated:\n" + tags["name"] + "\n"
                            if name_uk != None:
                                error += "Provided Ukrainian name:\n" + name_uk.strip() + "\n"
                            else:
                                error += "No provided Ukrainian name"
                            if name_ru:
                                error += "Provided Russian name:\n" + name_ru.strip() + "\n"
                            else:
                                error += "No provided Russian name"

                            report_of_problems += error
                            print(error + "\n")
                            skip_edit = True
                    if name_ru != None:
                        if "name:ru" in tags and name_ru.strip() != tags["name:ru"].strip():
                            error = "RUSSIAN NAME MISMATCH ( " + link + " )!\n"
                            error += "Provided:\n" + name_ru.strip() + "\n"
                            error += "In OSM:\n" + tags["name:ru"].strip() + "\n"
                            error += "Translated:\n" + tags["name"] + "\n"
                            if name_uk != None:
                                error += "Provided Ukrainian name:\n" + name_uk.strip() + "\n"
                            else:
                                error += "No provided Ukrainian name"
                            if name_ru:
                                error += "Provided Russian name:\n" + name_ru.strip() + "\n"
                            else:
                                error += "No provided Russian name"

                            report_of_problems += error
                            print(error + "\n")
                            skip_edit = True

                    if make_edits == False or skip_edit:
                        continue

                    useful_edit = False
                    # may be not needed anymore?
                    if "name:ru" in tags and element["tag"]["name:ru"].strip() == "":
                        useful_edit = True
                        del element["tag"]["name:ru"]
                        print("cleaning empty name! Sorry!")
                    if "name:uk" in tags and element["tag"]["name:uk"].strip() == "":
                        useful_edit = True
                        del element["tag"]["name:uk"]
                        print("cleaning empty name! Sorry!")

                    if name_ru != None and name_ru.strip() != "":
                        if ("name:ru" not in tags or element["tag"]["name:ru"] != name_ru.strip()):
                            element["tag"]["name:ru"] = name_ru.strip()
                            useful_edit = True
                    if name_uk != None and name_uk.strip() != "":
                        if ("name:uk" not in tags or element["tag"]["name:uk"] != name_uk.strip()):
                            element["tag"]["name:uk"] = name_uk.strip()
                            useful_edit = True

                    if useful_edit == False:
                        continue

                    if changeset == None:
                        description = "dodawanie nazw ukraińskich i rosyjskich (edycje osób które zgodziły się na dystrybucje ich pracy ale edytowały listę nazw a nie bezpośrednio w edytorze OSM)"
                        description += " - " + file.replace("_", " ").replace(".csv", "")
                        changeset = build_changeset(False, description, "https://forum.openstreetmap.org/viewtopic.php?id=75019", "https://wiki.openstreetmap.org/wiki/Mechanical_Edits/Mateusz_Konieczny_-_bot_account/name_translation_proxy_ukraine_refugee_crisis")
                    osm_bot_abstraction_layer.update_element(changeset, osm_element_type, element)
                row_index += 1
        try:
            if make_edits and changeset != None:
                changeset.ChangesetClose()
        except osmapi.ApiError as e:
            if is_exception_about_already_closed_changeset(e):
                pass
            else:
                raise e
    print(report_of_problems)

def build_id_to_index_number(header_row_array):
    matcher = {}
    for index, column in enumerate(header_row_array):
        if column in ["id", "@id"]:
            matcher["id"] = index
        elif column in "name":
            matcher["name"] = index
        elif column in "name:ru":
            matcher["name:ru"] = index
        elif column in "name:uk":
            matcher["name:uk"] = index
    if "id" not in matcher:
        raise "id missing in header"
    if "name" not in matcher:
        raise "name missing in header"
    if "name:ru" not in matcher and "name:uk" not in matcher:
        raise "neither name:ru nor name:uk present in header"
    if "name:uk" not in matcher:
        raise "name:uk missing in header"
    return matcher

def show_overpass_query(file):
    with open(file, newline='') as csvfile:
        spamreader = csv.reader(csvfile, delimiter=',', quotechar='"')
        row_index = 0

        query_data_rows = ""

        matcher = None
        for row in spamreader:
            if row_index == 0:
                matcher = build_id_to_index_number(row)
            else:
                osm_element_type = row[0].split("/")[0]
                osm_element_id = row[0].split("/")[1]
                query_data_rows += osm_element_type + "(" + osm_element_id + ");\n"
            row_index += 1
        print(overpass_query_builder(query_data_rows))

def overpass_query_builder(query_data_rows):
    overpass_query = """
            [out:xml][timeout:2500];
    (
    node(1);
    );
    out body;
    >;
    out skel qt;
    """
    overpass_query_prefix = """[out:xml][timeout:2500];
    ("""
    overpass_query_suffix = """);
    out body;
    >;
    out skel qt;"""
    return overpass_query_prefix + query_data_rows + overpass_query_suffix

def build_changeset(is_in_manual_mode, changeset_comment, discussion_url, osm_wiki_documentation_page):
    automatic_status = osm_bot_abstraction_layer.manually_reviewed_description()
    if is_in_manual_mode == False:
        automatic_status = osm_bot_abstraction_layer.fully_automated_description()
    comment = changeset_comment
    source = None
    api = osm_bot_abstraction_layer.get_correct_api(automatic_status, discussion_url)
    affected_objects_description = ""
    builder = osm_bot_abstraction_layer.ChangesetBuilder(affected_objects_description, comment, automatic_status, discussion_url, osm_wiki_documentation_page, source)
    builder.create_changeset(api)
    return api

main(make_edits=True)


from bs4 import BeautifulSoup
import requests
from rus import send_mail
from soc import messages_to_string

def parse_hearpwn_page(page):
    page = requests.get(page)
    soup = BeautifulSoup(page.text, 'html.parser')
    messages = soup.find_all('div', itemprop='text')
    return messages

def parse_salty_thread_page(pageid):
    page = 'http://www.hearthpwn.com/forums/hearthstone-general/general-discussion/28947-group-' \
           'therapy-need-to-blow-off-steam-mega-salty?page=' + str(pageid)
    return parse_hearpwn_page(page)

def pretty_print(messages):
    for el in messages:
        print(el.getText(separator = ' '))

def main():
    print(messages_to_string(parse_salty_thread_page(2180)))
    send_mail(messages_to_string(parse_salty_thread_page(2180)))

if __name__ == '__main__':
    main()


# 케이스를 2가지 밖에 생각 못함 ,이번꺼 안먹은 경우// 이번꺼 먹고 + dp[i-2]
# + 추가로 이번꺼 저번꺼 먹은 경우도 생각 해줬어야함 lst[i-2],lst[i-1],dp[i-3]

# lst랑 dp랑 인덱스 안맞기때문에 헷갈리는거 조심, 가짓수를 더 생각해보자!!!
import sys
input=sys.stdin.readline

n=int(input())
lst=[]
dp=[0]*(n+1)

for _ in range(n):
    lst.append(int(input()))

dp[1]=lst[0]
if n>1:
    dp[2]=lst[0]+lst[1]

for i in range(3,n+1):
    # case 1 이번 포도주 먹고 전꺼 안 먹은경우
    case1=dp[i-2]+lst[i-1]
    # case 2 이번 포도주 먹고 전꺼 먹은경우
    case2=lst[i-2]+lst[i-1]+dp[i-3]
    # case 이번 포도주 안 먹은 경우
    case3=dp[i-1]
    dp[i]=max(case1,case2,case3)

print(dp[n])


import json
import os
import socket
import sys
import threading
import time

class Server:
    __instance = None

    @staticmethod
    def getInstance(callback=None):
        if Server.__instance == None:
            Server(callback)
        return Server.__instance

    def __init__(self, callback):

        if Server.__instance != None:
            raise Exception("This class is a singleton!")
        else:
            Server.__instance = self

        self.callback = callback
        self.clients = {}
        self.size = 2048
        self.port = os.getenv("PORT_SOCKET",2693)
        self.request_time = 10
        self.timeout = 5
        self.addres = os.getenv("HOST","0.0.0.0")
        self.command = {}
        self.data = {}

        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            self.server.bind((self.addres, int(self.port)))
        except Exception as e:
            print(f"[SERVER] Error: {e}")
            exit()
        print("[SERVER] Starting...")
        thread = threading.Thread(name="server", target=self.run, daemon=True)
        thread.start()

    def handle_client(self, conn, addr):
        print(f"[SERVER] {addr} connected.")
        conn.settimeout(self.timeout)
        left = 3
        while left > 0:
            msg = conn.recv(self.size).decode()
            if msg:
                try:
                    code, name = msg.split(":", 1)
                except:
                    code, name = None, None
                if code == "CON":
                    if self.clients.get(name):
                        if self.ping(name):
                            conn.send(
                                str.encode(
                                    "ERR:Name is taken! Pleace selcet other name."
                                )
                            )
                            left -= 1
                            continue
                    print(f"[SERVER] {addr} registered with name: {name}.")
                    conn.send(str.encode("OK:Connected sucessfuly"))
                    self.clients[name] = conn
                    self.command[name] = None
                    self.data[name] = None
                    self.listen(name)
            left -= 1
        print(f"[SERVER] {addr} timeout.")
        conn.shutdown(socket.SHUT_RDWR)
        sys.exit()

    def listen(self, name):
        while True:
            try:
                msg = self.clients[name].recv(self.size).decode()
            except Exception as e:
                if type(e) == socket.timeout:
                    continue
                print(f"[SERVER] Error: {e}, {self.clients}")
                try:
                    self.clients[name].shutdown(socket.SHUT_RDWR)
                    self.clients.pop(name)
                    self.command.pop(name)
                    self.data.pop(name)
                except:
                    pass
                sys.exit()

            if not msg:
                continue

            code, info = msg.split(":", 1)
            print(f"[SERVER] {code} : {info}")
            if self.command[name]:
                if self.command[name] == "GET":
                    if code != "DATA":
                        self.data[name] = {"error": True, "info": "Wrong response"}
                    else:
                        self.data[name] = {"error": False, "info": json.loads(info)}
                elif self.command[name] == "SET":
                    if code == "ERR":
                        self.data[name] = {"error": True, "info": info}
                    elif code != "OK":
                        self.data[name] = {"error": True, "info": "Wrong response"}
                    else:
                        self.data[name] = {"error": False, "info": "OK"}
                self.command[name] = None
                continue
            if code == "PING":
                self.send("OK:OK", name)
            elif code == "DATA":
                data = json.loads(info)
                self.callback("get", {"name": name, "payload": {"data": data}})
                self.send("OK:OK", name)
            elif code == "OK":
                continue

    def ping(self, name):
        other = self.clients.get(name)
        try:
            other.send(str.encode(f"PING:{name}"))
            msg = other.recv(self.size).decode()
            if not "OK" in msg:
                raise Exception("Not responding")
        except:
            print(f"[SERVER] {name} diconnected (not responding).")
            try:
                other.shutdown(socket.SHUT_RDWR)
            except:
                pass
            self.clients.pop(name)
            self.command.pop(name)
            self.data.pop(name)
            return False
        print(f"[SERVER] {name} is still alive.")
        return True

    def async_ping(self, name):
        thread = threading.Thread(name=f"ping {name}", target=self.ping, args=(name,))
        thread.start()

    def send_set(self, name, data):
        self.data[name] = None
        self.command[name] = "SET"
        self.send(f"SET:{json.dumps(data)}", name)
        start_time = time.perf_counter()
        while self.data[name] is None:
            if time.perf_counter() - start_time > self.request_time:
                self.async_ping(name)
                return {"error": True, "info": "Timeout"}
            pass
        return self.data[name]

    def send_get(self, name):
        self.data[name] = None
        self.command[name] = "GET"
        self.send(f"GET:GET", name)
        start_time = time.perf_counter()
        while self.data[name] is None:
            if time.perf_counter() - start_time > self.request_time:
                self.async_ping(name)
                return {"error": True, "info": "Timeout"}
            pass
        return self.data[name]

    def send_slient_get(self, name):
        self.send(f"GET:GET", name)

    def isName(self, name):
        c = self.clients.get(name)
        if c is None:
            return False
        return True

    def send(self, msg, name):
        c = self.clients.get(name)
        message = msg.encode()
        c.send(message)

    def run(self):
        self.server.listen()
        print(f"[SERVER] Server is listening on {self.port}")
        while True:
            conn, addr = self.server.accept()
            thread = threading.Thread(target=self.handle_client, args=(conn, addr))
            thread.start()

if __name__ == "__main__":
    Server()
    while True:
        pass


import ply.yacc as yacc
from mathpy.grammar.paranthesis.lexer import tokens

precedence = (
    ('nonassoc', 'NUMBER'),
    ('nonassoc', 'SINE', 'COSINE', 'SECANT', 'COSECANT', 'TANGENT', 'COTANGENT', 'LOG', 'EXP', 'ARCSINE', 'ARCCOSINE', 'ARCTANGENT', 'SINEH', 'COSINEH', 'TANGENTH', 'ARCSINEH', 'ARCCOSINEH', 'ARCTANGENTH'),
    ('left', 'PLUS', 'MINUS'),
    ('left', 'MUL', 'DIV'),
    ('right', 'POW'),
    ('nonassoc', 'COMPLEX')
    )

def p_b(t):
    'e : LP e RP'
    t[0] = t[2]

def p_id(t):
    'e : ID'
    t[0] = t[1]

def p_complex(t):
    'e : COMPLEX'
    t[0] = '(' + t[1] + ')'

def p_imag(t):
    'e : IMAG'
    t[0] = '(' + t[1] + ')'

def p_exp(t):
    '''e : e POW e
         | e PLUS e
         | e MINUS e
         | e MUL e
         | e DIV e
    '''
    t[0] = '(' + t[1] + ')' + t[2] + '(' + t[3] + ')'

def p_sine(t):
    '''e : SINE LP e RP
         | COSINE LP e RP
         | SECANT LP e RP
         | COSECANT LP e RP
         | TANGENT LP e RP
         | COTANGENT LP e RP
         | LOG LP e COMMA e RP
         | LN LP e RP
         | EXP POW LP e RP
         | ARCSINE LP e RP
         | ARCCOSINE LP e RP
         | ARCTANGENT LP e RP
         | SINEH LP e RP
         | COSINEH LP e RP
         | TANGENTH LP e RP
         | ARCSINEH LP e RP
         | ARCCOSINEH LP e RP
         | ARCTANGENTH LP e RP
    '''
    if t[1] == 'sin':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'cos':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'sec':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'cosec':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'tan':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'cot':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'log':
        t[0] = t[1] + t[2]+ t[3] + t[4] + t[5] + t[6]
    elif t[1] == 'ln':
        t[0] = t[1] + t[2] + t[3] + t[4]
    elif t[1] == 'e':
        t[0] = t[1] + t[2]+ t[3] + t[4] + t[5]
    elif t[1] == 'asin':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'acos':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'atan':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'sinh':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'cosh':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'tanh':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'asinh':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'acosh':
        t[0] = t[1] + t[2]+ t[3] + t[4]
    elif t[1] == 'atanh':
        t[0] = t[1] + t[2]+ t[3] + t[4]

def p_val(t):
    '''e : e SC g
       g : g COMMA e
         | e
    '''
    if len(t) == 4:
        t[0] = t[1] + t[2] + t[3]
    else:
        t[0] = t[1]

def p_number(t):
    'e : NUMBER'
    t[0] = t[1]

def p_error(t):
    print('Syntax error', t)

parser = yacc.yacc()


#!/usr/bin/env python
import os
import shutil
import argparse
import subprocess
import random
import pandas as pd
import numpy as np
import pickle as pkl
import scipy as sp
import networkx as nx
import scipy.stats as stats
import scipy.sparse as sparse

from torch import nn
from torch import optim
from torch.nn import functional as F

from scripts.ulity import *
from scripts.preprocessing import *
from scripts.cnnscript import *
from shutil import which
from collections import Counter
from Bio import SeqIO
from Bio.SeqRecord import SeqRecord
from Bio.Blast.Applications import NcbiblastnCommandline
from models.phamer import Transformer
from models.CAPCNN import WCNN
from models.PhaGCN import GCN
from models import Cherry
from scipy.special import softmax
from scripts.data import load_data, preprocess_features, preprocess_adj, sample_mask

parser = argparse.ArgumentParser(description="""Main script of PhaSUIT.""")
parser.add_argument('--contigs', help='FASTA file of contigs',  default = 'inputs.fa')
parser.add_argument('--threads', help='number of threads to use', type=int, default=4)
parser.add_argument('--len', help='minimum length of contigs', type=int, default=3000)
parser.add_argument('--reject', help='threshold to reject prophage',  type=float, default = 0.2)
parser.add_argument('--rootpth', help='rootpth of the user', default='user_0/')
parser.add_argument('--out', help='output path of the user', default='out/')
parser.add_argument('--midfolder', help='mid folder for intermidiate files', default='midfolder/')
parser.add_argument('--dbdir', help='database directory',  default = 'database/')
parser.add_argument('--scriptpth', help='path of parameters',  default = 'scripts/')
parser.add_argument('--parampth', help='path of parameters',  default = 'parameters/')
parser.add_argument('--proteins', help='FASTA file of predicted proteins (optional)')
inputs = parser.parse_args()

contigs   = inputs.contigs
midfolder = inputs.midfolder
rootpth   = inputs.rootpth
db_dir    = inputs.dbdir
out_dir   = inputs.out
parampth  = inputs.parampth
threads   = inputs.threads
length    = inputs.len
scriptpth = inputs.scriptpth

if not os.path.exists(db_dir):
    print(f'Database directory {db_dir} missing or unreadable')
    exit(1)

check_path(os.path.join(rootpth, out_dir))
check_path(os.path.join(rootpth, midfolder))

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
if device == 'cpu':
    print("running with cpu")
    torch.set_num_threads(inputs.threads)

###############################################################
#######################  Filter length ########################
###############################################################

rec = []
ID2length = {}
for record in SeqIO.parse(contigs, 'fasta'):
    ID2length[record.id] = len(record.seq)
    if len(record.seq) > inputs.len:
        rec.append(record)

if not rec:
    with open(f'{rootpth}/{out_dir}/phamer_prediction.csv', 'w') as file_out:
        file_out.write("Accession,Pred,Score\n")
        for record in SeqIO.parse(contigs, 'fasta'):
            file_out.write(f'{record.id},filtered,0\n')
    exit()

SeqIO.write(rec, f'{rootpth}/filtered_contigs.fa', 'fasta')

###############################################################
##########################  PhaMer ############################
###############################################################

translation(rootpth, os.path.join(rootpth, midfolder), 'filtered_contigs.fa', 'test_protein.fa', threads, inputs.proteins)
run_diamond(f'{db_dir}/phamer_database.dmnd', os.path.join(rootpth, midfolder), 'test_protein.fa', 'phamer', threads)
convert_xml(os.path.join(rootpth, midfolder), 'phamer', scriptpth)
if os.path.getsize(f'{rootpth}/{midfolder}/phamer_results.abc') == 0:
    with open(f'{rootpth}/{out_dir}/phamer_prediction.csv', 'w') as file_out:
        file_out.write("Accession,Pred,Score\n")
        for record in SeqIO.parse(contigs, 'fasta'):
            if len(record.seq) > inputs.len:
                file_out.write(f'{record.id},non-phage,0\n')
            else:
                file_out.write(f'{record.id},filtered,0\n')
    exit()
contig2sentence(db_dir, os.path.join(rootpth, midfolder), 'test_protein.fa', 'phamer')

pcs2idx = pkl.load(open(f'{rootpth}/{midfolder}/phamer_pc2wordsid.dict', 'rb'))
num_pcs = len(set(pcs2idx.keys()))

src_pad_idx = 0
src_vocab_size = num_pcs+1

model, optimizer, loss_func = reset_model(Transformer, src_vocab_size, device)
try:
    pretrained_dict=torch.load(f'{parampth}/transformer.pth', map_location=device)
    model.load_state_dict(pretrained_dict)
except:
    print('cannot find pre-trained model')
    exit(1)

sentence   = pkl.load(open(f'{rootpth}/{midfolder}/phamer_sentence.feat', 'rb'))
id2contig  = pkl.load(open(f'{rootpth}/{midfolder}/phamer_sentence_id2contig.dict', 'rb'))
proportion = pkl.load(open(f'{rootpth}/{midfolder}/phamer_sentence_proportion.feat', 'rb'))
contig2id  = {item: key for key, item in id2contig.items()}

all_pred = []
all_score = []
with torch.no_grad():
    _ = model.eval()
    for idx in range(0, len(sentence), 500):
        try:
            batch_x = sentence[idx: idx+500]
            weight  = proportion[idx: idx+500]
        except:
            batch_x = sentence[idx:]
            weight  = proportion[idx:]
        batch_x = return_tensor(batch_x, device).long()
        logit = model(batch_x)
        logit = torch.sigmoid(logit.squeeze(1))
        logit = reject_prophage(logit, weight, inputs.reject)
        pred  = ['phage' if item > 0.5 else 'non-phage' for item in logit]
        all_pred += pred
        all_score += [float('{:.3f}'.format(i)) for i in logit]

#FLAGS
if len(set(all_pred)) == 1 and all_pred[0] == 'non-phage':
    with open(f'{rootpth}/{out_dir}/phamer_prediction.csv', 'w') as file_out:
        file_out.write("Accession,Pred,Score\n")
        for record in SeqIO.parse(contigs, 'fasta'):
            file_out.write(f'{record.id},non-phage,0\n')
    exit()

### Add filtered label (Nov. 8th)
contigs_list = list(id2contig.values())
contigs_add = []
pred_rec = []
seq_dict = {}
phage_rec = []
for record in SeqIO.parse(f'{contigs}', 'fasta'):
    seq_dict[record.id] = str(record.seq)
    if record.id not in contigs_list:
        if len(record.seq) < inputs.len:
            contigs_add.append(record.id)
            all_pred.append('filtered')
            all_score.append(0)
            continue
        contigs_add.append(record.id)
        all_pred.append('non-phage')
        all_score.append(0)

contigs_list += contigs_add
length_list = [ID2length[item] for item in contigs_list]

pred_csv = pd.DataFrame({"Accession":contigs_list, "Length":length_list, "Pred":all_pred, "Score":all_score})
pred_csv.to_csv(f'{rootpth}/{out_dir}/phamer_prediction.csv', index = False)
phage_list = pred_csv[pred_csv['Pred'] == 'phage']['Accession'].values

for record in SeqIO.parse(f'{contigs}', 'fasta'):
    if record.id in phage_list:
        phage_rec.append(record)

SeqIO.write(phage_rec, f'{rootpth}/predicted_phage.fa', 'fasta')

##### for phage-only results #####
blast_df = pd.read_csv(f"{rootpth}/{midfolder}/phamer_results.abc", sep=' ', names=['query', 'ref', 'evalue'])
protein2evalue = parse_evalue(blast_df, f'{rootpth}/{midfolder}', 'phamer')
rec = []
for record in SeqIO.parse(f'{rootpth}/{midfolder}/test_protein.fa', 'fasta'):
    try:
        protein2evalue[record.id]
        rec.append(record)
    except:
        pass
SeqIO.write(rec, f'{rootpth}/{out_dir}/significant_proteins.fa', 'fasta')
os.system(f"cp {rootpth}/{midfolder}/phamer_results.tab {rootpth}/{out_dir}/blast_results.tab")
os.system(f"sed -i '1i\qseqid\tsseqid\tpident\tlength\tmismatch\tgapopen\tqstart\tqend\tsstart\tsend\tevalue' {rootpth}/{out_dir}/blast_results.tab")


from __future__ import unicode_literals
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from hazm import *
import fasttext
import string
import emoji
import hazm
import json
import os
import re
#
normalizer = Normalizer()

def remove_extra_chars(text):
    eng_alphabets = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',\
                     'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
    eng_pattern = r'(?:{})'.format('|'.join([r"{}".format(ch) for ch in eng_alphabets]))

    with open("words_with_2_duplicate_letters.txt", encoding="utf-8") as text_file:
        certain_words = [line.strip() for line in text_file.readlines()]

    text = text.lower()
    # if url exists in the text
    url_pattern = r"(?:(?:https?):\/\/)?[\w/\-?=%.]+\.[\w/\-?=%.]+"
    if re.findall(url_pattern, text, re.IGNORECASE):
        text = re.sub(url_pattern,"",text)

    if re.findall(r"@(\w+[.]*\b)", text):
        text = re.sub(r"@(\w+[.]*\b)","",text)

    # if number length is more than 3 numbers
    text = re.sub(r'\d{3,}', '', text)

    # remove english characters
    text = re.sub(eng_pattern, '', text)

    # if text contains @
    # text = re.sub(r'\s@\s', '', text)

    # if text contains extra character
    # remove all punctuation in fasttext or glove in ai_model
    regex = re.compile('[%s]' % re.escape(string.punctuation))
    text = regex.sub(' ', text)

    text = unifing_alphabets(text)

    duplicate_letter_pattern = re.compile(r"(.)\1{2,}")
    text_with_pattern2 = duplicate_letter_pattern.sub(r"\1\1", text)
    differences2 = [word for word in text_with_pattern2.split(" ") if word not in text.split(" ")]
    if differences2:
        curse_pattern = r'\b(?:{})\b'.format('|'.join(certain_words))
        if re.findall(curse_pattern, " ".join(differences2)):
            text = text_with_pattern2
        else:
            text = duplicate_letter_pattern.sub(r"\1", text)

    text = (" ").join([word.strip() for word in text.split()])
    return text

def emoji_space(text):
    regex = re.compile(r'\d+(.*?)(?:\u263a|\U0001f645)')
    all_emoji = regex.findall(text)

    edited_text = []
    for c in text:
        if c in emoji.UNICODE_EMOJI:
            edited_text.append(" "+c+" ")
        else:
            edited_text.append(c)

    edited_text = ("").join(edited_text)
    return(edited_text)

def unifing_alphabets(text):
    text = re.sub(r'اَ|اِ|اُ|اٌ|اٍ|اً|أ|إ', 'ا', text)
    text = re.sub(r'بَ|بِ|بُ|بّ', 'ب', text)
    text = re.sub(r'پَ|پِ|پُ', 'پ', text)
    text = re.sub(r'تَ|تِ|تُ|تّ', 'ت', text)
    text = re.sub(r'ثَ|ثِ|ثُ', 'ث', text)
    text = re.sub(r'جَ|جِ|جُ|جّ', 'ج', text)
    text = re.sub(r'چَ|چِ|چُ|چّ', 'چ', text)
    text = re.sub(r'حَ|حِ|حُ', 'ح', text)
    text = re.sub(r'خَ|خِ|خُ', 'خ', text)
    text = re.sub(r'دَ|دِ|دُ|دّ', 'د', text)
    text = re.sub(r'ذَ|ذِ|ذُ', 'ذ', text)
    text = re.sub(r'رَ|رِ|رُ|رّ', 'ر', text)
    text = re.sub(r'زَ|زِ|زُ|زّ', 'ز', text)
    text = re.sub(r'ژَ|ژِ|ژُ', 'ژ', text)
    text = re.sub(r'سَ|سِ|سُ|سّ', 'س', text)
    text = re.sub(r'شَ|شِ|شُ', 'ش', text)
    text = re.sub(r'صَ|صِ|صُ', 'ص', text)
    text = re.sub(r'ضَ|ضِ|ضُ', 'ض', text)
    text = re.sub(r'طَ|طِ|طُ', 'ط', text)
    text = re.sub(r'ظَ|ظِ|ظُ', 'ظ', text)
    text = re.sub(r'عَ|عِ|عُ', 'ع', text)
    text = re.sub(r'غَ|غِ|غُ', 'غ', text)
    text = re.sub(r'فَ|فِ|فُ|فّ', 'ف', text)
    text = re.sub(r'قَ|قِ|قُ|قّ', 'ق', text)
    text = re.sub(r'کَ|کِ|کُ|ك|كَ|كِ|كُ|کّ|كّ', 'ک', text)
    text = re.sub(r'گَ|گِ|گُ', 'گ', text)
    text = re.sub(r'لَ|لِ|لُ|لّ', 'ل', text)
    text = re.sub(r'مَ|مِ|مُ', 'م', text)
    text = re.sub(r'نَ|نِ|نُ|نّ', 'ن', text)
    text = re.sub(r'وَ|وِ|وُ|ؤ|ؤَ|ؤُ|ؤِ|وّ|ؤّ', 'و', text)
    text = re.sub(r'هَ|هِ|هُ|ة', 'ه', text)
    text = re.sub(r'یَ|یِ|یُ|ي|يَ|يِ|يُ|يّ|یّ', 'ی', text)
    text = re.sub(r'ئَ|ئِ|ئُ|ئّ', 'ئ', text)
    return text

train_dataset_path ="fastai_7lbl_train2.txt"
test_dataset_path= "fastai_7lbl_test2.txt"

model = fasttext.train_supervised(train_dataset_path,
                                 dim=100,
                                 lr=0.9, #[0.1 - 1.0]
                                 loss="hs",
                                 wordNgrams=7, #[1 - 5]
                                 ws=3,
                                 epoch=100, #[5 - 50]
                                 minn=3,#3
                                 maxn=6,#6
                                 lrUpdateRate=10,
                                 neg=10,
                                 t=0.0001
                                 )

model.quantize(input=train_dataset_path,
               qnorm=True,
               retrain=True,
               epoch=1,
               cutoff=100000
               )

quantized_model_path = "fastai_7lbl.ftz"
model.save_model(quantized_model_path)

print("test: ", model.test(test_dataset_path))

#number label
labels = set()
with open("fastai_7lbl_test2.txt", 'r') as f:
    for line in f:
        # print(line)
        labels.add(line.split(' ')[0])

print(labels,"test")

labels = set()
with open("fastai_7lbl_train2.txt", 'r') as f:
    for line in f:
        # print(line)
        labels.add(line.split(' ')[0])

print(labels,"train")

fasttext_model = fasttext.load_model("fastai_7lbl.ftz")
count=0
y_pred=[]
y_true=[]
with open ('fastai_7lbl_test2.txt', 'r') as f :
    # print(f)
    for line in f:
        # print(y_true[line])
        # print(line)
        label = line.split(' ', maxsplit=1)[0].strip()

        y_true.append(label)

        sentence = line.split(' ', maxsplit=1)[1].strip()

        outputs = fasttext_model.predict(sentence)

        y_pred.append(outputs[0])

def plot_confusion_matrix(y_true, y_pred, classes,
                          normalize=False,
                          title=None,
                          cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    if not title:
        if normalize:
            title = 'Normalized confusion matrix'
        else:
            title = 'Confusion matrix, without normalization'

    # Compute confusion matrix
    cm = confusion_matrix(y_true, y_pred)
    # Only use the labels that appear in the data
    #     classes = classes[unique_labels(y_true, y_pred)]
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        print("Normalized confusion matrix")
    else:
        print('Confusion matrix, without normalization')

    print(cm)

    fig, ax = plt.subplots()
    im = ax.imshow(cm, interpolation='nearest', cmap=cmap)
    ax.figure.colorbar(im, ax=ax)
    # We want to show all ticks...
    ax.set(xticks=np.arange(cm.shape[1]),
           yticks=np.arange(cm.shape[0]),
           # ... and label them with the respective list entries
           xticklabels=classes, yticklabels=classes,
           title=title,
           ylabel='True label',
           xlabel='Predicted label')

    # Rotate the tick labels and set their alignment.
    plt.setp(ax.get_xticklabels(), rotation=45, ha="right",
             rotation_mode="anchor")

    # Loop over data dimensions and create text annotations.
    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i in range(cm.shape[0]):
        for j in range(cm.shape[1]):
            ax.text(j, i, format(cm[i, j], fmt),
                    ha="center", va="center",
                    color="white" if cm[i, j] > thresh else "black")
    fig.tight_layout()
    return ax

class_names = ['__label__4', '__label__7', '__label__5', '__label__1', '__label__6', '__label__2', '__label__3']

# Plot non-normalized confusion matrix
plot_confusion_matrix(y_true, y_pred, classes=class_names,
                      title='Confusion matrix, without normalization')

# Plot normalized confusion matrix
plot_confusion_matrix(y_true, y_pred, classes=class_names, normalize=True,
                      title='Normalized confusion matrix')

plt.show()


#!/usr/bin/env python3
from Crypto.Util import number
from binascii import hexlify, unhexlify
from gmpy2 import next_prime, powmod, gcdext, gcd
from itertools import count
from random import randint

class MPRSA(object):
    def __init__(self):
        self.public_key = None
        self.secret_key = None

    def key_gen(self, bits, prime_numbers=4):
        delta = randint(5, 15)
        bit_prime = int(bits // prime_numbers)

        P = [next_prime(number.getPrime(bit_prime) + 1)]
        for i in range(1, prime_numbers):
            P.append(next_prime(P[i - 1] * delta))

        n = self.__compute_module(P)
        phi = self.__compute_phi(P)

        for d_next in count(int(pow(P[0] // 2, 0.5)), -1):
            g, e, __ = gcdext(d_next, phi)
            if (1 < e < n) and (g == 1) and (gcd(phi, e) == 1):
                d = d_next
                break

        self.public_key = (e, n)
        self.secret_key = (d, n)

    def import_keys(self, public_key, secret_key):
        self.public_key = public_key
        self.secret_key = secret_key

    def export_keys(self):
        return self.public_key, self.secret_key

    @staticmethod
    def __compute_module(primes):
        n = 1
        for prime in primes:
            n *= prime
        return n

    @staticmethod
    def __compute_phi(primes):
        phi = 1
        for prime in primes:
            phi *= (prime - 1)
        return phi

    @staticmethod
    def __encode_message(data):
        return int(hexlify(data), 16)

    @staticmethod
    def __decode_message(data):
        return unhexlify(format(data, "x"))

    def encryption(self, ptext):
        data = self.__encode_message(ptext)
        return powmod(data, self.public_key[0], self.public_key[1])

    def decryption(self, ctext):
        data = powmod(ctext, self.secret_key[0], self.secret_key[1])
        return MPRSA.__decode_message(data)