import os
import time
import wandb
import pickle
import numpy as np
import utils.io as uio
import multiprocessing as mp
import state_generator as sg
import models.kg_policynet as kgpn

from core.loss import SGD
from core.utils import *
from configs.kgna_config import Config

def is_better(a, b):

    if(a < b):
        return True
    else:
        return False

def is_worse(a, b):

    if(a > b):
        return True
    else:
        return False

def dominates(individualA, individualB):
    '''
        Dominates
        Retuen the domination relationship
    '''
    a = False
    for i in range(0, len(individualA)):
        if is_worse(individualA[i], individualB[i]):
            return False
        if is_better(individualA[i], individualB[i]):
            a = True
    return a

def fast_non_dominated_sort(objectives):
    '''
        Fast NonDominated Sort
        Return the non-dominated sets
    '''
    f = []
    f.append([])

    dominated_index = []

    dominated_count = []

    for i in objectives:
        dominated_index.append([])
        dominated_count.append(0)

    # calculate the dominated relationship between each individual

    for idx_A, individual_A in enumerate(objectives):
        # print(individualA.name)
        for idx_B, individual_B in enumerate(objectives):

            if dominates(individual_A, individual_B):
                dominated_index[idx_A].append(idx_B)

                # print("\t",individualB.name)
            elif dominates(individual_B, individual_A):
                dominated_count[idx_A] = dominated_count[idx_A] + 1

        if dominated_count[idx_A] == 0:  # if np == 0:
            f[0].append(idx_A)

        # calculate and sort the ranks relationship
    i = 0
    while(len(f[i]) != 0):
        h = []
        for p_idx in f[i]:
            for q in dominated_index[p_idx]:  # for q in sp:
                dominated_count[q] = dominated_count[q] - 1
                if dominated_count[q] == 0:
                    h.append(q)
                    # q.rank = i + 1 #Agrega el atributo de rank en el individuo...
        i = i + 1

        f.append(h)  # f[i] = h

    return f

def knee_mdd_selection(non_dominated_objectives):

    obj_max_array = []
    obj_min_array = []
    Lm = []

    dist = []

    for i in range(non_dominated_objectives.shape[0]):
        dist.append(0)

    for m in range(non_dominated_objectives.shape[1]):
        obj_max_array.append(np.max(non_dominated_objectives[:, m]))
        obj_min_array.append(np.min(non_dominated_objectives[:, m]))

        Lm.append(obj_max_array[m]-obj_min_array[m])

        for i, obj_A in enumerate(non_dominated_objectives):
            dist[i] = dist[i] + \
                ((obj_A[m] - obj_min_array[m]) / Lm[m])  # Lm[m]

            #print('idl:',i,'obj: ',m,'dist: ',( (obj_A[m] - obj_min_array[m]) / Lm[m] ))

    kneeval = np.max(dist)
    kneeidx = np.argmax(dist)
    for idx, val in enumerate(dist):
        if(val == 1):
            continue
        if(val < kneeval):
            kneeval = val
            kneeidx = idx

    return kneeidx

def boundary_individuals_selection(non_dominated_objectives):

    obj_max_array = []
    obj_min_array = []

    obj_max_idx = []
    obj_min_idx = []

    for i in range(non_dominated_objectives.shape[1]):
        # obj_max_array.append(np.max(self.non_dominated_objectives[:,i]))
        obj_min_array.append(np.min(non_dominated_objectives[:, i]))

        # obj_max_idx.append(np.argmax(self.non_dominated_objectives[:,i]))
        obj_min_idx.append(np.argmin(non_dominated_objectives[:, i]))

    return obj_min_idx

def train(X, Y, I, L, net_shapes, net_params, optimizer, utility, pool, individual_size, sigma, boundary_size=4):

    noise_seed = np.random.randint(
        0, 2 ** 32 - 1, size=individual_size, dtype=np.uint32).repeat(2)    # mirrored sampling

    pick_seed = np.random.randint(
        0, boundary_size, size=individual_size, dtype=np.uint32).repeat(2)    # mirrored sampling

    # distribute training in parallel
    jobs = [pool.apply_async(kgpn.get_reward, (net_shapes, net_params[pick_seed[k_id]], X, Y, I, L, sigma,
                                               [noise_seed[k_id], k_id], )) for k_id in range(individual_size*2)]

    rewards = np.array([j.get()[0] for j in jobs])

    new_params = ([j.get()[1] for j in jobs])

    sort_rewards = rewards[:, 0]

    # rank kid id by reward
    kids_rank = np.argsort(sort_rewards)[::-1]

    non_domin_rank = fast_non_dominated_sort(rewards)

    non_dominted_set_idxs = non_domin_rank[0]

    if(len(non_dominted_set_idxs) < boundary_size):
        non_dominted_set_idxs.append(non_domin_rank[1][0])

    non_dominated_objectives = np.array(
        [rewards[idx] for idx in non_dominted_set_idxs])

    knee_idx = knee_mdd_selection(non_dominated_objectives)

    # get the best individual, aka the knee individual

    best_params = new_params[non_dominted_set_idxs[knee_idx]]

    best_rewards = rewards[non_dominted_set_idxs[knee_idx]]

    boundary_idxs = boundary_individuals_selection(non_dominated_objectives)

    knee_boundary_idxs = [non_dominted_set_idxs[x] for x in boundary_idxs]

    knee_boundary_idxs.insert(0, non_dominted_set_idxs[knee_idx])

    cumulative_update = np.zeros_like(
        net_params[0])       # initialize update values

    knee_boundary_set = [new_params[x] for x in knee_boundary_idxs]

    #variations
    for ui, k_id in enumerate(knee_boundary_idxs):
        # reconstruct noise using seed
        np.random.seed(noise_seed[k_id])
        cumulative_update += utility[ui] * np.random.randn(net_params[0].size)

    gradients = optimizer.get_gradients(cumulative_update/((len(knee_boundary_idxs))*sigma))

    for p in knee_boundary_set:
        p = p + gradients

    print(len(knee_boundary_set),rewards[knee_boundary_idxs[0]])
    print(len(knee_boundary_set),rewards[knee_boundary_idxs[1]])
    print(len(knee_boundary_set),rewards[knee_boundary_idxs[2]])
    print(len(knee_boundary_set),rewards[knee_boundary_idxs[3]])
    return knee_boundary_set, best_rewards

def execute(config, trainX, trainY, trainI, trainL, testX, testY, testI, testL, pretrained=None, wandb=None):

    # utility instead reward for update parameters (rank transformation)
    base = config.individual_size * 2    # *2 for mirrored sampling
    rank = np.arange(1, base + 1)
    util_ = np.maximum(0, np.log(base / 2 + 1) - np.log(rank))
    utility = util_ / util_.sum() - 1 / base #

    # build Network
    net_shapes, net_params = kgpn.build_net(
        config.input_size, config.action_size, config.output_size)

    if(pretrained is not None):
        print("load pretrained")
        net_params[(config.input_size+1):] = pretrained

    optimizer = SGD(net_params, config.learning_rate)
    pool = mp.Pool(processes=config.core_size)
    mar = None      # moving average reward

    params_set = [net_params, net_params, net_params, net_params]

    for g in range(config.population_size):
        t0 = time.time()
        params_set, kid_rewards = train(trainX, trainY, trainI, trainL,
                                        net_shapes, params_set, optimizer, utility, pool, config.individual_size, config.sigma)

        # test trained net without noise
        net_r = kgpn.get_reward(
            net_shapes, params_set[0], trainX, trainY, trainI, trainL, None)[0]

        # mar = net_r if mar is None else 0.9 * mar + 0.1 * net_r       # moving average reward

        testing_r = kgpn.get_reward(
            net_shapes, params_set[0], testX, testY, testI, testL, None, real_value = True)[0]

        if (wandb is not None):

            wandb.log({'epoch': g,
                       "training/accuracy": 1-net_r[0],
                       "training/earliness": net_r[1],
                       "training/reward": net_r[2],
                       "testing/accuracy": 1-testing_r[0],
                       "testing/earliness": testing_r[1],
                       "testing/reward": testing_r[2]
                       })

        print(
            'Gen: ', g,
            '| Accuracy: %.4f' % float(1-net_r[0]),
            '| Earliness: %.4f' % float(net_r[1]),
            '| Reward: %.4f' % float(net_r[2]),
            '| Gen_T: %.2f' % (time.time() - t0),)

        print(
            'Testing: ', g,
            '| Accuracy: %.4f' % float(1-testing_r[0]),
            '| Earliness: %.4f' % float(testing_r[1]),
            '| Reward: %.4f' % float(testing_r[2]),

        )

        # if mar >= CONFIG['eval_threshold']: break

    return net_shapes, params_set

if __name__ == "__main__":

    for seed in range(1, 2):

        config = Config(seed = seed,message ="{Setting a mark}",
                        population_size=500,output_size=9,learning_rate=0.01,
                        model_name="CNNLSTM",state_model_name="CNNLSTM",dataset_name="ICBEB")

        state_path = os.path.join(config.root_dir,
                                  config.output_dir,
                                  config.state_dir,
                                  config.state_model_name,
                                  config.dataset_name,
                                  str(seed))

        model_path = os.path.join(config.root_dir,
                                  config.output_dir,
                                  config.model_dir,
                                  config.model_name,
                                  config.dataset_name,
                                  str(seed))

        log_path = os.path.join(config.root_dir,
                                          config.output_dir,
                                          config.wandb_dir,
                                          config.model_name,
                                          config.dataset_name,
                                          str(seed))

        uio.check_folder(model_path)

        uio.check_folder(log_path)

        wandb.init(project="etscmoo",
                           entity='hugo',
                           dir = log_path,
                           name = config.model_name,
                           config=config,
                           reinit=True)

        if (config.dataset_name in ["ICBEB","ptbxl"]):
            weight_path = os.path.join(config.root_dir,
                                            config.output_dir,
                                            config.weight_dir,
                                            config.state_model_name,
                                            config.dataset_name,
                                            str(seed))
            uio.check_folder(weight_path)

            weight_dict = uio.load_pkfile(weight_path+"/"+config.weight_name)

            pretrained = np.concatenate((weight_dict['weight'].flatten(),weight_dict['bias']))

        data_dict = uio.load_state_data(
            state_path+"/"+config.state_name)

        trainX = data_dict['training']
        trainY = data_dict['training_label']
        testX = data_dict['testing']
        testY = data_dict['testing_label']
        trainI = data_dict["training_index"]
        testI = data_dict["testing_index"]
        trainL = data_dict['training_length']
        testL = data_dict['testing_length']

        net_shapes, params_set = execute(
            config, trainX, trainY, trainI, trainL,
            testX, testY, testI, testL,
            pretrained = pretrained, wandb=wandb)

        model = {"shapes": net_shapes,
                 "knee": params_set[0],
                 "boundary_1": params_set[1],
                 "boundary_2": params_set[2],
                 "boundary_3": params_set[3]}

        uio.save_pkfile(model_path+"/"+config.model_save_name, model)

        wandb.save(model_path+"/"+config.model_save_name)


import nussl
import pytest
import numpy as np
from nussl.core.audio_signal import AudioSignalException
from nussl.core.masks import BinaryMask, SoftMask, MaskBase
from copy import deepcopy

sr = nussl.constants.DEFAULT_SAMPLE_RATE
dur = 3  # seconds
length = dur * sr
stft_tol = 1e-6

