import copy
from components.episode_buffer import EpisodeBatch
from modules.mixers.vdn import VDNMixer
from modules.mixers.qmix import QMixer
from modules.mixers.qmix_multi import QMixerMulti

import torch as th
from torch.optim import RMSprop

class QLearnerMulti:
    def __init__(self, mac, scheme, logger, args):
        self.args = args
        self.n_agents_team1 = args.n_agents_team1
        self.n_agents_team2 = args.n_agents_team2
        self.mac = mac
        self.logger = logger
        self.params = [list(param) for param in mac.parameters()]

        self.last_target_update_episode = 0

        self.mixer = None
        if args.mixer is not None:
            if args.mixer == "vdn":
                self.mixer = VDNMixer()
                self.params += list(self.mixer.parameters())
                self.target_mixer = copy.deepcopy(self.mixer)
            elif args.mixer == "qmix":
                self.mixer = QMixer(args)
                self.params += list(self.mixer.parameters())
                self.target_mixer = copy.deepcopy(self.mixer)
            elif args.mixer == "qmix_multi":
                self.mixer = [
                    QMixerMulti(args, self.n_agents_team1),
                    QMixerMulti(args, self.n_agents_team2)
                ]
                for idx, mixer in enumerate(self.mixer):
                    self.params[idx] += list(mixer.parameters())
                self.target_mixer = copy.deepcopy(self.mixer)
            else:
                raise ValueError("Mixer {} not recognised.".format(args.mixer))

        self.optimiser = [
            RMSprop(params=param, lr=args.lr, alpha=args.optim_alpha,
                    eps=args.optim_eps) for param in self.params]

        # a little wasteful to deepcopy (e.g. duplicates action selector),
        # but should work for any MAC
        self.target_mac = copy.deepcopy(mac)

        self.log_stats_t = -self.args.learner_log_interval - 1

    def train(self, batch: EpisodeBatch, t_env: int, episode_num: int):
        # Get the relevant quantities
        rewards = batch["reward"][:, :-1]

        actions = batch["actions"][:, :-1]
        terminated = batch["terminated"][:, :-1].float()
        mask = batch["filled"][:, :-1].float()
        mask[:, 1:] = mask[:, 1:] * (1 - terminated[:, :-1])
        avail_actions = batch["avail_actions"]

        # TODO: automate that
        rewards = [rewards[:, :, :self.n_agents_team1],
                   rewards[:, :, self.n_agents_team1:]]
        actions = [actions[:, :, :self.n_agents_team1],
                   actions[:, :, self.n_agents_team1:]]
        avail_actions = [avail_actions[:, :, :self.n_agents_team1],
                         avail_actions[:, :, self.n_agents_team1:]]

        # Calculate estimated Q-Values
        mac_out = [[] for _ in rewards]

        self.mac.init_hidden(batch.batch_size)
        for t in range(batch.max_seq_length):
            agent_outs_array = self.mac.forward(batch, t=t)
            for idx, _ in enumerate(rewards):
                mac_out[idx].append(agent_outs_array[idx])

        mac_out = [
            th.stack(mac_out_team_, dim=1)
            for mac_out_team_ in mac_out
        ]  # concat over time

        # Pick the Q-Values for the actions taken by each aent

        chosen_action_qvals = []
        for idx, mac_out_ in enumerate(mac_out):
            # Remove the last dim
            chosen_action_qvals.append(
                th.gather(mac_out_[:, :-1], dim=3, index=actions[idx])
                    .squeeze(3))

        # Calculate the Q-Values necessary for the target
        target_mac_out = [[] for _ in mac_out]

        self.target_mac.init_hidden(batch.batch_size)
        for t in range(batch.max_seq_length):
            target_agent_outs_array = self.target_mac.forward(batch, t=t)
            for idx, _ in enumerate(rewards):
                target_mac_out[idx].append(target_agent_outs_array[idx])

        # We don't need the first timesteps Q-Value estimate
        # for calculating targets
        target_mac_out = [
            th.stack(target_mac_out_team_[1:], dim=1)
            for target_mac_out_team_ in target_mac_out
        ]

        # Mask out unavailable actions
        for idx, target_mac_out_ in enumerate(target_mac_out):
            target_mac_out[idx][avail_actions[idx][:, 1:] == 0] = -9999999

        # Max over target Q-Values
        if self.args.double_q:
            # Get actions that maximise live Q (for double q-learning)
            for idx, mac_out_ in enumerate(mac_out):
                mac_out[idx][
                    avail_actions[idx] == 0
                    ] = -9999999

            cur_max_actions = [
                mac_out_[:, 1:].max(dim=3, keepdim=True)[1]
                for mac_out_ in mac_out
            ]

            target_max_qvals = [
                th.gather(target_mac_out_team_, 3,
                          cur_max_actions_team_).squeeze(3)
                for target_mac_out_team_, cur_max_actions_team_ in
                zip(target_mac_out, cur_max_actions)
            ]
        else:
            target_max_qvals = [
                target_mac_out_team_.max(dim=3)[0]
                for target_mac_out_team_ in target_mac_out
            ]

        # Mix
        if self.mixer is not None:
            if type(self.mixer) is list:
                chosen_action_qvals = [
                    mixer(chosen_action_qvals_, batch["state"][:, :-1])
                    for mixer, chosen_action_qvals_ in
                    zip(self.mixer, chosen_action_qvals)
                ]
                target_max_qvals = [
                    target_mixer(target_max_qvals_, batch["state"][:, 1:])
                    for target_mixer, target_max_qvals_ in
                    zip(self.target_mixer, target_max_qvals)
                ]
            else:
                chosen_action_qvals = self.mixer(chosen_action_qvals,
                                                 batch["state"][:, :-1])
                target_max_qvals = self.target_mixer(target_max_qvals,
                                                     batch["state"][:, 1:])

        # Calculate 1-step Q-Learning targets
        targets = [
            rewards_ + self.args.gamma * (1 - terminated) * target_max_qvals_
            for rewards_, target_max_qvals_ in
            zip(rewards, target_max_qvals)
        ]

        # Td-error

        td_error = [
            (chosen_action_qvals_ - targets_.detach())
            for chosen_action_qvals_, targets_ in
            zip(chosen_action_qvals, targets)
        ]

        mask = [
            mask.expand_as(td_error_)
            for idx, td_error_ in enumerate(td_error)
        ]

        # 0-out the targets that came from padded data
        masked_td_error = [
            td_error_ * mask_
            for td_error_, mask_ in zip(td_error, mask)
        ]

        # Normal L2 loss, take mean over actual data
        loss = [
            (masked_td_error_ ** 2).sum() / mask_.sum()
            for masked_td_error_, mask_ in zip(masked_td_error, mask)
        ]

        # Optimise
        grad_norm = []
        for idx, optimiser in enumerate(self.optimiser):
            optimiser.zero_grad()
            loss[idx].backward()
            grad_norm.append(th.nn.utils.clip_grad_norm_(self.params[idx],
                                                         self.args.grad_norm_clip))
            optimiser.step()

        if (episode_num - self.last_target_update_episode) \
                / self.args.target_update_interval >= 1.0:
            self._update_targets()
            self.last_target_update_episode = episode_num

        if t_env - self.log_stats_t >= self.args.learner_log_interval:
            for idx, loss_ in enumerate(loss):
                self.logger.log_stat("loss_" + str(idx), loss_.item(), t_env)

                self.logger.log_stat("grad_norm_" + str(idx), grad_norm[idx],
                                     t_env)

                mask_elems = mask[idx].sum().item()
                self.logger.log_stat("td_error_abs_" + str(idx), (
                        masked_td_error[idx].abs().sum().item() / mask_elems),
                                     t_env)
                self.logger.log_stat("q_taken_mean_" + str(idx),
                                     (chosen_action_qvals[idx] * mask[
                                         idx]).sum().item() / (
                                             mask_elems * self.args.n_agents),
                                     t_env)
                self.logger.log_stat("target_mean_" + str(idx),
                                     (targets[idx] * mask[
                                         idx]).sum().item() / (
                                             mask_elems * self.args.n_agents),
                                     t_env)
                self.log_stats_t = t_env

    def _update_targets(self):
        self.target_mac.load_state(self.mac)
        if self.mixer is not None:
            for idx, _ in enumerate(self.target_mixer):
                self.target_mixer[idx].load_state_dict(
                    self.mixer[idx].state_dict())
        self.logger.console_logger.info("Updated target network")

    def cuda(self):
        self.mac.cuda()
        self.target_mac.cuda()
        if self.mixer is not None:
            for mixer in self.mixer:
                mixer.cuda()
            for target_mixer in self.target_mixer:
                target_mixer.cuda()

    def save_models(self, path):
        self.mac.save_models(path)
        for idx, optimiser in enumerate(self.optimiser):
            if self.mixer is not None:
                th.save(self.mixer[idx].state_dict(),
                        "{}/mixer".format(path) + str(idx) + ".th")
            th.save(optimiser.state_dict(),
                    "{}/opt".format(path) + str(idx) + ".th")

    def load_models(self, path):
        self.mac.load_models(path)
        # Not quite right but I don't want to save target networks
        self.target_mac.load_models(path)
        if self.mixer is not None:
            for idx, _ in enumerate(self.mixer):
                self.mixer[idx].load_state_dict(
                    th.load("{}/mixer".format(path) + str(idx) + ".th",
                            map_location=lambda storage,
                                                loc: storage))
        for idx, _ in enumerate(self.optimiser):
            self.optimiser[idx].load_state_dict(
                th.load("{}/opt".format(path) + str(idx) + ".th",
                        map_location=lambda storage,
                                            loc: storage))


