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

import os
import csv
import time
import json
import logging
import numpy as np
import tensorflow as tf
from sklearn.metrics import auc, roc_curve

# calculate_auc : calculate AUC rate
def calculate_auc(labels, predicts):
    fpr, tpr, _ = roc_curve(labels, predicts, pos_label=1)
    AUC = auc(fpr, tpr)
    return fpr, tpr, AUC

def contrastive_loss(labels, distance):
    loss = tf.to_float(tf.reduce_sum(tf.square(distance - labels)))
    return loss

def compute_accuracy(prediction, labels, threshold=0.5):
    accu = 0.0
    for i in xrange(len(prediction)):
        if labels[i][0] == 1:
            if prediction[i][0] > threshold:
                accu += 1.0
        else:
            if prediction[i][0] < threshold:
                accu += 1.0
    acc = accu / len(prediction)
    return acc

# read_and_decode : generate a queue based on filename
def read_and_decode(filename):
    filename_queue = tf.train.string_input_producer([filename])
    reader = tf.TFRecordReader()
    _, serialized_example = reader.read(filename_queue)
    features = tf.parse_single_example(serialized_example, features={
        'label': tf.FixedLenFeature([], tf.int64),
        'cfg_1': tf.FixedLenFeature([], tf.string),
        'cfg_2': tf.FixedLenFeature([], tf.string),
        'dfg_1': tf.FixedLenFeature([], tf.string),
        'dfg_2': tf.FixedLenFeature([], tf.string),
        'fea_1': tf.FixedLenFeature([], tf.string),
        'fea_2': tf.FixedLenFeature([], tf.string),
        'num1': tf.FixedLenFeature([], tf.int64),
        'num2': tf.FixedLenFeature([], tf.int64),
        'max': tf.FixedLenFeature([], tf.int64)})

    label = tf.cast(features['label'], tf.int32)

    cfg_1 = features['cfg_1']
    cfg_2 = features['cfg_2']
    dfg_1 = features['dfg_1']
    dfg_2 = features['dfg_2']

    num1 = tf.cast(features['num1'], tf.int32)
    fea_1 = features['fea_1']
    num2 =  tf.cast(features['num2'], tf.int32)
    fea_2 = features['fea_2']

    max_num = tf.cast(features['max'], tf.int32)
    return label, cfg_1, cfg_2, dfg_1, dfg_2, fea_1, fea_2, num1, num2, max_num

# GoCloneTfHandler : handler using tensorflow to detect code clone in Golang
class GoCloneTfHandler(object):
    def __init__(self, iteration_times=5, embedding_depth=2, embedding_size=64, feature_num=10, mini_batch=10, learning_rate=0.0001, max_iter=1, decay_steps=10, decay_rate=0.0001, snapshot=1, test_num=1000, train_tfrecord="tfrecord/train.tfrecord",test_tfrecord="tfrecord/test.tfrecord",valid_tfrecord="tfrecord/valid.tfrecord", exist_model="", ckpt_file="", test_file="", result_file="",func_info_path=""):
        # self.iteration_times = iteration_times # T
        self.embedding_depth = embedding_depth # N
        self.embedding_size = embedding_size # P
        self.feature_num = feature_num # D
        self.mini_batch = mini_batch # B
        self.learning_rate = learning_rate # lr
        self.max_iter = max_iter
        self.decay_steps = decay_steps
        self.decay_rate = decay_rate
        self.snapshot = snapshot
        self.test_file = test_file
        self.result_file = result_file
        self.test_num = test_num
        self.train_tfrecord = train_tfrecord
        self.test_tfrecord = test_tfrecord
        self.valid_tfrecord = valid_tfrecord
        self.exist_model = exist_model
        self.ckpt_file = ckpt_file
        self.func_info_path = func_info_path
        self.pair_list = []

        self.logger = logging.getLogger("default")
        self.logger_init()

    def load_csv_as_pair(self, pair_label_file):
        with open(pair_label_file, "r") as fp:
            pair_label = csv.reader(fp)
            for line in pair_label:
                self.pair_list.append((line[0], line[1]))

    # logger_init : initialize logger for console and file
    def logger_init(self):
        self.logger.setLevel(logging.DEBUG)
        log_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

        console_handler = logging.StreamHandler()
        console_handler.setLevel(logging.DEBUG)
        console_handler.setFormatter(log_format)
        self.logger.addHandler(console_handler)

        log_file_name = "logs/log%s.txt" % time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime())
        file_handler = logging.FileHandler(log_file_name, mode='w', encoding='utf-8')
        file_handler.setLevel(logging.INFO)
        file_handler.setFormatter(log_format)
        self.logger.addHandler(file_handler)

    # structure2vec : Construct pairs dataset to train the model.
    def structure2vec(self, mu_prev, cfg, dfg, x, name="structure2vec"):
        with tf.variable_scope(name):
            W_1 = tf.get_variable('W_1', [self.feature_num, self.embedding_size], tf.float32, tf.truncated_normal_initializer(mean=0.0, stddev=0.1))

            param_cfg = tf.get_variable('param_cfg', 1, tf.float32, tf.truncated_normal_initializer(mean=0.0, stddev=0.1))
            P_CFG_1 = tf.get_variable('P_CFG_1', [self.embedding_size, self.embedding_size], tf.float32, tf.truncated_normal_initializer(mean=0.0, stddev=0.1))
            P_CFG_2 = tf.get_variable('P_CFG_2', [self.embedding_size, self.embedding_size], tf.float32, tf.truncated_normal_initializer(mean=0.0, stddev=0.1))
            L_CFG = tf.reshape(tf.matmul(cfg, mu_prev, transpose_a=True), (-1, self.embedding_size))
            S_CFG =param_cfg*tf.reshape(tf.matmul(tf.nn.relu(tf.matmul(L_CFG, P_CFG_2)), P_CFG_1), (-1, self.embedding_size))

            param_dfg = tf.get_variable('param_dfg', 1, tf.float32, tf.truncated_normal_initializer(mean=0.0, stddev=0.1))
            P_DFG_1 = tf.get_variable('P_DFG_1', [self.embedding_size, self.embedding_size], tf.float32, tf.truncated_normal_initializer(mean=0.0, stddev=0.1))
            P_DFG_2 = tf.get_variable('P_DFG_2', [self.embedding_size, self.embedding_size], tf.float32, tf.truncated_normal_initializer(mean=0.0, stddev=0.1))
            L_DFG = tf.reshape(tf.matmul(dfg, mu_prev, transpose_a=True), (-1, self.embedding_size))
            S_DFG = param_dfg*tf.reshape(tf.matmul(tf.nn.relu(tf.matmul(L_DFG, P_DFG_2)), P_DFG_1), (-1, self.embedding_size))

            return tf.tanh(tf.add(tf.add(tf.reshape(tf.matmul(tf.reshape(x, (-1, self.feature_num)), W_1), (-1, self.embedding_size)), S_CFG), S_DFG))

    def structure2vec_net(self, cfgs, dfgs, x, v_num):
        with tf.variable_scope("structure2vec_net") as structure2vec_net:
            B_mu_5 = tf.Variable(tf.zeros(shape = [0, self.embedding_size]), trainable=False)
            w_2 = tf.get_variable('w_2', [self.embedding_size, self.embedding_size], tf.float32, tf.truncated_normal_initializer(mean=0.0, stddev=0.1))
            for i in range(self.mini_batch):
                cur_size = tf.to_int32(v_num[i][0])
                mu_0 = tf.reshape(tf.zeros(shape = [cur_size, self.embedding_size]), (cur_size, self.embedding_size))
                cfg = tf.slice(cfgs[i], [0, 0], [cur_size, cur_size])
                dfg = tf.slice(dfgs[i], [0, 0], [cur_size, cur_size])
                fea = tf.slice(x[i],[0,0], [cur_size, self.feature_num])
                mu_1 = self.structure2vec(mu_0, cfg, dfg, fea)
                structure2vec_net.reuse_variables()
                mu_2 = self.structure2vec(mu_1, cfg, dfg, fea)
                mu_3 = self.structure2vec(mu_2, cfg, dfg, fea)
                mu_4 = self.structure2vec(mu_3, cfg, dfg, fea)
                mu_5 = self.structure2vec(mu_4, cfg, dfg, fea)
                B_mu_5 = tf.concat([B_mu_5,tf.matmul(tf.reshape(tf.reduce_sum(mu_5, 0), (1, self.embedding_size)), w_2)],0)
            return B_mu_5

    def cal_distance(self, model1, model2):
        a_b = tf.reduce_sum(tf.reshape(tf.reduce_prod(tf.concat([tf.reshape(model1,(1,-1)), tf.reshape(model2,(1,-1))],0),0),(self.mini_batch,self.embedding_size)),1,keep_dims=True)
        a_norm = tf.sqrt(tf.reduce_sum(tf.square(model1),1,keep_dims=True))
        b_norm = tf.sqrt(tf.reduce_sum(tf.square(model2),1,keep_dims=True))
        distance = a_b/tf.reshape(tf.reduce_prod(tf.concat([tf.reshape(a_norm,(1,-1)), tf.reshape(b_norm,(1,-1))],0),0),(self.mini_batch,1))
        return distance

    def get_batch(self, label, cfg_str1, cfg_str2, dfg_str1, dfg_str2, fea_str1, fea_str2, num1, num2, max_num):
        y = np.reshape(label, [self.mini_batch, 1])

        v_num_1 = []
        v_num_2 = []
        for i in range(self.mini_batch):
            v_num_1.append([int(num1[i])])
            v_num_2.append([int(num2[i])])

        cfg_1 = []
        cfg_2 = []
        dfg_1 = []
        dfg_2 = []
        for i in range(self.mini_batch):
            cfg_arr = np.array(cfg_str1[i].split(','))
            cfg_adj = np.reshape(cfg_arr, (int(num1[i]), int(num1[i])))
            cfg_ori1 = cfg_adj.astype(np.float32)
            cfg_ori1.resize(int(max_num[i]), int(max_num[i]), refcheck=False)
            cfg_1.append(cfg_ori1.tolist())

            cfg_arr = np.array(cfg_str2[i].split(','))
            cfg_adj = np.reshape(cfg_arr, (int(num2[i]), int(num2[i])))
            cfg_ori2 = cfg_adj.astype(np.float32)
            cfg_ori2.resize(int(max_num[i]), int(max_num[i]), refcheck=False)
            cfg_2.append(cfg_ori2.tolist())

            dfg_arr = np.array(dfg_str1[i].split(','))
            dfg_adj = np.reshape(dfg_arr, (int(num1[i]), int(num1[i])))
            dfg_ori1 = dfg_adj.astype(np.float32)
            dfg_ori1.resize(int(max_num[i]), int(max_num[i]), refcheck=False)
            dfg_1.append(dfg_ori1.tolist())

            dfg_arr = np.array(dfg_str2[i].split(','))
            dfg_adj = np.reshape(dfg_arr, (int(num2[i]), int(num2[i])))
            dfg_ori2 = dfg_adj.astype(np.float32)
            dfg_ori2.resize(int(max_num[i]), int(max_num[i]), refcheck=False)
            dfg_2.append(dfg_ori2.tolist())

        fea_1 = []
        fea_2 = []
        for i in range(self.mini_batch):
            fea_arr = np.array(fea_str1[i].split(','))
            fea_ori = fea_arr.astype(np.float32)
            fea_vec1 = np.resize(fea_ori, (np.max(v_num_1), self.feature_num))
            fea_1.append(fea_vec1)

            fea_arr = np.array(fea_str2[i].split(','))
            fea_ori= fea_arr.astype(np.float32)
            fea_vec2 = np.resize(fea_ori, (np.max(v_num_2), self.feature_num))
            fea_2.append(fea_vec2)

        return y, cfg_1, cfg_2, dfg_1, dfg_2, fea_1, fea_2, v_num_1, v_num_2

    def run(self):
        tf.global_variables_initializer()
        global_step = tf.Variable(0, trainable=False)
        learning_rate = tf.train.exponential_decay(self.learning_rate, global_step, self.decay_steps, self.decay_rate, staircase=True)

        v_num_left = tf.placeholder(tf.float32, shape=[self.mini_batch, 1], name='v_num_left')
        cfg_left = tf.placeholder(tf.float32, shape=([self.mini_batch, None, None]), name='cfg_left')
        dfg_left = tf.placeholder(tf.float32, shape=([self.mini_batch, None, None]), name='dfg_left')
        fea_left = tf.placeholder(tf.float32, shape=([self.mini_batch, None, self.feature_num]), name='fea_left')

        v_num_right = tf.placeholder(tf.float32, shape=[self.mini_batch, 1], name='v_num_right')
        cfg_right = tf.placeholder(tf.float32, shape=([self.mini_batch, None, None]), name='cfg_right')
        dfg_right = tf.placeholder(tf.float32, shape=([self.mini_batch, None, None]), name='dfg_right')
        fea_right = tf.placeholder(tf.float32, shape=([self.mini_batch, None, self.feature_num]), name='fea_right')

        labels = tf.placeholder(tf.float32, shape=([self.mini_batch, 1]), name='gt')

        dropout_f = tf.placeholder("float")

        with tf.variable_scope("siamese") as siamese:
            model1 = self.structure2vec_net(cfg_left, dfg_left, fea_left, v_num_left)
            siamese.reuse_variables()
            model2 = self.structure2vec_net(cfg_right, dfg_right, fea_right, v_num_right)

        dis = self.cal_distance(model1, model2)

        loss = contrastive_loss(labels, dis)

        optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)

        list_test_label, list_test_cfg_1, list_test_cfg_2, list_test_dfg_1, list_test_dfg_2, list_test_fea_1, \
        list_test_fea_2, list_test_num1, list_test_num2, list_test_max = read_and_decode(self.test_tfrecord)
        batch_test_label, batch_test_cfg_1, batch_test_cfg_2, batch_test_dfg_1, batch_test_dfg_2, batch_test_fea_1, \
        batch_test_fea_2, batch_test_num1, batch_test_num2, batch_test_max  \
            = tf.train.batch([list_test_label, list_test_cfg_1, list_test_cfg_2, list_test_dfg_1, list_test_dfg_2,
                            list_test_fea_1, list_test_fea_2, list_test_num1, list_test_num2, list_test_max],
                            batch_size=self.mini_batch, capacity=10)
        init_opt = tf.global_variables_initializer()

        saver = tf.train.Saver()
        os.environ["CUDA_VISIBLE_DEVICES"] = "0"

        # read json from func_info_path
        with open(self.func_info_path, 'r') as f:
            func_info_dic = json.load(f)
        result_dic = {}

        with tf.Session() as sess:
            writer = tf.summary.FileWriter('logs/', sess.graph)

            # check whether to load exist models
            if self.exist_model == "":
                sess.run(init_opt)
            else:
                saver = tf.train.import_meta_graph(self.ckpt_file)
                saver.restore(sess, tf.train.latest_checkpoint(self.exist_model))
                self.logger.info("Loading models from %s" % self.ckpt_file)

            coord = tf.train.Coordinator()
            threads = tf.train.start_queue_runners(sess=sess, coord=coord)
            # Training cycle
            iter=0
            self.load_csv_as_pair(self.test_file)
            while iter < self.max_iter:
                iter += 1
                total_batch = int(self.test_num / self.mini_batch)

                if iter % self.snapshot == 0:
                    total_labels = []
                    total_predicts = []
                    avg_loss = 0.
                    avg_acc = 0.
                    test_total_batch = int(self.test_num / self.mini_batch)
                    start_time = time.time()
                    for m in range(test_total_batch):
                        test_label, test_cfg_1, test_cfg_2, test_dfg_1, test_dfg_2, \
                        test_fea_1, test_fea_2, test_num1, test_num2, test_max = sess.run(
                            [batch_test_label, batch_test_cfg_1, batch_test_cfg_2, batch_test_dfg_1, batch_test_dfg_2, batch_test_fea_1, batch_test_fea_2, batch_test_num1, batch_test_num2, batch_test_max])
                        y, cfg_1, cfg_2, dfg_1, dfg_2, fea_1, fea_2, v_num_1, v_num_2 \
                            = self.get_batch(test_label, test_cfg_1, test_cfg_2, test_dfg_1, test_dfg_2,
                                        test_fea_1, test_fea_2, test_num1, test_num2, test_max)
                        predict = dis.eval(
                            feed_dict={cfg_left: cfg_1, dfg_left: dfg_1, fea_left: fea_1, v_num_left: v_num_1, cfg_right: cfg_2,
                                    dfg_right: dfg_2, fea_right: fea_2, v_num_right: v_num_2, labels: y, dropout_f: 1.0})
                        for k, p in enumerate(predict):
                            (id1, id2) = self.pair_list[y[k][0]]
                            result_dic[(func_info_dic[id1], func_info_dic[id2])] = p[0]
                        if m % 20 == 0:
                           self.logger.info("Testing: %s/%s" % (m, test_total_batch))

            coord.request_stop()
            coord.join(threads)
            result_desc = sorted(result_dic.items(), key=lambda item:-item[1])
            with open(self.result_file, "w") as f:
                for r in result_desc:
                    f.write("%s\n%s\n%.4f\n\n" % (r[0][0], r[0][1], r[1]))