def test_apply_mask(benchmark_audio):
    for key, path in benchmark_audio.items():
        signal = nussl.AudioSignal(path)
        signal.stft()

        mask_data = np.random.rand(*signal.stft_data.shape)
        soft_mask = SoftMask(mask_data)
        inverse_mask = soft_mask.inverse_mask()
        bad_mask = SoftMask(mask_data[0])

        signal.stft_data = None
        pytest.raises(AudioSignalException, signal.apply_mask, soft_mask)
        signal.stft()
        pytest.raises(AudioSignalException, signal.apply_mask, [0])
        pytest.raises(AudioSignalException, signal.apply_mask, bad_mask)

        s1 = signal.apply_mask(soft_mask)
        s1.istft(truncate_to_length=signal.signal_length)
        s2 = signal.apply_mask(inverse_mask)
        s2.istft(truncate_to_length=signal.signal_length)

        recon = s1 + s2

        assert np.allclose(recon.audio_data, signal.audio_data, atol=stft_tol)

        mask_data = np.random.rand(*signal.stft_data.shape) > .5
        binary_mask = BinaryMask(mask_data)
        inverse_mask = binary_mask.inverse_mask()

        s1 = signal.apply_mask(binary_mask)
        s1.istft(truncate_to_length=signal.signal_length)
        s2 = signal.apply_mask(inverse_mask)
        s2.istft(truncate_to_length=signal.signal_length)

        recon = s1 + s2

        assert np.allclose(recon.audio_data, signal.audio_data, atol=stft_tol)

        signal.apply_mask(binary_mask, overwrite=True)

        assert np.allclose(signal.stft_data, s1.stft_data)

def test_create_mask():
    mask_data = np.random.rand(1025, 400, 1)
    pytest.raises(NotImplementedError, lambda x: MaskBase(x), mask_data)
    pytest.raises(ValueError, lambda x: MaskBase(), mask_data)
    pytest.raises(NotImplementedError,
                  lambda x: MaskBase._validate_mask(mask_data), mask_data)
    pytest.raises(ValueError, lambda x: MaskBase(
        input_mask=mask_data, mask_shape=mask_data.shape), mask_data)
    bad_data = np.random.rand(1025, 400, 1, 1)
    pytest.raises(ValueError, lambda x: SoftMask(input_mask=x), bad_data)
    bad_data = np.random.rand(1025)
    pytest.raises(ValueError, lambda x: SoftMask(input_mask=x), bad_data)
    pytest.raises(ValueError, SoftMask, [0])

    pytest.raises(ValueError, lambda x: SoftMask(input_mask=x), mask_data > .5)

    s1 = SoftMask(mask_data)
    thresholds = [.1, .2, .5, 1.0]
    for t in thresholds:
        binary_mask = s1.mask_to_binary(t)
        assert np.allclose(binary_mask.mask, mask_data > t)

    m1 = np.zeros((1025, 400, 1))
    s1 = SoftMask.zeros(m1.shape)
    assert np.allclose(s1.mask, m1)

    m1 = np.ones((1025, 400, 1))
    s1 = SoftMask.ones(m1.shape)
    assert np.allclose(s1.mask, m1)

    m1 = np.ones((1025, 400, 1)).astype(float)
    s1 = SoftMask(m1)
    assert s1.dtype == float
    assert s1.shape == (1025, 400, 1)
    assert s1.num_channels == 1

    m1 = np.zeros((1025, 400, 1))
    s1 = SoftMask(mask_shape=m1.shape)
    assert np.allclose(s1.mask, m1)

def test_binary_mask():
    mask_data = np.random.rand(1025, 400, 2)
    mask_data = mask_data > .5
    binary_mask = BinaryMask(mask_data)

    assert np.allclose(binary_mask.mask_as_ints(), mask_data.astype(int))

    for ch in range(mask_data.shape[-1]):
        int_mask = binary_mask.mask_as_ints(ch)
        assert np.allclose(int_mask, mask_data[..., ch].astype(int))

    pytest.raises(ValueError, BinaryMask, mask_data + 1)
    pytest.raises(ValueError, BinaryMask, mask_data * .5)

    binary_mask = BinaryMask(mask_data * .9999)
    assert np.allclose(binary_mask.mask, mask_data)

def test_mask_get_channels():
    mask_data = np.random.rand(1025, 400, 2)
    soft_mask = SoftMask(mask_data)
    for ch in range(mask_data.shape[-1]):
        _mask_ch = soft_mask.get_channel(ch)
        assert np.allclose(_mask_ch, mask_data[..., ch])

    pytest.raises(ValueError, soft_mask.get_channel, 2)
    pytest.raises(ValueError, soft_mask.get_channel, -1)

def test_mask_arithmetic():
    m1 = np.random.rand(1025, 400, 1)
    m2 = np.random.rand(1025, 400, 1)
    s1 = SoftMask(m1)
    s2 = SoftMask(m2)

    pytest.raises(ValueError, lambda x: x * [0], s1)
    pytest.raises(ValueError, lambda x: x + [0], s1)

    r1 = s1 + s2
    assert np.allclose(r1.mask, m1 + m2)

    r1 = s1 + s2.mask
    assert np.allclose(r1.mask, m1 + m2)

    r1 = s1 - s2
    assert np.allclose(r1.mask, m1 - m2)

    r1 = s1 * 2
    assert np.allclose(r1.mask, m1 * 2)

    r1 = 2 * s1
    assert np.allclose(r1.mask, m1 * 2)

    r1 = deepcopy(s1)
    r1 += s1
    assert np.allclose(r1.mask, m1 * 2)

    r1 = deepcopy(s1)
    r1 -= s1
    assert np.allclose(r1.mask, m1 * 0)

    r1 = deepcopy(s1)
    r1 *= 2
    assert np.allclose(r1.mask, m1 * 2)

    r1 = deepcopy(s1)
    r1 /= .5
    assert np.allclose(r1.mask, m1 * 2)

    r2 = SoftMask(m1 * 2)
    assert r1 == r2
    r2 *= .5
    assert r1 != r2

def test_masks_sum_to_mix(benchmark_audio):
    for key, path in benchmark_audio.items():
        signal = nussl.AudioSignal(path)
        signal.stft()

        for num_sources in range(1, 4):
            shape = signal.stft_data.shape + (num_sources,)

            random_masks = np.random.random(shape)
            random_masks = (
                    random_masks /
                    np.sum(random_masks, axis=-1, keepdims=True)
            )
            estimates = []

            for i in range(num_sources):
                mask = SoftMask(random_masks[..., i])
                estimate = signal.apply_mask(mask)
                estimate.istft()
                estimates.append(estimate)

            assert np.allclose(
                sum(estimates).audio_data,
                signal.audio_data,
                atol=stft_tol
            )


class Solution(object):
    def calculateMinimumHP(self, dungeon):
        """
        :type dungeon: List[List[int]]
        :rtype: int
        """
        '''
        状态：健康点
        选择：往下还是往右
        从 grid[i][j] 到达终点（右下角）所需的最少生命值是 dp[i][j]
        base case：dp[i][j] = -dungeon[i][j] + 1 if dungeon[i][j]<=0 else 1
        根据选择，状态转移的逻辑:dp[i][j] = min(dp[i+1][j],dp[i][j+1]) - dungeon[i][j]
        '''
        m = len(dungeon)
        n = len(dungeon[0])
        dp = [[0]*n for _ in range(m)]
        dp[m-1][n-1]= -dungeon[m-1][n-1] + 1 if dungeon[m-1][n-1]<=0 else 1
        for i in range(m-2,-1,-1):
            res = dp[i+1][n-1] - dungeon[i][n-1]
            dp[i][n-1] = res if res > 0 else 1
        for j in range(n-2,-1,-1):
            res = dp[m-1][j+1] - dungeon[m-1][j]
            dp[m-1][j] = res if res > 0 else 1
        for i in range(m-2,-1,-1):
            for j in range(n-2,-1,-1):
                res = min(dp[i+1][j],dp[i][j+1]) - dungeon[i][j]
                #骑士的生命值至少为 1
                dp[i][j] = res if res > 0 else 1
        return dp[0][0]


# -*- coding: utf-8 -*-
from pypandoc import convert_file
from re import sub
from datetime import datetime

from .modules.plotter import Plotter

class TrackYou(object):
    def __init__(self, target: str, title: str, output_dir: str, plot_feature: bool = False):
        self.target = target
        self.title = title
        self.output_dir = output_dir
        self.plot_feature = plot_feature

        if plot_feature:
            self.trackyou_plt = Plotter(output_dir + title + '.tsv')

    def report(self):
        print(self.output_dir + self.title + '.tsv')

        with open(self.output_dir + self.title + '.tsv', 'a') as f:
            print(self._daystring(), self._count(), sep='\t', file=f)

        if self.plot_feature:
            self.trackyou_plt.run_server()

    def _count(self):
        document = convert_file(self.target, 'plain')
        document = sub(r'\n|\-|\s|=', '', document)
        return len(document)

    def _daystring(self):
        return str(datetime.today()).split()[0]


from itertools import combinations
'''
에라토스테네스의 체에 의한 소수 구하기
1. 2부터 n 까지의 소수를 구한다 하였을 때, n의 최대약수는 sqrt(n)이다
2. 2부터 시작하여 수의 배수를 모두 걸러준다.
3. 즉, 2 부터 sqrt(n)까지 반복하여 약수들의 배수를 모두 걸러준다
4. 최종적으로 걸러지지 않은 수들은 모두 소수이다
'''
nums = [1,2,7,6,4]

def prime_list(n):
    # 에라토스테네스의 체 초기화: n개 요소에 True 설정(소수로 간주)
    isPrime = [True] * n
    # n의 최대 약수가 sqrt(n) 이하이므로 i=sqrt(n)까지 검사
    m = int(n ** 0.5)+1
    for i in range(2, m):
        if isPrime[i] == True:           # i가 소수인 경우
            for j in range(i+i, n, i): # i를 제외하고 i의 배수들은 모두 걸러준다
                isPrime[j] = False
    # 소수 목록 산출
    return [i for i in range(2, n) if isPrime[i] == True]

def solution(nums):
    primeList = prime_list(3000)
    # nums 의 각 원소는 1 이상 1000 이하의 자연수이며 3개를 뽑기 때문에 최대 nums의 합은 3000이다.
    # 즉 2에서 3000까지의 소수들을 모두 구한뒤 시작한다
    primeCnt =0
    # combinations 를 이용하여 n개의 수중에서 r개를 뽑는 nCr을 만든다
    cases = list(combinations(nums,3)) #[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]
    # 각 케이스 별로 그들의 합이 소수인지 판별하여 소수인 경우의 수를 카운트 하여 리턴하자
    for case in cases:
        if sum(case) in primeList: # 만약 케이스의 합이 소수리스트에 있다면 카운트 +1
            primeCnt+=1
    return primeCnt

print(solution(nums))
'''
리뷰: 이전에 소수를 구하는 문제를 어느정도 접해봐서 생각했던 대로 구현할 수 있었습니다. 그리고 경우의 수를 구하는 것을 쉽게 해주는 combinations 라이브러리는
모든 경우의 수를 탐색하여 판별하는 문제에서 자주 등장하기 때문에 이번 기회에 다시 사용하면서 좀 익숙해진것 같습니다. 에라토스테네스의 체 같은 경우 일반적으로
떠올릴 수 있는 소수 판별법인 2부터 타겟 숫자까지를 나눴을 때 한번 밖에 안나눠떨어지면 소수이다 하는 방법은 O(n^2)인 반면 에라토스테네스의 체를 이용할 경우
O(Nlog(logN)으로 줄일 수 있기 때문에 확연한 차이를 보여준다. 이는 1000 단위를 넘어서는 순간부터는 O(n^2)의 방법을 사용할 경우 제시간에 문제가 도출되지
않는 점을 어느정도 개선할 수 있다 생각하여 좋았다. n까지의 최대약수가 루트n 이라는 점은 다소 이해하기 어려운 개념이였지만 계속 활용해나가며 익숙해지도록 노력
해야겠다
'''


from pathlib import Path

DATA = (Path(__file__).parent / "data" / "day2.txt").read_text()

def puzzle1():
    entries = list(filter(bool, DATA.split("\n")))

    class Point:
        __slots__ = ("x", "y")

        def __init__(self, x: int, y: int):
            self.x = x
            self.y = y

        def __add__(self, other: "Point") -> "Point":
            return self.__class__(self.x + other.x, self.y + other.y)

        def __repr__(self):
            return f"<Point({self.x}, {self.y})>"

    movement = {
        "forward": lambda x: Point(x, 0),
        "down": lambda x: Point(0, x),
        "up": lambda x: Point(0, -x),
    }

    pos = Point(0, 0)
    for item in entries:
        command, value = item.split()
        pos += movement[command](int(value))

    print(pos)
    print(pos.x * pos.y)