"""
Copyright (c) 2018 Mickaël "Kilawyn" Walter

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""

import os
import html
from datetime import datetime

from lib.console import Console
from lib.utils import get_by_id

class Exporter:
    """
    Utility functions to export data
    """

    @staticmethod
    def export_posts(posts, folder, tags_list=None, categories_list=None,
    users_list=None):
        """
        Exports posts as HTML to specified export folder
        param posts: the posts to export
        param folder: the export folder
        param tags_list: a list of tags to associate them with tag ids
        param categories_list: a list of categories to associate them with
        category ids
        param user_list: a list of users to associate them with author id
        """
        exported_posts = 0

        date_format = "%Y-%m-%dT%H:%M:%S-%Z"

        if not os.path.isdir(folder):
            os.makedirs(folder)
        for post in posts:
            post_file = None
            if 'slug' in post.keys():
                post_file = open(os.path.join(folder, post['slug'])+".html",
                "wt")
            else:
                post_file = open(os.path.join(folder, str(post['id']))+".html",
                "wt")

            title = "Unknown"
            if 'title' in post.keys() and 'rendered' in post['title'].keys():
                title = post['title']['rendered']

            date_gmt = "Unknown"
            if 'date_gmt' in post.keys():
                date_gmt = datetime.strptime(post['date_gmt'] +
                                             "-GMT", date_format)
            modified_gmt = "Unknown"
            if 'modified_gmt' in post.keys():
                modified_gmt = datetime.strptime(post['modified_gmt'] +
                                                 "-GMT", date_format)
            status = "Unknown"
            if 'status' in post.keys():
                status = post['status']

            post_type = "Unknown"
            if 'type' in post.keys():
                post_type = post['type']

            link = "Unknown"
            if 'link' in post.keys():
                link = html.escape(post['link'])

            comments = "Unknown"
            if 'comment_status' in post.keys():
                comments = html.escape(post['comment_status'])

            content = "Unknown"
            if 'content' in post.keys() and 'rendered' in \
                    post['content'].keys():
                content = post['content']['rendered']

            excerpt = "Unknown"
            if 'excerpt' in post.keys() and 'rendered' in \
                    post['excerpt'].keys():
                excerpt = post['excerpt']['rendered']

            author = "Unknown"
            if 'author' in post.keys() and users_list is not None:
                author_obj = get_by_id(users_list, post['author'])
                author = "%d: " % post['author']
                if author_obj is not None:
                    if 'name' in author_obj.keys():
                        author += author_obj['name']
                    if 'slug' in author_obj.keys():
                        author += "(%s)" % author_obj['slug']
                    if 'link' in author_obj.keys():
                        author += " - %s" % \
                                  (author_obj['link'], author_obj['link'])
            elif 'author' in post.keys():
                author = str(post['author'])

            categories = "
Unknown
"
            if 'categories' in post.keys() and categories_list is not None:
                categories = ""
                for cat in post['categories']:
                    cat_obj = get_by_id(categories_list, cat)
                    categories += "
%d: " % cat
                    if cat_obj is not None:
                        if 'name' in cat_obj.keys():
                            categories += cat_obj['name']
                        if 'link' in cat_obj.keys():
                            categories += " - %s" % \
                                          (html.escape(cat_obj['link']),
                                           html.escape(cat_obj['link']))
                    categories += "
"
            elif 'categories' in post.keys():
                categories = ""
                for cat in post['categories']:
                    categories += "
" + str(post['categories']) + "
"

            tags = "
Unknown
"
            if 'tags' in post.keys() and tags_list is not None:
                tags = ""
                for tag in post['tags']:
                    tag_obj = get_by_id(tags_list, tag)
                    tags += "
%d: " % tag
                    if tag_obj is not None:
                        if 'name' in tag_obj.keys():
                            tags += tag_obj['name']
                        if 'link' in tag_obj.keys():
                            tags += " - %s" % \
                                    (html.escape(tag_obj['link']),
                                     html.escape(tag_obj['link']))
                    tags += "
"
            elif 'tags' in post.keys():
                tags = ""
                for cat in post['tags']:
                    tags += "
" + str(post['categories']) + "
"

            buffer = \
"""<!DOCTYPE html>

        <title>{title}</title>

Metadata

Date (GMT): {date_gmt}

Date modified (GMT): {modified_gmt}

Status: {status}

Type: {post_type}

Link: {link}

Author: {author}

Comment status: {comments}

                    Categories:

                        {categories}

                    Tags:

                        {tags}

Excerpt

            {excerpt}

{title}

            {content}