from enum import IntEnum, auto
from typing import List, Mapping, Union, Tuple, Optional

from .aetg import AETGGenerator
from .matrix import MatrixGenerator
from ...model import int_enum_loads
from ...reflection import progressive_for

__all__ = ['tmatrix']

@int_enum_loads(enable_int=False, name_preprocess=str.upper)
class MatrixMode(IntEnum):
    AETG = auto()
    MATRIX = auto()

def tmatrix(ranges: Mapping[Union[str, Tuple[str, ...]], List],
            mode='aetg', seed: Optional[int] = 0, level: int = 2) -> Tuple[List[str], List[Tuple]]:
    """
    Overview:
        Test matrix generator, which can be used in ``pytest.mark.parameterize``.

    :param ranges: Ranges of the values
    :param mode: Mode of the matrix, should be one of the ``aetg`` or ``matrix``. Default is ``aetg``.
    :param seed: Random seed, default is ``0`` which means the result is fixed (recommended).
    :param level: Lavel of AETG generating algorithm, default is ``2``.
    :returns: A tuple - ``(names, values)``.

    Examples::
        >>> from hbutils.testing import tmatrix
        >>> names, values = tmatrix(
        ...     {
        ...         'a': [2, 3],
        ...         'e': ['a', 'b', 'c'],
        ...         ('b', 'c'): [(1, 7), (4, 6), (9, 12)],
        ...     }
        ... )
        >>> print(names)
        ['a', 'e', 'b', 'c']
        >>> for i, v in enumerate(values):
        ...     print(i, v)
        0 (2, 'c', 9, 12)
        1 (3, 'c', 4, 6)
        2 (2, 'c', 1, 7)
        3 (3, 'b', 9, 12)
        4 (2, 'b', 4, 6)
        5 (3, 'b', 1, 7)
        6 (3, 'a', 9, 12)
        7 (2, 'a', 4, 6)
        8 (3, 'a', 1, 7)

    .. note::
        This can be directly used in ``pytest.mark.parametrize`` function.

        >>> @pytest.mark.unittest
        ... class TestTestingGeneratorFunc:
        ...     @pytest.mark.parametrize(*tmatrix({
        ...         'a': [2, 3],
        ...         'e': ['a', 'b', 'c'],
        ...         ('b', 'c'): [(1, 7), (4, 6), (9, 12)],
        ...     }))
        ...     def test_tmatrix_usage(self, a, e, b, c):
        ...         print(a, e, b, c)
    """
    mode = MatrixMode.loads(mode)

    key_map = {}
    final_names = []
    final_values = {}
    for ki, (key, value) in enumerate(ranges.items()):
        kname = f'key-{ki}'
        key_map[kname] = key
        final_names.append(kname)
        final_values[kname] = value

    names = []
    for key in ranges.keys():
        if isinstance(key, str):
            names.append(key)
        elif isinstance(key, tuple):
            for k in key:
                names.append(k)

    if mode == MatrixMode.MATRIX:
        generator = MatrixGenerator(final_values, final_names)
    elif mode == MatrixMode.AETG:
        generator = AETGGenerator(
            final_values, final_names, rnd=seed,
            pairs=list(progressive_for(final_names, min(level, len(names)))),
        )
    else:
        raise ValueError(f'Invalid mode - {mode!r}.')  # pragma: no cover

    pairs = []
    for case in generator.cases():
        _v_case = {}
        for name in final_names:
            key = key_map[name]
            if isinstance(key, str):
                _v_case[key] = case[name]
            elif isinstance(key, tuple):
                for ikey, ivalue in zip(key, case[name]):
                    _v_case[ikey] = ivalue

        pairs.append(tuple(_v_case[name] for name in names))

    return names, pairs


__authors__ = ["T. Vincent"]
__license__ = "MIT"
__date__ = "28/06/2018"

import logging
import numpy
import weakref
import functools
from typing import Optional

from ....utils.weakref import WeakList
from ... import qt
from .. import items
from ..items import core
from ...colors import rgba

logger = logging.getLogger(__name__)

class _RegionOfInterestBase(qt.QObject):
    """Base class of 1D and 2D region of interest

    :param QObject parent: See QObject
    :param str name: The name of the ROI
    """

    sigAboutToBeRemoved = qt.Signal()
    """Signal emitted just before this ROI is removed from its manager."""

    sigItemChanged = qt.Signal(object)
    """Signal emitted when item has changed.

    It provides a flag describing which property of the item has changed.
    See :class:`ItemChangedType` for flags description.
    """

    def __init__(self, parent=None):
        qt.QObject.__init__(self)
        if parent is not None:
            self.setParent(parent)
        self.__name = ''

    def getName(self):
        """Returns the name of the ROI

        :return: name of the region of interest
        :rtype: str
        """
        return self.__name

    def setName(self, name):
        """Set the name of the ROI

        :param str name: name of the region of interest
        """
        name = str(name)
        if self.__name != name:
            self.__name = name
            self._updated(items.ItemChangedType.NAME)

    def _updated(self, event=None, checkVisibility=True):
        """Implement Item mix-in update method by updating the plot items

        See :class:`~silx.gui.plot.items.Item._updated`
        """
        self.sigItemChanged.emit(event)

    def contains(self, position):
        """Returns True if the `position` is in this ROI.

        :param tuple[float,float] position: position to check
        :return: True if the value / point is consider to be in the region of
                 interest.
        :rtype: bool
        """
        return False  # Override in subclass to perform actual test

class RoiInteractionMode(object):
    """Description of an interaction mode.

    An interaction mode provide a specific kind of interaction for a ROI.
    A ROI can implement many interaction.
    """

    def __init__(self, label, description=None):
        self._label = label
        self._description = description

    @property
    def label(self):
        """Short name"""
        return self._label

    @property
    def description(self):
        """Longer description of the interaction mode"""
        return self._description