def puzzle2():
    entries = list(filter(bool, DATA.split("\n")))

    pos, depth, aim = 0, 0, 0
    for item in entries:
        command, value = item.split()
        value = int(value)
        if command == "down":
            aim += value
        elif command == "up":
            aim -= value
        elif command == "forward":
            pos += value
            depth += aim * value
        else:
            raise RuntimeError(f"Unknown command: {command}")

    print(pos, depth, aim)
    print(pos * depth)

if __name__ == "__main__":
    try:
        puzzle2()
    except NameError as e:
        if str(e) != "name 'puzzle2' is not defined":
            raise
        puzzle1()


# amount of ingredients needed for 1 cup of coffee and its price depending on its type
espresso = {'water': 250, 'beans': 16, 'money': 4}
latte = {'water': 350, 'milk': 75, 'beans': 20, 'money': 7}
cappuccino = {'water': 200, 'milk': 100, 'beans': 12, 'money': 6}

coffee_type = {1: espresso, 2: latte, 3: cappuccino}

# intial coffee machine stock
stock = {'water': 400, 'milk': 540, 'beans': 120, 'cups': 9, 'money': 550}

def buy_coffee(coffee):
    # checking if sufficient quantity of ingredients is available in stock
    for item, quantity in coffee.items():
        if item == 'money':
            continue
        elif stock[item] < quantity:
            return print(f'Sorry, not enough {item}!')

    # deduct amount of respective ingredients in stock and add money
    for key, value in coffee.items():
        if key == 'money':
            stock[key] = stock[key] + value
        else:
            stock[key] = stock[key] - value
    stock['cups'] -= 1

def print_stock():
    print('\nThe coffee machine has:')
    print(f'{stock["water"]} ml of water')
    print(f'{stock["milk"]} ml of milk')
    print(f'{stock["beans"]} g of coffee beans')
    print(f'{stock["cups"]} disposable cups')
    print(f'{stock["money"]} of money')
    return

def fill_coffee_machine():
    replenish = {'water': 0, 'milk': 0, 'beans': 0, 'cups': 0}
    print('Write how many ml of water you want to add:')
    replenish['water'] = int(input())
    print('Write how many ml of milk you want to add:')
    replenish['milk'] = int(input())
    print('Write how many grams of coffee beans you want to add:')
    replenish['beans'] = int(input())
    print('Write how many disposable cups you want to add:')
    replenish['cups'] = int(input())

    for key, value in replenish.items():
        stock[key] = stock[key] + value

def withdraw_cash():
    print(f'\nI gave you ${stock["money"]}')
    stock['money'] = 0

def select_coffee():
    print('\nWhat do you want to buy? 1 - espresso, 2 - latte, 3 - cappuccino, back - to main menu:')
    try:
        coffee = int(input())
        return buy_coffee(coffee_type[coffee])
    except ValueError:
        return main()

def main():
    print('\nWrite action (buy, fill, take, remaining, exit):')
    user_input = input()
    if user_input == 'buy':
        select_coffee()
    elif user_input == 'fill':
        fill_coffee_machine()
    elif user_input == 'take':
        withdraw_cash()
    elif user_input == 'remaining':
        print_stock()
    elif user_input == 'exit':
        exit()
    return main()

if __name__ == '__main__':
    main()


from copy import copy

def main():
    # Take a sequence from the user
    sequence = input("Enter a sequence of letter: ")

    # Recursively add the permutations of the string
    permutations = get_permutation(sequence)

    print(f"\n-----------\nNumber of permutations: {len(permutations)}\nPermutations: {permutations}\n----------\n")

def get_permutation(sequence):

    # Base case
    if len(sequence) == 1:
        return list(sequence)
    else:
        # We hold the first letter of the sequence and sends the rest to the recursive function

        return permute(get_permutation(sequence[1:]), sequence[0])

def permute(sequence_list, letter):
    """Returns a list of all the permutation of a sequence of characters."""

    permutation_list = []
    # For each words in the sequence_list we will add the letter at all the positions in the sequence
    for word in sequence_list:
        length = len(word)

        # Include the letter at every position in the current sequence
        for i in range(length + 1):
            permutation_list.append(word[0:i] + letter + word[i:])

    return permutation_list

if __name__ == "__main__":
    main()


# pip install --upgrade tf-keras-vis tensorflow

import numpy as np
import tensorflow as tf

from tensorflow.keras.applications.vgg16 import VGG16 as Vgg16Model

model = Vgg16Model(weights='imagenet', include_top=True)
print (model.summary())

# define a function to modify the model
# we will change the softmax to a linear function

def model_modifier(modl):
    modl.layers[-1].activation = tf.keras.activations.linear # All the layers except the last one will have activation=linear

# create an object instance of Acticvation maximization class

from tf_keras_vis.activation_maximization import ActivationMaximization

activation_maximization = ActivationMaximization(model,
                                                model_modifier,
                                                clone=True) # clone means , duplicate the model and not update the current one

# Now , We will define a loss function that maximize a specific class.
# leats maximize the class of "Persian cat" , class no. 283

# https://deeplearning.cms.waikato.ac.nz/user-guide/class-maps/IMAGENET/

def loss(output):
    return output[:, 283]

# visual the class

from tf_keras_vis.utils.callbacks import Print

activation = activation_maximization(loss,
                                    callbacks=[Print(interval=50)]    )

#lets grab the image after running the process
image = activation[0].astype(np.uint8)

# show the image using OpenCv
import cv2

# change the image from RGB to BGR

imageCV = cv2.cvtColor(image , cv2.COLOR_RGB2BGR)

# enlarge the image
scale_percent = 200
w = int(imageCV.shape[1]* scale_percent / 100)
h = int(imageCV.shape[0]* scale_percent / 100)
dim = (w, h)

resized = cv2.resize(imageCV, dim , interpolation=cv2.INTER_AREA)

cv2.imshow("Persian Cat",resized )
cv2.waitKey(0)


import os

from jupyter_core.application import JupyterApp
from overrides import overrides
from traitlets import Bool, Unicode, default

from .._version import __version__
from .base_app import DEFAULT_LANGUAGE, PYTHON, SCALA, BaseSpecApp, R

DEFAULT_KERNEL_NAMES = {PYTHON: "docker_python", SCALA: "docker_scala", R: "docker_r"}
KERNEL_SPEC_TEMPLATE_NAMES = {
    PYTHON: "container_python",
    SCALA: "container_scala",
    R: "container_r",
}
DEFAULT_DISPLAY_NAMES = {PYTHON: "Docker Python", SCALA: "Docker Scala", R: "Docker R"}
DEFAULT_IMAGE_NAMES = {
    PYTHON: "elyra/kernel-py",
    SCALA: "elyra/kernel-scala",
    R: "elyra/kernel-r",
}

DOCKER_PROVISIONER_NAME = "docker-provisioner"
SWARM_PROVISIONER_NAME = "docker-swarm-provisioner"
LAUNCHER_NAME = "launch_docker.py"

class DockerSpecInstaller(BaseSpecApp):
    """CLI for extension management."""

    name = "jupyter-docker-spec"
    description = (
        "Creates a Jupyter kernel specification for use within a Docker or Docker Swarm cluster."
    )
    # Note that the left justification of the second example is necessary to ensure proper
    # alignment with the first example during --help output.
    examples = """
    jupyter-docker-spec install --language=R --kernel-name=r_docker --image_name=foo/my_r_kernel_image:v4_0

jupyter-docker-spec install --swarm --kernel-name=python_swarm
    """

    @default("kernel_name")
    def _kernel_name_default(self) -> str:
        return DEFAULT_KERNEL_NAMES[DEFAULT_LANGUAGE]

    @default("display_name")
    def _display_name_default(self) -> str:
        return DEFAULT_DISPLAY_NAMES[DEFAULT_LANGUAGE]

    # Image name
    image_name_env = "GP_IMAGE_NAME"
    image_name = Unicode(
        None,
        config=True,
        allow_none=True,
        help="""The kernel image to use for this kernel specification. If this specification is
enabled for Spark usage, this image will be the driver image. (GP_IMAGE_NAME env var)""",
    )

    @default("image_name")
    def _image_name_default(self):
        return os.getenv(self.image_name_env)

    # Flags
    swarm = Bool(
        False, config=True, help="Install kernelspec for use within a Docker Swarm cluster."
    )

    provisioner_name = Unicode(DOCKER_PROVISIONER_NAME, config=False)
    launcher_name = Unicode(LAUNCHER_NAME, config=False)

    aliases = {
        "image-name": "DockerSpecInstaller.image_name",
    }
    aliases.update(BaseSpecApp.aliases)

    flags = {
        "swarm": (
            {"DockerSpecInstaller": {"swarm": True}},
            swarm.help,
        ),
    }
    flags.update(BaseSpecApp.flags)

    @overrides
    def detect_missing_extras(self):
        super().detect_missing_extras()
        try:
            import docker  # type:ignore[import] # noqa: F401
        except ImportError:
            self.log.warning(
                "The extra package 'docker' is not installed in this environment and is required.  "
                "Ensure that gateway_provisioners is installed by specifying the extra 'docker' "
                "(e.g., pip install 'gateway_provisioners[docker]')."
            )

    @overrides
    def validate_parameters(self):
        super().validate_parameters()

        self.language = self.language.lower()
        self.launcher_dir_name = "docker"
        self.resource_dir_name = self.language

        self.provisioner_name = SWARM_PROVISIONER_NAME if self.swarm else DOCKER_PROVISIONER_NAME

        if self.kernel_name == DEFAULT_KERNEL_NAMES[DEFAULT_LANGUAGE]:
            self.kernel_name = DEFAULT_KERNEL_NAMES[self.language]
        if self.display_name == DEFAULT_DISPLAY_NAMES[DEFAULT_LANGUAGE]:
            self.display_name = DEFAULT_DISPLAY_NAMES[self.language]

        self.kernel_spec_dir_name = KERNEL_SPEC_TEMPLATE_NAMES[self.language]

        if self.image_name is None:
            self.image_name = f"{DEFAULT_IMAGE_NAMES[self.language]}:{self._get_tag()}"

        # sanitize kernel_name
        self.kernel_name = self.kernel_name.replace(" ", "_")

    @overrides
    def get_substitutions(self, install_dir) -> dict:
        substitutions = super().get_substitutions(install_dir)
        substitutions["image_name"] = self.image_name
        substitutions["provisioner_name"] = self.provisioner_name
        substitutions["launcher_name"] = self.launcher_name
        return substitutions

class DockerProvisionerApp(JupyterApp):
    """Application responsible for driving the creation of Docker-based kernel specifications."""

    version = __version__
    name = "jupyter docker-spec"
    description = """Application used to create kernel specifications for use on Docker or Docker Swarm clusters
    via the DockerProvisioner or DockerSwarmProvisioner kernel provisioners."""
    subcommands = {
        "install": (
            DockerSpecInstaller,
            DockerSpecInstaller.description.splitlines()[0],
        ),
    }
    aliases = {}
    flags = {}

    def start(self):
        super().start()

        if self.subapp is None:
            print(f"No subcommand specified. Must specify one of: {list(self.subcommands)}")
            print()
            self.print_description()
            self.print_subcommands()
            self.exit(1)

if __name__ == "__main__":
    DockerProvisionerApp.launch_instance()


import time
import re
import numpy as np
from colonyModule.Node import Node
from colonyModule.Colony import Colony

def read_dataset(path):
    dataset = open(path, "r")

    i = 0

    while True:
        line = dataset.readline()

        if not line:
            break

        if(i == 0):
            n_nodes = int(line)
            costs = {(i, j): 0 for i in range(n_nodes) for j in range(n_nodes)}
        elif(i == 1):
            demand = [int(q) for q in line.split()]
        elif(i == 2):
            capacity_vehicles = int(line)
        else:
            j = 0
            for el in line.split():
                costs[(i-3, j)] = float(el)
                j = j+1

        i = i+1

    dataset.close()

    return (n_nodes, costs, demand, capacity_vehicles)