"""
            buffer = buffer.format(
            title=title,
            date_gmt=date_gmt.strftime("%d/%m/%Y %H:%M:%S"),
            modified_gmt=modified_gmt.strftime("%d/%m/%Y %H:%M:%S"),
            status=status,
            post_type=post_type,
            link=link,
            author=author,
            comments=comments,
            categories=categories,
            tags=tags,
            excerpt=excerpt,
            content=content
            )

            post_file.write(buffer)
            post_file.close()
            exported_posts += 1

        return exported_posts


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('sis', '0039_auto_20151104_1138'),
    ]

    operations = [
        migrations.AddField(
            model_name='job',
            name='level',
            field=models.IntegerField(help_text='число для сортировки', blank=True, default=0),
        ),
    ]


# Copyright (c) 2017 The University of Manchester
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import pyNN.spiNNaker as pynn

import numpy as np
import matplotlib.pyplot as plt
from pyNN.random import RandomDistribution
from pyNN.utility.plotting import Figure, Panel
from spynnaker.pyNN.extra_algorithms.splitter_components import (
    SplitterAbstractPopulationVertexNeuronsSynapses, SplitterPoissonDelegate)

simulator_Name = 'spiNNaker'
# exec('import pyNN.%s as pynn' % simulator_Name)

def poisson_generator(rate, rng, t_start=0.0, t_stop=1000.0, array=True,
                      debug=False):
    """
    Returns a SpikeTrain whose spikes are a realization of a Poisson process
    with the given rate (Hz) and stopping time t_stop (milliseconds).

    Note: t_start is always 0.0, thus all realizations are as if
    they spiked at t=0.0, though this spike is not included in the SpikeList.

    Inputs:
        rate    - the rate of the discharge (in Hz)
        t_start - the beginning of the SpikeTrain (in ms)
        t_stop  - the end of the SpikeTrain (in ms)
        array   - if True, a numpy array of sorted spikes is returned,
                  rather than a SpikeTrain object.

    Examples:
        >> gen.poisson_generator(50, 0, 1000)
        >> gen.poisson_generator(20, 5000, 10000, array=True)

    See also:
        inh_poisson_generator, inh_gamma_generator,
        inh_adaptingmarkov_generator
    """

    n = (t_stop - t_start) / 1000.0 * rate
    number = np.ceil(n + 3 * np.sqrt(n))
    if number < 100:
        number = min(5 + np.ceil(2 * n), 100)

    if number > 0:
        isi = rng.exponential(1.0 / rate, number) * 1000.0
        if number > 1:
            spikes = np.add.accumulate(isi)
        else:
            spikes = isi
    else:
        spikes = np.array([])

    spikes += t_start
    i = np.searchsorted(spikes, t_stop)

    extra_spikes = []
    if i == len(spikes):
        # ISI buf overrun

        t_last = spikes[-1] + rng.exponential(1.0 / rate, 1)[0] * 1000.0

        while (t_last < t_stop):
            extra_spikes.append(t_last)
            t_last += rng.exponential(1.0 / rate, 1)[0] * 1000.0

        spikes = np.concatenate((spikes, extra_spikes))

        if debug:
            print("ISI buf overrun handled. len(spikes)=%d,"
                  " len(extra_spikes)=%d" % (len(spikes), len(extra_spikes)))

    else:
        spikes = np.resize(spikes, (i,))

    if debug:
        return spikes, extra_spikes
    else:
        return [round(x) for x in spikes]

# Total number of neurons
Neurons = 1000
sim_time = 1000.0
g = 5.0
eta = 2.0
delay = 2.0
epsilon = 0.1

tau_m = 20.0  # ms (20ms will give a FR of 20hz)
tau_ref = 2.0
v_reset = 10.0
V_th = 20.0
v_rest = 0.0
tauSyn = 1.0

N_E = int(round(Neurons * 0.8))
N_I = int(round(Neurons * 0.2))

C_E = N_E * 0.1
C_I = N_I * 0.1

# Excitatory and inhibitory weights
J_E = 0.1
J_I = -g * J_E

# The firing rate of a neuron in the external pop
# is the product of eta time the threshold rate
# the steady state firing rate which is
# needed to bring a neuron to threshold.
nu_ex = eta * V_th / (J_E * C_E * tau_m)

# population rate of the whole external population.
# With CE neurons the pop rate is simply the product
# nu_ex*C_E  the factor 1000.0 changes the units from
# spikes per ms to spikes per second.
p_rate = 1000.0 * nu_ex * C_E
print("Rate is: %f HZ" % (p_rate / 1000))

# Neural Parameters
pynn.setup(timestep=0.1, time_scale_factor=1, min_delay=0.1)

if simulator_Name == "spiNNaker":

    # Makes it easy to scale up the number of cores
    pynn.set_number_of_neurons_per_core(pynn.IF_curr_exp, 64)
    pynn.set_number_of_neurons_per_core(pynn.SpikeSourcePoisson, 64)

exc_cell_params = {
    'cm': 1.0,  # pf
    'tau_m': tau_m,
    'tau_refrac': tau_ref,
    'v_rest': v_rest,
    'v_reset': v_reset,
    'v_thresh': V_th,
    'tau_syn_E': tauSyn,
    'tau_syn_I': tauSyn,
    'i_offset': 0.9
}

inh_cell_params = {
    'cm': 1.0,  # pf
    'tau_m': tau_m,
    'tau_refrac': tau_ref,
    'v_rest': v_rest,
    'v_reset': v_reset,
    'v_thresh': V_th,
    'tau_syn_E': tauSyn,
    'tau_syn_I': tauSyn,
    'i_offset': 0.9
}

# Set-up pynn Populations
E_pop_splitter = SplitterAbstractPopulationVertexNeuronsSynapses(3, 128, False)
E_pop = pynn.Population(
    N_E, pynn.IF_curr_exp(**exc_cell_params), label="E_pop",
    additional_parameters={"splitter": E_pop_splitter}, seed=1)

I_pop_splitter = SplitterAbstractPopulationVertexNeuronsSynapses(3, 128, False)
I_pop = pynn.Population(
    N_I, pynn.IF_curr_exp(**inh_cell_params), label="I_pop",
    additional_parameters={"splitter": I_pop_splitter}, seed=2)

Poiss_ext_E_splitter = SplitterPoissonDelegate()
Poiss_ext_E = pynn.Population(
    N_E, pynn.SpikeSourcePoisson(rate=10.0), label="Poisson_pop_E",
    additional_parameters={"seed": 3,
                           "splitter": Poiss_ext_E_splitter})
Poiss_ext_I_splitter = SplitterPoissonDelegate()
Poiss_ext_I = pynn.Population(
    N_I, pynn.SpikeSourcePoisson(rate=10.0), label="Poisson_pop_I",
    additional_parameters={"seed": 4,
                           "splitter": Poiss_ext_I_splitter})

# Connectors
E_conn = pynn.FixedProbabilityConnector(epsilon)
I_conn = pynn.FixedProbabilityConnector(epsilon)

# Use random delays for the external noise and
# set the inital membrance voltage below the resting potential
# to avoid the overshoot of activity in the beginning of the simulation
delay_distr = RandomDistribution('uniform', low=0.1, high=12.8)
Ext_conn = pynn.OneToOneConnector()

uniformDistr = RandomDistribution('uniform', low=-10, high=0)
E_pop.initialize(v=uniformDistr)
I_pop.initialize(v=uniformDistr)

# Projections
E_E = pynn.Projection(
    E_pop, E_pop, E_conn, receptor_type="excitatory",
    synapse_type=pynn.StaticSynapse(weight=J_E, delay=delay))
I_E = pynn.Projection(
    I_pop, E_pop, I_conn, receptor_type="inhibitory",
    synapse_type=pynn.StaticSynapse(weight=J_I, delay=delay))
E_I = pynn.Projection(
    E_pop, I_pop, E_conn, receptor_type="excitatory",
    synapse_type=pynn.StaticSynapse(weight=J_E, delay=delay))
I_I = pynn.Projection(
    I_pop, I_pop, I_conn, receptor_type="inhibitory",
    synapse_type=pynn.StaticSynapse(weight=J_I, delay=delay))

Ext_E = pynn.Projection(
    Poiss_ext_E, E_pop, Ext_conn, receptor_type="excitatory",
    synapse_type=pynn.StaticSynapse(weight=J_E * 10, delay=delay_distr))
Ext_I = pynn.Projection(
    Poiss_ext_I, I_pop, Ext_conn, receptor_type="excitatory",
    synapse_type=pynn.StaticSynapse(weight=J_E * 10, delay=delay_distr))

# Record stuff
E_pop.record("spikes")

pynn.run(sim_time)

esp = None
isp = None
pe = None
pi = None
v_esp = None

esp = E_pop.get_data("spikes")

Figure(
    # raster plot of the presynaptic neuron spike times
    Panel(esp.segments[0].spiketrains,
          yticks=True, markersize=1, xlim=(0, sim_time)),
    title="Brunnel example",
    annotations="Simulated with {}".format(pynn.name())
)
plt.show()

pynn.end()


# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.

import pytest
from shrike.spark.spark_net import *
from unittest import mock

def test_get_default_spark_session():
    mock_app_name = mock.MagicMock()
    mock_app = mock.MagicMock()

    # https://stackoverflow.com/a/34668809
    mock_app_name.getOrCreate = lambda: mock_app

    with mock.patch(
        "pyspark.sql.SparkSession.builder.appName", return_value=mock_app_name
    ):
        rv = get_default_spark_session()

    assert mock_app == rv

@pytest.mark.parametrize(
    "py_files,py_file,expected",
    [
        ("a/b/c/d.zip,a/b/e.zip", "d.zip", "a/b/c/d.zip"),
        ("a/b.zip/c.zip,a/b.zip", "b.zip", "a/b.zip"),
    ],
)
def test_full_pyfile_path(py_files, py_file, expected):
    spark = mock.MagicMock()
    spark_conf = {"spark.yarn.dist.pyFiles": py_files}

    # https://stackoverflow.com/a/39457691
    spark.sparkContext.getConf = lambda: spark_conf

    rv = full_pyfile_path(spark, py_file)
    assert expected == rv

@pytest.mark.parametrize("args", [[], [1, 2], ["a", "b", "c"]])
def test_java_args(args):
    """
    https://github.com/dkmiller/pyconfigurableml/blob/master/tests/test_entry.py
    """
    spark = mock.MagicMock()
    gateway = mock.MagicMock()
    gateway.new_array = lambda _, n: [None] * n

    with mock.patch("pyspark.SparkContext._gateway", gateway):
        rv = java_args(spark, args)

    assert rv == args

@pytest.mark.parametrize("zip,binary,args", [("foo.zip", "bar.dll", ["a", "b"])])
def test_run_spark_net_from_known_assembly(zip, binary, args):
    spark = mock.MagicMock()
    spark_conf = {"spark.yarn.dist.pyFiles": zip}

    # https://stackoverflow.com/a/39457691
    spark.sparkContext.getConf = lambda: spark_conf

    main = mock.MagicMock()
    spark._jvm.org.apache.spark.deploy.dotnet.DotnetRunner.main = main

    gateway = mock.MagicMock()
    gateway.new_array = lambda _, n: [None] * n

    with mock.patch("pyspark.SparkContext._gateway", gateway):
        run_spark_net_from_known_assembly(spark, zip, binary, args)

    # https://stackoverflow.com/a/21611963
    assert main.call_count == 1
    assert main.call_args[0][0] == [zip, binary] + args

@pytest.mark.parametrize(
    "args,expected",
    [
        (
            ["--zipFile", "foo.zip", "--binaryName", "bar.dll", "--arg1", "val1"],
            ["foo.zip", "bar.dll", "--arg1", "val1"],
        ),
        (
            ["--binaryName", "bar.dll", "--arg1", "val1", "--zipFile", "foo.zip"],
            ["foo.zip", "bar.dll", "--arg1", "val1"],
        ),
    ],
)
def test_run_spark_net(args, expected):
    gateway = mock.MagicMock()
    gateway.new_array = lambda _, n: [None] * n

    spark = mock.MagicMock()
    spark_conf = {"spark.yarn.dist.pyFiles": ",".join(args)}
    spark.sparkContext.getConf = lambda: spark_conf

    main = mock.MagicMock()
    spark._jvm.org.apache.spark.deploy.dotnet.DotnetRunner.main = main

    # https://stackoverflow.com/a/34668809
    mock_app_name = mock.MagicMock()
    mock_app_name.getOrCreate = lambda: spark

    with mock.patch("sys.argv", args):
        with mock.patch("pyspark.SparkContext._gateway", gateway):
            with mock.patch(
                "pyspark.sql.SparkSession.builder.appName", return_value=mock_app_name
            ):
                run_spark_net()

    # https://stackoverflow.com/a/21611963
    assert main.call_count == 1
    assert main.call_args[0][0] == expected


import json

def testOne():
	json_loader=open('<Path>')
	data=json.load(json_loader)
	json_loader.close() #close file

	Numbus_Headers=data['Numbus_Header']
	Numbus_Events=data['Numbus_Events']
	Numbus_HTTP=data['Numbus_HTTP']

	json_loader=open('<Path>')
	data_proxy =json.load(json_loader)
	json_loader.close()

	fileWriter= open('<Path>','w')
	fileWriter_proxy= open('<Path>','w')
	configureProxy(data_proxy,fileWriter_proxy)
	handleNumbusHeaderrequest(Numbus_Headers,fileWriter)
	handleNumbusEvents(Numbus_Events,fileWriter)
	handleNumbusHeaderHTTPrequest(Numbus_HTTP,fileWriter)

def handleNumbusHeaderrequest(Numbus_Headers,fileWriter):
	#print(Numbus_Headers)
	for l_headers,l_values in Numbus_Headers.items():
		fileWriter.write(l_headers+' '+l_values+'\n')

def handleNumbusEvents(Numbus_Events,fileWriter):
	#print(Numbus_Events)
	fileWriter.write('events {\n')
	for l_events,l_values in Numbus_Events.items():
		fileWriter.write(l_events+' '+l_values)
	fileWriter.write('\n}')

def handleNumbusHeaderHTTPrequest(Numbus_HTTP,fileWriter):
	#print(Numbus_HTTP)
	#doing this to keep in order for configuration file to exact i do not want to restrcure the code to fit my needs
	fileWriter.write('http {\n')
	upstream=Numbus_HTTP['upstream']
	servers=Numbus_HTTP['servers']
	lib_conf=Numbus_HTTP['include']
	Numbus_HTTP.pop('upstream')
	Numbus_HTTP.pop('servers')
	Numbus_HTTP.pop('access_log')
	Numbus_HTTP.pop('include')

	for l_include in lib_conf:
		fileWriter.write('include '+l_include+'\n')

	for keys, values in Numbus_HTTP.items():
		fileWriter.write('\n'+keys+' '+values+'\n')

	for keys,values in upstream.items():
		fileWriter.write(keys+' {\n')
		for t_values in values:
			for th_keys ,th_values in t_values.items():
				fileWriter.write(th_keys+th_values+'\n')
	fileWriter.write('}')

	for l_servers in servers:
		fileWriter.write('server {\n')
		for keys,values in l_servers.items():
			print('Keys :'+ keys)
			if 'location' in keys:
				fileWriter.write( keys+ '{\n')
				for i in values:
					for t_keys, t_values in i.items():
						fileWriter.write(t_keys+' '+t_values+'\n')
				fileWriter.write('}\n')
			else:
				fileWriter.write(keys+' '+values+'\n')
		fileWriter.write('}')

	fileWriter.write('}')

def configureProxy(data_proxy,fileWriter_proxy):
	configuration = data_proxy['proxy_configuration']
	for keys,values in configuration.items():
		fileWriter_proxy.write(keys+' '+str(values)+'\n')

	fileWriter_proxy.close()

if __name__=='__main__':
	testOne()


import matplotlib.pyplot as plt
import cv2 as cv
import numpy as np
from genetic_algorithm import GeneticAlgorithm
import utils
from individual import Individual
from gen_record import GenRecord

IMG_SIZE = 256

# read target image
img = cv.imread("face.png", cv.IMREAD_GRAYSCALE)
img = cv.resize(img, (IMG_SIZE, IMG_SIZE))

ga = GeneticAlgorithm(img, num_gens=1000000, init_pop=20, new_per_gen=10, mut_pct=0.001, checkpoints=100)
print(f'Best fitness {ga.max_fitness}')
input('Press any key to begin simulation...')
ga_results = ga.run_simulation()

# process GA results
imgs = []
for r in ga_results:
  img = chromosome2img(r.chromosome, (IMG_SIZE, IMG_SIZE))
  imgs.append(img)
  cv.imwrite(f'./output/img/best_{r.gen_number}.png', img)
# append target image
imgs = [img] + imgs

# show image results
cols = 5
rows = len(imgs) // cols
fig, axs = plt.subplots(nrows=rows, ncols=cols, figsize=(10, 10))
for r in range(rows):
    for c in range(cols):
        axs[r][c].imshow(imgs[r + c], cmap='gray')
        axs[r][c].axis('off')
plt.tight_layout()
plt.show()

# show how fitness was improving
xs = [x.gen_number for x in ga_results]
ys = [x.fitness for x in ga_results]
fig, ax = plt.subplots()
ax.plot(xs, ys)
ax.set(xlabel='Número de Generación', ylabel='Fitness',
       title='Evolución de Fitness')
ax.grid()
fig.savefig("fitness.png")
plt.show()


from django.contrib import messages
from django.core.files.storage import FileSystemStorage
from django.shortcuts import render, redirect

# Create your views here.
from .models import Books, Comments, Audio

def record(request):
    return  render(request, 'record.html')

def books(request):
    allbooks = Books.objects.all()
    allaudios = Audio.objects.all()
    return render(request,'stories.html',{'allbooks': allbooks, 'allaudios': allaudios})

def read(request,id):
    vi = Books.objects.filter(id = id)[0]
    comments = Comments.objects.filter(post = vi)

    context = {'vi':vi, 'comments': comments, 'user': request.user}
    return render(request, "view.html", context)

def postComment(request):
    if request.method == "POST":
        comment = request.POST.get('comment')
        user = request.user
        postSno = request.POST.get("postSno")
        post = Books.objects.get(id=postSno)
        comment = Comments(comment=comment, user=user, post=post)
        comment.save()
        messages.success(request, "Your comment has been posted successfully")
    return redirect(f"/all/read/{post.id}")

def upload(request):
    thank = False
    if request.method == "POST":
        # user = request.user
        imgs = request.FILES.get('imgs')
        book_name = request.POST.get('book_name')
        book_desc = request.POST.get('book_desc')
        # fs = FileSystemStorage()
        # fs.save(img.name, img)
        profile = Books( img=imgs, book_desc=book_desc, book_name=book_name)
        profile.save()
        messages.add_message(request, messages.SUCCESS, "Successfully Uploaded")

        thank = True
    return render(request, 'upload.html')

def audio(request):
    if request.method == "POST":
        user = request.user
        story_audio = request.FILES['story_audio']
        story_name = request.POST.get('story_name')
        fa = FileSystemStorage()
        fa.save(story_audio.name, story_audio)
        profile = Audio(user=user, story_name = story_name, story_audio=story_audio)
        profile.save()
        messages.add_message(request, messages.SUCCESS, "Successfully Uploaded")

    return render(request, 'audiobook.html')

def audioplay(request,id):
    ai = Audio.objects.filter(id = id)[0]
    # comments = Comments.objects.filter(post = vi)

    context = {'ai':ai, 'user': request.user}
    return render(request, "audios.html", context)


from rest_framework.response import Response

def json_result(data=None, code=200):
    res_status = {"status": code}
    res_ver = {"version": "1.0",
               "version_note": "ChatBot"}
    if data is not None:
        res = res_status.copy()
        res.update(data)
        res.update(res_ver)
    else:
        res = res_status.copy()
        res.update(res_ver)

    return Response(res, status=code)


import unittest, json
from mock import patch, MagicMock, Mock
from strava import client, athlete, activity

class TestActivityInit(unittest.TestCase):

    mock_athlete = Mock()
    mock_athlete.__class__ = 'athlete.Athlete'
    mock_athlete_id = 227615
    mock_activity_id = '321934'
    mock_activity_summary_json = '{}'
    mock_activity_summary_dict = json.loads(mock_activity_summary_json)
    mock_activity_streams = 'mock_stream_object'

    @patch.object(activity.Activity, '_retrieve_activity_streams', return_value=mock_activity_streams)
    @patch.object(activity.Activity, '_retrieve_activity_summary',
                  return_value=(mock_activity_summary_json, mock_activity_summary_dict))
    @patch.object(activity.Activity, '_init_athlete', return_value = mock_athlete)
    def test_init_athlete_is_called(self,
                                    mock_init_athlete, mock_retrieve_activity_summary, mock_retrieve_activity_streams):
        test_activity = activity.Activity(self.mock_activity_id)
        mock_init_athlete.assert_called_with(None)
        self.assertEqual(test_activity.athlete, self.mock_athlete)

    @patch.object(activity.Activity, '_retrieve_activity_streams', return_value=mock_activity_streams)
    @patch.object(activity.Activity, '_retrieve_activity_summary',
                  return_value=(mock_activity_summary_json, mock_activity_summary_dict))
    @patch('strava.athlete.Athlete', return_value = mock_athlete)
    def test_athlet_instantiation_if_no_athlete_provided(self,
                                                         mock_class_Athlete, mock_retrieve_activity_summary, mock_retrieve_activity_streams):
        test_activity = activity.Activity(self.mock_activity_id)
        # mock_class_Athlete.assert_called()
        self.assertEqual(test_activity.athlete, self.mock_athlete)
        self.assertEqual(test_activity.athlete.__class__, 'athlete.Athlete')

    @patch.object(activity.Activity, '_retrieve_activity_streams', return_value=mock_activity_streams)
    @patch.object(activity.Activity, '_retrieve_activity_summary',
                  return_value=(mock_activity_summary_json, mock_activity_summary_dict))
    @patch('strava.athlete.Athlete', return_value=mock_athlete)
    def test_athlete_is_passed_through_when_provided(self,
                                                     mock_class_Athlete, mock_retrieve_activity_summary, mock_retrieve_activity_streams):
        test_athlete = athlete.Athlete()
        test_activity = activity.Activity(self.mock_activity_id, _athlete=test_athlete)
        # mock_class_Athlete.assert_called_once()
        self.assertEqual(test_activity.athlete, self.mock_athlete)

    @patch.object(activity.Activity, '_retrieve_activity_streams', return_value=mock_activity_streams)
    @patch.object(activity.Activity, '_retrieve_activity_summary',
                  return_value=(mock_activity_summary_json, mock_activity_summary_dict))
    @patch('strava.athlete.Athlete', return_value=mock_athlete)
    def test_call_retrieve_current_activity_summary(self,
                                                    mock_class_Athlete, mock_retrieve_activity_summary, mock_retrieve_activity_streams):
        test_activity = activity.Activity(self.mock_activity_id)
        # mock_retrieve_activity_summary.assert_called_once()
        self.assertEqual(test_activity.activity_json, self.mock_activity_summary_json)
        self.assertEqual(test_activity.activity_dict, self.mock_activity_summary_dict)

    @patch.object(activity.Activity, '_retrieve_activity_streams', return_value=mock_activity_streams)
    @patch.object(activity.Activity, '_retrieve_activity_summary',
                  return_value=(mock_activity_summary_json, mock_activity_summary_dict))
    @patch('strava.athlete.Athlete', return_value=mock_athlete)
    def test_call_retrieve_activity_streams(self,
                                            mock_class_Athlete, mock_retrieve_activity_summary, mock_retrieve_activity_streams):
        test_activity = activity.Activity(self.mock_activity_id)
        # mock_retrieve_activity_streams.assert_called_once()
        self.assertEqual(test_activity.streams, self.mock_activity_streams)

class TestActivityMetrics(unittest.TestCase):

    #TODO Find a way to mock the actual dict
    mock_activity_id = '321934'
    mock_activity_name = 'Evening Ride'

    # Define mock for activity object
    mock_activity = Mock()
    mock_activity.__class__ = 'activity.Activity'
    mock_activity.activity_id.return_value = mock_activity_id

    # Define mock for athlete object
    mock_athlete = Mock()
    mock_athlete.__call__ = 'athlete.Athlete'

    def test(self):
        pass

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

#
# class TestActivityMetricsInit(unittest.TestCase):
#
#     def SetUp(self):
#         self.activity_id = '628508858' #mdd30
#         self.client   = client.Client() # not needed for now, but will be required for access_token exchange
#         self.athlete  = athlete.Athlete()
#         self.activity = activity.Activity(athlete=self.athlete, activity_id=self.activity_id)
#
#     # def test_init_activity_metrics_should_return_correct_class(self):
#     #     self.activity_metrics = activity.ActivityMetrics(athlete=self.athlete, activity=self.activity)
#     #     # Assert correct class init
#     #     self.assertEqual(str(self.activity_metrics.__class__), 'strava.activity.ActivityMetrics')


# -*- coding:utf-8 -*-
# Author : ZRQ
# Data : 2019/6/22 16:43

import time
import asyncio

# 这是定义异步函数，先记住写法即可
async def hello():
    asyncio.sleep(1)
    # time.sleep(1)
    print('Hello World:%s' % time.time())

def run():
    for i in range(10):
        # 将协程加入到事件循环loop
        loop.run_until_complete(hello())

# 创建一个事件loop
loop = asyncio.get_event_loop()
if __name__ == '__main__':
    run()


import torch

from ..box_heads.box_utils import (
    pairwise_iou,
    xywha_to_xyxy,
    xyxy_to_xywha,
)

def encode(boxes, priors, variances):
    """Encode the variances from the priorbox layers into the ground truth boxes
    we have boxes (based on jaccard overlap) with the prior boxes.
    Args:
        boxes (tensor): [num_priors, 4] coords of ground truth for each prior in XYXY_REL BoxMode
        priors (tensor): [num_priors, 4] prior boxes in XYWHA_REL BoxMode
        variances (list[float]): variances of prior boxes
    Return:
        encoded boxes (tensor) [num_priors, 4]
    """
    boxes = xyxy_to_xywha(boxes)
    locations = boxes_to_locations(boxes, priors, variances)
    return locations

# Adapted from https://github.com/Hakuyume/chainer-ssd
def decode(locations, priors, variances):
    """Decode locations from predictions using priors to undo
    the encoding we did for offset regression at train time.
    Args:
        locations (tensor): [num_priors, 4] location predictions for locations layers
        priors (tensor): [num_priors, 4] prior boxes in XYWHA_REL BoxMode
        variances (list[float]): variances of prior boxes
    Return:
        decoded bounding box predictions
    """

    boxes = locations_to_boxes(locations, priors, variances)
    boxes = xywha_to_xyxy(boxes)
    return boxes

def boxes_to_locations(boxes, priors, variances):
    r"""Convert boxes into regressional location results of SSD
    Args:
        boxes (Tensor): [num_targets, 4] in XYWHA_REL BoxMode
        priors (Tensor): [num_targets] in XYWHA_REL BoxMode
        variances (list(float)): used to change the scale of center.
            change of scale of size.
    """
    # priors can have one dimension less
    if priors.dim() + 1 == boxes.dim():
        priors = priors.unsqueeze(0)
    return torch.cat([
        (boxes[..., :2] - priors[..., :2]) / priors[..., 2:] / variances[0],
        torch.log(boxes[..., 2:] / priors[..., 2:]) / variances[1],
    ], dim=boxes.dim() - 1)

def locations_to_boxes(locations, priors, variances):
    r"""Convert regressional location results of SSD into boxes in XYWHA_REL BoxMode
    The conversion:
        $$predicted\_center \times variance_center =
            \frac{real\_center - prior\_center}{prior\_hw}$$
        $$\exp(predicted\_hw \times variance_size) = \frac{real\_hw}{prior\_hw}$$
    We do it in the inverse direction here.
    Args:
        locations (Tensor): [batch_size, num_priors, 4] the regression output of SSD.
            It will contain the outputs as well.
        priors (Tensor): [num_priors, 4] or [batch_size, num_priors, 4] prior boxes.
        variances (list(float)): used to change the scale of center and
            change of scale of size.
    Returns:
        boxes: priors (Tensor): converted XYWHA_REL BoxMode. All the values
            are relative to the image size.
    """
    # priors can have one dimension less.
    if priors.dim() + 1 == locations.dim():
        priors = priors.unsqueeze(0)
    return torch.cat([
        locations[..., :2] * variances[0] * priors[..., 2:] + priors[..., :2],
        torch.exp(locations[..., 2:] * variances[1]) * priors[..., 2:],
    ], dim=locations.dim() - 1)

def assign_priors(gt_boxes, gt_labels, priors, iou_threshold):
    """Assign ground truth boxes and targets to priors.
    Args:
        gt_boxes (Tensor): [num_targets, 4]: ground truth boxes
        gt_labels (Tensor): [num_targets,]: labels of targets
        priors (Tensor): [num_priors, 4]: XYXY_REL BoxMode
        iou_threshold (float): iou threshold
    Returns:
        boxes (Tensor): [num_priors, 4] real values for priors.
        labels (Tensor): [num_priros] labels for priors.
    """
    ious = pairwise_iou(gt_boxes.unsqueeze(0), priors.unsqueeze(1))  # num_priors x num_targets
    best_target_per_prior, best_target_per_prior_index = ious.max(1)  # num_priors
    best_prior_per_target, best_prior_per_target_index = ious.max(0)  # num_targets

    for target_index, prior_index in enumerate(best_prior_per_target_index):
        best_target_per_prior_index[prior_index] = target_index
    # 2.0 is used to make sure every target has a prior assigned
    best_target_per_prior.index_fill_(0, best_prior_per_target_index, 2)

    labels = gt_labels[best_target_per_prior_index]  # num_priors
    labels[best_target_per_prior < iou_threshold] = 0  # the backgound id
    boxes = gt_boxes[best_target_per_prior_index]
    return boxes, labels


from __future__ import print_function

from os.path import dirname, join
import os.path
import pickle
from typing import Optional

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow, Flow
from googleapiclient.discovery import build

from pygsuite.utility.decorators import lazy_property

SCOPES = [
    "https://www.googleapis.com/auth/documents",
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/presentations",
    "https://www.googleapis.com/auth/drive",
]

SHEETS_VERSION = "v4"
DOCS_VERSION = "v1"
SLIDES_VERSION = "v1"
DRIVE_VERSION = "v2"

def json_str_to_oauth(token_str: str) -> Credentials:
    """Convert a JSON-like string into a Google OAuth `Credentials` object.

    Args:
        token_str (str): A JSON-like string containing Google authentication information.

    Returns a `Credentials` object.
    """
    import json

    cred_dict = json.loads(token_str)
    return Credentials(**cred_dict)

def get_oauth_credential(credential_string: str) -> Credentials:
    """Convert a JSON-like string into a Google OAuth `Credentials` object,
    and refresh the credentials if they are expired and contain a refresh token.
    Raises a `ValueError` if invalid credentials cannot be refreshed.

    Args:
        credential_string (str): A JSON-like string containing Google authentication information.

    Returns a valid `Credentials` object.
    """
    creds = json_str_to_oauth(credential_string)
    if not creds.valid:
        if creds.expired and creds.refresh_token:
            creds.refresh(Request())
            return creds
        raise ValueError(
            "Stored user token is no longer valid and no refresh token! Must be regenerated"
        )
    return creds

class _Clients(object):
    """Base client object for authorization to all Google APIs.
    This object contains methods to authorize local files, `Credentials` objects, and more.
    """

    def __init__(self):
        """Class constructor"""
        self.cred_path = None
        self.cred_text = None
        self.auth = None

    def validate(self):
        """Method to verify authorization has been obtained.
        Raises a `ValueError` if no `Credentials` object exists in `self.auth`.
        """
        if not self.auth:
            raise ValueError("Need to provide credential path or credential text or auth object.")

    def auth_default(self, project: Optional[str] = None):
        """Gets the default credentials for the current environment.
        More information in [Google's default auth documentation](
            https://google-auth.readthedocs.io/en/master/reference/google.auth.html#google.auth.default
        )

        Args:
            project (Optional[str]): The project ID.

        Sets the client auth to the default credentials fetched from Google.
        """
        import google.auth

        self.auth, project_id = google.auth.default(quota_project_id=project)

    def create_client_file_from_string(self) -> Flow:
        """Creates a OAuth 2.0 Authorization Flow object from a credential string if provided.

        Returns a constructed `Flow` object with credential information from credential string.
        """
        from tempfile import TemporaryDirectory
        import os

        with TemporaryDirectory() as temppath:
            with open(os.path.join(temppath, "writer-key.json"), "w") as keyfile:
                keyfile.write(self.cred_text)
            flow = InstalledAppFlow.from_client_secrets_file(keyfile.name, SCOPES)
        return flow

    def authorize(self, auth: Credentials, project: Optional[str] = None):
        """Sets the credentials for the current environment to a given `Credentials` object.

        Args:
            auth (Credentials): A valid `google.oauth2.credentials.Credentials` object.
            project (Optional[str]): The project ID, not currently used.
        """
        self.auth = auth

    def authorize_string(self, auth_string: str):
        """Sets the credentials for the current environment based on a JSON-like credentials string.

        Args:
            auth_string (str): A JSON-like string containing credentials information to be authenticated.
        """
        self.auth = get_oauth_credential(auth_string)

    def local_file_auth(self, filepath: str):
        """Sets the credentials for the current environment based on a local file with credentials.

        Args:
            filepath (str): Filepath to the credentials file.
        """
        directory = dirname(filepath)
        pickle_path = join(directory, "cache.pickle")
        creds = None
        if os.path.exists(pickle_path):
            with open(pickle_path, "rb") as token:
                creds = pickle.load(token)
        if not creds or not creds.valid:
            if creds and creds.expired and creds.refresh_token:
                creds.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file(filepath, SCOPES)
                creds = flow.run_local_server(port=0)
            with open(pickle_path, "wb") as token:
                pickle.dump(creds, token)
        self.auth = creds

    @lazy_property
    def docs_client(self):
        """Google Docs client"""
        self.validate()
        return build("docs", DOCS_VERSION, credentials=self.auth)

    @lazy_property
    def sheets_client(self):
        """Google Sheets client"""
        self.validate()
        return build("sheets", SHEETS_VERSION, credentials=self.auth)

    @lazy_property
    def slides_client(self):
        """Google Slides client"""
        self.validate()
        return build("slides", SLIDES_VERSION, credentials=self.auth)

    @lazy_property
    def _local_sheets_client(self):
        return build("sheets", SHEETS_VERSION, credentials=self.auth)

    @lazy_property
    def local_docs_client(self):
        return build("docs", DOCS_VERSION, credentials=self.auth)

    @lazy_property
    def _local_slides_client(self):
        return build("slides", SLIDES_VERSION, credentials=self.auth)

    @lazy_property
    def drive_client(self):
        """Google Drive client (API v3)"""
        return self.drive_client_v3

    @lazy_property
    def drive_client_v2(self):
        """Google Drive client (API v2)"""
        self.validate()
        return build("drive", DRIVE_VERSION, credentials=self.auth)

    @lazy_property
    def drive_client_v3(self):
        """Google Drive client (API v3)"""
        self.validate()
        return build("drive", "v3", credentials=self.auth)

Clients = _Clients()

{'google.auth': 'google.auth', 'TemporaryDirectory': 'tempfile.TemporaryDirectory', 'os': 'os'}


#! /usr/bin/env python3
# -*- coding:utf-8 -*-
import logging
logging.basicConfig(level=logging.INFO)
s=input('please input:')
s=int(s)
logging.info('s is %d' % s)
try:
    print('try... ...')
    r=10/s
    print('result:',r)
except ZeroDivisionError as e:
    print(e)
else:
    print('this is testing')
finally:
    print('finally... ...')
print('END')


import multiprocessing as mp
import sys
sys.path.append('D:/Users/Antoine/Documents/copenhague-1/togit/MyMCPython')
sys.path.append('D:/Users/Antoine/Documents/copenhague-1/togit/MyMCPython/MyMCPython_para')

import numpy as np
from MyMCPython_para import MC_3D_simulation_parallel
from MyMCPython_para import MC_intensities
import time

#simulation to run
simulation_name = "Nanofiber_experiment"

#intensity to use
Intensities = MC_intensities.get_Intensities()

#nb of particles
nbpart = 1000

#nb of available processors
nbproc = mp.cpu_count()
print("Number of processors : ", nbproc)

#nb of part simulated on each processor
data = [int(nbpart/nbproc) for i in range(nbproc)]

start = time.time()

#Initialize the pool
pool = mp.Pool(nbproc)

#launch a smaller simulation on each processor
results = pool.starmap(MC_3D_simulation_parallel.simulation_npart, [(subnbpart, Intensities) for subnbpart in data])

#Close the pool
pool.close()

#Display the time needed for the computation
end = time.time()
print(end-start)

sol_array = []
for i in range(1, nbproc):
    sol_array += results[i]

nb_iter = sol_array[0].y.shape[1]
nb_part = len(sol_array)
print("Nb part : ", nb_part)
print("Nb iteration :", nb_iter)

print('--saving traj data to .npz file--')
np.savez('D:/Users/Antoine/Documents/copenhague-1/togit/gaussian_forAntoine/solverp0_3D_'+simulation_name+'.npz',sol_arr=sol_array)
print('--done--')

Laser for transport/Near dielectric structure/Transport simulation/MCparallel.py


import torch
from torch.nn.parallel._functions import Scatter, Gather
from torch.nn.parallel.replicate import replicate
from torch.nn.parallel.parallel_apply import parallel_apply
import copy
from torchtext.data.batch import Batch

def data_parallel(module, inputs, device_ids=None, output_device=None, dim=0, module_kwargs=None):
    r"""Evaluates module(input) in parallel across the GPUs given in device_ids.

    This is the functional version of the DataParallel module.

    Args:
        module (Module): the module to evaluate in parallel
        inputs (tensor): inputs to the module
        device_ids (list of int or torch.device): GPU ids on which to replicate module
        output_device (list of int or torch.device): GPU location of the output  Use -1 to indicate the CPU.
            (default: device_ids[0])
    Returns:
        a Tensor containing the result of module(input) located on
        output_device
    """
    if not isinstance(inputs, tuple):
        inputs = (inputs,)

    if device_ids is None:
        device_ids = list(range(torch.cuda.device_count()))

    if output_device is None:
        output_device = device_ids[0]

    inputs, module_kwargs = scatter_kwargs(inputs, module_kwargs, device_ids, dim)
    if len(device_ids) == 1:
        return module(*inputs[0], **module_kwargs[0])
    used_device_ids = device_ids[:len(inputs)]
    replicas = replicate(module, used_device_ids)
    outputs = parallel_apply(replicas, inputs, module_kwargs, used_device_ids)
    return gather(outputs, output_device, dim)

def scatter(inputs, target_gpus, dim=0):
    r"""
    Slices tensors into approximately equal chunks and
    distributes them across given GPUs. Duplicates
    references to objects that are not tensors.
    """
    def scatter_map(obj):
        if isinstance(obj, torch.Tensor):
            return Scatter.apply(target_gpus, None, dim, obj)
        if isinstance(obj, tuple) and len(obj) > 0:
            return list(zip(*map(scatter_map, obj)))
        if isinstance(obj, list) and len(obj) > 0:
            return list(map(list, zip(*map(scatter_map, obj))))
        if isinstance(obj, dict) and len(obj) > 0:
            return list(map(type(obj), zip(*map(scatter_map, obj.items()))))
        if isinstance(obj, Batch):
            return list(map(lambda x:hoge(x, obj), zip(*map(scatter_map, fuga(obj)))))
        return [obj for targets in target_gpus]

    def hoge(xs, obj):
        obj = copy.copy(obj)
        for x in xs:
            field = x[0]
            value = x[1]
            setattr(obj, field, value)
        return obj
    def fuga(obj):
        return [[f, getattr(obj, f)] for f in obj.fields]

    # After scatter_map is called, a scatter_map cell will exist. This cell
    # has a reference to the actual function scatter_map, which has references
    # to a closure that has a reference to the scatter_map cell (because the
    # fn is recursive). To avoid this reference cycle, we set the function to
    # None, clearing the cell
    try:
        return scatter_map(inputs)
    finally:
        scatter_map = None

def scatter_kwargs(inputs, kwargs, target_gpus, dim=0):
    r"""Scatter with support for kwargs dictionary"""
    inputs = scatter(inputs, target_gpus, dim) if inputs else []
    kwargs = scatter(kwargs, target_gpus, dim) if kwargs else []
    if len(inputs) < len(kwargs):
        inputs.extend([() for _ in range(len(kwargs) - len(inputs))])
    elif len(kwargs) < len(inputs):
        kwargs.extend([{} for _ in range(len(inputs) - len(kwargs))])
    inputs = tuple(inputs)
    kwargs = tuple(kwargs)
    return inputs, kwargs

def gather(outputs, target_device, dim=0):
    r"""
    Gathers tensors from different GPUs on a specified device
      (-1 means the CPU).
    """
    def gather_map(outputs):
        out = outputs[0]
        if isinstance(out, torch.Tensor):
            return Gather.apply(target_device, dim, *outputs)
        if out is None:
            return None
        if isinstance(out, dict):
            if not all((len(out) == len(d) for d in outputs)):
                raise ValueError('All dicts must have the same number of keys')
            return type(out)(((k, gather_map([d[k] for d in outputs]))
                              for k in out))
        return type(out)(map(gather_map, zip(*outputs)))

    # Recursive function calls like this create reference cycles.
    # Setting the function to None clears the refcycle.
    try:
        return gather_map(outputs)
    finally:
        gather_map = None


# Geologic Materials Detection & Classification - Inspired by "Machine Learning Mastery with Python" by Jason Brownlee

# 1) Prepare Problem

# Load libraries
import numpy
from matplotlib import pyplot
from pandas import read_csv
from pandas import set_option
from pandas.plotting import scatter_matrix
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import ExtraTreesClassifier

# Load dataset
url = 'sonar.all-data.csv'
dataset = read_csv(url, header=None)

# 2) Summarize Data

# Descriptive statistics
print(dataset.shape) # Dimensions
set_option('display.max_rows', 500)
print(dataset.dtypes) # Data types for each attribute
set_option('display.width', 100)
print(dataset.head(20)) # Peek at first 20 data entries for each attribute
# Data has the same scale & the 'class' attribute has a string data type
set_option('precision', 3)
print(dataset.describe()) # Mean, median, range, & distribution for each attribute
# Data has same range (as expected) but differing mean values -> may want to standardize data
print(dataset.groupby(60).size()) # Class distribution -> classes are fairly balanced

# Data visualizations

# Univariate Plots
dataset.hist(sharex=False, sharey=False, xlabelsize=1, ylabelsize=1) # Histogram
pyplot.show() # Many attributes have Gaussian distributions & some have exponential distributions
dataset.plot(kind='density', subplots=True, layout=(8,8), sharex=False, legend=False, fontsize=1) # Density Plot
pyplot.show() # Many attributes have skewed distributions -> can correct skewness using a power transform (e.g. Box-Cox)

# Multivariate Plots
fig = pyplot.figure()
ax = fig.add_subplot(111)
cax = ax.matshow(dataset.corr(), vmin=-1, vmax=1, interpolation='none') # Correlation Matrix
fig.colorbar(cax)
pyplot.show() # Strong structure in attribute order -> makes sense due to sonar's angle of sensors
              # -> attributes closer together are more positively correlated
              # -> attributes farther apart are more negatively correlated

# 3) Prepare Data
'''
Data preparation will take place at the end of step 4 by creating a data pipeline
to fit, transform, and standardize the datset.
'''

# 4) Evaluate Algorithms

# Split-out validation dataset
array = dataset.values
x = array[:,0:60].astype(float)
y = array[:,60]
validation_size = 0.20 # 20% of dataset for testing & 80% for model training
seed = 7
x_train, x_validation, y_train, y_validation = train_test_split(x, y, test_size=validation_size, random_state=seed)

# Test options and evaluation metric
num_folds = 10 # 10-fold cross validation
seed = 7
scoring = 'accuracy' # evaluation metric

# Spot Check Algorithms
models = []
models.append(('LR', LogisticRegression(solver='liblinear'))) # Logistic Regression
models.append(('LDA', LinearDiscriminantAnalysis())) # Linear Discriminant Analysis
models.append(('KNN', KNeighborsClassifier())) # k-Nearest Neighbors
models.append(('DT', DecisionTreeClassifier())) # Decision Tree
models.append(('NB', GaussianNB())) # Naive Bayes
models.append(('SVM', SVC(gamma='auto'))) # Support Vector Machines

results = []
names = []
for name, model in models:
  kfold = KFold(n_splits=num_folds, random_state=seed, shuffle=True)
  cv_results = cross_val_score(model, x_train, y_train, cv=kfold, scoring=scoring)
  results.append(cv_results)
  names.append(name)
  print((name, cv_results.mean(), cv_results.std()))
  # k-Nearest Neighbors & Logistic Regression had the 1st & 2nd most accurate models

# Compare Algorithms
fig = pyplot.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
pyplot.boxplot(results) # Boxplot of each model's median accuracy & its distribution
ax.set_xticklabels(names)
pyplot.show() # KNN has low variance
# SVM has surprisingly poor results -> should standardize data for best results

# Dataset Standardization (Step 3)
pipelines = []
pipelines.append(('ScaledLR', Pipeline([('Scaler', StandardScaler()),('LR', LogisticRegression(solver='liblinear'))])))
pipelines.append(('ScaledLDA', Pipeline([('Scaler', StandardScaler()),('LDA', LinearDiscriminantAnalysis())])))
pipelines.append(('ScaledKNN', Pipeline([('Scaler', StandardScaler()),('KNN', KNeighborsClassifier())])))
pipelines.append(('ScaledCART', Pipeline([('Scaler', StandardScaler()),('CART', DecisionTreeClassifier())])))
pipelines.append(('ScaledNB', Pipeline([('Scaler', StandardScaler()),('NB', GaussianNB())])))
pipelines.append(('ScaledSVM', Pipeline([('Scaler', StandardScaler()),('SVM', SVC(gamma='auto'))])))

results = []
names = []
for name, model in pipelines:
  kfold = KFold(n_splits=num_folds, random_state=seed, shuffle=True)
  cv_results = cross_val_score(model, x_train, y_train, cv=kfold, scoring=scoring)
  results.append(cv_results)
  names.append(name)
  print(name, cv_results.mean(), cv_results.std())
  # SVM now has the most accurate model & KNN performance has also improved

# Compare Algorithms of Standardized Data
fig = pyplot.figure()
fig.suptitle('Scaled Algorithm Comparison')
ax = fig.add_subplot(111)
pyplot.boxplot(results) # Boxplot of each model's median accuracy & its distribution
ax.set_xticklabels(names)
pyplot.show() # SVM & KNN have the highest median accuracy with lower variance

# 5) Improve Accuracy

# Algorithm Tuning

# KNN Tuning
scaler = StandardScaler().fit(x_train)
rescaledx = scaler.transform(x_train)
neighbors = [1,3,5,7,9,11,13,15,17,19,21] # Find optimal number of neighbors
param_grid = dict(n_neighbors=neighbors)
model = KNeighborsClassifier() # KNN Classification
kfold = KFold(n_splits=num_folds, random_state=seed, shuffle=True) # 10-fold cross validation
grid = GridSearchCV(estimator=model, param_grid=param_grid, scoring=scoring, cv=kfold) # Grid Search Tuning
grid_result = grid.fit(rescaledx, y_train)
print((grid_result.best_score_, grid_result.best_params_)) # Find score associated with the best parameter

means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
    print((mean, stdev, param)) # Optimal neighbor size of 1 ->
                                # KNN should only use closest neighbor for making predictions

# SVM Tuning
scaler = StandardScaler().fit(x_train)
rescaledx = scaler.transform(x_train)
c_values = [0.1, 0.3, 0.5, 0.7, 0.9, 1.0, 1.3, 1.5, 1.7, 2.0] # Find optimal C value for optimal kernel
kernel_values = ['linear', 'poly', 'rbf', 'sigmoid'] # Find optimal C value for optimal kernel
param_grid = dict(C=c_values, kernel=kernel_values)
model = SVC(gamma='auto') # SVM Classification
kfold = KFold(n_splits=num_folds, random_state=seed, shuffle=True) # 10-fold cross validation
grid = GridSearchCV(estimator=model, param_grid=param_grid, scoring=scoring, cv=kfold) # Grid Search Tuning
grid_result = grid.fit(rescaledx, y_train)
print((grid_result.best_score_, grid_result.best_params_)) # Find score associated with the best parameter

means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
    print((mean, stdev, param)) # C = 1.5 for kernel = 'rbf'

# Ensembles
ensembles = []
ensembles.append(('AB', AdaBoostClassifier())) # AdaBoost Boosting Ensemble
ensembles.append(('GBM', GradientBoostingClassifier())) # Gradient Boosting Ensemble
ensembles.append(('RF', RandomForestClassifier(n_estimators=10))) # Random Forest Bagging Ensemble
ensembles.append(('ET', ExtraTreesClassifier(n_estimators=10))) # Extra Trees Bagging Ensemble

results = []
names = []
for name, model in ensembles:
  kfold = KFold(n_splits=num_folds, random_state=seed, shuffle=True) # 10-fold cross validation
  cv_results = cross_val_score(model, x_train, y_train, cv=kfold, scoring=scoring)
  results.append(cv_results)
  names.append(name)
  print(name, cv_results.mean(), cv_results.std()) # Boosting techniques have higher mean accuracy

# Compare Ensembles
fig = pyplot.figure()
fig.suptitle('Ensemble Algorithm Comparison')
ax = fig.add_subplot(111)
pyplot.boxplot(results) # Boxplot of each ensemble's median accuracy & its distribution
ax.set_xticklabels(names)
pyplot.show() # Gradient Boosting Ensemble Shows Highest Potential with >97% accuracy

# 6) Finalize Model

# Model Preparation
scaler = StandardScaler().fit(x_train) # Standardized Data Fitting
rescaledx = scaler.transform(x_train) # Standardized Data Transform
model = SVC(C=1.5) # SVM Classification
model.fit(rescaledx, y_train) # Build SVM classification model

rescaledValidationx = scaler.transform(x_validation)
predictions = model.predict(rescaledValidationx)
print(accuracy_score(y_validation, predictions)) # Model Accuracy
print(confusion_matrix(y_validation, predictions)) # Confusion Matrix
print(classification_report(y_validation, predictions)) # Classification Report

print('We are now complete with our machine learning project!')

Geologic Materials Detection & Classification/geologic_materials_detection_classification.py


#!usr/bin/python3

import json
import requests
import sys
import threading

url = 'https://api.vk.com/method/'

def get_friends(uid):
    method = 'friends.get'
    param = 'user_id'

    try:
        req = requests.get('{url}{method}?{param}={val}'.format(url=url, method=method, param=param, val=str(uid)))
        return json.loads(req.text)['response']
    except Exception as e:
        return e

def get_users(uids):
    param = 'user_ids'
    method = 'users.get'
    uids = ','.join(map(str, uids))

    try:
        req = requests.get('{url}{method}?{param}={val}'.format(url=url, method=method, param=param, val=uids))
        return json.loads(req.text)['response']
    except Exception as e:
        return e

def hidden_friends(uid):
    friends = get_friends(uid)

    if type(friends) is list:
        if target_uid in friends:
            hidden_uids.append(uid)
            print(uid)

def friends_of_friends(uid):
    global all_uids
    uids = get_friends(uid)

    if type(uids) is list:
        lock.acquire()
        all_uids |= set(uids)
        lock.release()

if __name__ == '__main__':
    try:
        target_uid = int(sys.argv[1])
    except:
        print('Please enter valid user id')
        sys.exit(1)

    try:
        user = get_users([target_uid])[0]
        for field in user:
            print('{f}: {v}'.format(f = field, v = user[field]))
    except Exception as e:
        print(e)
        sys.exit(1)

    print('[geting friends] status: START')
    friends = get_friends(target_uid)
    if type(friends) is list:
        print('[geting friends] status: OK')

        print('[geting friends of friends] status: START')
        all_uids = set()

        lock = threading.RLock()
        for c, uid in enumerate(friends):
            if (c % 100 == 0):
                print('{} / {}'.format(c, len(friends)))

            while threading.active_count() > 30:
                pass

            threading.Thread(target=friends_of_friends, args=(uid, )).start()

        while threading.active_count() > 1:
            pass

        print('[geting friends of friends] status: OK')

        all_uids -= set(friends)
        print('[find hidden friends] status: START')
        hidden_uids = []

        for c, uid in enumerate(all_uids):
            if (c % 100 == 0):
                print('{} / {}'.format(c, len(all_uids)))

            while threading.active_count() > 30:
                pass

            threading.Thread(target=hidden_friends, args=(uid, )).start()

        print('[find hidden friends] status: OK')
        print(hidden_uids)

        users = get_users(hidden_uids)

        if type(users) is list:
            for user in users:
                print(user)
        else:
            print(users) # Warning

    else:
        print('[geting friends] status: ERROR')
        print(friends)


""" 이 모듈은 미디 파일 데이터를 준비하여 훈련을 위해 신경 네트워크에 공급 """
import glob
import pickle
import numpy
from music21 import converter, instrument, note, chord
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import LSTM
from keras.layers import Activation
from keras.utils import np_utils
from keras.callbacks import ModelCheckpoint

def train_network():
    """ 음악을 생성하기 위해 신경망 훈련 """

    notes = get_notes()

    # 음높이 의 양
    n_vocab = len(set(notes))

    # 노트를 숫자 입력으로 변환
    network_input, network_output = prepare_sequences(notes, n_vocab)

    # 신경망 구조 생성
    model = create_network(network_input, n_vocab)

    train(model, network_input, network_output)

def get_notes():
    """ ./midi_songs 디렉토리의 midi 파일에서 모든 노트 및 코드 가져오기 """

    notes = []

    for file in glob.glob("midi_songs/*.mid"):
        midi = converter.parse(file)

        print("Parsing %s" % file)

        notes_to_parse = None

        try: #  악기 부분
            s2 = instrument.partitionByInstrument(midi)
            notes_to_parse = s2.parts[0].recurse()
        except: # flat 부분
            notes_to_parse = midi.flat.notes

        for element in notes_to_parse:
            # Note일 경우
            if isinstance(element, note.Note):
                notes.append(str(element.pitch))
            # Chord일 경우
            elif isinstance(element, chord.Chord):
                notes.append('.'.join(str(n) for n in element.normalOrder))

    # 자료형을 파일로 저장
    with open('data/notes', 'wb') as filepath:
        pickle.dump(notes, filepath)

    return notes

def prepare_sequences(notes, n_vocab):
    """ 신경망에서 사용하는 시퀀스 준비 """

    sequence_length = 100

    # 음높이 이름을 가져옴
    pitchnames = sorted(set(item for item in notes))

    # 음높이와 정수를 매핑하기 위한 dict
    note_to_int = dict((note, number) for number, note in enumerate(pitchnames))

    network_input = []
    network_output = []

    # 입력 시퀀스 및 해당 출력 생성
    for i in range(0, len(notes) - sequence_length, 1):
        sequence_in = notes[i:i + sequence_length]
        sequence_out = notes[i + sequence_length]
        network_input.append([note_to_int[char] for char in sequence_in])
        network_output.append(note_to_int[sequence_out])

    n_patterns = len(network_input)

    # 입력 내용을 LSTM 계층과 호환되는 형식으로 다시 작성
    network_input = numpy.reshape(network_input, (n_patterns, sequence_length, 1))
    # 정규화
    network_input = network_input / float(n_vocab)
    # one-hot 인코딩
    network_output = np_utils.to_categorical(network_output)

    return (network_input, network_output)

def create_network(network_input, n_vocab):
    """ 신경망의 구조 생성, Keras API 활용"""
    # LSTM : RNN 계층의 한 유형입니다.
    # Dropout : 정규화 기술. 이는 일부 노드를 임의로 삭제하여 모델이 과적 합되는 것을 방지합니다.
    # Dense : 이것은 모든 입력 노드가 모든 출력 노드에 연결되는 완전히 연결된 레이어입니다.
    # Activation : 노드의 출력을 생성하는 데 사용할 활성화 기능을 결정합니다.
    model = Sequential()
    model.add(LSTM(
        512,
        input_shape=(network_input.shape[1], network_input.shape[2]),
        return_sequences=True
    ))
    model.add(Dropout(0.2))
    model.add(LSTM(512, return_sequences=True))
    model.add(Dropout(0.2))
    model.add(LSTM(512))
    model.add(Dense(256))
    model.add(Dropout(0.2))
    model.add(Dense(n_vocab))
    # 결과를 확률값으로 해석하기 위해 활성함수로 softmax 사용
    model.add(Activation('softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

    return model

def train(model, network_input, network_output):
    """ 신경망 훈련, Checkpoint 생성, Keras fit 이용 """

    filepath = "weights-improvement-{epoch:02d}-{loss:.4f}-bigger.hdf5"
    # verbose = 해당 함수의 진행 사항의 출력 여부 옵션
    # save_best_only = 모델의 정확도가 최고값을 갱신했을 때만 저장하도록 하는 옵션
    checkpoint = ModelCheckpoint(
        filepath,
        monitor='loss',
        verbose=0,
        save_best_only=True,
        mode='min'
    )
    callbacks_list = [checkpoint]

    model.fit(network_input, network_output, epochs=200, batch_size=32, callbacks=callbacks_list)

if __name__ == '__main__':
    train_network()


"""Functions for custom GPs.