class InteractionModeMixIn(object):
    """Mix in feature which can be implemented by a ROI object.

    This provides user interaction to switch between different
    interaction mode to edit the ROI.

    This ROI modes have to be described using `RoiInteractionMode`,
    and taken into account during interation with handles.
    """

    sigInteractionModeChanged = qt.Signal(object)

    def __init__(self):
        self.__modeId = None

    def _initInteractionMode(self, modeId):
        """Set the mode without updating anything.

        Must be one of the returned :meth:`availableInteractionModes`.

        :param RoiInteractionMode modeId: Mode to use
        """
        self.__modeId = modeId

    def availableInteractionModes(self):
        """Returns the list of available interaction modes

        Must be implemented when inherited to provide all available modes.

        :rtype: List[RoiInteractionMode]
        """
        raise NotImplementedError()

    def setInteractionMode(self, modeId):
        """Set the interaction mode.

        :param RoiInteractionMode modeId: Mode to use
        """
        self.__modeId = modeId
        self._interactiveModeUpdated(modeId)
        self.sigInteractionModeChanged.emit(modeId)

    def _interactiveModeUpdated(self, modeId):
        """Called directly after an update of the mode.

        The signal `sigInteractionModeChanged` is triggered after this
        call.

        Must be implemented when inherited to take care of the change.
        """
        raise NotImplementedError()

    def getInteractionMode(self):
        """Returns the interaction mode.

        Must be one of the returned :meth:`availableInteractionModes`.

        :rtype: RoiInteractionMode
        """
        return self.__modeId

    def createMenuForInteractionMode(self, parent: qt.QWidget) -> qt.QMenu:
        """Create a menu providing access to the different interaction modes"""
        availableModes = self.availableInteractionModes()
        currentMode = self.getInteractionMode()
        submenu = qt.QMenu(parent)
        modeGroup = qt.QActionGroup(parent)
        modeGroup.setExclusive(True)
        for mode in availableModes:
            action = qt.QAction(parent)
            action.setText(mode.label)
            action.setToolTip(mode.description)
            action.setCheckable(True)
            if mode is currentMode:
                action.setChecked(True)
            else:
                callback = functools.partial(self.setInteractionMode, mode)
                action.triggered.connect(callback)
            modeGroup.addAction(action)
            submenu.addAction(action)
        submenu.setTitle("Interaction mode")
        return submenu

class RegionOfInterest(_RegionOfInterestBase, core.HighlightedMixIn):
    """Object describing a region of interest in a plot.

    :param QObject parent:
        The RegionOfInterestManager that created this object
    """

    _DEFAULT_LINEWIDTH = 1.
    """Default line width of the curve"""

    _DEFAULT_LINESTYLE = '-'
    """Default line style of the curve"""

    _DEFAULT_HIGHLIGHT_STYLE = items.CurveStyle(linewidth=2)
    """Default highlight style of the item"""

    ICON, NAME, SHORT_NAME = None, None, None
    """Metadata to describe the ROI in labels, tooltips and widgets

    Should be set by inherited classes to custom the ROI manager widget.
    """

    sigRegionChanged = qt.Signal()
    """Signal emitted everytime the shape or position of the ROI changes"""

    sigEditingStarted = qt.Signal()
    """Signal emitted when the user start editing the roi"""

    sigEditingFinished = qt.Signal()
    """Signal emitted when the region edition is finished. During edition
    sigEditionChanged will be emitted several times and
    sigRegionEditionFinished only at end"""

    def __init__(self, parent=None):
        # Avoid circular dependency
        from ..tools import roi as roi_tools
        assert parent is None or isinstance(parent, roi_tools.RegionOfInterestManager)
        _RegionOfInterestBase.__init__(self, parent)
        core.HighlightedMixIn.__init__(self)
        self.__text = None
        self._color = rgba('red')
        self._editable = False
        self._selectable = False
        self._focusProxy = None
        self._visible = True
        self._child = WeakList()

    def _connectToPlot(self, plot):
        """Called after connection to a plot"""
        for item in self.getItems():
            # This hack is needed to avoid reentrant call from _disconnectFromPlot
            # to the ROI manager. It also speed up the item tests in _itemRemoved
            item._roiGroup = True
            plot.addItem(item)

    def _disconnectFromPlot(self, plot):
        """Called before disconnection from a plot"""
        for item in self.getItems():
            # The item could be already be removed by the plot
            if item.getPlot() is not None:
                del item._roiGroup
                plot.removeItem(item)

    def _setItemName(self, item):
        """Helper to generate a unique id to a plot item"""
        legend = "__ROI-%d__%d" % (id(self), id(item))
        item.setName(legend)

    def setParent(self, parent):
        """Set the parent of the RegionOfInterest

        :param Union[None,RegionOfInterestManager] parent: The new parent
        """
        # Avoid circular dependency
        from ..tools import roi as roi_tools
        if (parent is not None and not isinstance(parent, roi_tools.RegionOfInterestManager)):
            raise ValueError('Unsupported parent')

        previousParent = self.parent()
        if previousParent is not None:
            previousPlot = previousParent.parent()
            if previousPlot is not None:
                self._disconnectFromPlot(previousPlot)
        super(RegionOfInterest, self).setParent(parent)
        if parent is not None:
            plot = parent.parent()
            if plot is not None:
                self._connectToPlot(plot)

    def addItem(self, item):
        """Add an item to the set of this ROI children.

        This item will be added and removed to the plot used by the ROI.

        If the ROI is already part of a plot, the item will also be added to
        the plot.

        It the item do not have a name already, a unique one is generated to
        avoid item collision in the plot.

        :param silx.gui.plot.items.Item item: A plot item
        """
        assert item is not None
        self._child.append(item)
        if item.getName() == '':
            self._setItemName(item)
        manager = self.parent()
        if manager is not None:
            plot = manager.parent()
            if plot is not None:
                item._roiGroup = True
                plot.addItem(item)

    def removeItem(self, item):
        """Remove an item from this ROI children.

        If the item is part of a plot it will be removed too.

        :param silx.gui.plot.items.Item item: A plot item
        """
        assert item is not None
        self._child.remove(item)
        plot = item.getPlot()
        if plot is not None:
            del item._roiGroup
            plot.removeItem(item)

    def getItems(self):
        """Returns the list of PlotWidget items of this RegionOfInterest.

        :rtype: List[~silx.gui.plot.items.Item]
        """
        return tuple(self._child)

    @classmethod
    def _getShortName(cls):
        """Return an human readable kind of ROI

        :rtype: str
        """
        if hasattr(cls, "SHORT_NAME"):
            name = cls.SHORT_NAME
        if name is None:
            name = cls.__name__
        return name

    def getColor(self):
        """Returns the color of this ROI

        :rtype: QColor
        """
        return qt.QColor.fromRgbF(*self._color)

    def setColor(self, color):
        """Set the color used for this ROI.

        :param color: The color to use for ROI shape as
           either a color name, a QColor, a list of uint8 or float in [0, 1].
        """
        color = rgba(color)
        if color != self._color:
            self._color = color
            self._updated(items.ItemChangedType.COLOR)

    def isEditable(self):
        """Returns whether the ROI is editable by the user or not.

        :rtype: bool
        """
        return self._editable

    def setEditable(self, editable):
        """Set whether the ROI can be changed interactively.

        :param bool editable: True to allow edition by the user,
           False to disable.
        """
        editable = bool(editable)
        if self._editable != editable:
            self._editable = editable
            self._updated(items.ItemChangedType.EDITABLE)

    def isSelectable(self):
        """Returns whether the ROI is selectable by the user or not.

        :rtype: bool
        """
        return self._selectable

    def setSelectable(self, selectable):
        """Set whether the ROI can be selected interactively.

        :param bool selectable: True to allow selection by the user,
           False to disable.
        """
        selectable = bool(selectable)
        if self._selectable != selectable:
            self._selectable = selectable
            self._updated(items.ItemChangedType.SELECTABLE)

    def getFocusProxy(self):
        """Returns the ROI which have to be selected when this ROI is selected,
        else None if no proxy specified.

        :rtype: RegionOfInterest
        """
        proxy = self._focusProxy
        if proxy is None:
            return None
        proxy = proxy()
        if proxy is None:
            self._focusProxy = None
        return proxy

    def setFocusProxy(self, roi):
        """Set the real ROI which will be selected when this ROI is selected,
        else None to remove the proxy already specified.

        :param RegionOfInterest roi: A ROI
        """
        if roi is not None:
            self._focusProxy = weakref.ref(roi)
        else:
            self._focusProxy = None

    def isVisible(self):
        """Returns whether the ROI is visible in the plot.

        .. note::
            This does not take into account whether or not the plot
            widget itself is visible (unlike :meth:`QWidget.isVisible` which
            checks the visibility of all its parent widgets up to the window)

        :rtype: bool
        """
        return self._visible

    def setVisible(self, visible):
        """Set whether the plot items associated with this ROI are
        visible in the plot.

        :param bool visible: True to show the ROI in the plot, False to
            hide it.
        """
        visible = bool(visible)
        if self._visible != visible:
            self._visible = visible
            self._updated(items.ItemChangedType.VISIBLE)

    def getText(self) -> str:
        """Returns the currently displayed text for this ROI"""
        return self.getName() if self.__text is None else self.__text

    def setText(self, text: Optional[str] = None) -> None:
        """Set the displayed text for this ROI.

        If None (the default), the ROI name is used.
        """
        if self.__text != text:
            self.__text = text
            self._updated(items.ItemChangedType.TEXT)

    def _updateText(self, text: str) -> None:
        """Update the text displayed by this ROI

        Override in subclass to custom text display
        """
        pass

    @classmethod
    def showFirstInteractionShape(cls):
        """Returns True if the shape created by the first interaction and
        managed by the plot have to be visible.

        :rtype: bool
        """
        return False

    @classmethod
    def getFirstInteractionShape(cls):
        """Returns the shape kind which will be used by the very first
        interaction with the plot.

        This interactions are hardcoded inside the plot

        :rtype: str
        """
        return cls._plotShape

    def setFirstShapePoints(self, points):
        """Initialize the ROI using the points from the first interaction.

        This interaction is constrained by the plot API and only supports few
        shapes.
        """
        raise NotImplementedError()

    def creationStarted(self):
        """Called when the ROI creation interaction was started.
        """
        pass

    def creationFinalized(self):
        """Called when the ROI creation interaction was finalized.
        """
        pass

    def _updateItemProperty(self, event, source, destination):
        """Update the item property of a destination from an item source.

        :param items.ItemChangedType event: Property type to update
        :param silx.gui.plot.items.Item source: The reference for the data
        :param event Union[Item,List[Item]] destination: The item(s) to update
        """
        if not isinstance(destination, (list, tuple)):
            destination = [destination]
        if event == items.ItemChangedType.NAME:
            value = source.getName()
            for d in destination:
                d.setName(value)
        elif event == items.ItemChangedType.EDITABLE:
            value = source.isEditable()
            for d in destination:
                d.setEditable(value)
        elif event == items.ItemChangedType.SELECTABLE:
            value = source.isSelectable()
            for d in destination:
                d._setSelectable(value)
        elif event == items.ItemChangedType.COLOR:
            value = rgba(source.getColor())
            for d in destination:
                d.setColor(value)
        elif event == items.ItemChangedType.LINE_STYLE:
            value = self.getLineStyle()
            for d in destination:
                d.setLineStyle(value)
        elif event == items.ItemChangedType.LINE_WIDTH:
            value = self.getLineWidth()
            for d in destination:
                d.setLineWidth(value)
        elif event == items.ItemChangedType.SYMBOL:
            value = self.getSymbol()
            for d in destination:
                d.setSymbol(value)
        elif event == items.ItemChangedType.SYMBOL_SIZE:
            value = self.getSymbolSize()
            for d in destination:
                d.setSymbolSize(value)
        elif event == items.ItemChangedType.VISIBLE:
            value = self.isVisible()
            for d in destination:
                d.setVisible(value)
        else:
            assert False

    def _updated(self, event=None, checkVisibility=True):
        if event == items.ItemChangedType.TEXT:
            self._updateText(self.getText())
        elif event == items.ItemChangedType.HIGHLIGHTED:
            style = self.getCurrentStyle()
            self._updatedStyle(event, style)
        else:
            styleEvents = [items.ItemChangedType.COLOR,
                           items.ItemChangedType.LINE_STYLE,
                           items.ItemChangedType.LINE_WIDTH,
                           items.ItemChangedType.SYMBOL,
                           items.ItemChangedType.SYMBOL_SIZE]
            if self.isHighlighted():
                styleEvents.append(items.ItemChangedType.HIGHLIGHTED_STYLE)

            if event in styleEvents:
                style = self.getCurrentStyle()
                self._updatedStyle(event, style)

        super(RegionOfInterest, self)._updated(event, checkVisibility)

        # Displayed text has changed, send a text event
        if event == items.ItemChangedType.NAME and self.__text is None:
            self._updated(items.ItemChangedType.TEXT, checkVisibility)

    def _updatedStyle(self, event, style):
        """Called when the current displayed style of the ROI was changed.

        :param event: The event responsible of the change of the style
        :param items.CurveStyle style: The current style
        """
        pass

    def getCurrentStyle(self):
        """Returns the current curve style.

        Curve style depends on curve highlighting

        :rtype: CurveStyle
        """
        baseColor = rgba(self.getColor())
        if isinstance(self, core.LineMixIn):
            baseLinestyle = self.getLineStyle()
            baseLinewidth = self.getLineWidth()
        else:
            baseLinestyle = self._DEFAULT_LINESTYLE
            baseLinewidth = self._DEFAULT_LINEWIDTH
        if isinstance(self, core.SymbolMixIn):
            baseSymbol = self.getSymbol()
            baseSymbolsize = self.getSymbolSize()
        else:
            baseSymbol = 'o'
            baseSymbolsize = 1

        if self.isHighlighted():
            style = self.getHighlightedStyle()
            color = style.getColor()
            linestyle = style.getLineStyle()
            linewidth = style.getLineWidth()
            symbol = style.getSymbol()
            symbolsize = style.getSymbolSize()

            return items.CurveStyle(
                color=baseColor if color is None else color,
                linestyle=baseLinestyle if linestyle is None else linestyle,
                linewidth=baseLinewidth if linewidth is None else linewidth,
                symbol=baseSymbol if symbol is None else symbol,
                symbolsize=baseSymbolsize if symbolsize is None else symbolsize)
        else:
            return items.CurveStyle(color=baseColor,
                                    linestyle=baseLinestyle,
                                    linewidth=baseLinewidth,
                                    symbol=baseSymbol,
                                    symbolsize=baseSymbolsize)

    def _editingStarted(self):
        assert self._editable is True
        self.sigEditingStarted.emit()

    def _editingFinished(self):
        self.sigEditingFinished.emit()

    def populateContextMenu(self, menu: qt.QMenu):
        """Populate a menu used as a context menu"""
        pass