def test_datasets(datasets, colony_size, alpha, beta, gamma, lam, rho, sigma, iterations):
    solutions = []
    for dataset in datasets:
        n_nodes, cost_dict, demand, max_load = read_dataset(dataset["file"])
        nodes = []

        for i in range(n_nodes):
            nodes.extend([Node(i)])

        def cost_function(from_node, to_node):
            return cost_dict[(from_node.id, to_node.id)]

        cost_matrix = np.array(list(cost_dict.values())).reshape(n_nodes, n_nodes)

        try:
            colony = Colony(nodes, demand, nodes[0], max_load, colony_size, alpha, beta,
                            gamma, lam, rho, sigma, iterations, cost_function, None, cost_matrix)
            start = time.time()
            solution = colony.foraging()
            end = time.time()
            datasetName = re.sub(r"\/.*\/", "", dataset["file"])
            solution["dataset"] = datasetName
            solution["time"] = round(end-start, 2)
            solution["gap"] = round(
                (((solution["cost"]/dataset["best"])-1)*100), 2)
            solution["route"] = [node.id for route in solution["route"]
                                 for node in route]
            solutions.append(solution)
            print(datasetName + " ok")
        except IndexError as e:
            print(datasetName + " no", e)

    return solutions

if __name__ == "__main__":
    datasets = [{"file": "dataset/parma5.txt", "best": 19500},
                {"file": "dataset/bergamo5.txt", "best": 7900},
                {"file": "dataset/parma8.txt", "best": 22700},
                {"file": "dataset/bergamo8.txt", "best": 10400},
                {"file": "dataset/parma9.txt", "best": 23400},
                {"file": "dataset/bergamo9.txt", "best": 10200},
                {"file": "dataset/parma10.txt", "best": 25400},
                {"file": "dataset/bergamo10.txt", "best": 10800}]

    datasets += [{"file": "dataset/1Bari30.txt", "best": 14600},
                 {"file": "dataset/2Bari20.txt", "best": 15700},
                 {"file": "dataset/3Bari10.txt", "best": 20600},
                 {"file": "dataset/4ReggioEmilia30.txt", "best": 16900},
                 {"file": "dataset/5ReggioEmilia20.txt", "best": 23200},
                 {"file": "dataset/6ReggioEmilia10.txt", "best": 32500},
                 {"file": "dataset/7Bergamo30.txt", "best": 12600},
                 {"file": "dataset/8Bergamo20.txt", "best": 12700},
                 {"file": "dataset/9Bergamo12.txt", "best": 13500},
                 {"file": "dataset/10Parma30.txt", "best": 29000},
                 {"file": "dataset/11Parma20.txt", "best": 29000},
                 {"file": "dataset/12Parma10.txt", "best": 32500},
                 {"file": "dataset/13Treviso30.txt", "best": 29259},
                 {"file": "dataset/14Treviso20.txt", "best": 29259},
                 {"file": "dataset/15Treviso10.txt", "best": 31443},
                 {"file": "dataset/16LaSpezia30.txt", "best": 20746},
                 {"file": "dataset/17LaSpezia20.txt", "best": 20746},
                 {"file": "dataset/18LaSpezia10.txt", "best": 22811},
                 {"file": "dataset/19BuenosAires30.txt", "best": 76999},
                 {"file": "dataset/20BuenosAires20.txt", "best": 91619},
                 {"file": "dataset/21Ottawa30.txt", "best": 16202},
                 {"file": "dataset/22Ottawa20.txt", "best": 16202},
                 {"file": "dataset/23Ottawa10.txt", "best": 17576}]

    solutions = test_datasets(datasets, colony_size=50, alpha=6,
                              beta=5, gamma=5, lam=5, rho=0.4, sigma=1, iterations=100)

    print("\n")

    for solution in solutions:
        print(solution["dataset"], solution["cost"],
              solution["time"], solution["gap"])


import TextBox
import Button
import OptionsMenu
import pygame
import Colors

class MainMenu(object):
    """description of class"""
    def __init__(self, scr, mouse, keyboard, fscr_offset, maxOffset):
        self.scr = scr
        self.mouse = mouse
        self.keyboard = keyboard
        self.fscr_offset = fscr_offset
        self.maxOffset = maxOffset

        self.backgroundImage = pygame.transform.scale(pygame.image.load('assets/images/kpi_image.png'), self.scr.get_size())

        self.title = TextBox.TextBox(scr,
                                     topLeft=(8*50, 2*50),
                                     dimensions=(10*50, 50),
                                     fscr_offset=fscr_offset,
                                     text="Мафія на кампусі",
                                     textSize=40,
                                     textColor=Colors.BLACK,
                                     bgAlpha=0)
        self.levelsButton = Button.Button(mouse,
                                          scr,
                                          topLeft=(7*50, 5*50),
                                          dimensions=(6*50, 50),
                                          fscr_offset=fscr_offset,
                                          text="Рівні",
                                          textSize=18,
                                          borderColor=Colors.ButtonBorderDefault,
                                          textColor=Colors.ButtonBorderDefault,
                                          bgAlpha=180)
        self.optionsButton = Button.Button(mouse,
                                           scr,
                                           topLeft=(7*50, 7*50),
                                           dimensions=(6*50, 50),
                                           fscr_offset=fscr_offset,
                                           text="Налаштування",
                                           textSize=18,
                                           borderColor=Colors.ButtonBorderDefault,
                                           textColor=Colors.ButtonBorderDefault,
                                           bgAlpha=180)
        self.optionsMenu = None

    def update(self):
        if self.backgroundImage.get_size() != self.scr.get_size():
            self.backgroundImage = pygame.transform.scale(self.backgroundImage, self.scr.get_size())
        self.scr.blit(self.backgroundImage, (0, 0))

        self.title.update()
        self.levelsButton.update(isBlocked=(self.optionsMenu is not None))
        self.optionsButton.update(isBlocked=(self.optionsMenu is not None))
        if self.optionsButton.isPressed:
            self.optionsMenu = OptionsMenu.OptionsMenu(self.scr, self.mouse, self.keyboard, self.fscr_offset, self.maxOffset)

        if self.optionsMenu is not None:
            self.optionsMenu.update()
            if (self.optionsMenu.closeButton.isPressed) or (self.keyboard.esc is True):
                self.optionsMenu = None


import pytest

from libnmstate import netapplier

from .testlib import assertlib
from .testlib.statelib import INTERFACES

def test_set_a_down_iface_down(eth1_up):
    desired_state = {
        INTERFACES: [
            {
                'name': 'eth1',
                'type': 'ethernet',
                'state': 'down',
            }
        ]
    }
    netapplier.apply(desired_state)
    assertlib.assert_state(desired_state)

    netapplier.apply(desired_state)

    assertlib.assert_state(desired_state)

@pytest.mark.xfail(reason='Some ifaces cannot be removed', strict=True)
def test_removing_a_non_removable_iface(eth1_up):
    desired_state = {
        INTERFACES: [
            {
                'name': 'eth1',
                'type': 'ethernet',
                'state': 'absent',
            }
        ]
    }

    netapplier.apply(desired_state)

    assertlib.assert_state(desired_state)


import pytest

from src.csv import _validate

@pytest.mark.parametrize(
    "user_columns, reference_columns, expected_missing_columns",
    [
        pytest.param(
            ["a", "b", "c", "d"],
            ["a", "b", "c", "d"],
            [],
            id="no_missing_columns",
        ),
        pytest.param(
            ["a", "b", "c"],
            ["a", "b", "c", "d"],
            [],
            id="one_missing_column",
        ),
        pytest.param(
            ["b"],
            ["a", "b", "c", "d"],
            [],
            id="three_missing_columns",
        ),
        pytest.param(
            [],
            ["a", "b", "c", "d"],
            [],
            id="all_missing_columns",
        ),
        pytest.param(
            ["a", "b", "c", "d"],
            ["a", "b", "c"],
            ["d"],
            id="one_extra_column",
        ),
        pytest.param(
            ["a", "b", "c", "d", "e", "f"],
            ["a", "b", "c"],
            ["d", "e", "f"],
            id="three_extra_column",
        ),
        pytest.param(
            ["d", "e", "f"],
            ["a", "b", "c"],
            ["d", "e", "f"],
            id="only_extra_column",
        ),
    ],
)
def test_find_missing_columns(
    user_columns, reference_columns, expected_missing_columns
):
    # When
    actual_missing_columns = _validate.find_missing_columns(
        user_columns=user_columns,
        file_columns=reference_columns,
    )

    # Then
    assert actual_missing_columns == expected_missing_columns


from unittest.mock import patch

from click.testing import CliRunner

import main
from main import run

@patch.object(main.Copyist, "__init__")
@patch.object(main.Copyist, "match_source_and_replica")
@patch.object(main, "configure_logging")
def test_run_function(mock_logging, mock_match, mock_instance):
    mock_instance.return_value = None
    runner = CliRunner()
    mock_match.side_effect = Exception
    result = runner.invoke(
        run,
        [
            "--catalog-source",
            "catalog_source",
            "--catalog-replica",
            "catalog_replica",
            "--period",
            "1",
            "--path-log",
            "path_to_log",
        ],
    )
    assert result.exit_code == 1
    mock_logging.assert_called_once_with("path_to_log")
    mock_instance.assert_called_once_with(
        "catalog_source", "catalog_replica", mock_logging()
    )
    mock_match.assert_called_once()


import numpy as np
import pandas as pd
import sklearn
from sklearn import linear_model, pipeline, svm, neighbors
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
import matplotlib.pyplot as plt

def main():
	print("Reading data...")
	X,y = read_data("hackathon.csv")
	# scale_features(X)
	encode_categ_feats(X)

	X = X[:10000, :]
	y = y[:10000, 1]		# 0 = PREMIUM, 1 = TIV, 2 = DED
	# print(y)
	# print(y)
	print(X.shape)

	print("Training model...")
	X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state = 13)

	# Plot data against long and lat
	# plt.scatter(X[:100, 0], y)
	# plt.ylabel('Premium')
	# plt.xlabel('Latitude')
	# plt.show()

	# Polynomial Regression Model
	# poly = preprocessing.PolynomialFeatures(degree=1)
	# X_train = poly.fit_transform(X_train)
	# X_test = poly.fit_transform(X_test)
	# clf = linear_model.LinearRegression()
	# clf.fit(X_train, y_train)

	# SVM Regression Model
	# clf = svm.SVR(degree=5)
	# clf.fit(X_train, y_train)

	# KNN Model
	clf = neighbors.KNeighborsRegressor(n_neighbors=3)
	clf.fit(X_train, y_train)

	print("Computing test accuracies...")
	predictions = clf.predict(X_test)

	# prediction = clf.predict([34.845617, -82.364463, 1, 1, 1950, 980.0300293, 194.0998688])
	# print(prediction)

	# neigh = clf.kneighbors(X_train, return_distance=False)
	# print(neigh)
	# print(X_train[neigh])
	# print(y_train[neigh])
	# predictions = np.mean(y_train[neigh], axis=1)
	r2 = sklearn.metrics.r2_score(y_test, predictions)

	fig1 = plt.figure()
	fig1.suptitle('Estimated TIVs against Location Attributes')

	ax1 = fig1.add_subplot(311)
	ax1.scatter(X_test[:, 0], predictions, c='r', label='Model')
	ax1.scatter(X_test[:, 0], y_test, c='g', label='Actual')
	ax1.set_ylim([0, 1000000])
	ax1.legend(loc='upper left')
	plt.xlabel('Latitude')
	plt.ylabel('TIV')

	ax2 = fig1.add_subplot(312)
	ax2.scatter(X_test[:, 1], predictions, c='r', label='Model')
	ax2.scatter(X_test[:, 1], y_test, c='g', label='Actual')
	ax2.set_ylim([0, 1000000])
	plt.xlabel('Longitude')
	plt.ylabel('TIV')

	ax3 = fig1.add_subplot(313)
	ax3.scatter(X_test[:, 6], predictions, c='r', label='Model')
	ax3.scatter(X_test[:, 6], y_test, c='g', label='Actual')
	ax3.set_ylim([0, 600000])
	plt.xlabel('Distance to Coast')
	plt.ylabel('TIV')

	plt.show()

	abs_error = sklearn.metrics.mean_absolute_error(y_test, predictions)

	# print("Predict:\n", predictions)
	# print("Actual:\n" , y_test)
	print("R2: ", r2)
	print("Absolute error: ", abs_error)

