"""
This file is used to store some utility functions organized as separate functions
"""
def set_available_port():
    import os
    os.environ['MASTER_ADDR'] = 'localhost'
    for port in range(12350,20000):
        if not port_is_used(port):
            os.environ['MASTER_PORT'] = str(port)
            break
    else:
        raise RuntimeError("No Available Port for DDP")

def wait_for_everyone():
    import torch.distributed as dist
    if dist.is_available() and dist.is_initialized():
        torch.distributed.barrier()
    else:
        return

def postprocess_text(preds, labels):
    import nltk
    preds = [pred.strip() for pred in preds]
    labels = [label.strip() for label in labels]

    # rougeLSum expects newline after each sentence
    preds = ["\n".join(nltk.sent_tokenize(pred)) for pred in preds]
    labels = ["\n".join(nltk.sent_tokenize(label)) for label in labels]

    return preds, labels

def get_rouge_score(hyps,refs):
    import rouge
    hyps,refs = postprocess_text(hyps,refs) # add \n

    evaluator = rouge.Rouge(metrics=['rouge-n', 'rouge-l'],
                            max_n=2,
                            limit_length=True,
                            length_limit=100,
                            length_limit_type='words',
                            apply_avg=True,
                            apply_best=False,
                            alpha=0.5,  # Default F1_score
                            stemming=True)
    py_rouge_scores = evaluator.get_scores(hyps, refs)

    ## *100
    for k,v in py_rouge_scores.items():
        for _k,_v in v.items():
            py_rouge_scores[k][_k] = round(_v*100,4)

    return py_rouge_scores

def debpe(bpe):
    import re
    return re.sub(r'(@@ )|(@@ ?$)', '', bpe)

def get_bleu_score(hyps,refs,return_signature=False):
    """
    hyps:list of string
    refs:list of string
    """
    assert len(hyps) == len(refs)

    import sacrebleu
    scorer = sacrebleu.BLEU(force=True)
    score = scorer.corpus_score(hyps,[refs]).score
    signature = scorer.get_signature()
    if return_signature:
        return score,str(signature)
    else:
        return score
    # return sacrebleu.corpus_bleu(hyps,[refs],
    #                       force=True, lowercase=False,
    #                       tokenize='none').score
    # return sacrebleu.corpus_bleu(hyps,[refs],
    #                       force=True, lowercase=False).score

def get_chrf_score(hyps,refs,return_signature=False):

    assert len(hyps) == len(refs)
    import sacrebleu
    scorer = sacrebleu.CHRF()
    score = scorer.corpus_score(hyps,[refs]).score
    signature = scorer.get_signature()
    if return_signature:
        return score,str(signature)
    else:
        return score

def get_ter_score(hyps,refs,return_signature=False):

    assert len(hyps) == len(refs)
    import sacrebleu
    scorer = sacrebleu.TER()
    score = scorer.corpus_score(hyps,[refs]).score
    signature = scorer.get_signature()
    if return_signature:
        return score,str(signature)
    else:
        return score

def port_is_used(port,ip='127.0.0.1'):
    """
    test whether a port is used or not
    """
    import socket
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    try:
        s.connect((ip,port))
        s.shutdown(2)
        return True
    except:
        return False

def save_config(data_args,model_args,training_args):
    from dataclasses import asdict
    import os
    import json
    ret = {
        "data_args":{},
        "model_args":{},
        "training_args":{},
    }
    for k,v in vars(data_args).items():ret["data_args"][k] = v
    for k,v in vars(model_args).items():ret["model_args"][k] = v
    for k,v in vars(training_args).items():ret["training_args"][k] = v

    with open(os.path.join(training_args.output_dir,'config.json'),'w') as f:
        json.dump(ret,f,indent=4)

def move_to_device(maybe_tensor, device):

    import torch
    import numpy as np

    if torch.is_tensor(maybe_tensor):
        return maybe_tensor.to(device)
    elif isinstance(maybe_tensor, np.ndarray):
        return torch.from_numpy(maybe_tensor).to(device).contiguous()
    elif isinstance(maybe_tensor, dict):
        return {
            key: move_to_device(value, device)
            for key, value in maybe_tensor.items()
        }
    elif isinstance(maybe_tensor, list):
        return [move_to_device(x, device) for x in maybe_tensor]
    elif isinstance(maybe_tensor, tuple):
        return tuple([move_to_device(x, device) for x in maybe_tensor])
    return maybe_tensor

def update_args(args,model_args):
    from dataclasses import asdict
    import argparse
    """
    args:argparse.Namespace/dict
    # data_args:dataclass
    model_args:class
    # training_args:dataclass
    """
    model_keys = vars(model_args).keys()
    # print(model_keys)
    if isinstance(args,dict):
        for k,v in args.items():
            if k in model_keys:
                setattr(model_args,k,v)
    elif isinstance(args,argparse.Namespace):
        for key in vars(args):
            value = getattr(args,key)
            if value:
                # if key in model_keys:
                setattr(model_args,key,value)
    return model_args

def synchronize_args(data_args,model_args,training_args):
    # import os
    data_args.train_batch_size = training_args.train_batch_size
    # data_args.eval_batch_size = training_args.eval_batch_size
    data_args.max_trg_len = model_args.max_trg_len
    data_args.max_src_len = model_args.max_src_len
    # if 'src.vocab' in os.listdir(data_args.data_path):
    #     ## separate vocab
    #     model_args.use_joint_bpe = False
    # else:
    #     model_args.use_joint_bpe = True
    return data_args,model_args,training_args

def get_remain_time(start,max_step,cur_step):
    import time
    end = time.time()
    past = end-start
    remain = (max_step/cur_step)*past - past
    return s2hm(remain)

def s2hms(s):
    m, s = divmod(s, 60)
    h, m = divmod(m, 60)
    return  "%02d:%02d:%02d" % (h, m, s)
    # return  "%02d:%02d" % (h, m)

def s2hm(s):
    m, s = divmod(s, 60)
    h, m = divmod(m, 60)
    return  "%02d:%02d" % (h, m)

def s2ms(s):
    m,s = divmod(s,60)
    return "%02d:%02d" % (m, s)

def get_rank():
    import torch.distributed as dist
    if not dist.is_available():
        return 0
    if not dist.is_initialized():
        return 0
    return dist.get_rank()

def is_main_process():
    return get_rank() == 0

def safe_round(number, ndigits):
    import numpy as np
    import torch
    if hasattr(number, "__round__"):
        return round(number, ndigits)
    elif torch is not None and torch.is_tensor(number) and number.numel() == 1:
        return safe_round(number.item(), ndigits)
    elif np is not None and np.ndim(number) == 0 and hasattr(number, "item"):
        return safe_round(number.item(), ndigits)
    else:
        return number

def get_perplexity(loss, round=2, base='e'):
    # from fairseq.logging.meters import safe_round
    import math

    if loss is None:
        return 0.0
    try:
        if base=='e':
            return safe_round(math.exp(loss), round)
        else:
            return safe_round(base**loss,round)
    except OverflowError:
        return float("inf")

def format_step(step):
    if isinstance(step, str):
        return step
    s = ""
    if len(step) > 0:
        s += "Epoch: {} ".format(step[0])
    if len(step) > 1:
        s += "Iteration: {} ".format(step[1])
    if len(step) > 2:
        s += "Validation Iteration: {} ".format(step[2])
    return s

class dotdict(dict):
    """dot.notation access to dictionary attributes"""
    __getattr__ = dict.get
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

class MetricsTracer:
    def __init__(self,valid_metrics):
        if valid_metrics == 'ppl':
            self.cur_best_metrics = 1000000
            self.better = "<"
        elif valid_metrics == 'bleu':
            self.cur_best_metrics = 0
            self.better = ">"
    def is_better(self,new_metrics):
        if eval(str(new_metrics)+self.better+str(self.cur_best_metrics)):
            self.cur_best_metrics = new_metrics
            return True
        else:
            return False

import torch
class SequentialDistributedSampler(torch.utils.data.sampler.Sampler):
    """
    Distributed Sampler that subsamples indicies sequentially,
    making it easier to collate all results at the end.
    Even though we only use this sampler for eval and predict (no training),
    which means that the model params won't have to be synced (i.e. will not hang
    for synchronization even if varied number of forward passes), we still add extra
    samples to the sampler to make it evenly divisible (like in `DistributedSampler`)
    to make it easy to `gather` or `reduce` resulting tensors at the end of the loop.
    """

    def __init__(self, dataset, batch_size, rank=None, num_replicas=None):
        if num_replicas is None:
            if not torch.distributed.is_available():
                raise RuntimeError("Requires distributed package to be available")
            num_replicas = torch.distributed.get_world_size()
        if rank is None:
            if not torch.distributed.is_available():
                raise RuntimeError("Requires distributed package to be available")
            rank = torch.distributed.get_rank()
        self.dataset = dataset
        self.num_replicas = num_replicas
        self.rank = rank
        self.batch_size = batch_size
        self.num_samples = int(math.ceil(len(self.dataset) * 1.0 / self.batch_size / self.num_replicas)) * self.batch_size
        self.total_size = self.num_samples * self.num_replicas

    def __iter__(self):
        indices = list(range(len(self.dataset)))
        # add extra samples to make it evenly divisible
        indices += [indices[-1]] * (self.total_size - len(indices))
        # subsample
        indices = indices[self.rank * self.num_samples : (self.rank + 1) * self.num_samples]
        return iter(indices)

    def __len__(self):
        return self.num_samples