class HandleBasedROI(RegionOfInterest):
    """Manage a ROI based on a set of handles"""

    def __init__(self, parent=None):
        RegionOfInterest.__init__(self, parent=parent)
        self._handles = []
        self._posOrigin = None
        self._posPrevious = None

    def addUserHandle(self, item=None):
        """
        Add a new free handle to the ROI.

        This handle do nothing. It have to be managed by the ROI
        implementing this class.

        :param Union[None,silx.gui.plot.items.Marker] item: The new marker to
            add, else None to create a default marker.
        :rtype: silx.gui.plot.items.Marker
        """
        return self.addHandle(item, role="user")

    def addLabelHandle(self, item=None):
        """
        Add a new label handle to the ROI.

        This handle is not draggable nor selectable.

        It is displayed without symbol, but it is always visible anyway
        the ROI is editable, in order to display text.

        :param Union[None,silx.gui.plot.items.Marker] item: The new marker to
            add, else None to create a default marker.
        :rtype: silx.gui.plot.items.Marker
        """
        return self.addHandle(item, role="label")

    def addTranslateHandle(self, item=None):
        """
        Add a new translate handle to the ROI.

        Dragging translate handles affect the position position of the ROI
        but not the shape itself.

        :param Union[None,silx.gui.plot.items.Marker] item: The new marker to
            add, else None to create a default marker.
        :rtype: silx.gui.plot.items.Marker
        """
        return self.addHandle(item, role="translate")

    def addHandle(self, item=None, role="default"):
        """
        Add a new handle to the ROI.

        Dragging handles while affect the position or the shape of the
        ROI.

        :param Union[None,silx.gui.plot.items.Marker] item: The new marker to
            add, else None to create a default marker.
        :rtype: silx.gui.plot.items.Marker
        """
        if item is None:
            item = items.Marker()
            color = rgba(self.getColor())
            color = self._computeHandleColor(color)
            item.setColor(color)
            if role == "default":
                item.setSymbol("s")
            elif role == "user":
                pass
            elif role == "translate":
                item.setSymbol("+")
            elif role == "label":
                item.setSymbol("")

        if role == "user":
            pass
        elif role == "label":
            item._setSelectable(False)
            item._setDraggable(False)
            item.setVisible(True)
        else:
            self.__updateEditable(item, self.isEditable(), remove=False)
            item._setSelectable(False)

        self._handles.append((item, role))
        self.addItem(item)
        return item

    def removeHandle(self, handle):
        data = [d for d in self._handles if d[0] is handle][0]
        self._handles.remove(data)
        role = data[1]
        if role not in ["user", "label"]:
            if self.isEditable():
                self.__updateEditable(handle, False)
        self.removeItem(handle)

    def getHandles(self):
        """Returns the list of handles of this HandleBasedROI.

        :rtype: List[~silx.gui.plot.items.Marker]
        """
        return tuple(data[0] for data in self._handles)

    def _updated(self, event=None, checkVisibility=True):
        """Implement Item mix-in update method by updating the plot items

        See :class:`~silx.gui.plot.items.Item._updated`
        """
        if event == items.ItemChangedType.VISIBLE:
            for item, role in self._handles:
                visible = self.isVisible()
                editionVisible = visible and self.isEditable()
                if role not in ["user", "label"]:
                    item.setVisible(editionVisible)
                else:
                    item.setVisible(visible)
        elif event == items.ItemChangedType.EDITABLE:
            for item, role in self._handles:
                editable = self.isEditable()
                if role not in ["user", "label"]:
                    self.__updateEditable(item, editable)
        super(HandleBasedROI, self)._updated(event, checkVisibility)

    def _updatedStyle(self, event, style):
        super(HandleBasedROI, self)._updatedStyle(event, style)

        # Update color of shape items in the plot
        color = rgba(self.getColor())
        handleColor = self._computeHandleColor(color)
        for item, role in self._handles:
            if role == 'user':
                pass
            elif role == 'label':
                item.setColor(color)
            else:
                item.setColor(handleColor)

    def __updateEditable(self, handle, editable, remove=True):
        # NOTE: visibility change emit a position update event
        handle.setVisible(editable and self.isVisible())
        handle._setDraggable(editable)
        if editable:
            handle.sigDragStarted.connect(self._handleEditingStarted)
            handle.sigItemChanged.connect(self._handleEditingUpdated)
            handle.sigDragFinished.connect(self._handleEditingFinished)
        else:
            if remove:
                handle.sigDragStarted.disconnect(self._handleEditingStarted)
                handle.sigItemChanged.disconnect(self._handleEditingUpdated)
                handle.sigDragFinished.disconnect(self._handleEditingFinished)

    def _handleEditingStarted(self):
        super(HandleBasedROI, self)._editingStarted()
        handle = self.sender()
        self._posOrigin = numpy.array(handle.getPosition())
        self._posPrevious = numpy.array(self._posOrigin)
        self.handleDragStarted(handle, self._posOrigin)

    def _handleEditingUpdated(self):
        if self._posOrigin is None:
            # Avoid to handle events when visibility change
            return
        handle = self.sender()
        current = numpy.array(handle.getPosition())
        self.handleDragUpdated(handle, self._posOrigin, self._posPrevious, current)
        self._posPrevious = current

    def _handleEditingFinished(self):
        handle = self.sender()
        current = numpy.array(handle.getPosition())
        self.handleDragFinished(handle, self._posOrigin, current)
        self._posPrevious = None
        self._posOrigin = None
        super(HandleBasedROI, self)._editingFinished()

    def isHandleBeingDragged(self):
        """Returns True if one of the handles is currently being dragged.

        :rtype: bool
        """
        return self._posOrigin is not None

    def handleDragStarted(self, handle, origin):
        """Called when an handler drag started"""
        pass

    def handleDragUpdated(self, handle, origin, previous, current):
        """Called when an handle drag position changed"""
        pass

    def handleDragFinished(self, handle, origin, current):
        """Called when an handle drag finished"""
        pass

    def _computeHandleColor(self, color):
        """Returns the anchor color from the base ROI color

        :param Union[numpy.array,Tuple,List]: color
        :rtype: Union[numpy.array,Tuple,List]
        """
        return color[:3] + (0.5,)


from async_scrape import Scrape
import requests
import json

from selenium.webdriver import Edge
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

url = "https://order.marstons.co.uk/"
base_dir = "C:/Users/robert.franklin/Desktop/local_projects/random/marstons"

# GET ALL RESTAURANT DATA - selenium
browser = Edge()
browser.get(url)
wait = WebDriverWait(browser, 100).until(
    EC.presence_of_all_elements_located((By.CLASS_NAME, "venues-list"))
)
elements = browser.find_elements(By.CLASS_NAME, "venue-card")
hrefs = [e.get_dom_attribute("href") for e in elements]
browser.close()
print(f"Fetched {len(hrefs)} hrefs from {url}")

def post_process_func(html, resp, *args, **kwargs):
    # Save to file
    fn = resp.url.split("/")[-1]
    content = json.loads(resp.content)
    with open(f"{base_dir}/data/raw/{fn}.json", "w") as f:
        json.dump(content, f, indent=4)

base_url = "https://api-cdn.orderbee.co.uk/venues"
urls = [base_url + href for href in hrefs]
scrape = Scrape(post_process_func=post_process_func)
print(f"Begin scrape of {len(urls)} - Example: {urls[0]}")
scrape.scrape_all(urls)


import random

def limiter(count, num):
    while count != 0:
        try:
            guess = int(input('Guess a number: '))
            count -= 1
            if guess == (random.randint(1, num)):
                print('YOU GOT IT RIGHT!')
                break
            else:
                print("\n That was Wrong!")
                if count > 1:
                    print(f'You have {count} guesses left\n')
                else:
                    print(f'You have {count} guess left\n')
        except UnboundLocalError:
            print("Variable 'guess' not defined")
        except ValueError:
            print("Invalid value, please input a number")
    else:
        print('You ran out of guessing Life')
        print('GMAE OVER!')

def easy():
    print('''	__EASY LEVEL__ You have 6 GUESSES....''')
    limiter(6, 10)

def medium():
    print('''	__MEDIUM LEVEL__ You have 4 guesses...''')
    limiter(4, 20)

def hard():
    print('''	__HARD LEVEL__ You have 3 guesses...''')
    limiter(3, 50)

def choice():
    user_choice = input('Enter your desired level: ').upper()
    if user_choice == 'EASY':
        easy()
    elif user_choice == 'MEDIUM':
        medium()
    elif user_choice == 'HARD':
        hard()
    else:
        print("Not a valid LEVEL, try again")
        choice()

print('''There are 3 levels;
    EASY,
    MEDIUM,
    HARD \n''')

choice()


from django.conf.urls import patterns, include, url

urlpatterns = patterns('django_sprinkler',
    url(r"^get_context/?", "views.get_context", name="get_context"),
    url(r"^logs/?", "views.watering_logs", name="watering_logs"),
    url(r"^toggle_valve/(\d+)?/?", "views.toggle_valve", name="toggle_valve"),
    url(r"^activate_program/(\d+)?/?", "views.activate_program", name="activate_program"),
    url(r"^set_state/(\w+)?", "views.set_state", name="set_state"),
    url(r'^$', "views.home", name="home"),
    )