'''
Separates categorical and continuous data
Returns: 2-tuple (continuous feature indices, categorical feature indices)
'''
def cont_categ_split(feats):
	cont_vars = []
	categ_vars = []
	for col in range(feats.shape[1]):
		if isinstance(feats[0,col], str):
			categ_vars.append(col)
		else:
			cont_vars.append(col)

	return cont_vars, categ_vars

'''
Perform z-score standardization for scaling features
'''
def scale_features(feats):

	cont_vars, ret = cont_categ_split(feats)
	# perform z-score standarization on all continuous vars
	for col in cont_vars:
		mu = np.mean(feats[:, col])
		sd = np.std(feats[:, col])
		feats[:, col] = (feats[:, col] - mu)/sd

	return feats

'''
Transforms non-numeric features into integer categories
'''
def encode_categ_feats(feats):
	ret, categ_vars = cont_categ_split(feats)

	for col in categ_vars:
		lab_enc = preprocessing.LabelEncoder()
		# print("Before:\n", feats[:,col])
		feats[:, col] = lab_enc.fit_transform(feats[:, col])
		# print("After:\n", feats[:,col])

	# perform 1-hot encoding of categorical vars
	# might want to toggle 'sparse' arg
	one_enc = preprocessing.OneHotEncoder(categorical_features=categ_vars, sparse=False)
	# print("Before:\n", feats)
	feats = one_enc.fit_transform(feats)
	# print(one_enc.n_values)

	print(feats.shape)
	print("After:\n")
	print(feats.shape)

'''
Read and split data into training and test sets
'''
def read_data(file_name):
	df = pd.read_csv(file_name, low_memory=False, encoding = "ISO-8859-1")

	# eliminate % DED datapoints
	df = pd.concat([df[df.DED == 0], df[df.DED > 1]])

	# select features here
	# feats = ['PREMIUM', 'TIV', 'DED', 'LATITUDE', 'LONGITUDE', 'NUMBLDGS', 'BLDGSCHEME', 'NUMSTORIES', 'YEARBUILT', 'ELEVATION', 'DISTCOAST']
	df = df[df.COUNTRY == 'US']

	cols_needed = ['PREMIUM', 'TIV', 'DED', 'LATITUDE', 'LONGITUDE', 'NUMBLDGS', 'NUMSTORIES', 'YEARBUILT', 'ELEVATION', 'DISTCOAST']
	df['NUMBLDGS'] = pd.to_numeric(df['NUMBLDGS'])

	df = df[cols_needed]

	# replace invalid values by with NaN
	df['YEARBUILT'] = df['YEARBUILT'].replace([9999], np.nan)
	df.loc[df.ELEVATION <= 0, 'ELEVATION'] = np.nan
	df.loc[df.DISTCOAST <= 0, 'DISTCOAST'] = np.nan

	# # impute the means for these invalid values
	df['YEARBUILT'] = df['YEARBUILT'].fillna(value=np.nanmean(df['YEARBUILT']))
	df['ELEVATION'] = df['ELEVATION'].fillna(value=np.nanmean(df['ELEVATION']))
	df['DISTCOAST'] = df['DISTCOAST'].fillna(value=np.nanmean(df['DISTCOAST']))

	# print(df)
	df = df.values
	cols = df.shape[1]

	X = df[:, 3:]
	y = df[:, :3]
	return X,y

main()


import requests
import json
from util.notion import NotionClient
from airflow import DAG
from airflow.operators.dummy_operator import DummyOperator
from airflow.operators.python_operator import PythonOperator
from datetime import datetime

def get_office_hours(source_id='', target_id=''):
    print('test')
    # DEaaS (Office Hours)--
    # https://www.notion.so/astronomerio/195541b7cef24e2fab6ec3c936ad46bc?v=70d2cf5afcdc44588fc9fd4e1e597f1c
    # source_database_id = '195541b7cef24e2fab6ec3c936ad46bc'
    source_db = NotionClient(source_id)
    # Customer Task List - Customer Success
    # https://www.notion.so/astronomerio/964eb0aa7713477e8c19fd8cf3d1959b?v=9cafc0f6e49f41d6bcb170eacdc1a739
    # target_db_id='964eb0aa7713477e8c19fd8cf3d1959b'
    target_db = NotionClient(target_id)

    source = source_db._query_notion_database()
    target = target_db._query_notion_database()
    results = []
    for object in source['results']:
        try:
            try:
                day_left = object['properties']['Days to Renewal']['rollup']['array'][0]['formula']['number']
            except KeyError:
                day_left = 0
            customer = object['properties']['Customer']['title'][0]['text']['content']
            hours_committed = object['properties']['Hours Committed']['number']

            try:
                hours_delivered = object['properties']['Hours Delivered']['rollup']['number']
            except Exception as e:
                hours_delivered = 0
            if hours_committed == 0:
                percent_complete = 1
            else:
                percent_complete = round(hours_delivered / hours_committed, 2)
            if percent_complete < 1:
                results.append({'customer': customer,
                                'day_left': day_left,
                                'hours_committed': hours_committed,
                                'hours_delivered': hours_delivered,
                                'percent_complete': percent_complete,
                                'source_id': object['id']})
        except Exception as e:
            print(e)
    existing_ids = []

    for object in target['results']:
        try:
            existing_ids.append(object['properties']['Source Id']['rich_text'][0]['text']['content'])
        except KeyError:
            pass
        except IndexError:
            pass
    add_cnt = 0
    sorted_results = sorted(results, key=lambda k: k['day_left'])

    for result in sorted_results:
        if add_cnt >= 3:
            break
        elif result['source_id'] not in existing_ids:
            target_db.create_notion_page(f'{result["customer"]} has '
                                         f'{result["hours_committed"] - result["hours_delivered"]} '
                                         f'DEaaS Hours Remaining, they expire in {result["day_left"]} days',
                                         None, None, source_id=result['source_id'])
            add_cnt += 1

    # Default settings applied to all tasks

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'email_on_failure': False,
    'email_on_retry': False
}

# Using a DAG context manager, you don't have to specify the dag property of each task
with DAG('add_office_hours_expiration_ticket',
         start_date=datetime(2021, 8, 1),
         max_active_runs=3,
         schedule_interval='@weekly',
         default_args=default_args,
         catchup=False
         ) as dag:
    start = DummyOperator(
        task_id='start'
    )

    t1 = PythonOperator(
        task_id='move_tickets',
        python_callable=get_office_hours,
        op_kwargs={
            'source_id': '195541b7cef24e2fab6ec3c936ad46bc',
            'target_id': '964eb0aa7713477e8c19fd8cf3d1959b'
        }
    )

    finish = DummyOperator(
        task_id='finish'
    )

    start >> t1 >> finish


# -*- coding: utf-8 -*-
from itertools import chain
import logging
from django.utils.html import escape

try:
    from django.utils.six.moves import urllib_parse
    urlsplit = urllib_parse.urlsplit
    urlunsplit = urllib_parse.urlunsplit
except (ImportError, AttributeError) as e:  # Python 2, < Django 1.5
    from urlparse import urlsplit, urlunsplit
from django.contrib.admin import helpers
from django.contrib.admin.options import csrf_protect_m
try:
    from django.contrib.admin.utils import unquote
except ImportError:  # < 1.7 ... pragma: no cover
    from django.contrib.admin.util import unquote
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.core.exceptions import PermissionDenied
from django.db import transaction
try:
    from django.db.transaction import atomic
except ImportError:
    from django.db.transaction import commit_on_success as atomic
from django.forms.models import fields_for_model
from django.http import Http404, QueryDict
from django.shortcuts import render_to_response
try:
    from django.utils.encoding import force_text
except ImportError:  # < Django 1.5
    from django.utils.encoding import force_unicode as force_text
try:
    # >=1.6
    import json
    from functools import update_wrapper
except ImportError as e:
    # <=1.5
    from django.utils import simplejson as json
    from django.utils.functional import update_wrapper

from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
from adminlinks.changelist import AdminlinksChangeList
from adminlinks.constants import DATA_CHANGED, AUTOCLOSING

logger = logging.getLogger(__name__)

class AdminUrlWrap(object):
    """
    A minor helper for mixing into :class:`~django.contrib.admin.ModelAdmin`
    instances, exposing the url wrapping function used in the standard
    :meth:`~django.contrib.admin.ModelAdmin.get_urls`.
    """

    def _get_wrap(self):
        """
        Returns some magical decorated view that applies
        :meth:`~django.contrib.admin.AdminSite.admin_view` to a
        :class:`~django.contrib.admin.ModelAdmin` view::

            from django.contrib.admin import ModelAdmin

            class MyObj(AdminUrlWrap, ModelAdmin):

                def do_something(self):
                    wrapper = self._get_wrap()
                    wrapped_view = wrapper(self.my_custom_view)
                    return wrapped_view

        :return: a decorated view.
        """
        assert hasattr(self, 'admin_site') is True, "No AdminSite found ..."

        def wrap(view):
            def wrapper(*args, **kwargs):
                return self.admin_site.admin_view(view)(*args, **kwargs)
            return update_wrapper(wrapper, view)
        return wrap