class UnevenSequentialDistributedSampler(torch.utils.data.sampler.Sampler):
    """
    This is slightly different version of SequentialDistrbitedSample from
    https://github.com/huggingface/transformers/blob/81ac45f85c35244831f11f73c09ea10eee4f953a/src/transformers/trainer_pt_utils.py
    In thie version, the datset is not evenly split. Since we don't need tensors of same shape to reduce or gather
    """

    def __init__(self, dataset, num_replicas=None, rank=None):
        import math
        if num_replicas is None:
            if not torch.distributed.is_available():
                raise RuntimeError("Requires distributed package to be available")
            num_replicas = torch.distributed.get_world_size()
        if rank is None:
            if not torch.distributed.is_available():
                raise RuntimeError("Requires distributed package to be available")
            rank = torch.distributed.get_rank()
        self.dataset = dataset
        self.num_replicas = num_replicas
        self.rank = rank
        self.num_samples = int(math.ceil(len(self.dataset) * 1.0 / self.num_replicas))
        self.total_size = self.num_samples * self.num_replicas
        indices = list(range(len(self.dataset)))
        self.indices = indices[self.rank * self.num_samples : (self.rank + 1) * self.num_samples] ## a trick for python list ls[:infinity]

    def __iter__(self):
        return iter(self.indices)

    def __len__(self):
        return len(self.indices)

def dump_vocab(p,toker,direction='joint'):
    import os
    vocab = toker.dump_vocab() # dict {token:id}
    with open(os.path.join(p,direction+".vocab"),'w') as f:
        for k,v in vocab.items():
            f.write(k+'\t'+str(v)+'\n')

def get_current_gpu_usage():
    import GPUtil
    gpu = GPUtil.getGPUs()[0]
    return f"{gpu.memoryUsed}/{gpu.memoryTotal}"

import torch
class DocumentDataset(torch.utils.data.Dataset):
    def __init__(self,documents) -> None:
        super().__init__()
        self.documents = documents
    def __len__(self):
        return len(self.documents)
    def __getitem__(self,idx):
        return self.documents[idx]

import torch
class ListDataset(torch.utils.data.Dataset):
    def __init__(self,ls) -> None:
        super().__init__()
        self.ls = ls
        self._len = len(self.ls)
    def __len__(self):
        return self._len
    def __getitem__(self,idx):
        return self.ls[idx]

def move_to_device(maybe_tensor, device):

    import torch
    import numpy as np

    if torch.is_tensor(maybe_tensor):
        return maybe_tensor.to(device)
    elif isinstance(maybe_tensor, np.ndarray):
        return torch.from_numpy(maybe_tensor).to(device).contiguous()
    elif isinstance(maybe_tensor, dict):
        return {
            key: move_to_device(value, device)
            for key, value in maybe_tensor.items()
        }
    elif isinstance(maybe_tensor, list):
        return [move_to_device(x, device) for x in maybe_tensor]
    elif isinstance(maybe_tensor, tuple):
        return tuple([move_to_device(x, device) for x in maybe_tensor])
    return maybe_tensor

def debug_unsed_parameters(model):
    for name, param in model.named_parameters():
        if param.grad is None:
            print(name)


import os
import cv2
import matplotlib.pyplot as plt
import tkinter as tk
from math import *

def detect(dataPath, clf):
    """
    Please read detectData.txt to understand the format. Load the image and get
    the face images. Transfer the face images to 19 x 19 and grayscale images.
    Use clf.classify() function to detect faces. Show face detection results.
    If the result is True, draw the green box on the image. Otherwise, draw
    the red box on the image.
      Parameters:
        dataPath: the path of detectData.txt
      Returns:
        No returns.
    """
    # Begin your code (Part 4)
    """
             First , read the detectData.txt through given datapath in " main.py ".
        In "detectData.txt" , if a line's length equals to 2 , then collect its line[0] as file name
        of image and line[1] as number of faces , and set these two data in the "data" array. While a
        line's length equals to 4 , collect line[0]~[3] for locating the rectangles , then get a 19x19
        grayscale version of original image . After that, use " clf.classify() " to detect faces and
        get the result of "whether it's a face".
             If the result obtained above equals to 1 , then mark it with green lines , while using
        red lines for results that equals to 0 . After doing several turns of marking , the images marked
        with green/red rectangle in desired size will be shown .
    """

    data = []

    for line in open(dataPath, "r"):
        line = line.split()
        if len(line) == 2 :
            file_path = line[0]
            img = cv2.imread(dataPath[0:12] + file_path)
            pic = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            data.append((img, int(line[1])))

        else :
            for i in range(4) :
                line[i] = int(line[i])

            tmp_pic = pic[line[1] : line[1] + line[3], line[0] : line[0] + line[2]]
            tmp_pic = cv2.resize(tmp_pic,(19, 19))
            tmp_res = clf.classify(tmp_pic)
            if tmp_res == 1:
                cv2.rectangle(img, (line[0], line[1]), (line[0] + line[2], line[1] + line[3]), (0, 255, 0), 2)
            else:
                cv2.rectangle(img, (line[0], line[1]), (line[0] + line[2], line[1] + line[3]), (0, 0, 255), 2)

    for i in data:
        ims = cv2.resize(i[0], (960, 638))
        cv2.imshow('My Image',ims)
        cv2.waitKey(0)

    # raise NotImplementedError("To be implemented")
    # End your code (Part 4)


# -*- coding: utf-8 -*-
"""
Created on Sat Mar 14 12:45:48 2020

@author: Jinsung
"""

import torch
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as torchdata
import params
from core.pretrain import eval_src as test
from SSTask import SSTask
from SSHead import linear_on_layer3
from dset_classes.DsetNoLabel import DsetNoLabel