'''
3. (fatores) Programa que lê um número inteiro positivo n e determina a sua decomposição
em fatores primos calculando também a multiplicidade de cada fator.
'''

def main():

    n = int(input("Digite um numero (>1): "))

    fator = 2 # primeiro fator
    while n != 1:
        # conta a multiplicidade de fator em n
        mult = 0;
        while n%fator == 0:
            n = n / fator;
            mult = mult + 1;

        # imprime a multiplicade do fator
        if mult != 0:
            print("fator %d multiplicidade %d" %(fator, mult))

        fator = fator + 1

#-------------------------------------------------------
main() # chamada da função principal


# Plotting solution of x''(t) + x(t) = 0 equation
import numpy as np
import matplotlib.pyplot as plt
import os
from io import StringIO
import pandas as pd
from find_solution import find_solution
from plot_utils import create_dir

def plot_solution(plot_dir, t_end, delta_t):
    data = find_solution(t_end=t_end, delta_t=delta_t, print_last=False)

    create_dir(plot_dir)

    if data is None:
        return

    df = pd.read_csv(StringIO(data), skipinitialspace=True)
    plt.plot(df['t'], df['x'], label='Approximation')

    exact_t = np.arange(0.0, t_end, 0.01)
    exact_x = np.cos(exact_t)

    plt.plot(exact_t, exact_x, label='Exact $x=\cos(t)$', linestyle='--')
    plt.title(r'Solution of $\ddot{x} + x = 0, x(0)=1, \dot{x}(0)=0$ for dt=' + f'{delta_t}')
    plt.xlabel('t')
    plt.ylabel(r'x')
    plt.legend()
    plt.grid()
    plt.tight_layout()
    plotfile = os.path.join(plot_dir, f"approx_vs_exact_dt_{delta_t}.pdf")
    plt.savefig(plotfile)
    plt.show()

if __name__ == '__main__':
    plot_solution(plot_dir="plots", t_end=6.28, delta_t=1)
    plot_solution(plot_dir="plots", t_end=6.28, delta_t=0.1)


import cgi
import sys
import io
import genshin.database.operation as gdo

form = cgi.FieldStorage()
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

template = """

    <meta charset="utf-8">

Deleting...

"""

def delete_character_data(name):
    gdo.delete_character(name)

def main():
    name = form.getvalue("del")
    delete_character_data(name)

    print("Content-type: text/html\n")
    print(template.format(name=name))

main()


import image

def photo_to_bw(filename):
    img=image.Image(filename)
    win=image.ImageWin(img.getWidth(),img.getHeight())
    img.draw(win)
    img.setDelay(0)
    for row in range(img.getHeight()):
        for col in range(img.getWidth()):
            p=img.getPixel(col,row)
            newvalue=(p.getRed()+p.getGreen()+p.getBlue())//3
            if newvalue>127:
                pixelvalue=255
            else:
                pixelvalue=0
            newpixel=image.Pixel(pixelvalue,pixelvalue,pixelvalue)
            img.setPixel(col,row,newpixel)
    img.draw(win)
    win.exitonclick()

photo_to_bw("luther.jpg")


#!/usr/bin/env python

# two functions "dir" and "help" when exploring modules in python.

import urllib

# function are implemented in each module by using dir function.
dir(urllib)

# read about module more using help function.
help(urllib.urlopen)

import re

find_members = []
for member in dir(re):
    if "find" in member:
        find_members.append(member)

print(sorted(find_members))


# -*- coding: utf-8 -*-
"""
Created on Mon May  7 23:31:33 2018

@author: liguo

异常数据分析
"""

from __future__ import print_function
from nets import nets_factory
from preprocessing import vgg_preprocessing
import sys
sys.path.append('../../tensorflow/models/slim/') # add slim to PYTHONPATH

import tensorflow as tf
import os
import time
import shutil
import pandas as pd

slim = tf.contrib.slim

tf.app.flags.DEFINE_integer('num_classes', 2, 'The number of classes.')
tf.app.flags.DEFINE_string('infile', '../test', 'Image file, one image per line.')
tf.app.flags.DEFINE_string('model_name', 'resnet_v1_50', 'The name of the architecture to testuate.')
tf.app.flags.DEFINE_string('preprocessing_name', None, 'The name of the preprocessing to use. If left as `None`, then the model_name flag is used.')
tf.app.flags.DEFINE_string('checkpoint_path', 'checkpoint/','The directory where the model was written to or an absolute path to a checkpoint file.')
tf.app.flags.DEFINE_integer('test_image_size', None, 'test image size.')
tf.app.flags.DEFINE_string('outliers_path', 'outliers', 'The path to save outliers images.')
FLAGS = tf.app.flags.FLAGS

model_name_to_variables = {'resnet_v1_50':'resnet_v1_50', 'vgg_16':'vgg_16'}

def main(_):
    model_variables = model_name_to_variables.get(FLAGS.model_name)
    if model_variables is None:
        tf.logging.error("Unknown model_name provided `%s`." % FLAGS.model_name)
        sys.exit(-1)

    if tf.gfile.IsDirectory(FLAGS.checkpoint_path):
        checkpoint_path = tf.train.latest_checkpoint(FLAGS.checkpoint_path)
    else:
        checkpoint_path = FLAGS.checkpoint_path

    # 读入图像、预处理模型、网络模型
    image_string = tf.placeholder(tf.string)
    image = tf.image.decode_jpeg(image_string, channels=3, try_recover_truncated=True, acceptable_fraction=0.3)
    network_fn = nets_factory.get_network_fn(FLAGS.model_name, FLAGS.num_classes, is_training=False)

    # 数据预处理
    if FLAGS.test_image_size is None:
        test_image_size = network_fn.default_image_size
    processed_image = vgg_preprocessing.preprocess_image(image, test_image_size, test_image_size, is_training=False)
    processed_images    = tf.expand_dims(processed_image, 0)

    # 获取输出
    logits, _ = network_fn(processed_images)
    probabilities = tf.nn.softmax(logits)

    # 初始化
    init_fn = slim.assign_from_checkpoint_fn(checkpoint_path, slim.get_model_variables(model_variables))
    sess = tf.Session()
    init_fn(sess)
    start_time = time.time()

    # 进行推断
    result = []
    test_images = os.listdir(FLAGS.infile)
    for test_image in test_images:
        path = os.path.join(FLAGS.infile, test_image)
        content = tf.gfile.FastGFile(path, 'rb').read()
        _logits, _prob = sess.run([logits, probabilities], feed_dict={image_string:content})
        sum_squares = _logits[0, 0] * _logits[0, 0] + _logits[0, 1] * _logits[0, 1]
        _prob = _prob[0, 0:]
        _prob = _prob[1]
        classes = 'cat' if 'cat' in test_image else 'dog'
        result.append([path, test_image, classes, sum_squares, _prob, _logits[0, 0], _logits[0, 1]])

    sess.close()

    # 将结果输出到csv文件
    path_list = []
    name_list = []
    class_list = []
    sum_squares_list = []
    prob_list = []
    logits1_list = []
    logits2_list = []
    for item in result:
        path_list.append(item[0])
        name_list.append(item[1])
        class_list.append(item[2])
        sum_squares_list.append(item[3])
        prob_list.append(item[4])
        logits1_list.append(item[5])
        logits2_list.append(item[6])
    dataframe = pd.DataFrame({'path':path_list, 'name':name_list, 'class':class_list,
                              'sum_squares':sum_squares_list, 'prob':prob_list,
                              'logits1':logits1_list, 'logits2':logits2_list})
    dataframe.to_csv("outliers.csv", index=False, sep=',')

    if not os.path.exists(FLAGS.outliers_path):
        os.makedirs(FLAGS.outliers_path)
    # 输出sum_squares最小的部分图片
    all_path = os.path.join(FLAGS.outliers_path, 'min_sum_squares')
    if not os.path.exists(all_path):
        os.makedirs(all_path)
    for i in range(min(500, len(result))):
        for j in range(i+1, len(result)):
            if result[i][3] > result[j][3]:
                temp = result[i]
                result[i] = result[j]
                result[j] = temp
        shutil.copyfile(result[i][0], os.path.join(all_path, format(i, "3d")+"_"+result[i][1]))

    # 输出cat中最难识别的部分图片
    cat_path = os.path.join(FLAGS.outliers_path, 'cat_max_logits')
    if not os.path.exists(cat_path):
        os.makedirs(cat_path)
    for i in range(min(250, len(result))):
        for j in range(i+1, len(result)):
            if (result[j][2] == 'cat') and (result[i][2] == 'dog' or result[i][4] < result[j][4]):
                temp = result[i]
                result[i] = result[j]
                result[j] = temp
        shutil.copyfile(result[i][0], os.path.join(cat_path, format(result[i][4], ".3f")+"_"+result[i][1]))

    # 输出dog中最难识别的部分图片
    dog_path = os.path.join(FLAGS.outliers_path, 'dog_min_logits')
    if not os.path.exists(dog_path):
        os.makedirs(dog_path)
    for i in range(min(250, len(result))):
        for j in range(i+1, len(result)):
            if (result[j][2] == 'dog') and (result[i][2] == 'cat' or result[i][4] > result[j][4]):
                temp = result[i]
                result[i] = result[j]
                result[j] = temp
        shutil.copyfile(result[i][0], os.path.join(dog_path, format(result[i][4], ".3f")+"_"+result[i][1]))

    print('total time cost = %.2f' %(time.time() - start_time))

if __name__ == '__main__':
    tf.app.run()


 #Exercise 1: Cats
#Instantiate three Cat objects using the code provided above.
#Outside of the class, create a function that finds the oldest cat and returns the cat.
#Print the following string: “The oldest cat is <cat_name>, and is <cat_age> years old.”. Use the function previously created.
class Cat:
    def __init__(self, cat_name, cat_age):
        self.name = cat_name
        self.age = cat_age

cat1 = Cat("Malfoy", 3)
cat2 = Cat("Fluffy", 6)
cat3 = Cat("Germy", 8)

def find_oldest_cat(*cats):
    oldest_cat = None
    for cat in cats:
        if oldest_cat is None or cat.age > oldest_cat.age:
            oldest_cat = cat
    return oldest_cat

oldest_cat = find_oldest_cat(cat1, cat2, cat3)
print(f"The oldest cat is {oldest_cat.name}, and  he is {oldest_cat.age} years old.")

# Exercise 2 : Dogs
class Dog:
    def __init__(self, name, height):
        self.name = name
        self.height = height

    def bark(self):
        print(f"{self.name} goes woof!")

    def jump(self):
        print(f"{self.name} jumps {self.height * 2} cm high!")

davids_dog = Dog("Rex", 50)
print(f"David's dog is named {davids_dog.name} and is {davids_dog.height}cm tall.")
davids_dog.bark()
davids_dog.jump()

sarahs_dog = Dog("Teacup", 20)
print(f"Sarah's dog is named {sarahs_dog.name} and is {sarahs_dog.height}cm tall.")
sarahs_dog.bark()
sarahs_dog.jump()

if davids_dog.height > sarahs_dog.height:
    print(f"{davids_dog.name} is bigger.")
else:
    print(f"{sarahs_dog.name} is bigger.")

#Exercise 3 : Who’s The Song Producer?
# a class called Song, it will show the lyrics of a song.
#Inside your class create a method called sing_me_a_song that prints each element of lyrics on its own line.
#Create an object, for example:

#stairway= Song(["There’s a lady who's sure","all that glitters is gold", "and she’s buying a stairway to heaven"])
class Song:
    def __init__(self, lyrics):
        self.lyrics = lyrics

    def sing_me_a_song(self):
        for line in self.lyrics:
            print(line)
stairway = Song(["We all live in a yellow submarine", "Yellow submarine, yellow submarine", "We all live in a yellow submarine", "Yellow submarine, yellow submarine"])
stairway.sing_me_a_song()