class AdminlinksMixin(AdminUrlWrap):
    """
    Our mixin, which serves two purposes:

    * Allows for per-field editing through the use of the use of
      :meth:`~adminlinks.admin.AdminlinksMixin.change_field_view`.

       * Per-field editing requires the *change* permission for the object.
       * Per-field editing is not exposed in the :class:`~django.contrib.admin.AdminSite`
         at all.
       * Per-field editing may be enabled in the frontend by using the
         :class:`~adminlinks.templatetags.adminlinks_buttons.EditField` template
         tag

    * Allows for the following views to be automatically closed on success,
      using a customisable template (see
      :meth:`~adminlinks.admin.AdminlinksMixin.get_success_templates` for how
      template discovery works.)

        * The add view (:meth:`~django.contrib.admin.ModelAdmin.add_view`)
        * The edit view (:meth:`~django.contrib.admin.ModelAdmin.change_view`)
        * The delete view (:meth:`~django.contrib.admin.ModelAdmin.delete_view`)
        * The edit-field view (
          :meth:`~adminlinks.admin.AdminlinksMixin.change_field_view`)

    """

    @csrf_protect_m
    @atomic
    def change_field_view(self, request, object_id, fieldname, extra_context=None):
        """
        Allows a user to view a form with only one field (named in the URL args)
        to edit. All others are ignored.
        """
        model = self.model
        opts = model._meta

        obj = self.get_object(request, unquote(object_id))

        if not self.has_change_permission(request, obj):
            raise PermissionDenied

        if obj is None:
            raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)})

        all_fields = set(chain(fields_for_model(obj), self.form.base_fields))

        if fieldname not in all_fields:
            raise Http404(_('%(field)s does not exist on this object') % {'field': force_text(fieldname)})

        # if there are important fields, we'll assume they're denoted by a
        # leading underscore, like in treebeard

        fields_to_include = [x for x in all_fields
                             if x == fieldname or x.startswith('_')]
        fields_to_exclude = [x for x in all_fields
                             if x != fieldname and not x.startswith('_')]
        unique_together = frozenset(obj._meta.unique_together)
        if len(unique_together) > 0 and fieldname in unique_together:
            fields_to_include.extend(unique_together)
            fields_to_exclude = [x for x in fields_to_exclude
                                 if x not in unique_together]

        logger.debug("Excluding fields: {0!r}".format(fields_to_exclude))
        logger.debug("Including fields: {0!r}".format(fields_to_include))
        ModelForm = self.get_form(request, obj, exclude=fields_to_exclude,
                                  fields=fields_to_include)

        if request.method == 'POST':
            form = ModelForm(request.POST, request.FILES, instance=obj)
            if form.is_valid():
                form_validated = True
                new_object = self.save_form(request, form, change=True)
            else:
                logger.debug('{cls!r} instance was invalid: {errors!r}'.format(
                    errors=form.errors, cls=form))
                form_validated = False
                new_object = obj

            if form_validated:
                self.save_model(request, new_object, form, change=True)
                form.save_m2m()

                change_message = self.construct_change_message(request, form,
                                                               formsets=None)
                self.log_change(request, new_object, change_message)
                return self.response_change(request, new_object)

        else:
            form = ModelForm(instance=obj)

        the_fieldset = [
            (None, {
                'fields': [fieldname]}),
        ]
        remaining_fields = fields_to_include[:]
        remaining_fields.remove(fieldname)
        if remaining_fields:
            the_fieldset.append(
                (_("Other"), {
                    'fields': remaining_fields,
                    'classes': ['collapse']})
            )
        adminForm = helpers.AdminForm(form, the_fieldset, prepopulated_fields={},
                                      readonly_fields=None, model_admin=self)
        media = self.media + adminForm.media

        context = {
            'title': '',
            'adminform': adminForm,
            'object_id': object_id,
            'original': obj,
            'show_delete': False,
            'media': mark_safe(media),
            'errors': helpers.AdminErrorList(form, inline_formsets=[]),
            'root_path': getattr(self.admin_site, 'root_path', None),
            'app_label': opts.app_label,
            'is_popup': "_popup" in request.REQUEST,
        }
        context.update(extra_context or {})
        # tidy up after ourselves; by this point we don't need anything much ...
        # print(', '.join(locals().keys()))
        del (all_fields, adminForm, form, ModelForm, media, object_id,
             fields_to_exclude, fieldname, model, extra_context,
             the_fieldset, opts)
        return self.render_change_form(request, context, obj=obj)

    def get_urls(self):
        urls = super(AdminlinksMixin, self).get_urls()
        from django.conf.urls import url
        opts = self.model._meta
        app_label = opts.app_label
        # avoid deprecation warning
        if hasattr(opts, 'model_name'):
            model_name = opts.model_name
        else:
            model_name = opts.module_name
        # add change_field view into our URLConf
        new_url = url(
            regex=r'^(?P<object_id>.+)/change_field/(?P<fieldname>[\w_]+)/$',
            view=self._get_wrap()(self.change_field_view),
            name='{app}_{model}_change_field'.format(app=app_label,
                                                     model=model_name))
        urls.insert(0, new_url)
        return urls

    def get_success_templates(self, request):
        """
        Forces the attempted loading of the following:
            - a template for this model.
            - a template for this app.
            - a template for any parent model.
            - a template for any parent app.
            - a guaranteed to exist template (the base success file)

        :param request: The WSGIRequest
        :return: list of strings representing templates to look for.
        """
        app_label = self.model._meta.app_label
        model_name = self.model._meta.object_name.lower()
        any_parents = self.model._meta.parents.keys()
        templates = [
            "adminlinks/%s/%s/success.html" % (app_label, model_name),
            "adminlinks/%s/success.html" % app_label,
        ]
        for parent in any_parents:
            app_label = parent._meta.app_label
            model_name = parent._meta.object_name.lower()
            templates.extend([
                "adminlinks/%s/%s/ssuccess.html" % (app_label, model_name),
                "adminlinks/%s/success.html" % app_label,
            ])
        templates.extend(['adminlinks/success.html'])
        del app_label, model_name, any_parents
        return templates

    def wants_to_autoclose(self, request):
        """
        .. versionadded:: 0.8.1

        :return: Whether or not ``_autoclose`` was in the request
        """
        return AUTOCLOSING in request.GET or AUTOCLOSING in request.POST

    def wants_to_continue_editing(self, request):
        """
        .. versionadded:: 0.8.1

        :return: Whether **Save** was pressed, or whether **Save and add
                 another/continue editing** was.
        """
        return any((
            '_continue' in request.POST,
            '_saveasnew' in request.POST,
            '_addanother' in request.POST
        ))

    def data_changed(self, querydict):
        """
        Can be passed things like request.GET, or just dictionaries, whatever.
        This is our magic querystring variable.

        .. versionadded:: 0.8.1
        """
        return DATA_CHANGED in querydict

    def should_autoclose(self, request):
        """

        .. versionadded:: 0.8.1

        :return: Whether or not ``_autoclose`` was in the request and whether
                 **Save** was pressed, or whether **Save and add
                 another/continue editing** was.
        """
        if self.wants_to_continue_editing(request):
            return False
        if self.wants_to_autoclose(request):
            return True
        return False

    def maybe_fix_redirection(self, request, response, obj=None):
        """
        This is a middleware-ish thing for marking whether a redirect needs
        to say data changed ... it's pretty complex, so has lots of comments.

        .. versionadded:: 0.8.1
        """
        # if there's no Location string, it's not even a redirect!
        if not response.has_header('location'):
            return response

        response.redirect_parts = list(urlsplit(response['Location']))
        querystring = QueryDict(response.redirect_parts[3], mutable=True)

        # if we got this far, we know:
        #   * it's a redirect (it has a Location header)
        #   * because it's a redirect, something has changed (been added/edited)
        #   * it may want to autoclose, but can't (because add another/continue
        #     editing was selected)

        # if the redirect doesn't already know that data has been changed,
        # fix that here.
        if not self.data_changed(querystring):
            # if the redirect:
            #   * is to a changelist view
            #   * the changelist view does not subclass AdminlinksChangeListMixin
            # then this will cause another redirect to e=1 which may lose
            # any other querystring parts. Need to look into a fix for this.
            # Possibly we can resolve() the response.redirect_parts[2]
            # and figure it out using tracks_querystring_keys?
            querystring.update({DATA_CHANGED: 1})

        # the view wanted to autoclose, but couldn't because
        # `wants_to_continue_editing` was True, so keep track of the desire
        # to autoclose, and maybe next time 'save' is hit it'll still be around
        # to do so.
        if self.wants_to_autoclose(request) and AUTOCLOSING not in querystring:
            querystring.update({AUTOCLOSING: 1})

        # should there be a `next` parameter, we'll treat it as canonical
        # override for any other action.
        if REDIRECT_FIELD_NAME in request.GET:
            next_url = request.GET[REDIRECT_FIELD_NAME]
            if (self.wants_to_continue_editing(request)
                    and REDIRECT_FIELD_NAME not in querystring):
                # save & add another, or save & continue editing was clicked
                # so we just presist the redirection location ...
                querystring.update({REDIRECT_FIELD_NAME: next_url})
            else:
                # `save` was pressed
                redir = unquote(next_url)
                if redir.startswith('/') and not redir.startswith('//'):
                    # patch the existing redirect with the *FINAL* data.
                    # also maintaining any querystring changes.
                    new_parts = list(urlsplit(redir))
                    # change path
                    if new_parts[2]:
                        response.redirect_parts[2] = new_parts[2]
                        response.canonical = True
                    # include querystring.
                    if new_parts[3]:
                        querystring.update(QueryDict(new_parts[3], mutable=False))

        response.redirect_parts[3] = querystring.urlencode()
        response['Location'] = urlunsplit(response.redirect_parts)
        return response

    def response_change(self, request, obj, *args, **kwargs):
        """
        Overrides the Django default, to try and provide a better experience
        for frontend editing when editing an existing object.
        """
        if self.should_autoclose(request):
            ctx_dict = self.get_response_change_context(request, obj)
            ctx_json = json.dumps(ctx_dict)
            context = {'data': ctx_dict, 'json': ctx_json}
            return render_to_response(self.get_success_templates(request),
                                      context)
        response = super(AdminlinksMixin, self).response_change(request, obj,
                                                                *args, **kwargs)
        return self.maybe_fix_redirection(request, response, obj)

    def response_add(self, request, obj, *args, **kwargs):
        """
        Overrides the Django default, to try and provide a better experience
        for frontend editing when adding a new object.
        """
        if self.should_autoclose(request):
            ctx_dict = self.get_response_add_context(request, obj)
            ctx_json = json.dumps(ctx_dict)
            context = {'data': ctx_dict, 'json': ctx_json}
            return render_to_response(self.get_success_templates(request),
                                      context)
        response = super(AdminlinksMixin, self).response_add(request, obj,
                                                             *args, **kwargs)
        return self.maybe_fix_redirection(request, response, obj)

    def delete_view(self, request, object_id, extra_context=None):
        """
        Overrides the Django default, to try and provide a better experience
        for frontend editing when deleting an object successfully.

        Ridiculously, there's no response_delete method to patch, so instead
        we're just going to do a similar thing and hope for the best.
        """
        response = super(AdminlinksMixin, self).delete_view(request, object_id,
                                                            extra_context)
        if self.should_autoclose(request) and response.status_code in (301, 302):
            ctx_dict = self.get_response_delete_context(request, object_id,
                                                        extra_context)
            ctx_json = json.dumps(ctx_dict)
            context = {'data': ctx_dict, 'json': ctx_json}
            response = render_to_response(self.get_success_templates(request),
                                          context)
            del context, ctx_dict, ctx_json
        return self.maybe_fix_redirection(request, response)

    def get_response_add_context(self, request, obj):
        """
        Provides a context for the template discovered by
        :meth:`~adminlinks.admin.AdminlinksMixin.get_success_templates`. Only
        used when we could reliably determine that the request was in our
        JavaScript modal window, allowing us to close it automatically.

        For clarity's sake, it should always return the minimum values
        represented here.

        :return: Data which may be given to a template.
                 Must be JSON serializable, so that a template may pass it
                 back to the browser's JavaScript engine.
        :rtype: a dictionary.
        """
        return {
            'action': {
                'add': True,
                'change': False,
                'delete': False,
            },
            'object': {
                'pk': obj._get_pk_val(),
                'id': obj._get_pk_val(),
            }
        }

    def get_response_change_context(self, request, obj):
        """
        Provides a context for the template discovered by
        :meth:`~adminlinks.admin.AdminlinksMixin.get_success_templates`. Only
        used when we could reliably determine that the request was in our
        JavaScript modal window, allowing us to close it automatically.

        For clarity's sake, it should always return the minimum values
        represented here.

        :return: Data which may be given to a template.
                 Must be JSON serializable, so that a template may pass it
                 back to the browser's JavaScript engine.
        :rtype: a dictionary.
        """
        return {
            'action': {
                'add': False,
                'change': True,
                'delete': False,
            },
            'object': {
                'pk': obj._get_pk_val(),
                'id': obj._get_pk_val(),
            }
        }

    def get_response_delete_context(self, request, obj_id, extra_context):
        """
        Provides a context for the template discovered by
        :meth:`~adminlinks.admin.AdminlinksMixin.get_success_templates`. Only
        used when we could reliably determine that the request was in our
        JavaScript modal window, allowing us to close it automatically.

        For clarity's sake, it should always return the minimum values
        represented here.

        .. note::
            At the point this is called, the original object no longer exists,
            so we are stuck trusting the `obj_id` given as an argument.

        .. versionchanged::
            Introduced ``extra_context`` parameter.

        :return: Data which may be given to a template.
                 Must be JSON serializable, so that a template may pass it
                 back to the browser's JavaScript engine.
        :rtype: a dictionary.
        """
        return {
            'action': {
                'add': False,
                'change': False,
                'delete': True,
            },
            'object': {
                'pk': obj_id,
                'id': obj_id,
            }
        }

    def get_changelist(self, request, **kwargs):
        """
        If the changelist hasn't been customised, lets just replace it with
        our own, which should allow us to track data changes without erroring.

        .. versionadded:: 0.8.1

        """
        cl = super(AdminlinksMixin, self).get_changelist(request, **kwargs)
        fits_requirements = (
            hasattr(cl, 'tracks_querystring_keys'),
            DATA_CHANGED in getattr(cl, 'tracks_querystring_keys', ())
        )
        if all(fits_requirements):
            return cl
        else:
            logger.warning('Custom `ChangeList` discovered,'
                           'AdminlinksChangeListMixin is being mixed in '
                           'automatically. Hopefully it will work!')
            cl = type('AutoPatchedChangeList', (AdminlinksChangeList, cl), {})
        return cl