Custom implementations of main routines used for GP regression.
"""
import numpy as np
import sklearn.metrics
from scipy.linalg import solve_triangular
from scipy.sparse.linalg import eigsh
import time
import matplotlib.pyplot as plt
from profit.sur.backend.gpfunc import gpfunc

log2pihalf = 0.5*np.log(2.0*np.pi)

def k(xa, xb, l):
    return np.exp(-(xa-xb)**2 / (2.0*l**2))

# derivatives of kernel
def dkdxa(xa, xb, l):
    return -(xa-xb)/l**2*np.exp(-(xa-xb)**2 / (2.0*l**2))

def dkdxb(xa, xb, l):
    return -(xb-xa)/l**2*np.exp(-(xa-xb)**2 / (2.0*l**2))

def dkdxadxb(xa, xb, l):
    return (1.0/l**2 - (xa-xb)**2/l**4)*np.exp(-(xa-xb)**2 / (2.0*l**2))

# compute log-likelihood according to RW, p.19
def solve_cholesky(L, b):
    return solve_triangular(
        L.T, solve_triangular(L, b, lower=True, check_finite=False),
        lower=False, check_finite=False)

def invert_cholesky(L):
    """Inverts a positive-definite matrix A based on a given Cholesky decomposition
       A = L^T*L. Arguments: L"""
    return solve_triangular(
        L.T, solve_triangular(L, np.eye(L.shape[0]), lower=True, check_finite=False),
        lower=False, check_finite=False)

def invert(K, neig=0, tol=1e-10):
    """Inverts a positive-definite matrix A using either an eigendecomposition or
       a Cholesky decomposition, depending on the rapidness of decay of eigenvalues"""
    if (neig <= 0 or neig > 0.05*K.shape[0]):
        try:
            return invert_cholesky(np.linalg.cholesky(K))
        except:
            print('Warning! Fallback to eig solver!')
    w, Q = eigsh(K, neig, tol=tol)
    while np.abs(w[0]-tol) > tol:
        if neig > 0.05*K.shape[0]:  # TODO: get more stringent criterion
            try:
                return invert_cholesky(np.linalg.cholesky(K))
            except:
                print('Warning! Fallback to eig solver!')
        neig = 2*neig
        w, Q = eigsh(K, neig, tol=tol)
    return Q.dot(np.diag(1.0/w).dot(Q.T))

def build_K(x, x0, th, K):
    gpfunc.build_k_sqexp(x.T, x0.T, th, K)

def build_dKdth(dim, x, x0, th, K, dK):
    gpfunc.build_dkdth_sqexp(dim+1, x.T, x0.T, K, dK)

def nll_chol(hyp, x, y, K, dK=None, build_K=build_K):
    """Computes the negative log-likelihood.

    hyp: Hyperparameters (sig2f, sig2n, theta)
    x: Training points
    y: Function values at training points
    K: Empty matrix to store covariance
    dK: optional empty matrix to store covariance derivatives (default: None)
    build_K: Function to build covariance matrix (default: build_K)

    Computation according to Rasmussen&Williams 2006, p. 19, 113-114 .
    Default hyperparemeters are a tuple containing inverse squared length
    scales for each dimension of x.
    """
    nd = len(hyp) - 2
    nx = len(x)
    build_K(x, x, hyp[:-2], K)
    Ky = hyp[-2]*(K + hyp[-1]*np.diag(np.ones(nx)))
    L = np.linalg.cholesky(Ky)
    alpha = solve_cholesky(L, y)
    nll = 0.5*y.T.dot(alpha) + np.sum(np.log(L.diagonal())) + nx*log2pihalf

    if dK is None:
        return nll.item()

    # This is according to Rasmussen&Williams 2006, p. 114, Eq. (5.9).
    # We try to minimize the number of additional DxD matrices to store.
    # In particular, dK contiainig derivatives is overwritten for each
    # kernel hyperparameter in hyp[:-2].
    KyinvaaT = invert_cholesky(L)
    KyinvaaT -= np.outer(alpha, alpha)

    dnll = np.empty(len(hyp))
    for i in np.arange(nd):
        build_dKdth(i, x, x, hyp[:-2], K, dK)
        dnll[i] = 0.5*np.einsum('jk,kj', KyinvaaT, dK)

    # Derivatives w.r.t. sig2f and sig2n
    # TODO: optimize
    dnll[-2] = 0.5*np.einsum('jk,kj', KyinvaaT, K + hyp[-1]*np.diag(np.ones(nx)))
    dnll[-1] = 0.5*hyp[-2]*np.einsum('jk,kj', KyinvaaT, np.diag(np.ones(nx)))

    return nll.item(), dnll

def nll(hyp, x, y, neig=0, build_K=build_K):
    K = np.empty((len(x), len(x)))
    build_K(x, x, np.abs(hyp[:-1]), K)
    Ky = K + np.abs(hyp[-1])*np.diag(np.ones(len(x)))
    if (neig <= 0 or neig > 0.05*len(x)):
        try:
            return nll_chol(hyp, x, y, build_K)
        except:
            print('Warning! Fallback to eig solver!')
    w, Q = eigsh(Ky, neig, tol=max(1e-6*np.abs(hyp[-1]), 1e-15))
    while np.abs(w[0]-hyp[-1])/hyp[-1] > 1e-6 and neig < len(x):
        if neig > 0.05*len(x):  # TODO: get more stringent criterion
            try:
                return nll_chol(hyp, x, y, build_K)
            except:
                print('Warning! Fallback to eig solver!')
        neig =  2*neig
        w, Q = eigsh(Ky, neig, tol=max(1e-6*hyp[-1], 1e-15))

    alpha = Q.dot(np.diag(1.0/w).dot(Q.T.dot(y)))
    # print("l ", hyp[0])
    # print("sigm_noise2 ", hyp[-1])
    # print("\n\nalpha", alpha)
    # print("w ", w)
    # print("log w ", np.log(w))
    # print("sum log w ", np.sum(np.log(w)))
    # print("hyp-1 ", np.abs(hyp[-1]))

    ret = 0.5*y.T.dot(alpha) + 0.5*(np.sum(np.log(w)) + (len(x)-neig)*np.log(np.abs(hyp[-1])))
    return ret.item()

def predict_f(hyp, x, y, xtest, neig=0):
    Ktest = sklearn.metrics.pairwise.rbf_kernel(xtest, x, 0.5/hyp[0]**2)
    Ktest2 = sklearn.metrics.pairwise.rbf_kernel(xtest, xtest, 0.5/hyp[0]**2)
    K = sklearn.metrics.pairwise.rbf_kernel(x, x, 0.5/hyp[0]**2)
    Ky = K + hyp[-1]*np.diag(np.ones(len(x)))
    Kyinv = invert(Ky, neig, 1e-6*hyp[-1])
    Ef = Ktest.dot(Kyinv.dot(y))
    varf = (Ktest2 - Ktest.dot(Kyinv.dot(Ktest.T)))
    return Ef, varf

def predict_dfdx(hyp, x, y, xtest, neig=8, dkdxa=dkdxa, dkdxadxb=dkdxadxb):
    Ktest = np.fromfunction(lambda i, j: dkdxa(xtest[i,0], x[j,0], hyp[0]), (len(xtest), len(x)), dtype=int)
    Ktest2 = np.fromfunction(lambda i, j: dkdxadxb(xtest[i,0], xtest[i,0], hyp[0]), (len(xtest), len(xtest)), dtype=int)
    K = sklearn.metrics.pairwise.rbf_kernel(x, x, 0.5/hyp[0]**2)
    Ky = K + hyp[-1]*np.diag(np.ones(len(x)))
    Kyinv = invert(Ky, neig, 1e-6*hyp[-1])
    Edfdx = Ktest.dot(Kyinv.dot(y))
    vardfdx = Ktest2 - Ktest.dot(Kyinv.dot(Ktest.T))
    return Edfdx, vardfdx

def dk_logdl(xa, xb, l): # derivative of the kernel w.r.t log lengthscale
    dk_dl = ((xa - xb)**2.0 * np.exp(-(xa-xb)**2.0/(2 * l**2))) / l**3
    dk_logdl = dk_dl * np.log(10) * 10**(np.log10(l)) # from log lengthscale to lengthscale
    return dk_logdl

def dkdl(xa, xb, l): # derivative of the kernel w.r.t lengthscale
    dk_dl = ((xa - xb)**2.0 * np.exp(-(xa-xb)**2.0/(2 * l**2))) / l**3
    return dk_dl

def get_marginal_variance_BBQ(hess_inv, new_hyp, ntrain, ntest, xtrain, xtest, Kyinv, ytrain, varf, plot_result = False):

    tic = time.time()
    # Step 1 : invert the res.hess_inv to get H_tilde
    H_tilde = invert(hess_inv)
    # Step 2 Get H
    H = np.zeros((len(H_tilde), len(H_tilde)))
    for i in np.arange(len(H_tilde)):
        for j in np.arange(len(H_tilde)):
            H[i,j] = (1/np.log(10)**2) * H_tilde[i,j]/(new_hyp[i]*new_hyp[j])
    # Step 3 get Sigma
    H_inv = invert(H)
    sigma_m = H_inv
    tac = time.time()
    print("time consumed : ", (tac - tic)*1000," ms")

    ######################### Build needed Kernel Matrix #########################

    # Kernel K(train, train) of shape (ntrain, ntrain)
    K = np.empty((ntrain, ntrain))
    for i in np.arange(len(xtrain)):
        for j in np.arange(len(xtrain)):
            K[i, j] = k(xtrain[i], xtrain[j], new_hyp[0])

    # Kernel K_star(test, train) of shape (ntest, ntrain)
    # note that K_star(test, train) = K_star.T(train, test)
    K_star = np.empty((ntest, ntrain))
    for i in np.arange(len(xtest)):
        for j in np.arange(len(xtrain)):
            K_star[i, j] = k(xtest[i], xtrain[j], new_hyp[0])

    # Derivative of kernel K
    K_prime = np.empty((ntrain, ntrain))
    for i in np.arange(len(xtrain)):
        for j in np.arange(len(xtrain)):
            K_prime[i, j] = dkdl(xtrain[i], xtrain[j], new_hyp[0])

    # Derivative of kernel K_star
    K_star_prime = np.empty((ntest, ntrain))
    for i in np.arange(len(xtest)):
        for j in np.arange(len(xtrain)):
            K_star_prime[i, j] = dkdl(xtest[i], xtrain[j], new_hyp[0])
    ############################################################################

    alpha = np.dot(Kyinv, ytrain) # RW p17 paragraph 4

    dalpha_dl = -Kyinv.dot(K_prime).dot(Kyinv).dot(ytrain) # Compute the alpha's derivative w.r.t. lengthscale

    dalpha_ds = -Kyinv.dot(np.eye(ntrain)).dot(Kyinv).dot(ytrain) # Compute the alpha's derivative w.r.t. sigma noise
                                                                  # square
    #print("dl ", dalpha_dl)
    #print("\nds ", dalpha_ds)

    dm = np.empty((ntest,len(new_hyp), 1))

    for nb_hyp in range(len(new_hyp)):
        if nb_hyp == 0 :
            dm[:,nb_hyp,:] = np.dot(K_star_prime, alpha) -\
                             np.dot(K_star, dalpha_dl)
        else :
            dm[:,nb_hyp,:] = np.dot(K_star, dalpha_ds)

    V = varf # set V as the result of the predict_f diagonal

    dm_transpose = np.empty((ntest, 1, len(new_hyp)))
    dmT_dot_sigma = np.empty((ntest, 1, len(new_hyp)))
    dmT_dot_sigma_dot_dm = np.empty((ntest, 1))

    for i in range(ntest):
        dm_transpose[i] = dm[i].T
        dmT_dot_sigma[i] = dm_transpose[i].dot(sigma_m)
        dmT_dot_sigma_dot_dm[i] = dmT_dot_sigma[i].dot(dm[i])

    #print("dmT_dot_sigma_dot_dm = ", dmT_dot_sigma_dot_dm)
    V_tild = V.reshape((ntest,1)) + dmT_dot_sigma_dot_dm # Osborne et al. (2012) Active learning eq.19

    if plot_result == True:
        print("\nThe marginal Variance has a shape of ", V_tild.shape)
        print("\n\n\tMarginal variance\n\n", V_tild )

    return V_tild

def get_marginal_variance_MGP(hess_inv, new_hyp, ntrain, ntest, xtrain, xtest, Kyinv, ytrain, varf, plot_result = False):

    # Step 1 : invert the res.hess_inv to get H_tilde
    H_tilde = invert(hess_inv)
    # Step 2 Get H
    H = np.zeros((len(H_tilde), len(H_tilde)))
    for i in np.arange(len(H_tilde)):
        for j in np.arange(len(H_tilde)):
            H[i,j] = (1/np.log(10)**2) * H_tilde[i,j]/(new_hyp[i]*new_hyp[j])
    # Step 3 get Sigma
    H_inv = invert(H)
    sigma_m = H_inv

    ######################### Build needed Kernel Matrix #########################

    # Kernel K(train, train) of shape (ntrain, ntrain)
    K = np.empty((ntrain, ntrain))
    for i in np.arange(len(xtrain)):
        for j in np.arange(len(xtrain)):
            K[i, j] = k(xtrain[i], xtrain[j], new_hyp[0])

    # Kernel K_star(test, train) of shape (ntest, ntrain)
    # note that K_star(test, train) = K_star.T(train, test)
    K_star = np.empty((ntest, ntrain))
    for i in np.arange(len(xtest)):
        for j in np.arange(len(xtrain)):
            K_star[i, j] = k(xtest[i], xtrain[j], new_hyp[0])

    # Derivative of kernel K
    K_prime = np.empty((ntrain, ntrain))
    for i in np.arange(len(xtrain)):
        for j in np.arange(len(xtrain)):
            K_prime[i, j] = dkdl(xtrain[i], xtrain[j], new_hyp[0])

    # Derivative of kernel K_star
    K_star_prime = np.empty((ntest, ntrain))
    for i in np.arange(len(xtest)):
        for j in np.arange(len(xtrain)):
            K_star_prime[i, j] = dkdl(xtest[i], xtrain[j], new_hyp[0])

    K_2star_prime = np.empty((ntest, ntest))
    for i in np.arange(len(xtest)):
        for j in np.arange(len(xtest)):
            K_2star_prime[i, j] = dkdl(xtest[i], xtest[j], new_hyp[0])
    ############################################################################

    dKyinv_dl = -Kyinv.dot(K_prime).dot(Kyinv) # Compute the Kyinv's derivative w.r.t. lengthscale

    dKyinv_ds = -Kyinv.dot(np.eye(ntrain)).dot(Kyinv) # Compute the Kyinv's derivative w.r.t. sigma noise
                                                                  # square

    term1 = K_star_prime.dot(Kyinv).dot(K_star.T)

    # dm = np.empty((ntest,len(new_hyp), 1))
    #
    # for nb_hyp in range(len(new_hyp)):
    #     if nb_hyp == 0 :
    #         dm[:,nb_hyp,:] = np.dot(K_star_prime, alpha) -\
    #                          np.dot(K_star, dalpha_dl)
    #     else :
    #         dm[:,nb_hyp,:] = np.dot(K_star, dalpha_ds)
    #
    #
    #
    # V = varf # set V as the result of the predict_f diagonal
    #
    # dm_transpose = np.empty((ntest, 1, len(new_hyp)))
    # dmT_dot_sigma = np.empty((ntest, 1, len(new_hyp)))
    # dmT_dot_sigma_dot_dm = np.empty((ntest, 1))
    #
    # for i in range(ntest):
    #     dm_transpose[i] = dm[i].T
    #     dmT_dot_sigma[i] = dm_transpose[i].dot(sigma_m)
    #     dmT_dot_sigma_dot_dm[i] = dmT_dot_sigma[i].dot(dm[i])
    #
    # #print("dmT_dot_sigma_dot_dm = ", dmT_dot_sigma_dot_dm)
    # V_tild = V.reshape((ntest,1)) + dmT_dot_sigma_dot_dm # Osborne et al. (2012) Active learning eq.19
    #
    # if plot_result == True:
    #     print("\nThe marginal Variance has a shape of ", V_tild.shape)
    #     print("\n\n\tMarginal variance\n\n", V_tild )
    #
    # return V_tild

def wld_get_marginal_variance(wld_hess_inv, wld_hyp, ntrain, ntest, xtrain, xtest, Kyinv, ytrain, varf, plot_result = False):

    ######################### Build needed Kernel Matrix #########################
    wld_K = np.empty((ntrain, ntrain))
    for i in np.arange(len(xtrain)):
        for j in np.arange(len(xtrain)):
            wld_K[i, j] = k(xtrain[i], xtrain[j], wld_hyp[0])

    wld_K_star = np.empty((ntest, ntrain))
    for i in np.arange(len(xtest)):
        for j in np.arange(len(xtrain)):
            wld_K_star[i, j] = k(xtest[i], xtrain[j], wld_hyp[0])

    wld_K_prime = np.empty((ntrain, ntrain))
    for i in np.arange(len(xtrain)):
        for j in np.arange(len(xtrain)):
            wld_K_prime[i, j] = dkdl(xtrain[i], xtrain[j], wld_hyp[0])

    wld_K_star_prime = np.empty((ntest, ntrain))
    for i in np.arange(len(xtest)):
        for j in np.arange(len(xtrain)):
            wld_K_star_prime[i, j] = dkdl(xtest[i], xtrain[j], wld_hyp[0])
    ############################################################################

    wld_alpha = np.dot(Kyinv, ytrain) # RW p17 paragraph 4

    wld_dalpha_dl = -Kyinv.dot(wld_K_prime)\
        .dot(Kyinv)\
        .dot(ytrain)

    wld_dalpha_ds = -Kyinv.dot(np.eye(ntrain)).dot(Kyinv).dot(ytrain) # - Kyinv x I x Kyinv x ytrain

    wld_dm = np.empty((ntest,len(wld_hyp), 1))

    for nb_hyp in range(len(wld_hyp)):
        if nb_hyp == 0 :
            wld_dm[:,nb_hyp,:] = np.dot(wld_K_star_prime, wld_alpha) -\
                             np.dot(wld_K_star, wld_dalpha_dl)
        else :
            wld_dm[:,nb_hyp,:] = np.dot(wld_K_star, wld_dalpha_ds)

    V = varf # set V as the result of the predict_f diagonal
    wld_sigma = invert(wld_hess_inv)

    wld_dm_transpose = np.empty((ntest, 1, len(wld_hyp)))
    wld_dmT_dot_sigma = np.empty((ntest, 1, len(wld_hyp)))
    wld_dmT_dot_sigma_dot_dm = np.empty((ntest, 1))

    for i in range(ntest):
        wld_dm_transpose[i] = wld_dm[i].T
        wld_dmT_dot_sigma[i] = wld_dm_transpose[i].dot(wld_sigma)
        wld_dmT_dot_sigma_dot_dm[i] = wld_dmT_dot_sigma[i].dot(wld_dm[i])

    wld_V_tild = V.reshape((ntest,1)) + wld_dmT_dot_sigma_dot_dm # Osborne et al. (2012) Active learning eq.19

    if plot_result == True :
        print("The marginal Variance has a shape of ", wld_V_tild.shape)
        print("\n\n\tMarginal variance\n\n", wld_V_tild )

    return wld_V_tild

def plot_searching_phase(scores, xtest, next_candidate, ntrain):
    max = np.linspace(0, scores[next_candidate], 3)
    #plt.figure()
    plt.subplot(2,1,2)
    plot_line = np.linspace(xtest[next_candidate], xtest[next_candidate],3)
    plt.plot(xtest, scores, 'b')
    plt.plot(plot_line, max, 'r')
    plt.title('Iteration ' + str(ntrain + 1) + ' : searching phase')
    plt.xlabel('xtest')
    plt.ylabel('score')
    plt.savefig('Active Gaussian Process with '+ str(ntrain) + ' observation(s)')
    plt.show()