#Exercise 4 : Afternoon At The Zoo
class Zoo:
    def __init__(self, zoo_name):
        self.name = zoo_name
        self.animals = []

    def add_animal(self, new_animal):
        if new_animal not in self.animals:
            self.animals.append(new_animal)

    def get_animals(self):
        print("Animals in the zoo:")
        for animal in self.animals:
            print(animal)

    def sell_animal(self, animal_sold):
        if animal_sold in self.animals:
            self.animals.remove(animal_sold)

    def sort_animals(self):
        animal_dict = {}
        for animal in self.animals:
            if animal[0] not in animal_dict:
                animal_dict[animal[0]] = [animal]
            else:
                animal_dict[animal[0]].append(animal)
        sorted_animals = sorted(animal_dict.items())
        for key, value in sorted_animals:
            print(key + ": ", end="")
            print(", ".join(value))

    def get_groups(self):
        animal_dict = {}
        for animal in self.animals:
            if animal[0] not in animal_dict:
                animal_dict[animal[0]] = [animal]
            else:
                animal_dict[animal[0]].append(animal)
        for key, value in animal_dict.items():
            print(key + ": ", end="")
            print(", ".join(value))

# Create an object called ramat_gan_safari and call all the methods
ramat_gan_safari = Zoo("Ramat Gan Safari")
ramat_gan_safari.add_animal("Giraffe")
ramat_gan_safari.add_animal("Baboon")
ramat_gan_safari.add_animal("Bear")
ramat_gan_safari.add_animal("Cat")
ramat_gan_safari.add_animal("Cougar")
ramat_gan_safari.add_animal("Eel")
ramat_gan_safari.add_animal("Emu")
ramat_gan_safari.get_animals()
ramat_gan_safari.sell_animal("Eel")
ramat_gan_safari.sort_animals()
ramat_gan_safari.get_groups()


from typing import cast, Any

from aea.skills.behaviours import TickerBehaviour
from aea.helpers.search.models import Constraint, ConstraintType, Query

from packages.fetchai.protocols.oef_search.message import OefSearchMessage
from packages.fetchai.skills.tac_control.dialogues import (
    OefSearchDialogues,
)

from packages.gdp8.skills.agent_action_each_turn.strategy import BasicStrategy

DEFAULT_REGISTER_AND_SEARCH_INTERVAL = 5.0
environmentFound = False

DEFAULT_SEARCH_QUERY = {
    "search_key": "env",## is that the key of the environment ?
    "search_value": "v1",
    "constraint_type": "==",
}

class EnvSearchBehaviour(TickerBehaviour):
    """This class scaffolds a behaviour."""

    def setup(self) -> None:
        """
        Implement the setup.
        :return: None
        """

    def act(self) -> None:
        """
        Implement the act.
        :return: None
        """
        if not environmentFound:
            self._search_for_environment()

    def teardown(self) -> None:
        """
        Implement the task teardown.
        :return: None
        """

    def _search_for_environment(self) -> None:
        """
        Search for active environment (simulation controller).
        We assume that the environment is registered as a service
        (and with an attribute version = expected_version_id ## ??? do we really need to have that attribute ?)
        :return: None
        """
        ## can add a filter: close to my service if there are too many results
        service_key_filter = Constraint(
           DEFAULT_SEARCH_QUERY["search_key"],
            ConstraintType(
                DEFAULT_SEARCH_QUERY["constraint_type"],
                DEFAULT_SEARCH_QUERY["search_value"],
            ),
        )
        query = Query([service_key_filter],)
        oef_search_dialogues = cast(
            OefSearchDialogues, self.context.oef_search_dialogues
        )
        oef_search_msg, _ = oef_search_dialogues.create(
            counterparty=self.context.search_service_address,
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            query=query,
        )
        self.context.outbox.put_message(message=oef_search_msg)
        self.context.logger.info(
            "searching for environment, search_id={}".format(oef_search_msg.dialogue_reference)
        )

class AgentLogicBehaviour(TickerBehaviour):
    """Behaviour looks at if actions required in each tick:
       is there agent asking for water info? if so, tell them
       is the round done (on my end)? if so, stop
       is there enough info for making a decision? if so, do so,
       if not, might have to send message to ask for info"""

    def setup(self) -> None:
        """
        Implement the setup.

        :return: None
        """
        pass

    def act(self) -> None:

        strategy = cast(BasicStrategy, self.context.strategy)

        there_is_agent_asking_for_water_info = True
        while there_is_agent_asking_for_water_info:
            there_is_agent_asking_for_water_info = strategy.deal_with_an_agent_asking_for_water_info

        if not strategy.is_round_done:
            info_is_enough = strategy.enough_info_to_make_decision
            if info_is_enough:
                strategy.make_decision_send_to_env()
            else:
                asking_for_info = True
                while asking_for_info:
                    asking_for_info = strategy.potentially_ask_for_info

    def teardown(self) -> None:
        """
        Implement the task teardown.

        :return: None
        """
        pass


def getMoneySpent(keyboards, drives, b):
    budget_arr = []
    for keyboard in keyboards:
        if keyboards == b:
            continue
        for drive in drives:
            if drive == b:
                continue
            if (keyboard + drive) <= b:
                budget_arr.append(keyboard + drive)
    if not budget_arr:
        return -1
    else:
        return max(budget_arr)

if __name__ == '__main__':
    maxbudget = getMoneySpent([4], [5], 5)
    print(maxbudget)


""" Problem 34: Digit Factorials

https://projecteuler.net/problem=34

Goal: Find the sum of all numbers less than N that divide the sum of the factorial
of their digits (& therefore have minimum 2 digits).

Constraints: 10 <= N <= 1e5

Factorion: A natural number that equals the sum of the factorials of its digits.
The only non-single-digit factorions are: 145 and 40585.

e.g.: N = 20
      qualifying numbers = {19}
      as 1! + 9! = 362_881, which % 19 = 0
      e.g. 18 does not work as 1! + 8! = 40321, which % 18 > 0
      sum = 19
"""
from math import factorial

# pre-calculation of all digit factorials to increase performance
factorials = [factorial(x) for x in range(10)]

def sum_of_digit_factorials_HR(n: int) -> int:
    """
    HackerRank specific implementation that finds the sum of all numbers < n that
    are divisors of the sum of the factorials of their digits.
    """

    overall_total = 0
    for num in range(10, n):
        num_total = sum([factorials[int(ch)] for ch in str(num)])
        if num_total % num == 0:
            overall_total += num
    return overall_total

def sum_of_digit_factorials_PE() -> int:
    """
    Project Euler specific implementation that finds the sum of all numbers that
    are factorions.

    The numbers cannot have more than 7 digits, as 9! * 8 returns only a 7-digit
    number. 9! * 7 returns 2_540_160, so the 1st digit of the 7-digit number cannot
    be greater than 2.
    """

    overall_total = 0
    for n in range(10, 2_000_000):
        digits = [int(ch) for ch in str(n)]
        n_total = 0
        for digit in digits:
            n_total += factorials[digit]
            # prevents further unnecessary calculation
            if n_total > n:
                break
        if n_total == n:
            overall_total += n_total
    return overall_total


import torch
from torch import Tensor
from kornia.utils import one_hot
import torch.nn.functional as F
import numpy as np
from matplotlib import pyplot as plt

def reg_loss(prediction, ED, ES, device):
    # print(prediction)
    prediction_toSyn = prediction.squeeze().detach().cpu().numpy()
    y_k = synthetic_label(prediction_toSyn, ED.numpy(), ES.numpy())

    # print(prediction.squeeze())
    # print(y_k)
    # print(ED)
    # print(ES)
    # print('-----')
    mse_loss = F.mse_loss(prediction.squeeze(), y_k.to(device))
    temp_loss = ltemp(y_k, prediction_toSyn)

    loss = mse_loss + temp_loss

    return loss

def synthetic_label(prediction, ED, ES):
    y_k = []
    for k in range(len(prediction)):
        if (int(ED) < k) and (k <= int(ES)):
            y_k.append((abs((k-ES)/(ES-ED)))**3)
            # print(1)
        else:
            y_k.append((abs((k-ES)/(ES-ED)))**(1/3))
    # print(y_k)
    # plt.plot(y_k)
    # plt.savefig('y_k.png')
    return torch.from_numpy(np.array(y_k, dtype= "float32"))

def ltemp(y_k, prediction):
    Linc = linc(y_k, prediction)
    Ldec = ldec(y_k, prediction)
    ltemp = (Linc+Ldec)/2
    # print(ltemp)
    return torch.from_numpy(np.array(ltemp, dtype= "float32"))

def linc(y_k, prediction):
    Linc = 0
    for k in range(len(prediction)-1):
        if y_k[k+1] > y_k[k]:
            Linc = Linc + max(0,prediction[k]-prediction[k+1])
            # print('linc')
    return Linc/len(prediction)

def ldec(y_k, prediction):
    Ldec = 0
    for k in range(len(prediction)-1):
        if y_k[k+1] < y_k[k]:
            Ldec = Ldec + max(0,prediction[k+1]-prediction[k])
            # print('ldec')
    return Ldec/len(prediction)


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

from fealpy.mesh.uniform_mesh_2d import UniformMesh2d
from scipy.sparse.linalg import spsolve
#from ..decorator import cartesian

class MembraneOscillationPDEData: # 点击这里可以查看 FEALPy 中的代码

    def __init__(self, D=[0, 1, 0, 1], T=[0, 5]):
        """
        @brief 模型初始化函数

        @param[in] D 模型空间定义域
        @param[in] T 模型时间定义域
        """
        self._domain = D
        self._duration = T

    def domain(self):
        """
        @brief 空间区间
        """
        return self._domain

    def duration(self):
        """
        @brief 时间区间
        """
        return self._duration

    def source(self, p, t):
        """
        @brief 方程右端项

        @param[in] p numpy.ndarray, 空间点
        @param[in] t float, 时间点

        @return 0
        """
        return np.zeros_like(p[..., 0])

    def init_solution(self, p):
        """
        @brief 初值条件

        @param[in] p numpy.ndarray, 空间点
        @param[in] t float, 时间点

        @return 返回 val
        """

        x, y = p[..., 0], p[..., 1]
        val = x**2*(x+y)
        return val

    def init_solution_diff_t(self, p):
        """
         @brief 初值条件的导数

         @param[in] p numpy.ndarray, 空间点
        """
        return np.zeros_like(p[..., 0])

    #@cartesian
    def dirichlet(self, p, t):
        """
        @brief Dirichlet 边界条件

        @param[in] p numpy.ndarray, 空间点
        @param[in] t float, 时间点

        @return 边界条件函数值
        """
        return np.zeros_like(p[..., 0])

pde = MembraneOscillationPDEData()

# 空间离散
domain = pde.domain()
nx = 100
ny = 100
hx = (domain[1] - domain[0])/nx
hy = (domain[3] - domain[2])/ny
mesh = UniformMesh2d([0, nx, 0, ny], h=(hx, hy), origin=(domain[0], domain[2]))

# 时间离散
duration = pde.duration()
nt = 1000
tau = (duration[1] - duration[0])/nt

# 准备初值
uh0 = mesh.interpolate(pde.init_solution, 'node') # （nx+1, ny+1)
vh0 = mesh.interpolate(pde.init_solution_diff_t, 'node') # (nx+1, ny+1)
uh1 = mesh.function('node') # (nx+1, ny+1)