from tkinter import *
from tkinter import font
import datetime as dt
from time import *
import random as rd
import cmath
from Base import *
from Calculator import *
from Schedule import *
from Diary import *

class Menu:
   __classes_list = list()
   __Buttons = ['Home page', 'Diary', 'Schedule', 'Calculator', 'Save all']
   def home_page_lbl(self):
       #initalize:
       d = datetime.now()
       d.toordinal()
       t = str(d.strftime('%H : %M : %S'))
       self.__home_page_frm = LabelFrame(self.__base.get_BaseLbl(),
                                      text='',
                                      font=('Arial Rounded MT Bold', 50),
                                      bd=3,
                                      width=100,
                                      bg='white',
                                      fg='#00B0F0',
                                      foreground='#00B0F0',
                                      relief='flat',
                                      labelanchor='n')
       self.__home_page_lbl = Label(self.__home_page_frm,
                             text='Time is above nature',
                             font=('Arial Rounded MT Bold', 20),
                             width=70,
                             bg='white',
                             fg='#0070C0',
                             foreground='#0070C0',
                             relief='flat',
                             anchor='center')
       self.update_clock()
       #pack and grid:
       self.__home_page_frm.grid(sticky='ew', columnspan=2, column=3, row=2)
       self.__home_page_lbl.pack()
   def update_clock(self):
       d = datetime.now()
       d.toordinal()
       t = str(d.strftime('%H : %M : %S'))
       self.__home_page_frm.configure(text=t)
       self.__home_page_frm.after(200, self.update_clock)
   def save_all_func(self):
       self.__Schedule.save_data_func()
       self.__Diary.save_data_func()
   def change_lbl(self, btn):
        if btn == 'Save all':
            self.save_all_func()
        else:
            for c in self.__classes_list:
                c.get_BaseLbl().pack_forget()
            if btn == 'Schedule':
                self.__Schedule.get_BaseLbl().pack(side='right', fill='both', expand=1)
            elif btn == 'Calculator':
                self.__calc.get_BaseLbl().pack(side='right', fill='both', expand=1)
            elif btn == 'Diary':
                self.__Diary.get_BaseLbl().pack(side='right', fill='both', expand=1)
            elif btn == 'Home page':
                self.__base.get_BaseLbl().pack(side='right', fill='both', expand=1)
   def __init__(self, master):
       # initialize:
       self.__base = Base(master)
       self.__calc = Calculator(master)
       self.__Schedule = Schedule(master)
       self.__Diary = Diary(master)
       self.__my_menu = LabelFrame(master,
                                   text="Menu", font=('Arial Rounded MT Bold', 40),
                                   relief='groove', bg='#00B0F0',
                                   fg='WHITE')
       for btn in self.__Buttons:
           self.__btn = Button(self.__my_menu,
                                 text=btn,
                                 bd=7, relief='flat',
                                 bg='#00B0F0',
                                 fg='WHITE',
                                 font=('Arial Rounded MT Bold', 15),
                                 cursor='mouse',
                                 justify='left',
                                 command=lambda t=btn: self.change_lbl(t))
        # grid and pack:
           self.__btn.grid(sticky='w')
       self.__my_menu.pack(fill='y', side='left')
       self.__base.get_BaseLbl().pack(side='right', fill='both', expand=1)
       self.home_page_lbl()
       #bulid classes list:
       self.__classes_list.append(self.__base)
       self.__classes_list.append(self.__Diary)
       self.__classes_list.append(self.__calc)
       self.__classes_list.append(self.__Schedule)

class Main:
    def __init__(self):
        self.__root = Tk()
        self.__menu = Menu(self.__root)
        self.__root.minsize(1600, 1000)
        self.__root.mainloop()


'''
In this question we use BFS + coloring algortihm to find the answer
'''

def bipartite(graph):
    seen = {}

    for i in range(len(graph)):
        if i not in seen:
            if not check(graph,i,seen):
                return False
    return True

def check(graph,start,seen):
    q = [(start,1)]

    while len(q)>0:
        node,color = q.pop(0)

        if node in seen:
            if seen[node]!=color:
                return False
            continue
        seen[node]=color

        vertices = graph[node]
        for v in vertices:
            q.append((v,-color))
    return True

graph = [[1,3],[0,2],[1,3],[0,2]]
print(bipartite(graph))


from accounts.models import UserProfile
from analysis.data.grafics import IndividualStart, Start
from django.contrib import messages
from django.shortcuts import get_object_or_404, redirect, render
from project.models import vagasEmprego

# Create your views here.

def analises(request):
    if not request.user.user_is_teacher:
        messages.error(request, "Você não pode realizar essa operação!")
        return redirect("index")

    data = {}
    data = Start.define_data_info(data)
    data = Start.define_info_count_from_jobs(data)

    query_set_data = {}

    query_set_data = Start.query_set_info_from_jobs(query_set_data)

    # Quantidade alunos inscritos em pesquisas
    data = Start.cal_info_stundents_in_research_technological_project(
        query_set_data, data)['data']

    # Quantidade alunos inscritos em pesquisas
    data = Start.cal_info_stundents_in_research_scientific_project(
        query_set_data, data)['data']

    # Quntidade alunos inscritos em extensão
    data = Start.cal_info_students_in_extension_project(
        query_set_data, data)['data']

    #  Quantidade alunos em estágio
    data = Start.cal_info_students_in_intern(
        query_set_data, data)['data']

    # Quantidade de alunos em projeto de desenvolvimento
    data = Start.cal_info_students_in_developer(
        query_set_data, data)['data']

    return render(request, "analises/analises.html", {
        'title': "Analises gerais",
        'data': data
    })

def indiviual_analysis(request, vaga_id):
    if not request.user.user_is_teacher:
        messages.error(request, "Você não pode realizar essa operação!")
        return redirect("index")

    nome = request.user
    job = get_object_or_404(vagasEmprego, pk=vaga_id)

    if job.professor.user != nome:
        messages.error(request, "Você não pode realizar essa operação!")
        return redirect("index")

    alunos = []

    data = {}
    data = IndividualStart.define_data_info(data)
    data = IndividualStart.define_info_count_from_jobs(data, vaga_id)

    # catch stundents in job
    alunos = IndividualStart.info_subscribe_in_job(data, alunos)['alunos']
    data = IndividualStart.info_subscribe_in_job(data, alunos)['data']

    if data == False:
        messages.error(
            request, "A vaga não tem nenhum inscrito, por favor aguardar")
        return redirect("minhas_vagas")

    return render(request, "analises/individual.html", {
        'title': 'Graficos',
        'data': data
    })


import asyncio
import time

from replit import db
import os

from requests import Request, Session
from requests.exceptions import ConnectionError, Timeout, TooManyRedirects
import json

url='https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest'
parameters = {
    'slug':'bitcoin,ethereum,thetan-coin,thetan-arena',
    'convert':'USD' # Can be BRL
}
headers = {
    'Accepts':'application/json',
    'X-CMC_PRO_API_KEY': os.environ['CoinMarketCap']
}
session = Session()
session.headers.update(headers)

def cryptoRequest():
  try:
    response = session.get(url, params=parameters)
    data = json.loads(response.text)['data']

    BTCDATA = data['1']['quote']['USD']
    ETHDATA = data['1027']['quote']['USD']
    THCDATA = data['15250']['quote']['USD']
    THGDATA = data['11926']['quote']['USD']

    lastUpdate = 'Last updated: ' + BTCDATA["last_updated"][:10] + ' 0' + str(int(BTCDATA["last_updated"][11:13]) - 3) + BTCDATA["last_updated"][13:19]

    db["BTCDATA"] = BTCDATA
    db["ETHDATA"] = ETHDATA
    db["THCDATA"] = THCDATA
    db["THGDATA"] = THGDATA
    db["lastUpdate"] = lastUpdate

    print(db["lastUpdate"])
    print(f'BTC price: ${db["BTCDATA"]["price"]}')
    print(f'ETH price: ${db["ETHDATA"]["price"]}')
    print(f'THC price: ${db["THCDATA"]["price"]}')
    print(f'THG price: ${db["THGDATA"]["price"]}\n')

  except (ConnectionError, Timeout, TooManyRedirects) as e:
    print(e)

async def looping():
  while True: # not client.is_closed()
    try:
      await asyncio.sleep(20)
      cryptoRequest()
      updateAlarm()
      await asyncio.sleep(240)
    except Exception as e:
      print(e)
      await asyncio.sleep(180)

def updateAlarm():
  print("updating Alarms")
  if (db["THCDATA"]["percent_change_24h"] >= 5.0) or (db["THGDATA"]["percent_change_24h"] >= 5.0): # Liga se acima de algo
    if not db["GreenAlert"]:
      db["GreenAlert"] = True
  else: # Desliga se desceu novamente
    if db["GreenAlert"]:
      db["GreenAlert"] = False
  if (db["THCDATA"]["percent_change_24h"] <= -5.0) or (db["THGDATA"]["percent_change_24h"] <= -5.0): # Liga se abaixo de algo
    if not db["RedAlert"]:
      db["RedAlert"] = True
  else: # Desliga se subiu novamente
    if db["RedAlert"]:
      db["RedAlert"] = False
  print(f'Green Alert: {db["GreenAlert"]}\nRed Alert: {db["RedAlert"]}\n')


import importlib
import inspect
import logging
import os
import pkgutil
import sys

logger = logging.getLogger(__name__)

def ef_plugin(service_name):
  """
  Decorator for ef plugin classes. Any wrapped classes should contain a run() method which executes the plugin code.

  Args:
    service_name (str): The name of the service being extended.

  Example:
    @ef_plugin('ef-generate')
    class NewRelicPlugin(object):

      def run(self):
        exec_code()
  """
  def class_rebuilder(cls):

    class EFPlugin(cls):
      """
      Base class of ef-plugins. Defines which service is extended and provides access to the current instance of
      EFContext to the plugin.

      Args:
        context (obj:EFContext): Instance of EFContext created by ef-open command line tool
        clients (dict): Dictionary of boto3 clients created by ef_utils.create_aws_clients()
      """

      def __init__(self, context, clients):
        self.service = service_name
        self.context = context
        self.clients = clients
        self.oInstance = cls()

      def __getattribute__(self, s):
        """
        This is called whenever any attribute of a EFPlugin object is accessed. This function first tries to
        get the attribute off EFPlugin. If it fails then it tries to fetch the attribute from self.oInstance
        (an instance of the decorated class).
        """
        try:
          x = super(EFPlugin, self).__getattribute__(s)
        except AttributeError:
          pass
        else:
          return x
        return self.oInstance.__getattribute__(s)

    return EFPlugin

  return class_rebuilder

def run_plugins(context_obj, boto3_clients):
  """
  Executes all loaded plugins designated for the service calling the function.

  Args:
    context_obj (obj:EFContext): The EFContext object created by the service.
    boto3_clients (dict): Dictionary of boto3 clients created by ef_utils.create_aws_clients()
  """

  def print_if_verbose(message):
    if context_obj.verbose:
      print(message)

  service_name = os.path.basename(sys.argv[0]).replace(".py", "")
  try:
    import plugins
  except ImportError:
    print_if_verbose("no plugins detected.")
    return
  else:
    for plugin_importer, plugin_name, plugin_ispkg in pkgutil.iter_modules(plugins.__path__):
      if plugin_ispkg:
        plugin_package = importlib.import_module("plugins.{}".format(plugin_name))
        for importer, modname, ispkg in pkgutil.iter_modules(plugin_package.__path__):
          plugin_module = importlib.import_module("plugins.{}.{}".format(plugin_name, modname))
          for name, obj in inspect.getmembers(plugin_module):
            if inspect.isclass(obj) and obj.__name__ == "EFPlugin":
              plugin_class = getattr(plugin_module, name)
              plugin_instance = plugin_class(context=context_obj, clients=boto3_clients)
              if plugin_instance.service == service_name:
                print_if_verbose("plugin '{}' loaded".format(plugin_name))
                if not context_obj.commit:
                  print_if_verbose("dryrun: skipping plugin execution.")
                else:
                  try:
                    plugin_instance.run()
                  except AttributeError:
                    print("error executing plugin '{}'".format(modname))