def parse_tasks(tgt_encoder, supervision, sc_tr_dataset, sc_te_dataset, tg_tr_dataset, tg_te_dataset):
    sstasks = []

    if params.rotation:
        print("Task : rotation prediction")
        from dset_classes.DsetSSRotRand import Rotation

        digit = False
        if params.src_dataset in ['mnist', 'mnistm', 'svhn', 'svhn_exta', 'usps']:
            print("No rotation 180 for digits!")
            digit = True

        su_tr_dataset = Rotation(DsetNoLabel(sc_tr_dataset), digit = digit)
        su_te_dataset = Rotation(DsetNoLabel(sc_te_dataset), digit = digit)
        su_tr_loader = torchdata.DataLoader(su_tr_dataset, batch_size=params.batch_size//2, shuffle=True, num_workers=4)
        su_te_loader = torchdata.DataLoader(su_te_dataset, batch_size=params.batch_size//2, shuffle=False, num_workers=4)

        tu_tr_dataset = Rotation(DsetNoLabel(tg_tr_dataset), digit = digit)
        tu_te_dataset = Rotation(DsetNoLabel(tg_te_dataset), digit = digit)
        tu_tr_loader = torchdata.DataLoader(tu_tr_dataset, batch_size=params.batch_size//2, shuffle=True, num_workers=4)
        tu_te_loader = torchdata.DataLoader(tu_te_dataset, batch_size=params.batch_size//2, shuffle=False, num_workers=4)

        supervision = supervision
        criterion = nn.CrossEntropyLoss().cuda()
        optimizer = optim.SGD(list(tgt_encoder.parameters()) + list(supervision.parameters()), lr = 0.1, momentum=0.9, weight_decay=5e-4)
        scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, [5, 10], gamma=0.1, last_epoch=-1)
        sstask = SSTask(tgt_encoder, supervision, criterion, optimizer, scheduler, su_tr_loader, su_te_loader, tu_tr_loader, tu_te_loader)
        sstask.assign_test(test)
        sstasks.append(sstask)

    return sstasks


import torch.nn as nn
from torch.nn import Module
import torch.nn.functional as Func
import torch.optim as optim
from torch.autograd import Variable
import torch
from layers import HM_LSTM
from utils import masked_NLLLoss
import time

class HM_Net(Module):
    def __init__(self, a, size_list, dict_size, embed_size):
        super(HM_Net, self).__init__()
        self.dict_size = dict_size
        self.size_list = size_list
        self.drop = nn.Dropout(p=0.5)
        self.embed_in = nn.Embedding(dict_size, embed_size)
        self.HM_LSTM = HM_LSTM(a, embed_size, size_list)
        self.weight = nn.Linear(size_list[0]+size_list[1], 2)
        self.embed_out1 = nn.Linear(size_list[0], dict_size)
        self.embed_out2 = nn.Linear(size_list[1], dict_size)
        self.relu = nn.ReLU()
        # self.logsoftmax = nn.LogSoftmax()
        # self.loss = masked_NLLLoss()
        self.loss = nn.CrossEntropyLoss()

    def forward(self, inputs, target, hidden):
        # inputs : batch_size * time_steps
        # mask : batch_size * time_steps

        emb = self.embed_in(Variable(inputs, volatile=not self.training))  # batch_size * time_steps * embed_size
        emb = self.drop(emb)
        h_1, h_2, z_1, z_2, hidden = self.HM_LSTM(emb, hidden)  # batch_size * time_steps * hidden_size

        # mask = Variable(mask, requires_grad=False)
        # batch_loss = Variable(torch.zeros(batch_size).cuda())

        h_1 = self.drop(h_1)  # batch_size * time_steps * hidden_size
        h_2 = self.drop(h_2)
        h = torch.cat((h_1, h_2), 2)

        g = Func.sigmoid(self.weight(h.view(h.size(0)*h.size(1), h.size(2))))
        g_1 = g[:, 0:1]  # batch_size * time_steps, 1
        g_2 = g[:, 1:2]

        h_e1 = g_1.expand(g_1.size(0), self.dict_size)*self.embed_out1(h_1.view(h_1.size(0)*h_1.size(1), h_2.size(2)))
        h_e2 = g_2.expand(g_2.size(0), self.dict_size)*self.embed_out2(h_2.view(h_2.size(0)*h_2.size(1), h_2.size(2)))

        h_e = self.relu(h_e1 + h_e2)  # batch_size*time_steps, hidden_size
        batch_loss = self.loss(h_e, Variable(target))

        return batch_loss, hidden, z_1, z_2

    def init_hidden(self, batch_size):
        h_t1 = Variable(torch.zeros(self.size_list[0], batch_size).float().cuda(), requires_grad=False)
        c_t1 = Variable(torch.zeros(self.size_list[0], batch_size).float().cuda(), requires_grad=False)
        z_t1 = Variable(torch.zeros(1, batch_size).float().cuda(), requires_grad=False)
        h_t2 = Variable(torch.zeros(self.size_list[1], batch_size).float().cuda(), requires_grad=False)
        c_t2 = Variable(torch.zeros(self.size_list[1], batch_size).float().cuda(), requires_grad=False)
        z_t2 = Variable(torch.zeros(1, batch_size).float().cuda(), requires_grad=False)

        hidden = (h_t1, c_t1, z_t1, h_t2, c_t2, z_t2)
        return hidden

class Tutorial_Net(Module):

    def __init__(self, hidden_size, dict_size, embed_size):
        super(Tutorial_Net, self).__init__()
        self.dict_size = dict_size
        self.hidden_size = hidden_size
        self.drop = nn.Dropout(p=0.5)
        self.embed_in = nn.Embedding(dict_size, embed_size)
        self.LSTM = nn.LSTM(embed_size, hidden_size, 2, batch_first=True, dropout=0.5)
        self.embed_out = nn.Linear(hidden_size, dict_size)
        self.loss = nn.CrossEntropyLoss()

        self.init_weight()

    def forward(self, inputs, target, hidden):
        emb = self.embed_in(Variable(inputs, volatile=not self.training))  # batch_size * time_steps * embed_size
        emb = self.drop(emb)
        h, hidden = self.LSTM(emb, hidden)
        h = self.drop(h)  # batch_size * time_steps * hidden_size
        h_e = self.embed_out(h.view(h.size(0) * h.size(1), h.size(2)))  # batch_size*time_steps, hidden_size
        batch_loss = self.loss(h_e, Variable(target))
        return batch_loss, hidden

    def init_weight(self):
        initrange = 0.1
        self.embed_in.weight.data.uniform_(-initrange, initrange)
        self.embed_out.bias.data.fill_(0)
        self.embed_out.weight.data.uniform_(-initrange, initrange)

    def init_hidden(self, batch_size):
        h = Variable(torch.zeros(2, batch_size, 650).float().cuda())
        c = Variable(torch.zeros(2, batch_size, 650).float().cuda())

        hidden = (h, c)
        return hidden


import json
import os

import yaml

class ConfigError(Exception):
    pass

class ConfigOptionError(ConfigError):
    def __init__(self, keys, reason):
        self.keys = keys
        self.reason = reason
        super().__init__("Config option {}: {}".format(".".join(keys), reason))

    def with_key(self, key):
        return ConfigOptionError((key,) + self.keys, self.reason)

_NO_DEFAULT = object()

class Option:
    def __init__(self, description, default=_NO_DEFAULT, type=None):
        self.description = description
        self.default = default
        self.type = type

    def __str__(self):
        parts = [self.description]
        if self.default is not _NO_DEFAULT:
            parts.append("default: {!r}".format(self.default))
        if self.type is not None:
            parts.append("type: {!s}".format(self.type))
        return ", ".join(parts)

    def convert(self, x):
        if self.type is None:
            return x
        return self.type(x)

    def get(self, key, data):
        try:
            x = data[key]
        except KeyError as e:
            if self.default is _NO_DEFAULT:
                # Let the sub-config handle it's missing values
                if issubclass(self.type, Config):
                    x = {}
                else:
                    raise ConfigOptionError((), "missing value") from e
            else:
                x = self.default
        try:
            return self.convert(x)
        except (TypeError, ValueError) as e:
            raise ConfigOptionError((), "invalid value {!r}".format(x)) from e

    def make_property(self, key):
        @property
        def prop(config):
            try:
                return self.get(key, config._data)
            except ConfigOptionError as e:
                raise e.with_key(key) from e

        prop.__doc__ = str(self)
        return prop

class ConfigMeta(type):
    def __new__(metacls, name, bases, attrs):
        attrs["_options"] = attrs.get("_options", {})
        attrs["_options"].update(metacls.get_options(attrs))
        attrs.update(metacls.make_properties(attrs["_options"]))
        return super().__new__(metacls, name, bases, attrs)

    @staticmethod
    def get_options(dct):
        return {k: v for k, v in dct.items() if isinstance(v, Option)}

    @staticmethod
    def make_properties(options):
        return {k: v.make_property(k) for k, v in options.items()}

class Config(metaclass=ConfigMeta):
    _options = {}

    def __init__(self, data=None):
        self._data = dict(data) if data is not None else {}

    def set(self, keys, value):
        if isinstance(keys, str):
            keys = keys.split(".")

        current = self._data
        for k in keys[:-1]:
            current[k] = current.get(k, {})
            current = current[k]
        current[keys[-1]] = value

    @staticmethod
    def _is_config_type(value):
        return isinstance(value, type) and issubclass(value, Config)

    def validate(self):
        for k, opt in self._options.items():
            v = getattr(self, k)
            if self._is_config_type(opt.type):
                try:
                    v.validate()
                except ConfigOptionError as e:
                    raise e.with_key(k) from e

    def to_dict(self):
        d = {}
        for k, opt in self._options.items():
            v = getattr(self, k)
            if self._is_config_type(opt.type):
                d[k] = v.to_dict()
            else:
                d[k] = v
        return d

    @classmethod
    def help(cls, indent=""):
        for k, opt in cls._options.items():
            if cls._is_config_type(opt.type):
                print("{}{}:".format(indent, k))
                opt.type.help(indent + "    ")
            else:
                print("{}{}: {}".format(indent, k, str(opt)))

    def from_mapping(self, mapping):
        deep_merge(self._data, mapping)

    def from_yaml(self, yaml_stream):
        self.from_mapping(yaml.safe_load(yaml_stream))

    def from_json(self, json_str):
        self.from_mapping(json.loads(json_str))

    def from_file(self, filepath):
        _, ext = os.path.splitext(filepath)
        extensions = {
            ".json": self.from_json,
            ".yml": self.from_yaml,
            ".yaml": self.from_yaml,
        }
        if ext not in extensions:
            raise ConfigError("Unsupported file type {}".format(ext))
        with open(filepath, "r") as f:
            extensions[ext](f.read())

def deep_merge(dict_1, dict_2):
    for k, v2 in dict_2.items():
        if k in dict_1:
            v1 = dict_1[k]
            if isinstance(v2, dict):
                assert isinstance(v1, dict)
                deep_merge(v1, v2)
            else:
                assert not isinstance(v1, dict)
                dict_1[k] = v2
        else:
            dict_1[k] = v2


import h5py
import cv2
import numpy as np
from albumentations import (Compose, Rotate, Blur, RandomBrightnessContrast, IAAPerspective, RandomScale)

def read_hdf5_dataset(path_to_hdf5):
    hdf5_dataset = h5py.File(path_to_hdf5, "r")
    characters_images = hdf5_dataset["characters_images"]
    characters_labels = hdf5_dataset["labels"]

    return hdf5_dataset, (characters_images, characters_labels)

def apply_image_augmentation(augmentator, image):
    augmented_image = augmentator(image = image)["image"]
    return augmented_image

def horizontal_stack_images(image_1, image_2):
    return np.hstack((image_1, image_2))

if __name__ == "__main__":
    print("[INFO] Augmentation example, press 'q' to finish the example")
    # Instancia o objeto de augmentação
    augmentator = Compose(  [Rotate(15), Blur(5), IAAPerspective(scale = (0.025, 0.05), p = 0.8),
                            RandomBrightnessContrast(brightness_limit = 0.35, contrast_limit = 0.35)],
                            p = 0.7 )

    dataset, (characters_images, characters_labels) = read_hdf5_dataset("characters_dataset.hdf5")

    for idx, image in enumerate(characters_images):
        augmented_image = apply_image_augmentation(augmentator, image)
        cv2.imshow("Character x Augmented character", horizontal_stack_images(image, augmented_image))
        print("[INFO] Label => ", characters_labels[idx])

        key = cv2.waitKey(0) & 0xff
        if key == ord('q'):
            break

    dataset.close()
    print("[INFO] Augmentation example finished")


# 624. Remove Substrings
# 中文English
# Given a string s and a set of n substrings. You are supposed to remove every instance of those n
# substrings from s so that s is of the minimum length and output this minimum length.
#
# Example
# Example 1:
#
# Input:
# "ccdaabcdbb"
# ["ab","cd"]
# Output:
# 2
# Explanation:
# ccdaabcdbb -> ccdacdbb -> cabb -> cb (length = 2)
# Example 2:
#
# Input:
# "abcabd"
# ["ab","abcd"]
# Output:
# 0
# Explanation:
# abcabd -> abcd -> "" (length = 0)

import sys
from collections import deque

class Solution:
    """
    @param: s: a string
    @param: dict: a set of n substrings
    @return: the minimum length
    """

    def minLength(self, s, dict):
        # write your code here
        visited = set()
        visited.add(s)
        q = deque([s])
        min_len = sys.maxsize
        while q:
            substring = q.popleft()
            if len(substring) < min_len:
                min_len = len(substring)
            for successor in self.find_unvisit_successors(substring, dict):
                if successor not in visited:
                    q.append(successor)
                    visited.add(successor)

        return min_len

    def find_unvisit_successors(self, s, dictionary):
        successors = []
        for word in dictionary:
            idx = s.find(word)
            while idx != -1:
                successors.append(s[:idx] + s[idx + len(word):])
                idx = s.find(word, idx + 1)

        return successors

sol = Solution()
sol.find_unvisit_successors(s='abcdbdcde', dictionary=['cd'])
assert sol.minLength(s="abcabd", dict=["ab", "abcd"]) == 0
assert sol.minLength(s="ccdaabcdbb", dict=["ab", "cd"]) == 2
assert sol.minLength(s="twgbabcfw", dict=["ab", "bc", "gba", "ww", "gf", "tw"]) == 1


# -*- coding: utf-8 -*-
"""
Created on Tue May 19 14:52:01 2020

@author: mousekinga82
"""

import pandas as pd
import numpy as np
import tensorflow as tf
from tensorflow.keras.applications.densenet import DenseNet121
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.models import Model
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau, CSVLogger
from tensorflow.keras.optimizers import Adam
import tensorflow.keras.backend as K
from datetime import date
from utils import *
K.set_image_data_format('channels_last')

IMGDIR = './images'
IMG_H = 180
IMG_W = 180
batch_size = 64
val_split = 0.2

#Load from csv
df = pd.read_csv('my_list.csv')
df_key = list(df.keys())
LABELS = [e for e in df_key if e not in ('Patient ID', 'Patient Age', 'Patient Gender', 'Image', 'Is_tv')]

#leakage check
if leakage_check(df, 'Patient ID', 'Is_tv'):
    print('Leakage check pass :D')
else:
    print('Leakage check fail :(')
    exit()

#get mean and std of 1000 samples in train_val dataset
np.random.seed(1)
grab_mean_std = get_norm_data(df, image_dir = IMGDIR, H=IMG_H, W=IMG_W)
print(f'Sampled mean, std is : {grab_mean_std[0]:.2f}, {grab_mean_std[1]:.2f}')

#get split array for coss-validation
folds, most_n = get_split(df, val_split)
print(f"Validation Splits = {val_split}, Available folds for validation : {most_n}")
train_fold, val_fold = get_train_val_split(folds, 0)

#get generator for train & val set
train_gen, val_gen = get_tv_generator(df, train_fold, val_fold, grab_mean_std, LABELS, IMGDIR, IMG_H, IMG_W, batch_size = batch_size)
N_train, N_val, N_test = len(train_gen.filenames), len(val_gen.filenames), len(df[df['Is_tv'] == False])
print(f"train, val, test samples : {N_train}, {N_val}, {N_test}")

#Deal with class imbalance
plot_class_freq(LABELS, train_gen)
freq_pos, freq_neg = compute_class_freqs(train_gen)
plot_PN_class_ratio(train_gen, LABELS)

# create the base pre-trained model
base_model = DenseNet121(weights='densenet.hdf5', include_top=False)
x = base_model.output
# add a global spatial average pooling layer
x = GlobalAveragePooling2D()(x)
# and a logistic layer
predictions = Dense(len(LABELS), activation="sigmoid")(x)
model = Model(inputs=base_model.input, outputs=predictions)
model.summary()

#complie the model
model.compile(optimizer=Adam(learning_rate=0.01), loss=get_weighted_loss(freq_pos, freq_neg), metrics=[tf.keras.metrics.AUC()])

#define callbacks
day = str(date.today())
callbacks = [EarlyStopping(monitor='val_loss', patience=5, verbose=1),
             ModelCheckpoint(f'Model_Weights_{day}.h5', save_best_only=True, save_weights_only=True),
             ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1, min_lr=1e-8),
             CSVLogger(f'log_{day}.csv', separator=",", append=False)]

#start training
model.fit_generator(train_gen,
                    validation_data=val_gen,
                    steps_per_epoch=N_train/batch_size,
                    validation_steps=N_val/batch_size,
                    epochs = 100,
                    callbacks = callbacks)

model.load_weights('Model_Weights_2020-05-21.h5')

#Testing
test_gen = get_test_generator(df, grab_mean_std, LABELS, IMGDIR, IMG_H, IMG_W)
predicted_vals = model.predict(test_gen, steps = len(test_gen))

#ROC curve
auc_rocs = get_roc_curve(LABELS, predicted_vals, test_gen)
#GradCAM, only show the lables with top 4 AUC
labels_to_show = np.take(LABELS, np.argsort(auc_rocs)[::-1])[:4]
compute_gradcam(model, grab_mean_std, '00000096_001.png', IMGDIR, df, LABELS, labels_to_show)


# 1. 모듈 가져오기
from flask import Flask, request, render_template

# # 2. 앱 생성(서버 생성)
app = Flask(__name__)

# 3. 라우팅(요청을 분석하여 어떤 함수가 응답할지 매칭)

@app.route('/')  # 내부적으로 이렇게 호출 : home()
def home():
    teams = [ {'rank':1, 'team':'프랑스'},
    {'rank':2, 'team':'벨기에'},
    {'rank':3, 'team':'잉글랜드'},
    {'rank':4, 'team':'크로아티아'} ]
    # teams 안의 팀을 하나씩 출력하시오
    for team in teams:
        # 랭킹하고 팀명을 출력하시오 -> 인덱싱(indexing) : 변수명[키]
        print(team['rank'], team['team'])

    # 응답
    return render_template('index.html', title='제목', fourTeams=teams)

# 4. 서버 가동
if __name__ == '__main__':
    app.run(debug=True)


import tensorflow as tf
from sklearn.cross_validation import train_test_split
from sklearn.datasets import make_classification
from sklearn.preprocessing import LabelEncoder
import pandas as pd
import numpy as np

TRAIN_DATA_FILE = 'data/interview_dataset_train'
TEST_DATA_FILE = 'data/interview_dataset_test_no_tags'

def process_data_file(file_name):
    df_data = pd.read_csv(file_name, sep='\t')

    # encode categorized features
    lb_make = LabelEncoder()
    colums = ['target_product_category', 'shopper_segment', 'delivery_time']
    for c in colums:
        df_data[c + "_code"] = lb_make.fit_transform(df_data[c])
    # remove non-numerical
    data_num_df = df_data.select_dtypes(include=[np.number])

    return data_num_df

# Parameters
learning_rate = 0.01
training_epochs = 100
batch_size = 100
display_step = 5

data_num_df = process_data_file(TRAIN_DATA_FILE)
y_num_df = data_num_df['tag']
x_num_df = data_num_df.drop(['tag'], axis=1)
X = x_num_df.fillna(0)
Y = np.array([y_num_df, -(y_num_df - 1)]).T  # The model currently needs one column for each class
X, X_dev, Y, Y_dev = train_test_split(X, Y)

# Network Parameters
n_hidden_1 = 25 # 1st layer number of features
n_hidden_2 = 10 # 2nd layer number of features
n_input = len(x_num_df.columns) # Number of feature
n_classes = 2 # Number of classes to predict

# tf Graph input
x = tf.placeholder("float", [None, n_input])
y = tf.placeholder("float", [None, n_classes])

# Create model
def multilayer_perceptron(x, weights, biases):
    # Hidden layer with RELU activation
    layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1'])
    layer_1 = tf.nn.relu(layer_1)
    # Hidden layer with RELU activation
    layer_2 = tf.add(tf.matmul(layer_1, weights['h2']), biases['b2'])
    layer_2 = tf.nn.relu(layer_2)
    # Output layer with linear activation
    out_layer = tf.matmul(layer_2, weights['out']) + biases['out']
    return out_layer

# Store layers weight & bias
weights = {
    'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
    'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
    'out': tf.Variable(tf.random_normal([n_hidden_2, n_classes]))
}

biases = {
    'b1': tf.Variable(tf.random_normal([n_hidden_1])),
    'b2': tf.Variable(tf.random_normal([n_hidden_2])),
    'out': tf.Variable(tf.random_normal([n_classes]))
}

# Construct model
pred = multilayer_perceptron(x, weights, biases)

# Define loss and optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

# Initializing the variables
init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)

    # Training cycle
    for epoch in range(training_epochs):
        avg_cost = 0.
        total_batch = int(len(X) / batch_size)
        X_batches = np.array_split(X, total_batch)
        Y_batches = np.array_split(Y, total_batch)
        # Loop over all batches
        for i in range(total_batch):
            batch_x, batch_y = X_batches[i], Y_batches[i]
            # Run optimization op (backprop) and cost op (to get loss value)
            _, c = sess.run([optimizer, cost], feed_dict={x: batch_x,
                                                          y: batch_y})
            # Compute average loss
            avg_cost += c / total_batch
        # Display logs per epoch step
        if epoch % display_step == 0:
            print("Epoch:", '%04d' % (epoch + 1), "cost={:.9f}".format(avg_cost))
            # Test model
            correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
            # Calculate accuracy
            accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
            print("Accuracy:", accuracy.eval({x: X_dev, y: Y_dev}))

    print("Optimization Finished!")

    X_test = process_data_file(TEST_DATA_FILE)
    result = tf.argmax(pred, 1).eval({x: X_test, y: np.zeros([X_test.size,n_classes])})
    with open('pred','w') as f:
        for r in result:
            f.writelines(str(r)+'\n')


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

ser = serial.Serial('COM3') //windows
ser.timeout = 1
time.sleep(2)

s = ''
while (s != 'K'):
    time.sleep(1)
    ser.write('?')
    s = ser.read(10)
print('connected')

while True:
    plt.clf()
    ser.write('g')
    ttime = float(ser.readline().rstrip())/512.
    nums = np.zeros(512)
    for i in range(512):
        nums[i] = int(ser.readline().rstrip())
    axis = np.arange(0, 512*ttime, ttime)
    plt.subplot(2, 1, 1)
    plt.xlabel('microseconds')
    plt.ylabel('light intensity')
    plt.plot(axis, nums, 'b')

    k = np.arange(-0.5, 0.5, 1./512)
    Y = np.fft.fftshift(np.fft.fft(nums))/512.
    plt.subplot(2, 1, 2)
    plt.xlabel('megahertz')
    plt.plot(k, abs(Y), 'r')
    plt.show()
    plt.pause(0.05)

ser.close()
print('disconnected')


from enum import Enum
from typing import Any

import tensorflow as tf

LABEL_COLUMN = "fare_amount"

class NNMode(Enum):
    EVAL = "eval"
    TRAIN = "train"

def load_dataset(file_pattern: str, batch_size: int, mode: NNMode = NNMode.EVAL) -> Any:
    dataset = tf.data.experimental.make_csv_dataset(
        file_pattern, batch_size=batch_size, label_name=LABEL_COLUMN
    )

    if mode is NNMode.TRAIN:
        dataset = dataset.shuffle(1000).repeat()
        dataset = dataset.prefetch(1)

    return dataset


from random import randint

m = 20
light_rects = 20
dark_rects = 10

def setup():
    size(1000, 500)
    noLoop()

def draw():
    background(0, 20, 30)
    noStroke()
    fill(240, 255, 240, 100)
    for _ in range(light_rects):
        w = randint(height // (m * 2), height // m) * m
        x = (randint(m, width - w - m) // m) * m
        h = randint(w // (4 * m), w // (2 * m)) * m
        y = (randint(m, height - h - m) // m) * m
        rect(x, y, w, h)
    fill(0, 30, 20, 240)
    for _ in range(dark_rects):
        x = (randint(m, width - m * 2) // m) * m
        y = (randint(m, height - m * 2) // m) * m
        square(x, y, m)

def keyPressed():
    redraw()


import pandas as pd
import sqlalchemy
import datetime

#connect to old database
engine = sqlalchemy.create_engine('postgresql://postgres@localhost:5432/foo')

#read from old postgres database foo to pandas
empl = pd.read_sql_query('select * from "empl"',con=engine)
offices = pd.read_sql_query('select * from "offices"',con=engine)
customers = pd.read_sql_query('select * from "customers"',con=engine)
customers = customers.rename(columns={"city": "customer_city", "state": "customer_state", "country": "customer_country"})
products = pd.read_sql_query('select * from "products"',con=engine)
offices = pd.read_sql_query('select * from "offices"',con=engine)
offices = offices.rename(columns={"city": "office_city", "state": "office_state","country": "office_country"})
order_overview = pd.read_sql_query('select * from "order_overview"',con=engine)
order_details = pd.read_sql_query('select * from "order_details"',con=engine)

#create measures table by joining all tables
measures= order_details.merge(products, how = 'inner', on = 'product_code').merge(order_overview, how = 'inner', on = 'order_number').merge(customers, how = 'inner', on = 'customer_number').merge(empl, how = 'inner', left_on = 'sales_rep_employee_number', right_on = 'employee_number').merge(offices, how = 'inner', on = 'office_code')
# drop the columns that are not needed in measures table
measures = measures[['order_number', 'product_code', 'quantity_ordered', 'price_each', 'order_line_number', 'quantity_in_stock', 'buy_price', '_m_s_r_p', 'order_date', 'shipped_date', 'required_date', 'customer_number', 'sales_rep_employee_number', 'credit_limit', 'reports_to', 'office_code']]
#create useful extra tables
measures['revenue']=measures['quantity_ordered']*measures['price_each']
measures['cost']=measures['quantity_ordered']*measures['buy_price']
measures['profit']=measures['revenue']-measures['cost']
measures['margin']=measures['profit']/measures['cost']

#create date dimension table
dates = pd.DataFrame(columns=['dates', 'years', 'day_of_month', 'months', 'day_of_week', 'quarter'])
dates['dates']=measures['order_date'].append(measures['shipped_date']).append(measures['required_date']).drop_duplicates().dropna()
dates['day_of_month'] = dates['dates'].map(lambda x: x.day)
dates['years'] = dates['dates'].map(lambda x: x.year)
dates['months'] = dates['dates'].map(lambda x: x.month)
dates['quarter'] = dates['dates'].map(lambda x: (x.month-1)//3+1)
dates['day_of_week'] = dates['dates'].map(lambda x: x.weekday())
# Use code '1111-11-11' for date that does not exist
dates=dates.append(pd.Series([datetime.date(year = 1111, month = 11, day = 11),None,None,None,None,None],index=['dates', 'years', 'day_of_month', 'months', 'day_of_week', 'quarter']),ignore_index=True)
measures['shipped_date']=measures['shipped_date'].fillna(datetime.date(year = 1111, month = 11, day = 11))
measures['order_date']=measures['order_date'].fillna(datetime.date(year = 1111, month = 11, day = 11))
measures['required_date']=measures['required_date'].fillna(datetime.date(year = 1111, month = 11, day = 11))

#create the other dimension tables
order_line = measures['order_line_number'].drop_duplicates()
offices = offices[['office_code','office_city','office_state','office_country','office_location']]
empl = empl[['employee_number', 'last_name','first_name','job_title']]
customers = customers[['customer_number','customer_name' ,'customer_city' ,'customer_state' ,'customer_country','customer_location']]
products = products[['product_code' ,'product_line' ,'product_name' ,'product_scale' ,'product_vendor' ,'product_description']]
orders = order_overview[['order_number','status','comments' ]]

#connect to new database
engine2 =  sqlalchemy.create_engine('postgresql://postgres@localhost:5432/bar')

# insert new tables into new database
dates.to_sql('dates', engine2, if_exists = 'append', index = False)
offices.to_sql('offices', engine2, if_exists = 'append', index = False)
empl.to_sql('empl', engine2, if_exists = 'append', index = False)
customers.to_sql('customers', engine2, if_exists = 'append', index = False)
products.to_sql('products', engine2, if_exists = 'append', index = False)
orders.to_sql('orders', engine2, if_exists = 'append', index = False)
order_line.to_sql('order_line', engine2, if_exists = 'append', index = False)
measures.to_sql('measures', engine2, if_exists = 'append', index = False)


import pymongo
import time

client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client['stellaris-red-vs-blue']
server_col = db['servers']
game_col = db['games']

# def setup_server(serverid, gather_spot, team_1, team_1_role, team_2, team_2_role, neutral, neutral_role, gm_role):
#     server_col.insert_one(
#         {
#             '_id': serverid,
#             'gathering_spot': gather_spot,
#             'team_1': team_1,
#             'team_1_role': team_1_role,
#             'team_2': team_2,
#             'team_2_role': team_2_role,
#             'neutral': neutral,
#             'neutral_role': neutral_role,
#             'gamemaster_role': gm_role
#         })

def setup_server(serverid, bot_channel, gather_spot):
    server_col.insert_one(
        {
            '_id': serverid,
            'bot_channel': bot_channel,
            'gathering_spot': gather_spot
        })

def get_server(serverid):
    return server_col.find_one({'_id': serverid})

def delete_game(msgid):
    game_col.delete_one({'_id': msgid})

def new_game(msgid, guild, host, captain_1, captain_2, starting_players):
    game_col.insert_one({'_id': msgid,
                         'guild': guild,
                         'host': host,
                         'current_time': time.time(),
                         'initial_players': starting_players,
                         'teams': [
                             {
                                 'name': 'team_1',
                                 'captain': captain_1,
                                 'players': [captain_1]
                             }, {
                                 'name': 'team_2',
                                 'captain': captain_2,
                                 'players': [captain_2]
                             }]
                         })

def add_player(msgid, team, player):
    game_col.update_one({'_id': msgid, 'teams.name': team
                         },
                        {
                            '$push': {
                                'teams.$.players': player
                            }
                        })

def remove_player(msgid, team, player):
    game_col.update_one({'_id': msgid, 'teams.name': team
                         },
                        {
                            '$pull': {
                                'teams.$.players': player
                            }
                        })

def remove_start_player(msgid, player):
    game_col.update_one({'_id': msgid
                         },
                        {
                            '$pull': {
                                'initial_players': player
                            }
                        })

def add_start_player(msgid, player):
    game_col.update_one({'_id': msgid
                         },
                        {
                            '$push': {
                                'initial_players': player
                            }
                        })

def get_host(msgid):
    a = game_col.find_one({'_id': msgid})
    return a['host']

def get_initial_players(msgid):
    a = game_col.find_one({'_id': msgid})
    return a['initial_players']

def get_all_teamed_players(msgid):
    a = game_col.find_one({'_id': msgid}, {'teams.players': 1})
    return [i['players'] for i in a['teams']]

def get_game(msgid):
    a = game_col.find({'_id': msgid})
    for i in a:
        return i

# def get_player_team(msgid, player):
#

def get_player_team(msgid, player):
    b = game_col.find_one({'_id': msgid})

    for team in b['teams']:
        if player in team['players']:
            return team['name']

def get_team(msgid, team):
    a = game_col.find_one({'_id': msgid})
    return ([t['players'] for t in a['teams'] if t['name'] == team] or [None])[0]

def get_captain_team(msgid, captain):
    b = game_col.aggregate([
        {
            '$match': {
                '_id': msgid
            }
        },
        {
            '$replaceRoot': {
                'newRoot': {
                    '$first': {
                        '$filter': {
                            'input': '$teams',
                            'as': 'team',
                            'cond': {
                                '$eq': [
                                    '$$team.captain',
                                    captain
                                ]
                            }
                        }
                    }
                }
            }
        }
    ])
    for i in b:
        return i['name']

def get_all_games():
    return [i for i in game_col.find({})]

# def test():
#     game = "222"
#     print(get_player_team(game, 703199010315305000))

# test()


import logging
import nltk
import os
import time
import shutil

import pandas as pd

from google.cloud import storage
from tensorflow.keras.models import load_model

from .utils import (make_prediction,
                    get_model_details,
                    get_scenario_articles,
                    get_bucket_ids,
                    insert_bucket_scores,
                    insert_entity_scores)

logging.basicConfig(level=logging.INFO)

def risk_classification():
    """
    download once and load when running from production
    """

    os.chdir(os.path.dirname(__file__))
    path = os.getcwd()

    HELPER_DIRECTORY = "{}/{}".format(path, "helpers")

    nltk.download('punkt')
    nltk.download('stopwords')

    storage_client = storage.Client()

    if not os.path.exists(HELPER_DIRECTORY):
        os.makedirs(HELPER_DIRECTORY)

    # fetch the latest model name from db
    results = get_model_details(scenario="Risk")

    if len(results) == 0:
        return

    model_uuid = results[0][0]
    bucket = results[0][1]
    model_path = results[0][2]
    model_name = results[0][3]

    logging.info("{}/{}".format(model_path, model_name))
    path = os.path.isfile("{}/{}".format(HELPER_DIRECTORY, model_name))
    if not path:
        shutil.rmtree("{}/".format(HELPER_DIRECTORY))
        os.makedirs(HELPER_DIRECTORY)
        logging.info("downloading the model")
        bucket = storage_client.get_bucket(bucket)
        blob = bucket.blob("{}/{}".format(model_path, model_name))
        blob.download_to_filename(
            "{}/{}".format(HELPER_DIRECTORY, model_name))

        # download tokenizer.pickle
        logging.info("downloading the tokenizer")
        blob = bucket.blob("{}/tokenizer.pickle".format(model_path))
        blob.download_to_filename(
            "{}/{}".format(HELPER_DIRECTORY, "tokenizer.pickle"))
    else:
        logging.info("model and tokenizer exists")

    # fetch articles
    articles = get_scenario_articles(model_uuid, scenario="Risk")

    df = pd.DataFrame(articles, columns=[
                      "uuid", "title", "published_date",
                      "sourceUUID", "entityUUID"])

    # loads model locally and makes prediction
    # fetch latest model name from db and load it
    time1 = time.time()

    logging.info("making prediction on {} items".format(df.shape[0]))
    model = load_model("{}/{}".format(HELPER_DIRECTORY, model_name))

    # make predictions
    count = 1
    predictions = []
    for _, row in df.iterrows():
        prediction = make_prediction(model, row['title'])
        predictions.append(prediction)
        count += 1
        if count % 100 == 0:
            logging.info(
                "processed: {}/{} articles".format(count, df.shape[0]))

    df['predictions'] = predictions

    df['financial_crime'] = df['predictions'].apply(
        lambda x: x['financial_crime'])
    df['cyber_crime'] = df['predictions'].apply(lambda x: x['cyber_crime'])
    df['other'] = df['predictions'].apply(lambda x: x['other'])

    df.drop('predictions', axis=1, inplace=True)

    time2 = time.time()
    logging.info(f'Took {time2-time1:.2f} s')

    bucket_ids, _ = get_bucket_ids(scenario="Risk")

    if df.shape[0] != 0:
        insert_bucket_scores(df, bucket_ids, model_uuid)
        insert_entity_scores(df, bucket_ids, model_uuid)
    else:
        logging.info(f'no entities to score')


"""Create a report for each sample."""
import json
import os

from dominate import tags as html_tags
from ezcharts.components.reports import labs
import pandas as pd

from .parsers import parse_mlst  # noqa: ABS101
from .process_resfinder_iso import (  # noqa: ABS101
    get_acquired_data,
    get_point_data
)   # noqa: I100,I202
from .util import get_named_logger, wf_parser  # noqa: ABS101

def convert_bp(size):
    """Convert bp values to appropriate metric prefix."""
    size = float(str(size).replace(",", ""))
    for x in ["bp", "Kb", "Mb", "Gb", "Tb"]:
        if size < 1000.0:
            if x == "bp":
                return "{:.0f} {}".format(size, x)
            else:
                return "{:.2f} {}".format(size, x)
        size /= 1000.0
    return size

def lead_section(text):
    """From a dict of key value pairs make a text section."""
    _div = html_tags.div()
    for key, value in text.items():
        if key == 'header':
            _div.add(html_tags.h3(value))
        else:
            _div.add(
                html_tags.small(key.replace("_", " ").upper(), cls="text-muted"),
                html_tags.h5(value if value is not None else "None")
            )
    return _div

def get_run_summary(read_stats, mlst_file, reference=None):
    """Get run summary statistics."""
    run_dict = dict()
    read_df = pd.read_csv(read_stats, sep="\t")
    total_yield = read_df["read_length"].sum()
    median_read_length = read_df["read_length"].median()
    median_read_quality = read_df["mean_quality"].median()
    mlst_df = parse_mlst(mlst_file)
    if mlst_df is None:
        taxon = "Unknown"
    else:
        taxon = mlst_df.loc[0, "scheme"]
    if reference is None:
        run_dict["taxon"] = taxon.capitalize()
    else:
        run_dict["reference"] = os.path.basename(reference)
    run_dict["total_yield"] = convert_bp(total_yield),
    run_dict["median_read_length"] = convert_bp(median_read_length),
    run_dict["median_read_quality"] = median_read_quality
    return run_dict

def flye_section(flye_file):
    """Extract information on denovo assembly."""
    df = pd.read_csv(flye_file, sep="\t")
    contig_num = df.shape[0]
    total_yield = convert_bp(df["length"].sum())
    circular_num = len(df[df["circ."] == "Y"])

    _div = html_tags.div()
    _table = html_tags.table(cls="table table-striped")
    _thead = html_tags.thead()
    _thead.add(
        html_tags.tr(
            html_tags.th("# Contigs"),
            html_tags.th("Total length"),
            html_tags.th("# Circular contigs"),
        )
    )
    _table.add(_thead)
    _tr = html_tags.tr()
    _tr.add(html_tags.td(contig_num))
    _tr.add(html_tags.td(total_yield))
    _tr.add(html_tags.td(circular_num))
    _table.add(_tr)
    _div.add(_table)
    return _div

def ref_section(total):
    """Return coverage information on reference based assembly."""
    depth_df = pd.read_csv(total, sep="\t", names=["ref", "start", "end", "depth"])
    coverage_dict = dict()
    thresholds = [30, 50]
    for ref, depths in depth_df.groupby("ref"):
        ref_dict = dict()
        for t in thresholds:
            total_length = 0
            above_threshold = 0
            for index, row in depths.iterrows():
                total_length += row["end"] - row["start"]
                if row["depth"] >= t:
                    above_threshold += row["end"] - row["start"]
            above_threshold_pct = above_threshold / total_length * 100
            if "total_len" not in ref_dict:
                ref_dict["total_len"] = convert_bp(total_length)
            ref_dict[t] = round(above_threshold_pct, 3)
        coverage_dict[ref] = ref_dict

    # HTML table
    _div = html_tags.div()
    _table = html_tags.table(cls="table table-striped")
    _thead = html_tags.thead()
    _thead.add(
        html_tags.tr(
            html_tags.th("Contig"),
            html_tags.th("Total length"),
            [html_tags.th(f"% Coverage at {t}x") for t in thresholds]
        )
    )
    _table.add(_thead)
    for k, v in coverage_dict.items():
        _tr = html_tags.tr()
        _tr.add(html_tags.td(k))
        _tr.add(html_tags.td(v["total_len"]))
        _tr.add([html_tags.td(v[t]) for t in thresholds])
        _table.add(_tr)
    _div.add(_table)
    return _div

def amr_section(resfinder_json, html_id):
    """Parse resfinder JSON for accordion style table."""
    with open(resfinder_json) as fh:
        resfinder_data_raw = json.load(fh)
    acquired_data = get_acquired_data(resfinder_data_raw)
    point_data = get_point_data(resfinder_data_raw)
    if (not acquired_data and not point_data):
        return html_tags.p("No AMR genes detected in sample.")
    _div = html_tags.div(cls="accordion-item")
    # Point mutations
    row = 0   # Fault if gene name contains "'" (e.g aac(2')-Ic
    for gene, evidence in point_data.items():
        if not evidence:
            continue
        row += 1
        drugs = {drug.capitalize() for mut in evidence for drug in mut["drugs"]}
        _head = html_tags.h2(id=f"{row}", style="border: 1px solid rgba(0,0,0,.125);\
                            border-collapse: collapse;\
                             padding:0;\
                             margin-bottom:0")
        _button = html_tags.button(
            html_tags.span(html_tags.b(gene)),
            html_tags.span(
                [html_tags.span(d, cls="badge bg-dark me-1") for d in drugs]
            ),
            html_tags.span(
                "PointFinder",
                html_tags.span(
                    len(evidence),
                    cls="position-absolute badge rounded-pill bg-danger",
                    style="top:8px"
                    ),
                cls="badge bg-primary"),
            cls="accordion-button collapsed",
            type="button",
            data_bs_toggle="collapse",
            data_bs_target=f"#collapse{row}",
            aria_expanded="false",
            aria_controls=f"collapse{row}",
            style="display: grid; \
                    align-items: center;\
                    grid-template-columns: 150px 1fr max-content max-content;\
                    grid-gap: 25px"
            )
        _head.add(_button)
        _div.add(_head)
        _div1 = html_tags.div(
            id=f"collapse{row}",
            cls="accordion-collapse collapse",
            fr=f"{row}",
            aria_labelledby=f"{row}",
            data_bs_parent=f"#{html_id}")
        _div2 = html_tags.div(cls="accordion body")
        _table = html_tags.table(cls="table table-striped")
        _thead = html_tags.thead()
        _thead.add(
            html_tags.tr(
                html_tags.th("Antimicrobial resistance"),
                html_tags.th("Amino Acid"),
                html_tags.th("Nucleotide"),
            )
        )
        _table.add(_thead)
        for mutation in evidence:
            _tr = html_tags.tr()
            _tr.add(
                html_tags.td("; ".join(d.capitalize() for d in mutation["drugs"])),
                html_tags.td(mutation["aa"]),
                html_tags.td(mutation["nuc"].upper())
            )
            _table.add(_tr)
        _div2.add(_table)
        _div1.add(_div2)
        _div.add(_div1)

    # Acquired resistance
    for gene, evidence in acquired_data.items():
        row += 1
        _head = html_tags.h2(id="f{row}", style="border: 1px solid rgba(0,0,0,.125);\
                            border-collapse: collapse;\
                            padding:0;\
                            margin-bottom:0")
        _button = html_tags.button(
            html_tags.span(html_tags.b(gene)),
            html_tags.span(
                {html_tags.span(
                    d.capitalize(),
                    cls="badge bg-dark me-1"
                    ) for d in evidence["drugs"]}
                ),
            html_tags.span(
                "ResFinder",
                html_tags.span(
                    1,  # TODO add evidence as list for multiple shits of gene
                    cls="position-absolute badge rounded-pill bg-danger",
                    style="top:8px"
                    ),
                cls="badge bg-secondary"),
            cls="accordion-button collapsed",
            type="button",
            data_bs_toggle="collapse",
            data_bs_target=f"#collapse{row}",
            aria_expanded="false",
            aria_controls=f"collapse{row}",
            style="display: grid;\
                grid-template-columns: 150px 1fr max-content max-content;\
                align-items: center;\
                grid-gap: 25px")
        _head.add(_button)
        _div.add(_head)
        _div1 = html_tags.div(
            id=f"collapse{row}",
            cls="accordion-collapse collapse",
            fr=f"{row}",
            aria_labelledby=f"{row}",
            data_bs_parent=f"#{html_id}"
            )
        _div2 = html_tags.div(cls="accordion body")
        _table = html_tags.table(cls="table table-striped")
        _thead = html_tags.thead()
        _thead.add(
            html_tags.tr(
                html_tags.th("Antimicrobial resistance"),
                html_tags.th("Identity"),
                html_tags.th("Coverage")
            )
        )
        _table.add(_thead)
        _tr = html_tags.tr()
        _tr.add(
            html_tags.td("; ".join(d.capitalize() for d in evidence["drugs"])),
            html_tags.td(evidence["identity"]),
            html_tags.td(evidence["coverage"])
        )
        _table.add(_tr)
        _div2.add(_table)
        _div1.add(_div2)
        _div.add(_div1)
    return _div

def mlst_section(mlst_file):
    """Extract mlst results."""
    mlst_df = parse_mlst(mlst_file)
    if mlst_df is None:
        return html_tags.div(html_tags.p(
            "MLST was unable to identify a typing scheme for this sample. "
            "Please check coverage of sample."
            ))
    col_names = mlst_df.columns
    row_data = mlst_df.iloc[0, :].values
    # C apitalise all non-gene columns
    col_names = [x.capitalize() if i < 3 else x for i, x in enumerate(col_names)]
    # HTML section
    _div = html_tags.div()
    _table = html_tags.table(cls="table table-striped")
    _thead = html_tags.thead()
    _thead.add(html_tags.tr([html_tags.th(c) for c in col_names]))
    _table.add(_thead)
    _tr = html_tags.tr()
    for cell in row_data:
        _tr.add(html_tags.td(cell))
    _table.add(_tr)
    _div.add(_table)
    return _div

def main(args):
    """Run the entry point."""
    logger = get_named_logger("Report")
    report = labs.LabsReport(
        f"{args.sample_alias} | Isolate Sequencing Report",
        "wf-bacterial-genomes",
        args.params,
        args.versions,
    )

    lead_summary = lead_section(dict(
        sample=args.sample_alias,
        barcode=args.sample_barcode,
        run=args.wf_session,
        version=args.wf_version,
    ))
    with open(args.params) as fh:
        params_data = json.load(fh)

    run_summary_dict = get_run_summary(
        "report_files/per-read-stats.tsv",
        f"report_files/{args.sample_alias}.mlst.json",
        params_data["reference"]
        )

    run_summary = lead_section(run_summary_dict)

    with report.add_section('Workflow details', 'Workflow', True):
        with html_tags.div(cls="row"):
            html_tags.div(lead_summary, cls="col-sm-12", style="float: left; width:50%")
            html_tags.div(run_summary, cls="col-sm-12", style="float: right; width:50%")

    with report.add_section("Multilocus sequencing typing (MLST)", "MLST"):
        with html_tags.div(cls="row"):
            mlst_section(f"report_files/{args.sample_alias}.mlst.json")

    with report.add_section('Antimicrobial resistance prediction', 'AMR', True):
        with html_tags.div(cls="accordion", id="accordionTable"):
            if os.path.exists(
                f"report_files/{args.sample_alias}_resfinder_results/"
                f"{args.sample_alias}_resfinder.json"
            ):
                html_tags.p(
                    "Analysis was performed using ResFinder. "
                    "Click on each gene for more information."
                )
                amr_section(
                    f"report_files/{args.sample_alias}_resfinder_results/"
                    f"{args.sample_alias}_resfinder.json",
                    "accordionTable"
                )
            else:
                html_tags.p("No AMR genes detected for specific species.")

    with report.add_section("Assembly QC", "Assembly", True):
        with html_tags.div(cls="row"):
            if not args.denovo:
                html_tags.p(
                    "Analysis was completed using an alignment with the provided "
                    "reference, and Medaka was used for variant calling."
                )
                ref_section(f"report_files/{args.sample_alias}.total.regions.bed.gz")
            else:
                html_tags.p(
                    "As no reference was provided the reads were assembled"
                    " and corrected using Flye and Medaka."
                )
                flye_section(f"report_files/{args.sample_alias}_flye_stats.tsv")

    report.write(args.output)
    logger.info(f"Report written to {args.output}.")

def argparser():
    """Argument parser for entrypoint."""
    parser = wf_parser("report")
    parser.add_argument(
        "--denovo",
        action="store_true",
        help="Analysis performed de-novo assembly (instead of variant calling).",
    )
    parser.add_argument(
        "--prokka", action="store_true", help="Prokka analysis was performed."
    )
    parser.add_argument(
        "--isolates", action="store_true", help="Resfinder analysis was performed."
    )
    parser.add_argument(
        "--versions",
        required=True,
        help="directory containing CSVs containing name,version.",
    )
    parser.add_argument(
        "--params",
        default=None,
        required=True,
        help="A JSON file containing the workflow parameter key/values",
    )
    parser.add_argument("--output", help="Report output filename")
    parser.add_argument("--sample-alias", required=True)
    parser.add_argument("--sample-barcode", required=True)
    parser.add_argument("--wf-session", required=True)
    parser.add_argument("--wf-version", required=True)
    return parser


######################################################################################################################
# This code was taken from https://github.com/arianemarandon/adadetect.git
#                   by "Machine learning meets false discovery rate" (Marandon et. al 2022)
#
# Additional implementations have been added to the file
######################################################################################################################

import math
import numpy as np
from scipy.stats import ttest_ind

def EmpBH(null_statistics, test_statistics, level):
    """
    Algorithm 1 of "Semi-supervised multiple testing", Roquain & Mary : faster than computing p-values and applying BH

    test_statistics: scoring function evaluated at the test sample i.e. g(X_1), ...., g(X_m)
    null_statistics: scoring function evaluated at the null sample that is used for calibration of the p-values i.e.
                    g(Z_k),...g(Z_n)
    level: nominal level

    Return: rejection set
    """
    n = len(null_statistics)
    rejections = []
    m = len(test_statistics)

    mixed_statistics = np.concatenate([null_statistics, test_statistics])
    sample_ind = np.concatenate([np.ones(len(null_statistics)), np.zeros(len(test_statistics))])

    sample_ind_sort = sample_ind[np.argsort(-mixed_statistics)]
    #np.argsort(-mixed_statistics) gives the order of the stats in descending order
    # sample_ind_sort sorts the 1-labels according to this order

    fdp = 1
    V = n
    K = m
    l=m+n

    while (fdp > level and K >= 1):
        l-=1
        if sample_ind_sort[l] == 1:
            V-=1
        else:
            K-=1
        fdp = (V+1)*m / ((n+1)*K) if K else 1

    test_statistics_sort_ind = np.argsort(-test_statistics)
    return test_statistics_sort_ind[:K]

def BH(pvalues, level):
    """
    Benjamini-Hochberg procedure.
    """
    rejections = []
    n = len(pvalues)
    pvalues_sort_ind = np.argsort(pvalues)
    pvalues_sort = np.sort(pvalues) #p(1) < p(2) < .... < p(n)

    comp = pvalues_sort <= (level* np.arange(1,n+1)/n)
    #get first location i0 at which p(k) <= level * k / n
    comp = comp[::-1]
    comp_true_ind = np.nonzero(comp)[0]
    i0 = comp_true_ind[0] if comp_true_ind.size > 0 else n
    nb_rej = n - i0
    threshold = pvalues[pvalues_sort_ind[nb_rej - 1]]
    return pvalues_sort_ind[:nb_rej], threshold

def compute_pvalue(test_statistic, null_statistics):
    return (1 + np.sum(null_statistics >= test_statistic)) / (len(null_statistics)+1)

def eBH(evalues, level):
    """
    E-values Benjamini-Hochberg procedure.
    """
    n = len(evalues)
    evalues_sort_ind = np.argsort(evalues)[::-1]
    evalues_sort = np.sort(evalues)[::-1] #e(1) > e(2) > .... > e(n)

    comp = evalues_sort >= (n / (level * np.arange(1,n+1)))
    # get first (largest) location i0 at which e(k) >= n / level * k
    comp = comp[::-1]
    comp_true_ind = np.nonzero(comp)[0]
    i0 = comp_true_ind[0] if comp_true_ind.size > 0 else n
    nb_rej = n - i0
    threshold = evalues[evalues_sort_ind[nb_rej - 1]]
    return evalues_sort_ind[:nb_rej], threshold

def compute_evalue(test_statistics, null_statistics, t):
    denominator = (1 + np.sum(null_statistics >= t)) / (1 + null_statistics.shape[0])
    evalues = ((test_statistics >= t).astype(int) / denominator)
    return evalues

def compute_threshold(test_statistics, null_statistics, level):
    n, m = len(null_statistics), len(test_statistics)
    mixed_statistics = np.concatenate([null_statistics, test_statistics])
    sample_ind = np.concatenate([np.ones(len(null_statistics)), np.zeros(len(test_statistics))])

    sample_ind_sort = sample_ind[np.argsort(-mixed_statistics)]

    fdp = 1
    V = n
    K = m
    l = m + n

    while (fdp > level and K >= 1):
        l -= 1
        if sample_ind_sort[l] == 1:
            V -= 1
        else:
            K -= 1
        fdp = (V * m) / (n * K) if K else 1

    mixed_statistics_sort_ind = np.argsort(-mixed_statistics)
    if fdp > level:
        threshold = mixed_statistics[mixed_statistics_sort_ind[0]] + 1
    else:
        threshold = mixed_statistics[mixed_statistics_sort_ind[l-1]]
    return threshold

def get_weight(test_scores, scores_null, weight_metric, trim_prec=0.1):
    if weight_metric == 'uniform':
        return 1
    elif weight_metric == 't-test' or weight_metric == 'avg_score':
        # sort and trim
        scores = np.concatenate((test_scores, scores_null), axis=0)
        sorted_scores = np.sort(scores)
        large_group = sorted_scores[-1*math.ceil(trim_prec*test_scores.shape[0]):]
        small_group = sorted_scores[:-1*math.ceil(trim_prec*test_scores.shape[0])]
        if weight_metric == 'avg_score':
            w = np.mean(small_group)  # can be negative
            weight = np.exp(-1 * w)
            return weight
        elif weight_metric == 't-test':
            statistic, _ = ttest_ind(small_group, large_group)
            return np.abs(statistic)
    else:
        raise ValueError(f'The following weight metric is not supported - {weight_metric}')

def calibrator_p_to_e(pvalues, calibrator_type, null_s, test_s, r):
    if calibrator_type == 'Shafer':
        # 1/sqrt(p) - 1
        evalues = (1 / np.sqrt(pvalues)) - 1
        return evalues
    elif calibrator_type == 'VS':
        safe_pvalues = pvalues + (pvalues == 1).astype(float)
        evalues = (pvalues <= np.exp(-1)) * -1 * np.exp(-1) / (pvalues*np.log(safe_pvalues)) + (pvalues > np.exp(-1))
        return evalues
    elif calibrator_type == 'soft-rank':
        cal_min = np.min(null_s)
        cal_max = np.max(null_s)
        tmp_w_min = np.concatenate((test_s.reshape((-1, 1)), np.ones_like(test_s.reshape((-1, 1)))*cal_min), axis=-1)
        tmp_w_max = np.concatenate((test_s.reshape((-1, 1)), np.ones_like(test_s.reshape((-1, 1)))*cal_max), axis=-1)
        L_min = np.min(tmp_w_min, axis=-1).reshape((-1, 1))
        L_max = np.max(tmp_w_max, axis=-1).reshape((-1, 1))
        # normalize statistics values
        test_stats = np.divide((test_s.reshape((-1, 1)) - L_min), (L_max - L_min))  # (n_test,)
        cal_stats = np.divide((null_s.reshape((1, -1)) - L_min), (L_max - L_min))  # (n_test, n_cal)
        # Note: min value supposed to be 0
        cal_min = np.min(cal_stats, axis=-1).reshape((-1, 1))  # (n_test,)
        tmp = np.concatenate((test_stats.reshape((-1, 1)), cal_min), axis=-1)
        L_min = np.min(tmp, axis=-1).reshape((-1, 1))  # (n_test,)
        assert (L_min == np.zeros_like(L_min)).all(), "Error: after normalize, L_min is not zeros."
        if r == 0:
            R_values = test_stats.reshape((-1, 1)) - L_min
            R_cal_values = cal_stats - L_min
        else:
            R_values = (np.exp(r*test_stats.reshape((-1, 1))) - np.exp(r*L_min)) / r
            R_cal_values = (np.exp(r*cal_stats) - np.exp(r*L_min)) / r
        evalues = (1 + null_s.shape[0]) * R_values / (np.sum(R_cal_values, axis=-1).reshape((-1,1)) + R_values)
        return evalues.reshape((-1,))
    elif calibrator_type == 'integral':
        safe_pvalues = pvalues + (pvalues == 1).astype(float)
        numerator = 1 - pvalues + pvalues*np.log(pvalues)
        demon = pvalues * np.power(-1 * np.log(safe_pvalues), 2)
        evalues = (numerator / demon) * (pvalues != 1) + 0.5 * (pvalues == 1)
        return evalues
    else:
        raise ValueError(f'The following calibrator is not supported - {calibrator_type}')

def compute_all_pvalue(test_statistic, null_statistics):
    return (1 + np.sum(null_statistics.reshape((1, -1)) >= test_statistic.reshape((-1, 1)), axis=1)) / (len(null_statistics)+1)


import turtle
import pandas as pd

pen = turtle.Turtle()
pen.hideturtle()
pen.penup()
screen = turtle.Screen()
screen.title("Game")
image = "/Users/aryankumar/Desktop/python/blank_states_img.gif"
screen.addshape(image)
turtle.shape(image)
state_data = pd.read_csv("/Users/aryankumar/Desktop/python/50_states.csv")
states = state_data["state"]

play = True

while play:
    answer_state = screen.textinput(title="Guess the state",prompt="enter the state name")

    found = False

    for ans in states:
        if ans == answer_state:
            row = state_data[state_data["state"]==ans]
            xpos = row.iloc[0]['x']
            ypos = row.iloc[0]['y']
            pen.goto(xpos,ypos)
            pen.write(ans,align="center",font=("Arial",12,"normal"))

screen.exitonclick()


import cv2,numpy as np

img = cv2.imread('messi5.jpg')

#citanje piksela

pixel = img[100,100]
pixel_red = img[100,100,2]

print(pixel)
print(pixel_red)
#izmena piksela
img[100,100] = [0,0,0]

#numpy access i izmena

pixel = img.item(100,100,2)
print(pixel)
img.itemset((100,100,0),255)
img.itemset((100,100,1),255)
img.itemset((100,100,2),255)

print(pixel)
#print(pixel2)

cv2.imshow('Image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

2.Core Operations/1.Basic Operation on Image/1.Image_access_modif.py