def advance_explicit(n, *frags):
    """
    @brief 时间步进为显格式

    @param[in] n int, 表示第 n 个时间步
    """
    t = duration[0] + n*tau
    if n == 0:
        return uh0, t
    elif n == 1:
        rx = tau/hx
        ry = tau/hy
        uh1[1:-1, 1:-1] = 0.5*rx**2*(uh0[0:-2, 1:-1] + uh0[2:, 1:-1]) + \
                0.5*ry**2*(uh0[1:-1, 0:-2] + uh0[1:-1, 2:]) + \
                (1 - rx**2 - ry**2)*uh0[1:-1, 1:-1] + tau*vh0[1:-1, 1:-1]
        gD = lambda p: pde.dirichlet(p, t)
        mesh.update_dirichlet_bc(gD, uh1)
        return uh1, t
    else:
        A = mesh.wave_operator_explicit(tau)
        source = lambda p: pde.source(p, t + tau)
        f = mesh.interpolate(source, intertype='node')
        f *= tau**2
        uh2 = A@uh1.flat - uh0.flat

        uh0[:] = uh1[:]
        uh1.flat = uh2

        gD = lambda p: pde.dirichlet(p, t + tau)
        mesh.update_dirichlet_bc(gD, uh1)

        #solution = lambda p: pde.solution(p, t + tau)
        #e = mesh.error(solution, uh1, errortype='max')
        #print(f"the max error is {e}")

        return uh1, t
def advance_implicit(n, *frags):
    """
    @brief 时间步进为隐格式

    @param[in] n int, 表示第 n 个时间步
    """
    t = duration[0] + n*tau
    if n == 0:
        return uh0, t
    elif n == 1:
        rx = tau/hx
        ry = tau/hy
        uh1[1:-1, 1:-1] = 0.5*rx**2*(uh0[0:-2, 1:-1] + uh0[2:, 1:-1]) + \
                0.5*ry**2*(uh0[1:-1, 0:-2] + uh0[1:-1, 2:]) + \
                (1 - rx**2 - ry**2)*uh0[1:-1, 1:-1] + tau*vh0[1:-1, 1:-1]
        gD = lambda p: pde.dirichlet(p, t)
        mesh.update_dirichlet_bc(gD, uh1)
        return uh1, t
    else:
        A0, A1, A2 = mesh.wave_operator_implicit(tau)
        source = lambda p: pde.source(p, t + tau)
        f = mesh.interpolate(source, intertype='node')
        f *= tau**2
        f.flat += A1@uh1.flat + A2@uh0.flat

        uh0[:] = uh1[:]
        gD = lambda p: pde.dirichlet(p, t + tau)
        A0, f = mesh.apply_dirichlet_bc(gD, A0, f)
        uh1.flat = spsolve(A0, f)

        #solution = lambda p: pde.solution(p, t + tau)
        #e = mesh.error(solution, uh1, errortype='max')
        #print(f"the max error is {e}")

        return uh1, t
"""
box = [0, 1, 0, 1, 0, 5]
fig, axes = plt.subplots()
mesh.show_animation(fig, axes, box, advance_explicit,
                    fname='explicit.mp4', plot_type='imshow', frames=nt+1)
plt.show()
"""
box = [0, 1, 0, 1, -2, 2]
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
axes = fig.add_subplot(111, projection='3d')
mesh.show_animation(fig, axes, box, advance_explicit,
                    fname='explicit.mp4', plot_type='surface', frames=nt+1)
plt.show()
"""
box = [0, 1, 0, 1, -1, 1]
fig, axes = plt.subplots()
mesh.show_animation(fig, axes, box, advance_implicit,fname='implicit.mp4', plot_type='imshow', frames=nt+1)
plt.show()

box = [0, 1, 0, 1, -2.0, 2.0]

fig = plt.figure()
axes = fig.add_subplot(111, projection='3d')
mesh.show_animation(fig, axes, box, advance_implicit,fname='implicit.mp4', plot_type='surface', frames=nt+1)
plt.show()
"""


import matplotlib.pyplot as plt
from astropy.io import fits
from astropy.visualization import make_lupton_rgb
from matplotlib.colors import LogNorm
from astropy.wcs import WCS
import numpy as np

db_open = [fits.open('frame-g-006793-1-0130.fits'),
           fits.open('frame-i-006793-1-0130.fits'),
           fits.open('frame-r-006793-1-0130.fits'),
           fits.open('frame-u-006793-1-0130.fits'),
           fits.open('frame-z-006793-1-0130.fits')]

class Glx(object):

    def __init__(self, d):
        self.g = d[0]
        self.i = d[1]
        self.r = d[2]
        self.u = d[3]
        self.z = d[4]

    def img_rgb(self, nome='Galáxia'):
        ## rgb = make_lupton_rgb(self.i[0].data[8:1396,::], self.r[0].data[0:1388,::], self.g[0].data[12:1400,::], stretch=1, Q=10)
        rgb = make_lupton_rgb(self.i[0].data, self.g[0].data, self.u[0].data, stretch=1, Q=10)
        plt.imshow(rgb, origin='lower')
        plt.title(nome)
        plt.show()

    def Log_Norm(self):
        plt.imshow(self.r[0].data, cmap='gray', origin='lower', norm=LogNorm())
        plt.show()

    def Img_1_cor(self):
        fig, ((ax0, ax1, ax2), (ax3, ax4, ax5)) = plt.subplots(nrows=2, ncols=3, sharex=True, figsize=(18, 8))

        ax0.imshow(self.i[0].data, origin='lower', vmin=0.0001, vmax=0.6, cmap='RdBu')
        ax0.set_title('Filtro I')
        ax1.imshow(self.g[0].data, origin='lower', vmin=0.0001, vmax=0.6, cmap='RdBu')
        ax1.set_title('Filtro G')
        ax3.imshow(self.r[0].data, origin='lower', vmin=0.0001, vmax=0.6, cmap='RdBu')
        ax3.set_title('Filtro R')
        ax4.imshow(self.z[0].data, origin='lower', vmin=0.0001, vmax=0.6, cmap='RdBu')
        ax4.set_title('Filtro Z')
        ax5.imshow(self.u[0].data, origin='lower', vmin=0.0001, vmax=0.6, cmap='RdBu')
        ax5.set_title('Filtro U')

        fig.delaxes(ax=ax2)

        plt.show()

    def pl(self):
        g = self.g[0].data
        print(g.shape)
        print(g.min())
        print(g.max())
        print(g.mean())
        print(np.percentile(g.flatten(),3))
        print(np.percentile(g.flatten(), 97))

        fig, (ax0, ax1) = plt.subplots(nrows=1, ncols=2, sharex=True, figsize=(18, 8))
        ax0.imshow(g, vmin=0.1, vmax=6, origin='lower', cmap='viridis')
        ax1.imshow(g, vmin=np.percentile(g.flatten(),5), vmax=np.percentile(g.flatten(), 95), origin='lower', cmap='viridis')
        plt.show()

def main(db):
    galaxia = Glx(db)
    galaxia.pl()

if __name__ == '__main__':
    main(db=db_open)


#!/usr/bin/env python
# coding: utf-8

# # Import Library

# In[387]:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from glob import glob
from sklearn.metrics import mean_absolute_error
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import accuracy_score , classification_report
import pandas_profiling
from category_encoders import OneHotEncoder
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import cross_validate

# In[388]:

t=pd.read_csv("test.csv")
t.info()

# # Import Data

# In[389]:

def wrangel(path):
    # read data
    df=pd.read_csv(path)
    #extract the social name
    df["title"]=df["Name"].str.extract("([A-Za-z]+)\.",expand=False)
    #convert title categorcal data
    df.loc[df["title"]=="Mr"   , "title"]   = 0
    df.loc[df["title"]=="Miss"   , "title"]   = 1
    df.loc[df["title"]=="Mrs"   , "title"]   = 2
    df.loc[df["title"]=="Master"   , "title"]   = 3
    conditions = (df["title"] == 'Ms') | (df["title"] == 'Col') | (df["title"] == 'Rev') | (df["title"] == 'Dr') | (df["title"] == 'Dona')
    df.loc[conditions, "title"] = 4
    #fill NAN Value of Fare Accorging to Social Name
    df["Fare"].fillna(df.groupby("Pclass")["Fare"].transform("median"),inplace=True)
    #fill NAN Value of Age Accorging to Social Name
    df["Age"].fillna(df.groupby("title")["Age"].transform("median"),inplace=True)
    #fill NAN Value of Embarked Accorging to Median
    df["Embarked"]=df["Embarked"].fillna("S")
    #remove nan columns
    drop=[]
    drop.append("Cabin")
    drop.append("Name")
    drop.append("Ticket")
    drop.append("title")
    df.drop(columns=drop,inplace=True)
    #convert Sex categorcal data
    df.loc[df["Sex"]=="male"     , "Sex"]   = 0         # Male   ---> 0
    df.loc[df["Sex"]=="female"   , "Sex"]   = 1         # Female ---> 1
    #convert Embarked categorcal data
    df.loc[df["Embarked"]=="S"   , "Embarked"]   = 0    # S ---> 1
    df.loc[df["Embarked"]=="C"   , "Embarked"]   = 1    # C ---> 2
    df.loc[df["Embarked"]=="Q"   , "Embarked"]   = 2    # Q ---> 3

    return df

# In[390]:

test  =  wrangel("test.csv")
df    =  wrangel("train.csv")

# In[340]:

df.head()

# In[341]:

df.info()

# In[391]:

pandas_profiling.ProfileReport(df)

# In[343]:

df["Embarked"].value_counts()

# In[344]:

test.info()

# In[352]:

test.isnull().sum()

# # Exploer Data

# In[353]:

print("Survive :",(df["Survived"]==1).sum())
print("Deceased :",(df["Survived"]==0).sum())

# In[354]:

df.describe()

# In[355]:

# Create the pie chart
values=df["Survived"].value_counts()
label=["Deceased ","Survive "]
plt.pie(values, labels=label,autopct='%1.1f%%')
# Add a title
plt.title('Distribution of Survived')
# Display the chart
plt.show()

# In[356]:

plt.hist(df["Parch"],bins=5, edgecolor='black');
plt.xlabel('Values')
plt.ylabel('Frequancy')
plt.title("Values of Parch")
plt.show();

# In[357]:

survive=df[df["Survived"]==1]["SibSp"].value_counts()
death=df[df["Survived"]==0]["SibSp"].value_counts()
dx=pd.DataFrame([survive,death],index=["survive","death"])
dx.plot(kind="bar");
plt.title("Survive of SibSp ");

# In[358]:

survive=df[df["Survived"]==1]["Pclass"].value_counts()
death=df[df["Survived"]==0]["Pclass"].value_counts()
dx=pd.DataFrame([survive,death],index=["survive","death"])
dx.plot(kind="bar");
plt.title("Survive of Pclass ");

# In[359]:

class1=df[df["Pclass"]==1]["Embarked"].value_counts()
class2=df[df["Pclass"]==2]["Embarked"].value_counts()
class3=df[df["Pclass"]==3]["Embarked"].value_counts()
dx=pd.DataFrame([class1,class2,class3],index=["class 1","class 2","class 3"])
dx.plot(kind="bar",stacked=True);
plt.title("Survive of Pclass ");

# We Found that Embarked from S in 1st & 2nd & 3rd Class

# In[360]:

# Create the pie chart
values=df["Sex"].value_counts()
label=["male","female"]
plt.pie(values, labels=label,autopct='%1.1f%%')
# Add a title
plt.title('Distribution of Survived')
# Display the chart
plt.show()

# In[361]:

survive = df[df["Survived"]==1]["Sex"].value_counts()
death   = df[df["Survived"]==0]["Sex"].value_counts()
dx      = pd.DataFrame([survive,death],index=["survive","death"])
dx=dx.rename(columns={0:"male",1:"female"})
dx.plot(kind="bar")
plt.legend()
plt.title("Survive of Sex");

# In[ ]:

# In[362]:

corrleation = df.drop(columns="Survived").corr()
sns.heatmap(corrleation)

# # Split Data

# In[ ]:

# In[363]:

df

# In[364]:

target="Survived"
y = df[target]
X = df.drop(columns=target)
x_train , x_test , y_train , y_test = train_test_split(X,y,test_size=0.2,random_state=42)
print("X_train shape:", x_train.shape)
print("y_train shape:", y_train.shape)
print("X_test shape:", x_test.shape)
print("y_test shape:", y_test.shape)

# # Baseline

# In[365]:

y_train_mean = y_train.mean()
print ("Baseline :",round(y_train_mean,2))

# # Logestic Regression

# # Itrate

# In[366]:

log_model = LogisticRegression(max_iter=10000)

# In[367]:

log_model.fit(x_train,y_train)

# #

# # Evaluate

# In[368]:

accuracy=classification_report(y_test,log_model.predict(x_test))
print(accuracy)

# In[369]:

acc_test = accuracy_score(y_test,log_model.predict(x_test))
acc_test = accuracy_score(y_test,log_model.predict(x_test))
acc_train= accuracy_score(y_train,log_model.predict(x_train))
print("Accuracy test:",round(acc_test,2))
print("Accuracy train:",round(acc_train,2))

# # KNN Classfier

# In[370]:

knn= KNeighborsClassifier(n_neighbors=13)
knn.fit(x_train,y_train)

# In[371]:

accuracy=classification_report(y_test,knn.predict(x_test))
print(accuracy)

# In[372]:

scoring="accuracy"
score = cross_validate(knn , x_train.drop(columns=["PassengerId"],axis=1),y_train,cv=k_fold, n_jobs=1,scoring=scoring)
print(score['test_score'])

# In[373]:

print("Accuracy :",round(np.mean(score['test_score']),2))

# # Descion Tree

# In[374]:

# Create a decision tree classifier
dec_tree=  DecisionTreeClassifier()
# Train the classifier
dec_tree.fit(x_train, y_train)

# In[375]:

accuracy=classification_report(y_test,dec_tree.predict(x_test))
print(accuracy)

# In[376]:

acc_test = accuracy_score(y_test,dec_tree.predict(x_test))
print("Accuracy test:",round(acc_test,2))

# In[377]:

scoring="accuracy"
score = cross_validate(dec_tree , x_train.drop(columns=["PassengerId"],axis=1),y_train,cv=k_fold, n_jobs=1,scoring=scoring)
print("Accuracy :",round(np.mean(score['test_score']),2))

# # Random Forest

# In[378]:

# Create a Random Forest classifier
rf_classifier = RandomForestClassifier()
# Train the classifier
rf_classifier.fit(x_train, y_train)

# In[379]:

# Calculate the accuracy
accuracy = accuracy_score(y_test, rf_classifier.predict(x_test))
print("Accuracy:", round(accuracy,2))

# In[380]:

scoring="accuracy"
score = cross_validate(rf_classifier , x_train.drop(columns=["PassengerId"],axis=1),y_train, n_jobs=1,scoring=scoring)
print("Accuracy :",round(np.mean(score['test_score']),1))

# # Naive Bayes

# In[381]:

nav= GaussianNB()
# Train the classifier
nav.fit(x_train, y_train)

# In[382]:

# Calculate the accuracy
accuracy = accuracy_score(y_test, nav.predict(x_test))
print("Accuracy:", round(accuracy,2))

# In[383]:

scoring="accuracy"
score = cross_validate(nav , x_train.drop(columns=["PassengerId"],axis=1),y_train, n_jobs=1,scoring=scoring)
print("Accuracy :",round(np.mean(score['test_score']),2))

# # Communicat

# The best model is Random Forest with Accuracy : 82

# In[384]:

pred_test=rf_classifier.predict(test)

data = pd.DataFrame({'PassengerId': test["PassengerId"], 'Survived': pred_test})

# In[385]:

data.head()

# In[386]:

data.to_csv(r'D:\projects\gender_submission.csv', index=False)

# In[ ]:


'''
You are given an integer n. There is an undirected graph with n nodes, numbered from 0 to n - 1. You are given a 2D integer array edges where edges[i] = [ai, bi] denotes that there exists an undirected edge connecting nodes ai and bi.

Return the number of pairs of different nodes that are unreachable from each other.

Example 1:

Input: n = 3, edges = [[0,1],[0,2],[1,2]]
Output: 0
Explanation: There are no pairs of nodes that are unreachable from each other. Therefore, we return 0.
Example 2:

Input: n = 7, edges = [[0,2],[0,5],[2,4],[1,6],[5,4]]
Output: 14
Explanation: There are 14 pairs of nodes that are unreachable from each other:
[[0,1],[0,3],[0,6],[1,2],[1,3],[1,4],[1,5],[2,3],[2,6],[3,4],[3,5],[3,6],[4,6],[5,6]].
Therefore, we return 14.

Constraints:

1 <= n <= 105
0 <= edges.length <= 2 * 105
edges[i].length == 2
0 <= ai, bi < n
ai != bi
There are no repeated edges.
'''

class Solution:
    def countPairs(self, n: int, edges: List[List[int]]) -> int:
        adj = defaultdict(list)
        for edge in edges:
            adj[edge[0]].append(edge[1])
            adj[edge[1]].append(edge[0])
        num_pairs = 0
        size = 0
        remaining = n
        visit = [False] * n
        for i in range(n):
            if not visit[i]:
                size = self.dfs(i, adj, visit)
                num_pairs += size * (remaining - size)
                remaining -= size
        return num_pairs

    def dfs(self, node, adj, visit):
        count = 1
        visit[node] = True
        if node not in adj:
            return count
        for nei in adj[node]:
            if not visit[nei]:
                count += self.dfs(nei, adj, visit)
        return count


#Vertex class
class Vertex:
    def __init__(self, key):
        self.id = key
        self.connected_to = {}
    #Add neighbors
    def add_neighbor(self, nbr, weight=0):
        self.connected_to[nbr] = weight

    #return all keys in connected to dict
    def get_connections(self):
        self.connected_to.keys()

    #Return id
    def get_id(self):
        return self.id

    #Return weight
    def get_weight(self, nbr):
        return self.connected_to[nbr]

    def __str__(self):
        return str(self.id) + ' connected to: ' + str([x.id for x in self.connected_to])

#Graph class, represented as an adjacency list
class Graph:

    def __init__(self):
        self.vert_list = {}
        self.num_vert = 0

    #Add vertex at index key
    def add_vertex(self, key):
        self.num_vert += 1
        new_vertex = Vertex(key)
        self.vert_list[key] = new_vertex
        return new_vertex

   #Return vertex at index n
    def get_vertex(self, n):
        #Looks through keys in vert_list
        if n in self.vert_list:
            return self.vert_list[n]
        else:
            return None

    #Add an edge between two vertices
    def add_edge(self, f, t, cost=0):
        #f = from vertex
        #t = to
        #cost = weight
        if f not in self.vert_list:
            nv = self.add_vertex(f)
        if t not in self.vert_list:
            nv = self.add_vertex(t)

        self.vert_list[f].add_neighbor(self.vert_list[t], cost)

    #Reutns all vertices
    def get_vertices(self):
        return self.vert_list.keys()

    #make an iterattable object
    def __iter__(self):
        return iter(self.vert_list.values())

    def __contains__(self, n):
        return n in self.vert_list

#Rivalry class
class Rivalry:
    def __init__(self, boy1, boy2):
        self.boy1 = boy1
        self.boy2 = boy2

    @staticmethod
    def fromList(le):
        if len(le) !=2:
            raise Exception('Invalid boy line entry')
        return Rivalry(le[0], le[1])

    def __str__(self):
        return "Rivalry(boy1: {}, boy2: {})".format(self.boy1, self.boy2)

    def __repr__(self):
        return self.__str__()

#Boy class
class Boy:
    def __init__(self, index, boy):
        self.index = index
        self.boy = boy

    @staticmethod
    def fromList(le):
        if len(le) !=2:
            raise Exception('Invalid boy')
        return Boy(le[0], le[1])

    def __str__(self):
        return "Rivalry(index: {}, boy: {})".format(self.index, self.boy)

    def __repr__(self):
        return self.__str__()

def make_graph(boys, rivalries):
  #Add each boy as a vertex
    g = Graph()
    for i in range(len(boys)):
        g.add_vertex(boys[i])
    #Add each rivalry as an edge, using boy1 as a 'from' vertex and boy2 as a 'to' vertex
    for i in range(len(rivalries)):
        boy1 = rivalries[i].boy1
        boy2 = rivalries[i].boy2
        g.add_edge(boy1, boy2)

    return g

def bfs(graph_to_search, start, end):
    queue = [[start]]
    visited = set()
    while queue:
        # Gets the first path in the queue
        path = queue.pop(0)

        # Gets the last node in the path
        vertex = path[-1]

        # Checks if we got to the end
        if vertex == end:
            return path
        # We check if the current node is already in the visited nodes set in order not to recheck it
        elif vertex not in visited:
            # enumerate all adjacent nodes, construct a new path and push it into the queue
            neighbors = vertex.connected_to
            #for current_neighbour in graph_to_search.get_vertex(vertex).get_connections():
            for current_neighbour in  neighbors:
                new_path = list(path)
                new_path.append(current_neighbour)
                queue.append(new_path)

            # Mark the vertex as visited
            visited.add(vertex)

#Checks each edge to see that it goes between a Babyface and Heel
def edge_check(boys, rivalries, babyfaces, heels):
    valid_edges = False
    for rivalry in rivalries:
        if rivalry.boy1 in babyfaces:
            if rivalry.boy2 in heels:
            #then this connection is valid
                valid_edges = True
            else:
                valid_edges = False
        elif rivalry.boy1 in heels:
            if rivalry.boy2 in babyfaces:
                valid_edges = True
            else:
                valid_edges = False
    return valid_edges

#*****************************
#Get info from text file
lines = []
with open('boys.txt', 'r') as file:
    line = file.readline()
    while line:
        #Stick current line into new list
        cur_line = line.split()
        if len(cur_line) > 0:
            lines.append(cur_line)
        line = file.readline()

#Now that we have all the data, we can parse and format it
if len(lines[0]) != 1:
    raise Exception('invalid formatting for number of boys on line 1')
#first line
num_boys = int(lines[0][0])
# print("Number of boys:")
# print(num_boys)
boys = [boy[0] for boy in lines[1:(num_boys+1)]]

#From the number of rivalries to the end
#print("Rivalries:")
rivalries = lines[(2+num_boys):]
# print(rivalries)

# print("Boys")
# print(boys)

#Make a list of Rivalry objects
#rivalries = [Rivalry.fromList(riv) for riv in rivalries]

#Test data
#boys = ['Ace', 'Duke', 'Jax', 'Biggs', 'Stone']
rivalries = [['Ace', 'Duke'], ['Ace', 'Biggs'], ['Jax', 'Duke'], ['Stone', 'Biggs'], ['Stone', 'Duke'], ['Biggs', 'Jax']]

#print(rivalries)
rivalries = [Rivalry.fromList(riv) for riv in rivalries]

#Make the graph
g = make_graph(boys, rivalries)

#Get set of distances
babyfaces=[]
heels=[]
start = g.get_vertex(boys[0])
babyfaces.append(start.id)
#d = 0
for vertex in g:
    target = g.get_vertex(vertex.id)
    #Call bfs on this vertex to get its distance from Start
    if start!=target:
        #d +=1
        path = bfs(g, start, target)
        if path is not None:
            d = len(path)
        else:
            d = -1
        #print"Dist from %s to %s", (start.id, target.id)
        if d %2 == 0:
             babyfaces.append(vertex.id)
        else:
             heels.append(vertex.id)
#Check that edges go bewtween babyfaces and heels and not two of the same group
valid_edges = edge_check(boys, rivalries, babyfaces, heels)
if valid_edges == True:
    print("This is valid!")
    print("babyfaces:")
    print(babyfaces)
    print("Heels")
    print(heels)
else:
    print("No, it is not possible to designate this list of boys as one or the other with the given rivalries")