import pandas as pd
pd.options.mode.chained_assignment = None
from common_functions import *
import plotly.graph_objects as go

def radar_layout(fig, selected_hero):
    fig.update_layout(
        title=dict(text=selected_hero, x=0.5,y=0.95),
        polar=dict(
            radialaxis=dict(visible=True, range=[0,1.0]),
            angularaxis=dict(tickfont=dict(size=10), ticks="outside", ticklen=40)
        ),
        width=1200,
        margin=dict(t=150),
        height=900,
        showlegend=True,
        hoverlabel=dict(bgcolor="white", font_size=16),
        hovermode="y unified"
    )
    return fig

def radar_hero_trace(fig,df,selected_hero):
    fig.add_trace(
    go.Scatterpolar(
        r=list(df.loc[selected_hero]),
        theta=df.columns,
        mode='markers+lines',
        text=list(selected_hero),
        textposition="top center",
        textfont_size=15,
        fill="toself",
        fillcolor="#008FD3",
        line=dict(color="#F0AB00"),
        marker=dict(color="#AB7A00",size=5),
        opacity=0.5,
        name=selected_hero
        )
    )

def get_radar_heroes(selected_hero,df):
    fig = go.Figure()
    radar_hero_trace(fig,df,selected_hero)
    fig.update_traces(hovertemplate='%{theta}' + '
Value:%{r:.2f}
', selector=dict(type='scatterpolar'))
    fig.update_layout(title=dict(text=selected_hero,x=0.5,y=0.95),
                        polar=dict(radialaxis=dict(visible=True,range=[0,1.05]),
                                    angularaxis=dict(tickfont=dict(size=10),ticks="outside",ticklen=40),),
                        width=1200,
                        margin=dict(t=150),
                        height=900,
                        hoverlabel=dict(bgcolor="white",font_size=16),
                        hovermode='y unified')
    return fig


import random
import numpy as np
import copy
import pickle
from memory import Experience
from Environment import Environment
import time
import cv2

class Trainer():
	def __init__(self,
				 env=None,
				 controller=None,
				 experience_memory=None,
				 max_iter=2000*1024,
				 **kwargs):

		self.env = env
		self.controller = controller
		self.experience_memory = experience_memory
		# testing parameters
		self.testing_env = Environment(task=self.env.task) # testing environment
		self.testing_scores = [] # record testing scores
		self.epsilon_testing = 0.05
		self.max_steps_testing = 1000
		self.num_episodes_per_test = 10
		# training parameters
		self.max_iter = max_iter
		self.controller_target_update_freq = 10000
		self.learning_starts = 50000
		self.learning_freq = 4
		self.save_model_freq = 50000
		self.test_freq = 10000
		self.epsilon_start = 1.0
		self.epsilon_end = 0.1
		self.epsilon = self.epsilon_start
		self.epsilon_annealing_steps = int(1E6)
		self.repeat_noop_action = 0
		self.save_results_freq = int(1E5)

		self.__dict__.update(kwargs) # updating input kwargs params

		# counters
		self.step = 0
		self.game_episode = 0

		# learning variables
		self.episode_rewards = 0.0 # including step cost
		self.episode_scores = 0.0
		# keeping records of the performance
		self.episode_rewards_list = []
		self.episode_scores_list = []
		self.episode_steps_list = []
		self.episode_time_list = []
		self.episode_start_time = 0.0
		self.episode_end_time = 0.0

		print('init trainer --> OK')

	def train(self):
		print('-'*60)
		print('Training ',self.env.task, ' using DQN')
		print('-'*60)
		print('-'*60)
		print('game episode: ', self.game_episode, 'time step: ', self.step)
		self.episode_start_time = time.time()
		S = self.env.reset()
		self.s = self.four_frames_to_4_84_84(S)

		for t in range(self.learning_starts): # fill initial expereince memory
			self.play()
			self.step += 1

		for t in range(self.max_iter+1):
			self.play()
			self.step += 1

			if (t > 0) and (self.step % self.learning_freq == 0):
				self.controller.update_w()

			if (t > 0) and (self.step % self.controller_target_update_freq == 0):
				self.controller.update_target_params()

			# if (t > 0) and (self.step % self.save_model_freq == 0):
			# 	model_save_path = './models/' + self.env.task + '_steps_' + str(self.step) + '.model'
			# 	self.controller.save_model(model_save_path=model_save_path)

			if (t > 0) and (self.step % self.test_freq == 0): # test controller's performance
				self.test()

			results_file_path = './results/SGD_results_' + self.env.task + '_lr_' + str(self.controller.lr) + '.pkl'
			with open(results_file_path, 'wb') as f:
				pickle.dump([self.episode_steps_list,
							 self.episode_scores_list,
							 self.episode_rewards_list,
							 self.episode_time_list,
							 self.testing_scores,
							 self.controller.loss_list], f)

	def play(self):
		# self.env.render()
		s = self.s
		if self.step < self.learning_starts:
			a = self.env.action_space.sample()
		else:
			a = self.epsilon_greedy()
		old_lives = self.env.lives()
		SP, r, terminal, step_info = self.env.step(a)
		new_lives = self.env.lives()
		self.episode_scores += r
		sp = self.four_frames_to_4_84_84(SP)

		if new_lives < old_lives:
			print('agent died, current lives = ', new_lives)
			r = min(-1.0, r)

		if terminal and new_lives>0:
			task_done = True
			done = 1
			r = max(1.0,r)
			print('task is solved succesfully, end of episode')
		else:
			task_done = False
			done = 0
			r = min(-0.1,r) # just a tiny punishment

		self.episode_rewards += r

		if terminal and new_lives==0:
			terminal = True
			print('agent terminated, end of episode')
			r = min(-10.0,r)

		r = np.clip(r, -1.0, 1.0)
		experience = Experience(s, a, r, sp, done)
		self.experience_memory.push(experience)
		self.s = copy.deepcopy(sp)

		if terminal or task_done:
			self.episode_steps_list.append(self.step)
			self.episode_scores_list.append(self.episode_scores)
			self.episode_rewards_list.append(self.episode_rewards)
			self.game_episode += 1
			self.episode_rewards = 0.0
			self.episode_scores = 0.0
			self.episode_end_time = time.time()
			episode_time = self.episode_end_time - self.episode_start_time
			self.episode_time_list.append(episode_time)
			print('episode time: {0:.2f}' .format(episode_time))
			print('-'*60)
			print('game episode: ', self.game_episode)
			print('time step: ', self.step)
			self.episode_start_time = time.time()
			S = self.env.reset() # reset S
			self.s = self.four_frames_to_4_84_84(S) # get s

	def test(self):
		for i in range(self.num_episodes_per_test):
			self.total_score_testing = 0
			print('testing episode number: ', i)
			self.test_one_epsiode()
			self.testing_scores.append(self.total_score_testing)
			print('test score: ', self.total_score_testing)

	def test_one_epsiode(self):
		S = self.testing_env.reset()
		s = self.four_frames_to_4_84_84(S)
		for t in range(self.max_steps_testing):
			# self.testing_env.render()
			a = self.epsilon_greedy_testing(s)
			old_lives = self.testing_env.lives()
			SP, r, terminal, step_info = self.testing_env.step(a)
			new_lives = self.testing_env.lives()
			self.total_score_testing += r
			sp = self.four_frames_to_4_84_84(SP)

			if new_lives < old_lives:
				print('agent died, current lives = ', new_lives)

			if terminal and new_lives>0:
				print('task is solved succesfully, end of test episode')

			if terminal and new_lives==0:
				print('agent terminated, end of episode')

			s = copy.deepcopy(sp)

			if terminal:
				break

	def anneal_epsilon(self):
		if self.step < self.epsilon_annealing_steps:
			slop = (self.epsilon_start-self.epsilon_end)/self.epsilon_annealing_steps
			self.epsilon = self.epsilon_start - slop*self.step

	def epsilon_greedy(self):
		if random.random() < self.epsilon:
			return self.env.action_space.sample()
		else:
			return self.controller.get_best_action(self.s)

	def epsilon_greedy_testing(self,s):
		if random.random() < self.epsilon_testing:
			return self.env.action_space.sample()
		else:
			return self.controller.get_best_action(s)

	def four_frames_to_4_84_84(self,S):
		crop_top = 0
		crop_bottom = 0
		if 'Breakout' in self.env.task:
			crop_top = 14
			crop_bottom = 0
		if 'BeamRider' in self.env.task:
			crop_top = 20
			crop_bottom = 0
		if 'Enduro' in self.env.task:
			crop_top = 30
			crop_bottom = 40
		if 'Pong' in self.env.task:
			crop_top = 14
			crop_bottom = 5
		if 'Qbert' in self.env.task:
			crop_top = 0
			crop_bottom = 0
		if 'Seaquest' in self.env.task:
			crop_top = 20
			crop_bottom = 20
		if 'SpaceInvaders' in self.env.task:
			crop_top = 10
			crop_bottom = 6
		w = 84
		h = crop_top + 84 + crop_bottom
		for i, img in enumerate(S):
			gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
			gray_resized = cv2.resize(gray,(w,h))
			gray_cropped =  gray_resized[crop_top:h-crop_bottom,:]
			gray_reshaped = gray_cropped.reshape((1,84,84))
			if i == 0:
				s = gray_reshaped
			else:
				s = np.concatenate((s,gray_reshaped),axis=0)
		return s


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

# In[ ]:

import pandas as pd
import numpy as np

# In[ ]:

ant1=pd.DataFrame(pd.read_csv('ant1.txt',header=None,delimiter=' '))
ant2=pd.DataFrame(pd.read_csv('ant2.txt',header=None,delimiter=' '))

# In[ ]:

t_0=pd.DataFrame(np.transpose([ant1[:][0],ant2[:][0]]))

# In[ ]:

phase_total=pd.DataFrame(pd.read_csv('phase.txt',header=None,delimiter=' '))

# In[ ]:

phase = phase_total.iloc[:,20:]

# In[ ]:

def baseline(m,n):
    if m>n:
        m,n=n,m
    return np.intersect1d(t_0[t_0.iloc[:,0]==m].index,t_0[t_0.iloc[:,1]==n].index)[0]

# In[ ]:

def closurephase(m,n,time,N):
    total=phase.iloc[baseline(m,n),time]
    for j in range(N):
        if(j!=m and j!=n):
            total+=(phase.iloc[baseline(j,n),time]-phase.iloc[baseline(j,m),time])
    total/=(N-1)
    return total

# In[ ]:

p=np.zeros((30,phase.shape[1]))
n=6
for t in range(phase.shape[1]):
    for i in range(30):
        m=i
        if(m!=n):
            p[i,t]=closurephase(m,n,t,30)

# In[ ]:

np.savetxt('out_n_6.txt',p)

# In[ ]:

q=np.zeros((30,phase.shape[1]))
n=10
for t in range(phase.shape[1]):
    for i in range(30):
        m=i
        if(m!=n):
            q[i,t]=closurephase(m,n,t,30)

# In[ ]:

np.savetxt('out_n_10.txt',q)

# In[ ]:

r=np.zeros((30,phase.shape[1]))
n=21
for t in range(phase.shape[1]):
    for i in range(30):
        m=i
        if(m!=n):
            r[i,t]=closurephase(m,n,t,30)

# In[ ]:

np.savetxt('out_n_21.txt',r)