# This code is forked/revised from Tensorflow-NMT

"""Utility for evaluating various tasks, e.g., translation & summarization."""
import argparse
import os
import subprocess
import sys
import math
import re
import time
from multiprocessing import Pool

import numpy as np

from finedial.utils.evaluation.score_helper import ScoreManager
from finedial.utils.evaluation.scripts import bleu
from finedial.utils.evaluation.scripts import rouge
from finedial.utils.evaluation.scripts import embed
from finedial.utils.evaluation.scripts import tokens2wordlevel
from finedial.utils.logging.logger_helper import logger

from rouge import Rouge

from collections import Counter, defaultdict

__all__ = ["evaluate"]

def evaluate(metric, ground_truth_reference, ground_truth_query, generations, embed_file=0,
             dim=200, vocab_size=None, word_option=None, beam_width=10):
    """
    :param metric:
    :param ground_truth_reference: Ground-truth reference tgt file
    :param ground_truth_query: Ground-truth reference src file
    :param generations: : The generated tgt file
    :param embed_file:
    :param dim:
    :param vocab_size:
    :param word_option:
    :param beam_width:
    :return:
    """
    if metric.lower() == "embed":
        evaluation_score = embed.eval(ground_truth_query, ground_truth_reference, generations, embed_file, dim,
                                      word_option)
    elif metric.lower() == "f1":
        evaluation_score = f1(generations, ground_truth_reference, word_option=word_option)
    elif metric.lower() == "unk":
        evaluation_score = unk(generations, -1, word_option=word_option)
    elif metric.lower() == 'unk_sentence':
        evaluation_score = unk_sentence(generations, -1, word_option=word_option)
    elif len(metric.lower()) > 4 and metric.lower()[0:4] == 'bleu':
        max_order = int(metric.lower()[5:])
        evaluation_score = _bleu(ground_truth_reference, generations, max_order=max_order,
                                 word_option=word_option)
        reverse_evaluation_score = _bleu(ground_truth_query, generations, max_order=max_order,
                                         word_option=word_option)
        for key in reverse_evaluation_score.keys():
            evaluation_score['SRC_' + key] = reverse_evaluation_score[key]

    elif metric.lower() == "rouge":
        evaluation_score = _rouge(ground_truth_reference, generations,
                                  word_option=word_option)
    elif metric.lower()[0:len('distinct_c')] == 'distinct_c':
        max_order = int(metric.lower()[len('distinct_c') + 1:])
        evaluation_score = _distinct_c(generations, max_order, word_option=word_option)
    elif metric.lower()[0:len('distinct')] == 'distinct':
        max_order = int(metric.lower()[len('distinct') + 1:])
        evaluation_score = _distinct(generations, max_order, word_option=word_option)
    elif metric.lower()[0:len('intra_distinct')] == 'intra_distinct':
        max_order = int(metric.lower()[len('intra_distinct') + 1:])
        evaluation_score = _intra_distinct(generations, max_order, beam_width, word_option=word_option)
    elif metric.lower()[0:len('len')] == 'len':
        evaluation_score = seq_len(generations, -1, word_option=word_option)
    elif metric.lower() == 'std_ent':
        evaluation_score = _std_ent_n(generations, word_option=word_option)
    else:
        raise ValueError("Unknown metric %s" % metric)

    return evaluation_score

def _clean(sentence, word_option):
    sentence = tokens2wordlevel.revert_from_sentence(sentence, word_option)
    return sentence

# 验证没问题OK https://github.com/mgalley/DSTC7-End-to-End-Conversation-Modeling/blob/master/evaluation/src/metrics.py
def _distinct(trans_file, max_order=1, word_option=None):
    """Compute Distinct Score"""
    translations = []
    with open(trans_file, 'r', encoding='utf-8') as fh:
        for line in fh.readlines():
            line = _clean(line, word_option=word_option)
            translations.append(line.split(" "))

    num_tokens = 0
    unique_tokens = set()
    scores = []
    for words in translations:
        local_unique_tokens = set()
        local_count = 0.0
        # print(items)
        for i in range(0, len(words) - max_order + 1):
            valid_words = []
            for x in words[i:i + max_order]:
                if x.find('<unk>') == -1:
                    valid_words.append(x)
            tmp = ' '.join(valid_words)
            unique_tokens.add(tmp)
            num_tokens += 1
            local_unique_tokens.add(tmp)
            local_count += 1
        if local_count == 0:
            scores.append(0)
        else:
            scores.append(100 * len(local_unique_tokens) / local_count)
    if num_tokens == 0:
        ratio = 0
    else:
        ratio = len(unique_tokens) / num_tokens

    result_dict = {
        'DIST_%d' % max_order: ratio * 100,
        'DIST_%d_Scores' % max_order: scores,
    }
    return result_dict

def _intra_distinct(trans_file, max_order, beam_width, word_option=None):
    """Compute Distinct Score"""
    if beam_width == 0:
        beam_width = 1
    translations = []
    with open(trans_file, 'r', encoding='utf-8') as fh:
        for line in fh.readlines():
            line = _clean(line, word_option=word_option)
            translations.append(line.split(" "))

    assert len(translations) % beam_width == 0

    all_ratios = []
    for i in range(0, len(translations), beam_width):
        num_tokens = 0
        unique_tokens = set()
        for items in translations[i:i + beam_width]:
            # print(items)
            for i in range(0, len(items) - max_order + 1):
                valid_words = []
                for x in items[i:i + max_order]:
                    if x != '<unk>':
                        valid_words.append(x)
                tmp = ' '.join(valid_words)
                unique_tokens.add(tmp)
                num_tokens += 1
        if num_tokens == 0:
            ratio = 0
        else:
            ratio = len(unique_tokens) / num_tokens
        all_ratios.append(ratio * 100)

    result_dict = {
        'DIST_Intra_%d' % max_order: sum(all_ratios) / len(all_ratios),
        'DIST_Intra_%d_Scores' % max_order: all_ratios,
    }
    return result_dict

def seq_len(trans_file, max_order=1, word_option=None):
    """Compute Length Score"""
    sum = 0.0
    total = 0
    scores = []
    with open(trans_file, 'r', encoding='utf-8') as fh:
        for line in fh.readlines():
            line = _clean(line, word_option=word_option)
            word_len = len(line.split())
            sum += word_len
            scores.append(word_len)
            total += 1
    result_dict = {
        'Len': sum / total,
        'Len_Scores': scores,
    }
    return result_dict

def f1(trans_file, golden_file, word_option=None):
    """
    calc_f1
    """
    responses = []
    with open(trans_file, 'r', encoding='utf-8') as fh:
        for line in fh.readlines():
            line = _clean(line, word_option=word_option)
            responses.append(line.split(" "))
    golden_responses = []
    with open(golden_file, 'r', encoding='utf-8') as fh:
        for line in fh.readlines():
            line = _clean(line, word_option=word_option)
            golden_responses.append(line.split(" "))

    golden_char_total = 0.0
    pred_char_total = 0.0
    hit_char_total = 0.0
    for response, golden_response in zip(responses, golden_responses):
        golden_response = "".join(golden_response)
        response = "".join(response)
        common = Counter(response) & Counter(golden_response)
        hit_char_total += sum(common.values())
        golden_char_total += len(golden_response)
        pred_char_total += len(response)
    p = hit_char_total / pred_char_total
    r = hit_char_total / golden_char_total
    f1 = 2 * p * r / (p + r)
    result_dict = {
        'CharF1': f1 * 100
    }
    return result_dict

def unk(trans_file, max_order=1, word_option=None):
    """Compute UNK Number"""
    unk = 0.0
    total = 0.0
    scores = []
    with open(trans_file, 'r', encoding='utf-8') as fh:
        for line in fh.readlines():
            line = _clean(line, word_option=word_option).split()
            total += len(line)
            my_unk = 0.0
            for word in line:
                if word.find('<unk>') > -1:
                    unk += 1
                    my_unk += 1
            if len(line) == 0:
                scores.append(1.0)
            else:
                scores.append((my_unk / len(line)))

    result_dict = {
        'UNKRate': unk / total,
        'UNKRate_Scores': scores,
    }
    return result_dict

def unk_sentence(trans_file, max_order=1, word_option=None):
    """Compute UNK Number"""
    unk = 0.0
    total = 0.0
    scores = []
    with open(trans_file, 'r', encoding='utf-8') as fh:
        for line in fh.readlines():
            line = _clean(line, word_option=word_option).split()
            total += 1
            my_unk = 0.0
            for word in line:
                if word == '<unk>':
                    unk += 1
                    my_unk += 1
                    break
            if len(line) == 0:
                scores.append(1.0)
            else:
                scores.append(my_unk)
    result_dict = {
        'UNKSentRate': unk / total,
        'UNKSentRate_Scores': scores,
    }
    return result_dict

def _distinct_c(trans_file, max_order=1, word_option=None):
    """Compute Distinct Score"""

    translations = []
    with open(trans_file, 'r', encoding='utf-8') as fh:
        for line in fh.readlines():
            line = _clean(line, word_option=word_option)
            translations.append(line.split(" "))

    unique_tokens = set()
    local_counts = []
    for items in translations:
        # print(items)
        local_unique_tokens = set()
        for i in range(0, len(items) - max_order + 1):
            valid_words = []
            for x in items[i:i + max_order]:
                if x != '<unk>':
                    valid_words.append(x)
            tmp = ' '.join(valid_words)
            unique_tokens.add(tmp)
            local_unique_tokens.add(tmp)
        local_counts.append(len(local_unique_tokens))
    ratio = len(unique_tokens)
    result_dict = {
        'DIST_Count_%d' % max_order: ratio,
        'DIST_Count_%d_Scores' % max_order: local_counts,
    }
    return result_dict

def _std_ent_n(trans_file, word_option=None):
    # based on Yizhe Zhang's code https://github.com/mgalley/DSTC7-End-to-End-Conversation-Modeling/blob/master/evaluation/src/metrics.py
    ngram_scores = [0, 0, 0, 0]
    counter = [defaultdict(int), defaultdict(int), defaultdict(int), defaultdict(int)]
    i = 0
    for line in open(trans_file, encoding='utf-8'):
        i += 1
        words = _clean(line, word_option=word_option).split()
        for n in range(4):
            for idx in range(len(words) - n):
                ngram = ' '.join(words[idx:idx + n + 1])
                counter[n][ngram] += 1

    for n in range(4):
        total = sum(counter[n].values())
        for v in counter[n].values():
            ngram_scores[n] += - v / total * (np.log(v) - np.log(total))

    result_dict = {
        'ent1': ngram_scores[0],
        'ent2': ngram_scores[1],
        'ent3': ngram_scores[2],
        'ent4': ngram_scores[3],
    }

    return result_dict

# Follow //transconsole/localization/machine_translation/metrics/bleu_calc.py
def _bleu(ref_file, trans_file, max_order=4, word_option=None):
    """Compute BLEU scores and handling BPE."""
    smooth = False
    ref_files = [ref_file]
    reference_text = []
    for reference_filename in ref_files:
        with open(reference_filename, 'r+', encoding='utf-8') as fh:
            reference_text.append(fh.readlines())

    per_segment_references = []
    for references in zip(*reference_text):
        reference_list = []
        for reference in references:
            reference = _clean(reference, word_option)
            reference_list.append(reference.split(" "))
        per_segment_references.append(reference_list)

    #     print(per_segment_references[0:3])

    translations = []
    with open(trans_file, 'r+', encoding='utf-8') as fh:
        for line in fh.readlines():
            line = _clean(line, word_option=word_option)
            translations.append(line.split(" "))
    #     print(translations[0:3])

    # bleu_score, precisions, bp, ratio, translation_length, reference_length
    bleu_score, _, _, _, _, _ = bleu.compute_bleu(
        per_segment_references, translations, max_order, smooth)

    blue_scores = []
    for ref, trans in zip(per_segment_references, translations):
        tmp_bleu_score, _, _, _, _, _ = bleu.compute_bleu(
            [ref], [trans], max_order, smooth)
        blue_scores.append(tmp_bleu_score * 100)

    result_dict = {
        'BLEU-%d' % max_order: 100 * bleu_score,
        'BLEU-%d_Scores' % max_order: blue_scores,
    }
    return result_dict

def _rouge(ref_file, summarization_file, word_option=None):
    """Compute ROUGE scores and handling BPE."""

    references = []
    with open(ref_file, 'r', encoding='utf-8') as fh:
        for line in fh.readlines():
            references.append(_clean(line, word_option))

    hypotheses = []
    with open(summarization_file, 'r', encoding='utf-8') as fh:
        for line in fh.readlines():
            hypotheses.append(_clean(line, word_option=word_option))

    rouge_score_map = rouge.rouge(hypotheses, references)

    rouge_l_scores = []
    rouge_1_scores = []
    rouge_2_scores = []
    for hypo, ref in zip(hypotheses, references):
        tmp_rouge_score_map = rouge.rouge([hypo], [ref])
        rouge_l_scores.append(100 * tmp_rouge_score_map["rouge_l/f_score"])
        rouge_1_scores.append(100 * tmp_rouge_score_map["rouge_1/f_score"])
        rouge_2_scores.append(100 * tmp_rouge_score_map["rouge_2/f_score"])

    result_dict = {
        'ROUGE_L': 100 * rouge_score_map["rouge_l/f_score"],
        'ROUGE_L_Scores': rouge_l_scores,
        'ROUGE_1': 100 * rouge_score_map["rouge_1/f_score"],
        'ROUGE_1_Scores': rouge_1_scores,
        'ROUGE_2': 100 * rouge_score_map["rouge_2/f_score"],
        'ROUGE_2_Scores': rouge_2_scores,
    }
    return result_dict

def _moses_bleu(multi_bleu_script, tgt_test, trans_file, word_option=None):
    """Compute BLEU scores using Moses multi-bleu.perl script."""

    # TODO(thangluong): perform rewrite using python
    # BPE
    if word_option == "bpe":
        debpe_tgt_test = tgt_test + ".debpe"
        if not os.path.exists(debpe_tgt_test):
            # TODO(thangluong): not use shell=True, can be a security hazard
            subprocess.call("cp %s %s" % (tgt_test, debpe_tgt_test), shell=True)
            subprocess.call("sed s/@@ //g %s" % (debpe_tgt_test),
                            shell=True)
        tgt_test = debpe_tgt_test
    elif word_option == "spm":
        despm_tgt_test = tgt_test + ".despm"
        if not os.path.exists(despm_tgt_test):
            subprocess.call("cp %s %s" % (tgt_test, despm_tgt_test))
            subprocess.call("sed s/ //g %s" % (despm_tgt_test))
            subprocess.call(u"sed s/^\u2581/g %s" % (despm_tgt_test))
            subprocess.call(u"sed s/\u2581/ /g %s" % (despm_tgt_test))
        tgt_test = despm_tgt_test
    cmd = "%s %s < %s" % (multi_bleu_script, tgt_test, trans_file)

    # subprocess
    # TODO(thangluong): not use shell=True, can be a security hazard
    bleu_output = subprocess.check_output(cmd, shell=True)

    # extract BLEU score
    m = re.search("BLEU = (.+?),", bleu_output)
    bleu_score = float(m.group(1))

    return bleu_score

def std_eval(ref_src_file, ref_tgt_file, top1_out_file_path, topk_out_file_path,
             pre_embed_file, pre_embed_dim, subword, vocab_size, beam_width):

    metrics = 'unk,unk_sentence,rouge,bleu-1,bleu-2,bleu-3,bleu-4,' \
              'intra_distinct-1,intra_distinct-2,distinct-1,distinct-2,distinct_c-1,distinct_c-2,' \
              'len,std_ent,f1'.split(',')
    thread_pool = Pool(8)
    jobs = []
    for metric in metrics:
        if metric[:len('intra_distinct')] == 'intra_distinct':
            job = thread_pool.apply_async(evaluate, (
                metric, ref_tgt_file, ref_src_file, topk_out_file_path,
                pre_embed_file,  pre_embed_dim, None, subword, beam_width))
        else:
            job = thread_pool.apply_async(evaluate, (
                metric, ref_tgt_file, ref_src_file, top1_out_file_path,
                pre_embed_file, pre_embed_dim, None, subword, beam_width))
        jobs.append(job)

    thread_pool.close()
    thread_pool.join()

    scores_suffix = '_Scores'
    scores_suffix_len = len(scores_suffix)
    scores_len = -1

    result_dict = {}
    logger.info('[Pretrained-Embed]: %s' % pre_embed_file)
    if pre_embed_file is not None:
        embed_scores = evaluate('embed', ref_tgt_file, ref_src_file, top1_out_file_path,
                                             pre_embed_file, dim=pre_embed_dim, word_option=subword)

        for key in embed_scores:
            assert key not in result_dict
            result_dict[key] = embed_scores[key]
            if key[-scores_suffix_len:] != scores_suffix:
                print('%s->%s' % (key, embed_scores[key]))
            else:
                if scores_len == -1:
                    scores_len = len(embed_scores[key])
                else:
                    assert scores_len == len(embed_scores[key]), 'embed/'+key

    for job, metric in zip(jobs, metrics):
        scores = job.get()
        if scores is None:
            logger.info("[Metric] Ignore %s" % metric)
            continue
        for key in scores:
            assert key not in result_dict
            score_res = scores[key]
            if score_res is None:
                continue
            result_dict[key] = score_res
            if key[-scores_suffix_len:] != scores_suffix:
                print('%s->%s' % (key, score_res))
            else:
                if scores_len == -1:
                    scores_len = len(score_res)
                else:
                    assert scores_len == len(score_res), metric + '/' + key

    bleu_metrics = ['BLEU-1', 'BLEU-2', 'BLEU-3', 'BLEU-4']
    bleu_scores = [result_dict[x] for x in bleu_metrics]
    src_bleu_scores = [result_dict['SRC_' + x] for x in bleu_metrics]
    geomean_blue = bleu_scores[0] * bleu_scores[1] * bleu_scores[2] * bleu_scores[3]
    geomean_self_blue = src_bleu_scores[0] * src_bleu_scores[1] * src_bleu_scores[2] * src_bleu_scores[3]
    geomean_blue = math.pow(geomean_blue, 1/4)
    geomean_self_blue = math.pow(geomean_self_blue, 1/4)
    geomean_rouge = result_dict['ROUGE_L']
    geomean_overlap = geomean_rouge * geomean_blue
    geomean_overlap = math.pow(geomean_overlap, 1/2)

    geomean_diversity = result_dict['DIST_1'] * result_dict['DIST_2'] * result_dict['ent4']
    geomean_diversity = math.pow(geomean_diversity, 1/3)

    geomean_non_embed_score = geomean_overlap * geomean_diversity
    geomean_non_embed_score = math.pow(geomean_non_embed_score, 1/2)
    result_dict['GM_Relevance_Overlap'] = geomean_overlap
    result_dict['GM_Diversity'] = geomean_diversity
    result_dict['GM_Total_NoEmbed'] = geomean_non_embed_score
    result_dict['GM_Novelty_BLEU'] = 100 - geomean_self_blue

    if pre_embed_file is not None:
        geomean_embed = result_dict['EmbedA'] * result_dict['EmbedG'] * result_dict['EmbedX']
        geomean_embed = math.pow(geomean_embed, 1/3)
        geomean_embed_novelty = result_dict['SRC_EmbedA'] * result_dict['SRC_EmbedG'] * result_dict['SRC_EmbedX']
        geomean_embed_novelty = 1.0 - math.pow(geomean_embed_novelty, 1 / 3)
        geomean_relevance = geomean_overlap * geomean_embed
        geomean_relevance = math.pow(geomean_relevance, 1/2)
        geomean_score = geomean_relevance * geomean_diversity
        geomean_score = math.pow(geomean_score, 1/2)
        geomean_novelty = math.pow(geomean_self_blue * geomean_embed_novelty , 1/2)
        result_dict['GM_Relevance'] = geomean_relevance
        result_dict['GM_Relevance_Embed'] = geomean_embed
        result_dict['GM_Novelty_Embed'] = geomean_embed_novelty
        result_dict['GM_Novelty'] = geomean_novelty
        result_dict['GM_Total'] = geomean_score
        result_dict['GM_Total_Novel'] = math.pow(geomean_relevance * geomean_diversity * geomean_novelty, 1/3)

    return result_dict

def main(args):
    score_manager = ScoreManager(args.res_path, '')

    ref_src_file = args.ref_src_file
    ref_tgt_file = args.ref_tgt_file
    train_src_file = args.train_src_file
    train_tgt_file = args.train_tgt_file
    top1_out_file_path = args.test_file
    topk_out_file_path = args.test_file_topk
    pre_embed_file = args.pre_embed_file
    pre_embed_dim = args.pre_embed_dim
    vocab_size = args.vocab_size
    subword = args.subword

    res_dict = std_eval(ref_src_file, ref_tgt_file,
             top1_out_file_path, topk_out_file_path,
             pre_embed_file, pre_embed_dim, subword, vocab_size, args.beam_width)
    group_name = args.group_name
    score_manager.update_group(group_name, res_dict)

if __name__ == '__main__':
    start_time = time.time()
    parser = argparse.ArgumentParser()
    parser.add_argument("--res_path", type=str, default="",
                        help="enable binary selector")
    parser.add_argument("--pre_embed_file", type=str, default="/home/sixing/dataset/embed/tencent.txt",
                        help="enable binary selector")
    parser.add_argument("--test_file", type=str, default="", help="enable binary selector")
    parser.add_argument("--test_file_topk", type=str, default="", help="enable binary selector")
    parser.add_argument("--ref_src_file", type=str,
                        default="",
                        help="training src file")
    parser.add_argument("--ref_tgt_file", type=str,
                        default="",
                        help="enable binary selector")
    parser.add_argument("--train_src_file", type=str,
                        default="",
                        help="enable binary selector")
    parser.add_argument("--train_tgt_file", type=str,
                        default="",
                        help="enable binary selector")
    parser.add_argument("--fact_vocab", type=str, default="", help="enable binary selector")
    parser.add_argument("--test_fact_path", type=str, default="", help="enable binary selector")
    parser.add_argument("--pre_embed_dim", type=int, default=200, help="enable binary selector")
    parser.add_argument("--vocab_size", type=int, default=50000, help="enable binary selector")
    parser.add_argument("--thread", type=int, default=16, help="thread")
    parser.add_argument("--beam_width", type=int, default=0, help="beam_width")
    parser.add_argument("--group_name", type=str, default=None)
    parser.add_argument("--subword", type=str, default=None)
    args = parser.parse_args()

    main(args)
    print('Evaluation Time Consuming : %d' % (time.time() - start_time))


"""
Evaluating a pretrained HRNet model on the complete validation set

@author: Angel Villar-Corrales
"""

import os
from tqdm import tqdm

import numpy as np
import torch
from torch.nn import DataParallel

import data
import data.data_processing as data_processing
import lib.arguments as arguments
import lib.loss as loss
import lib.inference as inference
import lib.model_setup as model_setup
import lib.utils as utils
import lib.metrics as metrics
import lib.pose_parsing as pose_parsing
import lib.visualizations as visualizations
from lib.logger import Logger, log_function, print_
from models.utils.hrnet_config import update_config
from lib.utils import for_all_methods
import CONSTANTS
from CONFIG import CONFIG

@for_all_methods(log_function)
class Evaluator:
    """
    Class for loading an evaluation set, loading a pretrained model
    and evaluating on the validation set

    Args:
    -----
    exp_path: string
        path to the experiment directory
    checkpoint: string
        name of the file containing the desired state dictionaries
    """

    def __init__(self, exp_path, checkpoint=None, dataset_name=None, params=None):
        """ Initializer of the evaluator object """

        # relevant paths
        self.exp_path = exp_path
        self.checkpoint = checkpoint
        self.params = params
        self.plots_path = os.path.join(self.exp_path, "plots")
        self.models_path = os.path.join(self.exp_path, "models")
        self.valid_plots_path = os.path.join(self.plots_path, "valid_plots")
        self.img_path = os.path.join(self.plots_path, f"{dataset_name}_imgs")
        utils.create_directory(self.img_path)

        self.scales = [0.5, 1.0, 1.5, 2.0]
        self.exp_data = utils.load_experiment_parameters(exp_path)
        if(dataset_name is not None):
            self.exp_data["dataset"]["dataset_name"] = dataset_name
        self.dataset_name = self.exp_data["dataset"]["dataset_name"]
        self.kpt_thr = self.exp_data["evaluation"]["in_vis_thr"]

        # macros
        pose_parsing.SKELETON = CONSTANTS.SKELETON_HRNET
        data_processing.TO_COCO_MAP = CONSTANTS.COCO_MAP_HRNET
        data_processing.SKIP_NECK = False
        _ = update_config()
        return

    def setup_model_dataset(self):
        """ Loading the dataset and seting up the pretraiend model """

        # updating alpha and styles if necesary
        if(self.params.alpha is not None):
            print_(f"'Alpha' parameter changing to {self.params.alpha}")
            self.exp_data["dataset"]["alpha"] = self.params.alpha
        if(self.params.styles is not None):
            print_(f"'Styles' parameter changing to {self.params.styles}")
            self.exp_data["dataset"]["styles"] = self.params.styles

        # loading dataset
        self.batch_size = self.exp_data["training"]["batch_size"]
        _, self.valid_loader = data.load_dataset(
                exp_data=self.exp_data,
                train=False,
                validation=True,
                shuffle_train=True,
                shuffle_valid=False
            )
        self.image_size = self.exp_data["dataset"]["image_size"]

        # loading pretrained model
        torch.backends.cudnn.fastest = True
        self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

        # setting up model
        model = model_setup.load_model(self.exp_data, checkpoint=self.checkpoint)
        self.model = DataParallel(model)
        if(self.checkpoint is not None):
            print_(f"Loading checkpoint {self.checkpoint}")
            checkpoint_path = os.path.join(self.exp_path, "models", self.checkpoint)
            self.model = model_setup.load_checkpoint(checkpoint_path, model=self.model,
                                                     only_model=True)
        self.model = self.model.to(self.device)
        self.model.eval()
        self.model_name = self.exp_data["model"]["model_name"]

        # initalizing loss
        self.loss_function = loss.PersonMSELoss()
        return

    @torch.no_grad()
    def evaluate_model(self):
        """ Evaluating the pretrained model on the COCO validation set """
        labels_file = self.valid_loader.dataset.annotations_file
        preds_file = os.path.join(self.exp_path, CONFIG["paths"]["submission"])

        loss_values, accuracies = [], []
        all_boxes, all_preds, image_ids = [], [], []
        utils.reset_predictions_file(self.exp_path)
        self.total_imgs = 0
        for i, (imgs, target, target_weight, metadata) in enumerate(tqdm(self.valid_loader)):

            # setting data to CUDA
            imgs, target = imgs.float(), target.float()
            imgs, target = imgs.to(self.device), target.to(self.device)
            target_weight = target_weight.float().to(self.device)

            # forward pass (normal and flipped), and loss computation
            output = inference.forward_pass(
                    model=self.model,
                    img=imgs,
                    model_name=self.model_name,
                    device=self.device,
                    flip=True
                )
            cur_loss = self.loss_function(output, target, target_weight).item()
            loss_values.append(cur_loss)

            _, avg_acc, cnt, pred = metrics.accuracy(output.cpu().numpy(), target.cpu().numpy())
            accuracies.append(avg_acc)

            # extracting keypoints from network outputs
            centers = metadata["center"].numpy()
            scales = metadata["scale"].numpy()
            score = metadata["score"].numpy()

            output = output.clone().detach()
            keypoints, max_vals, coords = pose_parsing.get_final_preds_hrnet(
                    heatmaps=output.cpu().numpy(),
                    center=centers,
                    scale=scales
                )

            # saving image results if save parameter is activated
            if(self.params.save):
                poses, kpts = pose_parsing.create_pose_from_outputs(
                        dets=output,
                        keypoint_thr=self.kpt_thr
                    )
                for n in range(len(poses)):
                    savepath = os.path.join(
                            self.img_path,
                            f"img_{self.total_imgs}_{metadata['image'][n].split('/')[-1]}"
                        )
                    self.total_imgs = self.total_imgs + 1
                    visualizations.draw_pose(img=imgs[n, :].cpu().numpy(), poses=[poses[n]],
                                             all_keypoints=kpts, preprocess=True,
                                             savepath=savepath, axis_off=True)
                if(self.dataset_name != "arch_data" and i * self.batch_size > 180):
                    break

            # updating submission data
            n_imgs = len(metadata["image"])
            cur_preds = np.zeros((n_imgs, 17, 3), dtype=np.float32)
            cur_boxes = np.zeros((n_imgs, 6))
            cur_preds[:, :, :2] = keypoints[:, :, :2]
            cur_preds[:, :, 2:3] = max_vals
            cur_boxes[:, 0:2] = centers[:, 0:2]
            cur_boxes[:, 2:4] = scales[:, 0:2]
            cur_boxes[:, 4] = np.prod(scales*200, 1)
            cur_boxes[:, 5] = score
            all_preds.append(cur_preds)
            all_boxes.append(cur_boxes)
            # the image id is required by cocoapi
            image_ids += metadata["image_id"].tolist()

            # displaying average loss and precision/recall figures every 1000 images
            if(i == 0):
                continue
            if(i % (2000//self.batch_size) == 0 or i == len(self.valid_loader)-1):
                avg_loss = np.mean(loss_values)
                print_(f"Mean Loss: {avg_loss}")
                print_(f"Accuracy: {np.mean(accuracies)}")
                utils.reset_predictions_file(self.exp_path)
                metrics.generate_submission_hrnet(all_preds, all_boxes, image_ids, preds_file)
                _ = metrics.compute_precision(labels_file=labels_file, preds_file=preds_file)

        # computing precision results on the validation set
        avg_loss = np.mean(loss_values)
        print_(f"Mean Loss: {avg_loss}")
        print_(f"Accuracy: {np.mean(accuracies)}")
        stats = metrics.compute_precision(labels_file=labels_file, preds_file=preds_file)

        self.valid_stats = stats
        utils.save_evaluation_stats(
                stats=self.valid_stats,
                exp_path=self.exp_path,
                detector=False,
                checkpoint=self.checkpoint,
                dataset_name=self.dataset_name,
                alpha=self.exp_data["dataset"]["alpha"],
                styles=self.exp_data["dataset"]["styles"]
            )
        print_(f"Valid Stats: {self.valid_stats}")
        return

if __name__ == "__main__":

    os.system("clear")
    exp_path, checkpoint, dataset, params = arguments.get_directory_argument(
            get_checkpoint=True,
            get_dataset=True
        )

    # initializing logger and logging the beggining of the experiment
    logger = Logger(exp_path)
    message = "Initializing model evaluation."
    logger.log_info(message=message, message_type="new_exp")
    logger.log_info(message=f"  Checkpoint: {checkpoint}", message_type="params")
    logger.log_info(message=f"  Dataset: {dataset}", message_type="params")
    for param, val in vars(params).items():
        logger.log_info(message=f"  {param}: {val}", message_type="params")

    trainer = Evaluator(
            exp_path=exp_path,
            checkpoint=checkpoint,
            dataset_name=dataset,
            params=params
        )
    trainer.setup_model_dataset()
    trainer.evaluate_model()
    logger.log_info(message="Evaluation finished successfully.")

#


"""
    Game of Life: Object plain python implementation
    Author: Andrea Guzzo (JeyDi)
"""
import time
import typer
import logging

from config import configure_logging, ROWS, COLUMNS, MAX_PROB

from src.board import GameBoard
from src.rules import game_status

def main(
    user: int = typer.Option(1, min=0, max=1),
    rows: int = typer.Option(40, min=10),
    columns: int = typer.Option(40, min=10),
    max_prob: int = typer.Option(2, min=2, max=9),
    max_tick: int = typer.Option(60, min=-1),
    sleep: int = typer.Option(1, min=1),
    verbosity: str = typer.Option("info"),
):

    # Configure the logging
    configure_logging(verbosity, "./logs")

    # Use typer
    if user == "1":
        # Ask for the user value input
        rows = int(typer.prompt("Insert the number of rows"))
        columns = int(typer.prompt("Insert the number of columns"))
        max_prob = int(
            typer.prompt(
                "Insert the probability of spawning a new living cell"
            )
        )
        max_tick = int(
            typer.prompt(
                "Insert the number of iterations you want to observe (-1 for endless)"
            )
        )
        launch = typer.confirm("Do you want to launch the simulation?")
        if not launch:
            message = typer.style("Ok! Bye...", fg=typer.colors.RED, bold=True)
            typer.echo(message)
            raise typer.Abort()
        message = typer.style("Launching...", fg=typer.colors.GREEN, bold=True)
        typer.echo(message)

    # Define the simulation default parameters
    if rows == 0:
        rows = ROWS
    if columns == 0:
        columns = COLUMNS
    if max_prob == 0:
        max_prob = MAX_PROB

    tick = 0
    logging.info("Launching the game")

    logging.debug(f"Rows: {rows}")
    logging.debug(f"Columns: {columns}")
    logging.debug(f"Max_prob: {max_prob}")
    logging.debug(f"Max Ticks: {max_tick}")
    logging.debug(f"Verbosity: {verbosity}")
    logging.debug(f"Max Ticks: {sleep}")
    logging.debug(f"Alive probability: {1/(max_prob+1)}")

    # create a board:
    game_board = GameBoard(rows, columns, max_prob)

    # run the first iteration of the board:
    game_board.print_board(tick)

    # Update the game status for every tick
    while tick <= max_tick:
        logging.debug(f"Tick: {tick}")
        game_status(game_board, tick)
        time.sleep(sleep)
        tick += 1
        game_board.print_board(tick)

if __name__ == "__main__":
    typer.run(main)


import dash
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_pivottable

from data import data

def Header(name, app):
    img_style = {"float": "right", "height": 40, "margin-right": 10}
    dash_logo = html.Img(src=app.get_asset_url("dash.png"), style=img_style)
    ghub_logo = html.Img(src=app.get_asset_url("github.png"), style=img_style)

    return html.Div(
        [
            html.H1(name, style={"margin": 10, "display": "inline"}),
            html.A(dash_logo, href="https://plotly.com/dash/"),
            html.A(ghub_logo, href="https://github.com/plotly/dash-pivottable"),
            html.A(
                html.Button(
                    "Enterprise Demo",
                    style={
                        "float": "right",
                        "margin-right": "10px",
                        "margin-top": "5px",
                        "padding": "5px 10px",
                        "font-size": "15px",
                    },
                ),
                href="https://plotly.com/get-demo/",
            ),
            html.Hr(),
        ]
    )

app = dash.Dash(__name__)
app.title = "Dash Pivottable"
server = app.server

app.layout = html.Div(
    [
        Header("Dash Pivottable", app),
        dash_pivottable.PivotTable(
            id="table",
            data=data,
            cols=["Day of Week"],
            colOrder="key_a_to_z",
            rows=["Party Size"],
            rowOrder="key_a_to_z",
            rendererName="Grouped Column Chart",
            aggregatorName="Average",
            vals=["Total Bill"],
            valueFilter={"Day of Week": {"Thursday": False}},
        ),
        html.Div(id="output"),
    ]
)

@app.callback(
    Output("output", "children"),
    [
        Input("table", "cols"),
        Input("table", "rows"),
        Input("table", "rowOrder"),
        Input("table", "colOrder"),
        Input("table", "aggregatorName"),
        Input("table", "rendererName"),
    ],
)
def display_props(cols, rows, row_order, col_order, aggregator, renderer):
    return [
        html.P(str(cols), id="columns"),
        html.P(str(rows), id="rows"),
        html.P(str(row_order), id="row_order"),
        html.P(str(col_order), id="col_order"),
        html.P(str(aggregator), id="aggregator"),
        html.P(str(renderer), id="renderer"),
    ]

if __name__ == "__main__":
    app.run_server(debug=True)


from keithley import *

def runProgram():
    keithley = Keythley6221()
    keithley.connect()
    keithley.getStatus()
    keithley.reset()
    keithley.pulseSweep()
    keithley.configureSweep()
    keithley.cleanBuffer()
    keithley.setBufSize()
    keithley.initialise()
    keithley.run()
    time.sleep(keithley.calcDataDelay() + 1)
    keithley.complete()
    keithley.dataProcessing()
    draw(keithley.U, keithley.I)

runProgram()
showAllGraphs()


import time
import requests
from bs4 import BeautifulSoup
from tqdm import tqdm
import json

data = list()

def crawling_bot():
    for hd_cate in ['news', 'sports', 'life', 'money', 'tech', 'travel', 'opinion']:
        url = f'https://www.usatoday.com/{hd_cate}'
        res = requests.get(url)
        soup = BeautifulSoup(
            res.text,
            'html.parser'
        )
        try:
            for td in soup.find('main', attrs={"class": "gnt_cw"}).find_all('a'):
                try:
                    news_url = td['href']
                    news_split = news_url.split('/')
                    if news_split[1] == 'story':
                        news_res = requests.get('https://www.usatoday.com' + news_url)
                        news_soup = BeautifulSoup(news_res.text, 'html.parser')
                        news = news_soup.find('article', attrs={'class': 'gnt_pr'})
                        head = news.find('h1').string
                        body = ''
                        for bd in news.find_all('p', attrs={'class': 'gnt_ar_b_p'}):
                            a = bd.string
                            if a is not None:
                                body += a
                        cate = ",".join(news_split[2:-6])
                        date = "-".join(news_split[-6:-3])
                        data.append(
                            {'platform': 'usatoday', 'category': cate, 'headline': head, 'content': body, 'date': date})
                        time.sleep(.5)
                except:
                    pass
        except:
            pass

    return data

if __name__ == '__main__':
    data = crawling_bot()
    print(len(data))


num = int(input("Number of items: "))
total = 0

for n in range(num):
    items = float(input("price of items : "))
    total += items
    if total >=100:
        disc=total*0.1
    else:
        disc=0
sum=total-disc

print(f"Total price for {num} items is ${sum:.2f} ")


from django.db import models
from users.models import CustomUser

class Challenge(models.Model):
    """
    A sportive challenge
    """
    userPk = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    createTime = models.DateTimeField(auto_now_add=True) #save the create date time
    doneTime = models.DateTimeField() #when the challenged has been done
    custom = models.BooleanField() # if it was a custom one
    duration = models.DurationField() # time duration of the effort
    difficulty = models.IntegerField() # difficulty level
    length = models.FloatField() # in KM, length or the run
    effortType = models.IntegerField() #type of effort: constant run, fract...
    completion = models.FloatField() # percentage of completion

    def __str__(self):
        return str((self.userPk, self.duration, self.difficulty, self.length, self.effortType, self.completion))


#!/usr/bin/python3
import os
from shutil import copyfile
from multiprocessing import Pool
from multiprocessing import cpu_count

def Extract(xmlPath, outputPath):
	ExtractFile(xmlPath, outputPath, 1, 0)

def ExtractScene(xmlPath, outputPath):
	ExtractFile(xmlPath, outputPath, 1, 1)

def ExtractFile(xmlPath, outputPath, genSrcFile, incFilePrefix):
	execStr = "tools/ZAPD/ZAPD.out e -eh -i %s -b baserom/ -o %s -gsf %i -ifp %i -sm tools/ZAPD/SymbolMap_OoTMqDbg.txt" % (xmlPath, outputPath, genSrcFile, incFilePrefix)

	print(execStr)
	os.system(execStr)

def ExtractFunc(fullPath):
	outPath = ("assets/" + fullPath.split("assets/xml/")[1]).split(".xml")[0]

	if (fullPath.startswith("assets/xml/scenes/")):
		ExtractScene(fullPath, outPath)
	else:
		Extract(fullPath, outPath)

def main():
    xmlFiles = []

    for currentPath, folders, files in os.walk("assets"):
            for file in files:
                    fullPath = os.path.join(currentPath, file)
                    if file.endswith(".xml") and currentPath.startswith("assets/xml/"):
                            outPath = ("assets/" + fullPath.split("assets/xml/")[1]).split(".xml")[0]
                            xmlFiles.append(fullPath)

    numCores = cpu_count()
    print("Extracting assets with " + str(numCores) + " CPU cores.")
    p = Pool(numCores)
    p.map(ExtractFunc, xmlFiles)

    #os.system("make resources")

if __name__ == "__main__":
    main()


#!/usr/bin/python

import RPi.GPIO as GPIO
import time
import sys

direction = sys.argv[1]

GPIO.setmode(GPIO.BOARD)
hor = [7, 11, 13, 15]
vert = [12, 16, 18, 22]

for pin in hor:
    GPIO.setup(pin, GPIO.OUT)
    GPIO.output(pin, 0)

for pin in vert:
    GPIO.setup(pin, GPIO.OUT)
    GPIO.output(pin, 0)

fore = [
    [1, 0, 0, 1],
    [0, 0, 0, 1],
    [0, 0, 1, 1],
    [0, 0, 1, 0],
    [0, 1, 1, 0],
    [0, 1, 0, 0],
    [1, 1, 0, 0],
    [1, 0, 0, 0],
]

aft = [
    [1, 0, 0, 0],
    [1, 1, 0, 0],
    [0, 1, 0, 0],
    [0, 1, 1, 0],
    [0, 0, 1, 0],
    [0, 0, 1, 1],
    [0, 0, 0, 1],
    [1, 0, 0, 1]
]

def turnOne():
    for i in range(30):
        for halfstep in range(8):
            for pin in range(4):
                GPIO.output(hor[pin], fore[halfstep][pin])
            time.sleep(0.001)

def turnTwo():
    for i in range(30):
        for halfstep in range(8):
            for pin in range(4):
                GPIO.output(hor[pin], aft[halfstep][pin])
            time.sleep(0.001)

def turnThree():
    for i in range(20):
        for halfstep in range(8):
            for pin in range(4):
                GPIO.output(vert[pin], fore[halfstep][pin])
            time.sleep(0.001)

def turnFour():
    for i in range(20):
        for halfstep in range(8):
            for pin in range(4):
                GPIO.output(vert[pin], aft[halfstep][pin])
            time.sleep(0.001)

if direction == 'LEFT':
    turnOne()

if direction == 'RIGHT':
    turnTwo()

if direction == 'UP':
    turnThree()

if direction == 'DOWN':
    turnFour()

GPIO.cleanup()


import requests
import json

# set the url
url = "https://api.deversifi.dev/v1/trading/w/preRegister"

"""
set payload

starkKey
    hex-string (wihtout leading 0x), the x-value of the
    starkPublicKey

ethAddress
    hex-string, Your Ethereum Address.
    Be sure that You have access to its private key,
    You will need to sign data with it for other
    requests to this api
"""
payload = {
    "starkKey": "abcdef",
    "ethAddress": "0xabcDEF"
}

# standard headers
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json"
}

# execute the request and load into dictionary
response = json.loads(requests.request(
    "POST", url, headers=headers, json=payload).text)

# print the response from dictionary
print(json.dumps(response, indent=2))


# Kyle Ryan
# CISC 5825 Computer Algorithms
# Professor Josephine Altzman

# Recursive Fibonacci Sequence
def recursiveFib(n):
    # Filtering Invalid Inputs
    if type(n) != int or n < 0:
        return("Sorry, Not a Valid Input!")

    if n == 0:
        return 0
    if n == 1:
        return 1
    return recursiveFib(n - 1) + recursiveFib(n - 2)

#Iterative Fibonacci Sequence
def iterativeFib(n):
    # Filtering Invalid Inputs
    if type(n) != int or n < 0:
        return("Sorry, Not a Valid Input!")

    ultimate = 0
    current = 1
    i = 1
    while i < n:
        penultimate = ultimate
        ultimate = current
        current = penultimate + ultimate
        i += 1
    return current

# Closed Form Fibonacci Sequence
# Solution Based on: http://mathonline.wikidot.com/a-closed-form-of-the-fibonacci-sequence
def closedFormFib(n):
    # n Exists in the Series Provided in Theorum I
    try:
        if n < 0:
            return("Sorry, the Number is Not in the Series!")
        closedFormEq = (1/(5 ** 0.5)) * ( (((1+(5 ** 0.5))/2)**n) - (((1-(5 ** 0.5))/2)**n) )
        return int(closedFormEq)
    except:
        return("Sorry, Not a Valid Input!")

# Returns the nth Fibonacci Number
print(recursiveFib(21))
print(iterativeFib(21))
print(closedFormFib(21))

# Test Cases
# Invalid Inputs
'''
print(recursiveFib(-1))
print(recursiveFib(5.5))
print(recursiveFib('5'))

print(iterativeFib(-1))
print(iterativeFib(5.5))
print(iterativeFib('5'))

print(closedFormFib(-1))
print(closedFormFib(5.5))
print(closedFormFib('5'))
'''


class Solution(object):
    def maxProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums)==1:
            return nums[0]
        tmpMax=0
        tmpMin=0
        Max=0
        for x in nums:
            if x > 0 :
                tmpMax,tmpMin=max(x,x*tmpMax),x*tmpMin
            elif x < 0 :
                tmpMax,tmpMin=x*tmpMin,min(x,x*tmpMax)
            else:
                tmpMax,tmpMin=0,0
            Max = max(Max,tmpMax)
        return Max


# -*- coding: utf-8 -*-
"""
Created on Sun Feb 13 19:07:03 2022

@author: Deepjyoti
"""
#not proper coz extra memory# given that m+n = length of the nums1
def merge(nums1, m: int, nums2, n: int) -> None:
    nums1 = nums1[:m]+nums2[:n]
    print(sorted(nums1))
# %%
def merge1(nums1, m: int, nums2, n: int) -> None:
    last = m+n -1 #the last index #m and n here are pointers for us
    while m>0 and n>0: #run loop with condition of m and n
        if nums1[m-1] > nums2[n-1]:#if the last proper value of nums is less than last value in nums2
            nums1[last] = nums1[m-1]#replace the last index of nums1 with last value of nums1
            m -= 1 #decrement m, its for loop
        else:
            nums1[last] = nums2[n-1] # the inverse case
            n -= 1 #moving nums2 array 1 to left, ie moving to next value
        last -= 1 #moving the value of array by 1 to the left
    while n > 0: #if the last value of nums2 > last value of nums1, n remains greater than 0
        nums1[last] = nums2[n-1] #switch last value of nums2 with last value of nums1
        n, last = n-1, last-1 #decrementing the pointer so that they are zero
            #dont forget pointers
    print(nums1)
nums1 = [2,4,1,0,0,0]
nums2 = [1,5,6]
m=3
n=3
# merge(nums1, m , nums2, n)
merge1(nums1, m , nums2, n)


"""Calculate vars that are not in models/observations output files.

Author: Arthur Dandoy
"""

# Standard library
import sys

# Third-party
import numpy as np
import pandas as pd
#from ipdb import set_trace

# First-party
from plot_profile.plot_arome.get_arome import calc_arome_height_agl
from plot_profile.plot_arome.get_arome import coord_2_arome_pts
from plot_profile.utils.variables import vdf

def calculate_grad(var_bot, var_top, alt_bot, alt_top, verbose=False):
    """Calculate vertical gradient.

    Args:
        var_bot, var top (pd series):   bot and top variables time series
        alt_bot, alt_top (floats):      altitudes of bot and top (in meters)

    Returns:
        _pandas series : vertical gradient between level top and bot (in var_unit/m)

    """
    if verbose:
        print("Calculating vertical gradient.")

    grad = (var_top - var_bot) / (alt_top - alt_bot)

    return grad

def calculate_pot_temp(temp, press, temperature_metric="celsius", verbose=False):
    """Calculate potential temperature from temperature.

    Args:
        press (pd series):   air pressure in hPa
        temp (pd series):    air temperature in °C
        temperature_metric (str, optional): Input temperature unit. Defaults to "celsius".

    Returns:
        pandas series: potential temperature timeseries (in K)

    """

    #defining parameters
    press_r = 1000.0                  #reference pressure (hPa)
    Rd = 287.0                        #specific gas constant for dry air (J/kg*K)
    cp = 1004.0                       #speific heat of dry air at constant pressure (J/kg*K)

    #convert from °C to K
    t_kelvin = np.zeros(len(temp)) ; t_kelvin = temp + 273

    if verbose:
        print("Calculating potential Temperature.")

    #compute potential temperature
    pot_temp = t_kelvin*(press_r/press)**(Rd/cp)

    return pot_temp

def calculate_tdew_from_rh(rh, T, temperature_metric="celsius", verbose=False):
    """Calculate dew point temperature from relative humidity and temperature.

    Args:
        rh (pd series):    air relative humidity in %
        T (pd series):     air temperature in °C
        temperature_metric (str, optional): Input temperature unit. Defaults to "celsius".

    Returns:
        pandas series: dew point temperature timeseries (in °C or K)

    """
    if verbose:
        print(
            "Calculating dew point temperature (dewp_temp) from relative humidity and temp."
        )

    if temperature_metric != "celsius":
        if verbose:
            print("Assuming input temperature unit is Kelvin for rh calculation.")
        T = T - 273  # K to °C

    # inspired from humidity.to.dewpoint in:
    # https://github.com/geanders/weathermetrics/blob/master/R/moisture_conversions.R
    Tdew = (rh / 100) ** (1 / 8) * (112 + (0.9 * T)) - 112 + (0.1 * T)  # in °C

    if temperature_metric != "celsius":
        Tdew = Tdew + 273  # °C to K

    return Tdew

def calculate_rh_from_qv(T, qv, Press=1013.5, verbose=False):
    """Convert specific humidity into relative humidity.

    Args:
        Press (pd series):   air pressure in hPa
        T (pd series):       air temperature in °C
        qv (pd series):      specific humidity in kg/kg

    Returns:
        pandas series: relative humidity series in %

    """
    if verbose:
        print(
            "Calculating relative humidity (rh) from specific humidity, press and temp."
        )

    # inspired from "qair2rh" function in:
    # https://github.com/PecanProject/pecan/blob/master/modules/data.atmosphere/R/metutils.R
    es = 6.112 * np.exp((17.67 * T) / (T + 243.5))
    e = qv * 1e-3 * Press / (0.378 * qv * 1e-3 + 0.622)

    rh = e / es

    # assign 0 and 1 to values outside [0, 1]
    rh = rh.clip(lower=0, upper=1)

    # convert to %
    rh = 100 * rh

    return rh

def calculate_qv_from_tdew(Press, Tdew, verbose=False):
    """Calculate specific humidity from pressure and dew point temperature.

    Args:
        Press (pd series):   air pressure in hPa
        Tdew (pd series):    dew point temperature in °C

    Returns:
        pandas series: specific humidity series in kg/kg

    """
    if verbose:
        print("Calculating specific humidity (qv) from press and dewp_temp.")

    # after eq. 4.24 in Practical Meteorology from Stull
    # P in hPa, Td in °C and qv in kg/kg
    e = 6.112 * np.exp((17.67 * Tdew) / (Tdew + 243.5))
    qv = (0.622 * e) / (Press - (0.378 * e))

    return qv

def calculate_qv_from_rh(Press, rh, T, verbose=False):
    """Calculate specific humidity from pressure, relative humidity and temperature.

    Args:
        Press (pd series):   air pressure series in hPa
        rh    (pd series):   air relative humidity in %
        T     (pd series):   air temperature in K

    Returns:
        pandas series: specific humidity series in kg/kg

    """
    if verbose:
        print("Calculating specific humidity (qv) from press and relative humidity.")

    Tdew = calculate_tdew_from_rh(rh, T)

    qv = calculate_qv_from_tdew(Press, Tdew)

    return qv

def calculate_wind_vel_from_uv(u, v, verbose=False):
    """Calculate wind velocity from U, V components.

    Args:
        u (pd series) u wind component in m/s
        v (pd series) v wind component in m/s

    Returns:
        pd series: wind velocity in m/s

    """
    if verbose:
        print(
            "Calculating wind velocity (wind_vel) from meridian and zonal wind velocity."
        )

    wind_vel = np.sqrt(u**2 + v**2)

    return wind_vel

def calculate_wind_dir_from_uv(u, v, modulo_180=False, unwrap=False, verbose=False):
    """Calculate wind direction from U, V components.

    Args:
        u (pd series):     u wind component in m/s
        v (pd series):     v wind component in m/s
        modulo_180 (bool): if True, retruned angle will be between [-180,180]

    Returns:
        pd series: wind direction in °

    """
    if verbose:
        print(
            "Calculating wind direction (wind_dir) from meridian and zonal wind velocity."
        )

    # convert to wind direction coordinate, different from trig unit circle coords
    # if the wind directin is 360 then returns zero (by %360)
    # inspired from wind_uv_to_dir function in:
    # https://github.com/blaylockbk/Ute_WRF/blob/master/functions/wind_calcs.py

    wind_dir = (270 - np.rad2deg(np.arctan2(v, u))) % 360

    # if requested convert from [0,360] to [-180,180]
    if modulo_180 == True:
        wind_dir = (wind_dir + 180) % 360 - 180
        # wind_dir  = np.rad2deg(np.arctan2(v, u))

    if unwrap == True:
        wind_dir = np.unwrap(p=wind_dir, period=360)

    return wind_dir

def calc_rho_arome(df, levels, verbose=False):
    """Calculate air density.

    Args:
            p (pd series):   air pressure (Pa)
            t (pd series):   air temperature (K)
            qc (pd series):  liquid water content (kg/kg)
            rh (pd series):  air relative humidity in %

    Returns:
        dict :      air density (kg/m**3)

    """
    if verbose:
        print("Calculating air density (RHO) from press, temp, qc and qv")

    rho = {}

    # constants
    r_d = 287.05  # gas constant for dry air
    r_v = 461.51  # gas constant for moist air
    rvd_m_o = r_v / r_d - 1

    for level in levels:
        p = df[f"press~{level}"]  # in Pa
        t = df[f"temp~{level}"]  # in K
        qc = df[f"qc~{level}"]  # in kg/kg

        qv = calculate_qv_from_rh(
            Press=p, rh=df[f"rel_hum~{level}"], T=t, verbose=verbose
        )

        # density, after calrho in meteo_utilities from COSMO-code
        # rho = press/(r_d * temp * ( 1 + rvd_m_o * qv - qc))
        rho[level] = p / (r_d * t * (1 + rvd_m_o * qv - qc))

    return rho

def integrate_over_z(df, param_name, levels, lat, lon, verbose=False):
    """Integrate variable over vertical coordinates.

    Args:
        p (pd series):        air pressure (Pa)
        t (pd series):        air temperature (K)
        rh (pd series):       air relative humidity in %
        df (DataFrame):       contains series and param to integrate
        param_name (str):     param to integrate name (ex: qc)
        levels (list of int): vertical levels

    Returns:
        pd Series: integrated parameter

    """
    if verbose:
        print(f"Integrating {param_name} over the vertical dimension.")

    values = pd.Series()

    # get air density dataFrame
    rho = calc_rho_arome(df, levels)
    rho = pd.DataFrame.from_dict(rho)

    # get height levels in arome
    dx, dy = coord_2_arome_pts(lat, lon)
    heights = calc_arome_height_agl(dx, dy)
    altitudes = heights[levels[0] - 1 : levels[-1]]

    # adding the 0 level (ground)
    altitudes = np.insert(altitudes.to_numpy(), 0, 0)

    # level top - level base
    level_thickness = altitudes[1:] - altitudes[:-1]

    # select only var to integrate
    crit = list(map((lambda x: f"{param_name}~" + str(x)), levels))
    df = df[crit]

    for i in df.index:
        values.loc[i] = np.sum(
            np.array(df.loc[[i]]) * np.array(rho.loc[[i]]) * level_thickness
        )

    if verbose:
        print(f"Succesfully integrated {param_name} over vertical dimension.")

    return values

##########################################################################################
##########################################################################################
##########################################################################################
def calculate_potT(temp, press, temperature_metric="kelvin", verbose=False):

    #defining parameters
    press_r = 1000                  #reference pressure (hPa)
    Rd = 287                        #specific gas constant for dry air (J/kg*K)
    cp = 1004                       #speific heat of dry air at constant pressure (J/kg*K)

    #convert from °C to K
    t_kelvin = np.zeros(len(temp)) ; t_kelvin = temp + 273

    if verbose:
        print("Calculating potential Temperature.")

    #compute potential temperature
    potT = t_kelvin*(press_r/press)**(Rd/cp)

    return potT

def calc_new_var_profiles(df, new_var, device="arome", verbose=False):
    """Calculate vert. profile of requested variable from model output variables.

    Args:
        df (DataFrame):            model output variables
        new_var (str):             name of the variable to be calculated
        device (str):              device name. Defaults to "arome".
        verbose (bool, optional):  print details. Defaults to False.

    Returns:
        DataFrame: same format as the input but with newly calculated variable

    """
    if verbose:
        print(f"{new_var} needs to be calculated.")

    # parameters to calculate (alphabetical order):

    ## Relative humidity
    if new_var == "rel_hum":
        values = calculate_rh_from_qv(
            T=df["temp"],
            qv=df["qv"],
            verbose=verbose,
        )
        # delete remaining columns
        del df["temp"], df["qv"]

    ## Specific humidity
    elif new_var == "qv":
        if device == "pe_arome":
            values = calculate_qv_from_rh(
                Press=df["press"],
                T=df["temp"],
                rh=df["rel_hum"],
                verbose=verbose,
            )
            # delete remaining columns
            del df["press"], df["temp"], df["rel_hum"]

        else:
            values = calculate_qv_from_tdew(
                Press=df["press"],
                Tdew=df["dewp_temp"],
                verbose=verbose,
            )
            # delete remaining columns
            del df["press"], df["dewp_temp"]

    ## Wind velocity
    elif new_var == "wind_vel":
        values = calculate_wind_vel_from_uv(u=df["u"], v=df["v"], verbose=verbose)
        # delete remaining columns
        del df["u"], df["v"]

    ## Wind direction
    elif new_var == "wind_dir":
        values = calculate_wind_dir_from_uv(
            u=df["u"], v=df["v"], unwrap=False, verbose=verbose
        )
        # delete remaining columns
        del df["u"], df["v"]

    ## potential temperature
    elif new_var == "pot_temp":
        values = calculate_pot_temp(
            temp=df["temp"], press=df["press"], altitude=df["altitude"],
             verbose=verbose
        )
        # delete remaining columns
        del df["temp"], df["press"]

    else:
        print(f"{new_var} not available for calculation yet.")

    # convert values to pandas series
    values = pd.Series(values, name=new_var)

    # do some unity conversions
    if device == "arome" or "pe_arome":
        values = (
            values * vdf.loc["mult_arome"][new_var] + vdf.loc["plus_arome"][new_var]
        )

    if device == "icon":
        values = values * vdf.loc["mult"][new_var] + vdf.loc["plus"][new_var]

    # add values column to the dataframe
    df = pd.concat([df, values], axis=1)

    return df

def calc_new_var_timeseries(df, new_var, levels, lat, lon, verbose=False):
    """Calculate timeseries of requested variable from model output variables.

    Args:
        df (DataFrame):            model output variables
        new_var (str):             name of the variable to be calculated
        levels (list of int):      level of the variables output
        verbose (bool, optional):  defaults to False.

    Returns:
        DataFrame: same format as the input but with newly calculated variable

    """
    if verbose:
        print(f"{new_var} needs to be calculated.")

    # determine variables columns sufix
    sufix_levels = []

    # if level is integer make it a one element list
    if isinstance(levels, int):
        levels = [
            levels,
        ]

    for level in levels:
        if level == 0:
            sufix_levels.append("")
        else:
            sufix_levels.append(f"~{level}")

    ## Gradient vertical de température
    if new_var == "grad_temp":
        values = calculate_grad(
            var_bot=df[f"temp{sufix_levels[0]}"],
            var_top=df[f"temp{sufix_levels[1]}"],
            alt_bot=levels[0],
            alt_top=levels[1],
            verbose=verbose,
        )

        # delete remaining columns
        del df[f"temp{sufix_levels[0]}"], df[f"temp{sufix_levels[1]}"]
        sufix_levels = [""]

    ## Relative humidity
    elif new_var == "rel_hum":
        values = calculate_rh_from_qv(
            T=df[f"temp{sufix_levels[0]}"],
            qv=df[f"qv{sufix_levels[0]}"],
            verbose=verbose,
        )

        # delete remaining columns
        del df[f"temp{sufix_levels[0]}"], df[f"qv{sufix_levels[0]}"]

    ## Specific humidity
    elif new_var in ["qv", "2m_qv"]:
        if new_var == "2m_qv":
            prefix = "2m_"
        else:
            prefix = ""

        values = calculate_qv_from_tdew(
            Press=df[f"press{sufix_levels[0]}"],
            Tdew=df[f"{prefix}dewp_temp{sufix_levels[0]}"],
            verbose=verbose,
        )

        # delete remaining columns
        del df[f"press{sufix_levels[0]}"], df[f"{prefix}dewp_temp{sufix_levels[0]}"]

    ## Integrated cloud/vapor water
    elif new_var == "tqc":
        values = integrate_over_z(df, "qc", levels, lat, lon, verbose)
        for level in levels:
            del (
                df[f"press~{level}"],
                df[f"rel_hum~{level}"],
                df[f"temp~{level}"],
                df[f"qc~{level}"],
            )

    ## Wind velocity
    elif new_var == "wind_vel":
        values = calculate_wind_vel_from_uv(
            u=df[f"u{sufix_levels[0]}"], v=df[f"v{sufix_levels[0]}"], verbose=verbose
        )

        # delete remaining columns
        del df[f"u{sufix_levels[0]}"], df[f"v{sufix_levels[0]}"]

    ## Wind direction
    elif new_var == "wind_dir":
        values = calculate_wind_dir_from_uv(
            u=df[f"u{sufix_levels[0]}"], v=df[f"v{sufix_levels[0]}"], verbose=verbose
        )

        # delete remaining columns
        del df[f"u{sufix_levels[0]}"], df[f"v{sufix_levels[0]}"]

     ## Wind velocity at 10m
    elif new_var == "wind_vel_10m":
        values = calculate_wind_vel_from_uv(
            u=df[f"u_10m{sufix_levels[0]}"], v=df[f"v_10m{sufix_levels[0]}"], verbose=verbose
        )

        # delete remaining columns
        del df[f"u_10m{sufix_levels[0]}"], df[f"v_10m{sufix_levels[0]}"]

    ## Wind direction at 10m
    elif new_var == "wind_dir_10m":
        values = calculate_wind_dir_from_uv(
            u=df[f"u_10m{sufix_levels[0]}"], v=df[f"v_10m{sufix_levels[0]}"], verbose=verbose
        )

        # delete remaining columns
        del df[f"u_10m{sufix_levels[0]}"], df[f"v_10m{sufix_levels[0]}"]

    ## potential temperature
    elif new_var == "pot_temp":
        values = calculate_pot_temp(
            temp=df[f"temp{sufix_levels[0]}"], press=df[f"press{sufix_levels[0]}"], verbose=verbose
        )

        # delete remaining columns
        del df[f"temp{sufix_levels[0]}"], df[f"press{sufix_levels[0]}"]

    else:
        print(f"--- ! Variable {new_var} calculation not available yet.")
        sys.exit(1)

    # convert values to pandas series
    values = pd.Series(values, name=f"{new_var}{sufix_levels[0]}")

    # TODO si jamais icon detecter et appliquer les convertisseurs d'icon
    # do some unity conversions
    values = values * vdf.loc["mult_arome"][new_var] + vdf.loc["plus_arome"][new_var]

    # add values column to the dataframe
    df = pd.concat([df, values], axis=1)

    return df


"""
6019. 替换数组中的非互质数
给你一个整数数组 nums 。请你对数组执行下述操作：
从 nums 中找出 任意 两个 相邻 的 非互质 数。
如果不存在这样的数，终止 这一过程。
否则，删除这两个数，并 替换 为它们的 最小公倍数（Least Common Multiple，LCM）。
只要还能找出两个相邻的非互质数就继续 重复 这一过程。
返回修改后得到的 最终 数组。可以证明的是，以 任意 顺序替换相邻的非互质数都可以得到相同的结果。
生成的测试用例可以保证最终数组中的值 小于或者等于 108 。
两个数字 x 和 y 满足 非互质数 的条件是：GCD(x, y) > 1 ，其中 GCD(x, y) 是 x 和 y 的 最大公约数 。
"""
import math
from typing import List

def replaceNonCoprimes(nums: List[int]) -> List[int]:
    stack = []
    for num in nums:
        stack.append(num)
        while len(stack) >= 2:
            gcd = math.gcd(stack[-1], stack[-2])
            if gcd != 1:
                number1 = stack.pop(-1)
                number2 = stack.pop(-1)
                stack.append(number1 * number2 // gcd)
            else:
                break
    return stack

replaceNonCoprimes(nums = [6,4,3,2,7,6,2])

6019. 替换数组中的非互质数.py


from fastapi import FastAPI, Query
from datetime import datetime
import redis.asyncio as redis
from typing import Annotated
from concat_timestamp import concat_timestamp
from history_dto import History
from message_dto import Message

redis_app = redis.Redis(host="red01", port=6379)

app = FastAPI()

@app.post("/api/sens-messages/")
async def messages(message: Message) -> Message:
    await redis_app.publish('messages', str(message.dict()))
    return message

@app.get("/api/control-history/")
async def control_history(q: Annotated[str,
                                       Query(min_length=40, max_length=40,
                                             pattern=r'^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})D'
                                                     r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})$')]) \
        -> list[History]:

    start, end = q.split("D")
    start = datetime.strptime(start, "%Y-%m-%dT%H:%M:%S")
    end = datetime.strptime(end, "%Y-%m-%dT%H:%M:%S")
    keys = await redis_app.keys("*")
    keys.sort()
    signals_history = []
    for elem in keys:
        try:
            if start.timestamp() <= float(elem.decode()) <= end.timestamp():
                signals_history.append({"timestamp": float(elem.decode()), "status": await redis_app.get(elem)})
            if float(elem.decode()) > end.timestamp():
                break
        except:
            pass
    return await concat_timestamp(signals_history)

@app.get("/")
async def index():
    return "Hello!"


class MyCalendarThree(object):

    def __init__(self):
        self.ss, self.es = [], []
        self.k = 0

    def book(self, start, end):
        """
        :type start: int
        :type end: int
        :rtype: int
        """
        from bisect import bisect_left as bl, bisect_right as br, insort_left as il
        from heapq import heappop, heappush
        i, j = bl(self.es, start), br(self.ss, end)
        il(self.ss, start, i, j)
        il(self.es, end, i, j)
        heap = []
        for pp in range(i, j + 1):
            while heap and heap[0] <= self.ss[pp]:
                heappop(heap)
            heappush(heap, self.es[pp])
            self.k = max(self.k, len(heap))
        return self.k

# Your MyCalendarThree object will be instantiated and called as such:
# obj = MyCalendarThree()
# param_1 = obj.book(start,end)


"""Train Noise Removal on coco."""

import utils as u

import numpy as np
import os

#  from joblib import parallel_backend, Parallel, delayed

from sgg_lab import datasets as ds
from sgg_lab.callbacks import ModelSaveBestAvgAcc, filter_val_f1score

def to_regression(dataset, resizer, input_shape, image_id):
    masks, cls = dataset.load_mask(image_id)
    cls = cls / float(dataset.num_classes)
    result = np.zeros(input_shape[:2])
    mask = np.full(input_shape[:2], True, dtype=np.bool)
    for i in range(0, masks.shape[2]):
        m = resizer(masks[:, :, i].astype('uint8'))
        m[m > 0] = 1
        result[m == 1] = cls[i]
        mask = np.logical_and(m, mask)
    return result

def imageid2categoricalpixel(dataset, input_shape):
    """Convert image_id to categorical pixel."""
    resizer = ds.resize(input_shape)

    def f(image_id):
        return to_regression(dataset, resizer, input_shape, image_id)
    return f

def prepare(dataset, epochs, batch_size, input_shape, output_shape):
    i2c = imageid2categoricalpixel(dataset, input_shape)
    stream = ds.epochs(dataset.image_ids, epochs)
    stream = ds.stream(
        lambda x: (dataset._img_filenames[x], i2c(x)),
        stream)

    def adapt_y(x, y):
        y = np.array(y).transpose((2, 0, 1))
        y = y.reshape(y.shape + (1,))  # .astype('int32')
        return np.array(x), [v for v in y]

    batch = ds.stream_batch(stream, size=batch_size, fun=adapt_y)

    return batch

def save_all(gen, base_path, directory):
    """Save all resized images."""
    dest = os.path.join(base_path, directory)
    if not os.path.exists(dest):
        os.makedirs(dest)
    print('process {0}'.format(dest))
    for names, imgs in gen:
        for i in range(0, len(names)):
            res = np.array([imgs[j][i] for j in range(0, len(imgs))])
            path = os.path.join(dest, names[i])
            np.savez_compressed(path, res)

coco_path = '/media/hachreak/Magrathea/datasets/coco/coco'
model_path = ''
epochs = 1
batch_size = 3
input_shape = (320, 320, 3)
output_shape = (10, 10)

dest_path = '/media/hachreak/Magrathea/datasets/coco/v14_resize_{0}x{1}' \
        .format(*input_shape[:2])

# validation dataset
dataset_val = u.get_dataset(coco_path, 'val')
gen_val = prepare(dataset_val, epochs, batch_size, input_shape, output_shape)

save_all(gen_val, dest_path, 'val_output')

#  fuu = next(gen_val)
#  import ipdb; ipdb.set_trace()

# train dataset
dataset_train = u.get_dataset(coco_path, 'train')
gen_train = prepare(
    dataset_train, epochs, batch_size, input_shape, output_shape)

callback = ModelSaveBestAvgAcc(
    filepath="model-{epoch:02d}-{avgacc:.2f}.hdf5",
    verbose=True, cond=filter_val_f1score
)

save_all(gen_train, dest_path, 'train_output')

print('fine')


import pytest
import ckan.plugins.toolkit as toolkit
from ckan.tests import factories

@pytest.mark.ckan_config('ckan.plugins', "spectrum scheming_datasets")
@pytest.mark.usefixtures('clean_db', 'with_plugins')
class TestSysadminsOnlyCanAccessAPI():

    api_endpoints_to_test = [
        ('user_show', 200),
        ('package_list', 200),
        ('package_search', 200),
        ('user_list', 200),
        ('dataset_duplicate', 409),
        ('user_create', 409)
    ]

    def test_unregistered_user_can_access_home(self, app):
        # Regression test: this feature was found to block access to homepage
        response = app.get('/')
        assert response.status_code == 200

    @pytest.mark.parametrize('action', api_endpoints_to_test)
    def test_api_endpoints_inaccessible_to_anonymous_users(self, app, action):
        response = app.get(
            toolkit.url_for('api.action', ver=3, logic_function=action)
        )
        assert response.status_code == 403
        assert response.json == {
            'success': False,
            'error': {
                '__type': 'Not Authorized',
                'message': "Must be a system administrator."
            }
        }

    @pytest.mark.parametrize('action', api_endpoints_to_test)
    def test_api_endpoints_inaccessible_to_regular_users(self, app, action):
        user = factories.UserWithToken()
        response = app.get(
            toolkit.url_for('api.action', ver=3, logic_function=action),
            headers={
                'Authorization': user['token']
            }
        )
        assert response.status_code == 403
        assert response.json == {
            'success': False,
            'error': {
                '__type': 'Not Authorized',
                'message': "Must be a system administrator."
            }
        }

    @pytest.mark.parametrize('action, response_code', api_endpoints_to_test)
    def test_api_endpoints_accessible_to_sysadmin_users(self, app, action, response_code):
        user = factories.UserWithToken(sysadmin=True)
        response = app.post(
            toolkit.url_for('api.action', ver=3, logic_function=action),
            headers={
                'Authorization': user['token']
            }
        )
        assert response.status_code == response_code

@pytest.mark.usefixtures('clean_db', 'with_plugins')
class TestSubstituteUser():

    def test_error_raised_for_non_sysadmin_user(self, app):
        user = factories.UserWithToken()
        response = app.get(
            toolkit.url_for('api.action', ver=3, logic_function='package_list'),
            headers={
                'Authorization': user['token'],
                'CKAN-Substitute-User': 'fjelltopp_editor'
            }
        )
        assert response.status_code == 403

    def test_error_raised_for_invalid_substitute_user(self, app):
        user = factories.UserWithToken(sysadmin=True)
        response = app.get(
            toolkit.url_for('api.action', ver=3, logic_function='package_list'),
            headers={
                'Authorization': user['token'],
                'CKAN-Substitute-User': 'non_existant_user'
            }
        )
        assert response.status_code == 400
        assert response.json == {
            "success": False,
            "error": {
                "__type": "Bad Request",
                "message": "CKAN-Substitute-User header does "
                           "not identify a valid CKAN user"
            }
        }

    @pytest.mark.parametrize("user_field", ["id", "name"])
    def test_valid_substitute_user_request(self, app, user_field):
        sysadmin_user = factories.UserWithToken(sysadmin=True)
        substitute_user = factories.User()
        dataset = factories.Dataset()
        dataset_create_url = toolkit.url_for(
            'api.action',
            ver=3,
            logic_function='package_create',
            id=dataset['id']
        )
        response = app.post(
            dataset_create_url,
            json={'name': 'test-dataset'},
            headers={
                'Authorization': sysadmin_user['token'],
                'CKAN-Substitute-User': substitute_user[user_field]
            }
        )
        assert response.status_code == 200
        assert response.json['result']['creator_user_id'] == substitute_user['id']


import logging
import socket
import subprocess
import sys
import time
from os import path

import monotonic
import serial
import ast

from . import gpio
from . import pins
from . import usbdrive
from . import utils
from .analogclient import AnalogClient
from .bbid import MAC_ID0
from .bbio_common import setup_io
from .bmsclient import BmsClient
from .config import TUNING_FILE
from .deepseaclient import DeepSeaClient
from .filewriter import FileWriter
from .groveledbar import GroveLedBar
from .woodwardcontrol import WoodwardControl

#################################################
# Conditional import for Python 2/3 compatibility
#################################################
if sys.version_info[0] == 2:
    import Queue as queue
else:
    import queue

# Master values dictionary
# Keys should be one of
# a) Modbus address
# b) analog pin in
# c) our assigned "one true name" for each BMS variable
# d) PWM pin out for Woodward signals
data_store = {pins.GEN_CUR: None}

def main(config, handlers, daemon=False, watchdog=False, time_from_deepsea=False):
    """
    Enter a main loop, polling values from sources enabled in config.

    :param config:
        The master configuration map, containing a list of enabled data
        sources, global configuration values, and configuration maps
        specific to each enabled thread.

    :param handlers:
        An iterable of log handlers, which will be added to each logger
        throughout the program.

    :param daemon:
        A Boolean of whether to run the program as a daemon or in the
        foreground.

    :param watchdog:
        A Boolean of whether to use the hardware watchdog timer on the
        BeagleBone Black.

    :param time_from_deepsea:
        A Boolean of whether to set the Linux system time from the
        DeepSea time.
    """

    global logger   # Make the logger reference available everywhere.
    logger = logging.getLogger(__name__)
    for h in handlers:
        logger.addHandler(h)
    logger.setLevel(logging.DEBUG)

    # Keep a list of all threads we have running
    threads = []
    clients = []

    # Keep an exit code variable so we can exit nicely
    exit_code = 0

    ############################################
    # Setup IO pins
    ############################################
    setup_io()
    time.sleep(1)

    ############################################
    # Async Data Sources
    ############################################
    try:
        deepsea = DeepSeaClient(config['deepsea'], handlers, data_store)
    except ValueError:
        exc_type, exc_value = sys.exc_info()[:2]
        logger.error("Error with DeepSeaClient config: %s: %s"
                     % (str(exc_type), str(exc_value)))
        exit("Could not open DeepSeaClient")
    except serial.SerialException as e:
        logger.error("SerialException({0}) opening BmsClient: {1}"
                     .format(e.errno, e.strerror))
        exit("Could not open DeepSeaClient")
    except socket.error:
        exc_type, exc_value = sys.exc_info()[:2]
        logger.error("Error opening BMSClient: %s: %s"
                     % (str(exc_type), str(exc_value)))
        exit("Could not open DeepSeaClient")
    else:
        clients.append(deepsea)
        threads.append(deepsea)

    analog = None
    try:
        analog = AnalogClient(config['analog'], handlers, data_store)
    except ValueError:
        exc_type, exc_value = sys.exc_info()[:2]
        logger.error("Configuration error from AnalogClient: %s: %s"
                     % (str(exc_type), str(exc_value)))
        exit("Could not open AnalogClient")
    except RuntimeError:
        exc_type, exc_value = sys.exc_info()[:2]
        logger.error(
            "Error opening the analog to digital converter: %s: %s"
            % (str(exc_type), str(exc_value)))
        exit("Could not open AnalogClient")
    else:
        clients.append(analog)
        threads.append(analog)

    bms_queue = queue.Queue()
    try:
        bms = BmsClient(config['bms'], handlers, bms_queue)
    except serial.SerialException as e:
        logger.error("SerialException({0}) opening BmsClient: {1}"
                     .format(e.errno, e.strerror))
        exit("Could not open BmsClient")
    except (OSError, IOError):
        exc_type, exc_value = sys.exc_info()[:2]
        logger.error("Error opening BMSClient: %s: %s"
                     % (str(exc_type), str(exc_value)))
        exit("Could not open BmsClient")
    except ValueError:
        logger.error("ValueError with BmsClient config")
        exit("Could not open BmsClient")
    else:
        # clients.append(bms)
        threads.append(bms)

    #######################################
    # Other Threads
    #######################################
    # Woodward thread
    woodward = None

    # Let's remember the last woodward configuration so we don't needlessly update.
    last_wc = config['woodward']

    try:
        woodward = WoodwardControl(
            config['woodward'], handlers
        )
    # ValueError can be from a missing value in the config map
    # or from an error in the parameters to PWM.start(...)
    except ValueError as e:
        logger.error("ValueError: %s"
                     % (e.args[0]))
        exit("WoodwardControl thread did not start")
    else:
        # clients.append(woodward)
        threads.append(woodward)

    # Open filewriter thread
    csv_header = build_csv_header(clients, logger)
    slow_log_queue = queue.Queue()
    try:
        filewriter = FileWriter(
            config['filewriter'], handlers, slow_log_queue, bms_queue, csv_header)
    except ValueError as e:
        logger.error("FileWriter did not start with message \"{0}\""
                     .format(str(e)))
    except (IOError, OSError) as e:
        logger.error("FileWriter did not start with message \"{0}\""
                     .format(str(e)))
    else:
        threads.append(filewriter)

    ######################################
    # LED Gauges
    ######################################
    fuel_gauge = GroveLedBar(pins.FUEL_DATA, pins.FUEL_CLK)
    battery_gauge = GroveLedBar(pins.BAT_GG_DATA, pins.BAT_GG_CLK)

    # Start all the threads
    for thread in threads:
        thread.start()

    # If we get cancelled during this stage, stop threads cleanly.
    try:
        # Don't wait for DeepSea connection
        blink_leds(fuel_gauge, battery_gauge)
        update_gauges(fuel_gauge, battery_gauge)
    except SystemExit:
        stop_threads(threads)
        exit(0)

    # Keeps track of the next scheduled time for each interval
    # Key = period of job
    # value = monotonic scheduled time
    next_run = {
        0.1: 0,
        0.5: 0,
        1.0: 0,
        5.0: 0,
        10.0: 0,
        60.0: 0,
        3600.0: 0,
    }

    going = True
    shutdown = False
    ejecting = False
    potential_new_measurement_list = False
    heartbeat = False

    while going:
        # noinspection PyBroadException
        try:
            now = monotonic.monotonic()
            now_time = time.time()

            ###########################
            # Every tenth of a second
            ###########################
            if now >= next_run[0.1]:

                # Removed fast_log_queue operations.  Deep Sea couldn't respond this quickly, and
                #    the fast logs were useless clutter.

                # Connect the analog current in to the woodward process
                if woodward and not woodward.cancelled:
                    try:
                        cur = data_store[pins.GEN_CUR]
                        if cur is not None:
                            woodward.process_variable = cur
                    except KeyError:
                        logger.critical('Generator current is not being measured.')
                        exit('Generator current is not being measured.')

                # Schedule next run
                next_run[0.1] = now + 0.1

            ###########################
            # Twice a second
            ###########################
            if now >= next_run[0.5]:
                # Connect the CMS PID enable virtual LED from the deepSea to the PID
                try:
                    # Virtual LED 1
                    # From DeepSea GenComm manual, 10.57
                    pid_enable = data_store[DeepSeaClient.VIRTUAL_LED_1]
                    if not woodward.in_auto and pid_enable:
                        woodward.integral_term = 0.0
                        woodward.set_auto(True)
                    elif not pid_enable:
                        woodward.set_auto(False)
                        woodward.output = 0.0
                        woodward.integral_term = 0.0
                except UnboundLocalError:
                    pass
                except KeyError:
                    logger.critical("Key does not exist for the PID enable flag")

                # Check the eject button to see whether it's held
                if gpio.read(pins.USB_SW) == gpio.LOW and not ejecting:
                    if usbdrive.mounted():
                        filewriter.eject_drive = True
                        ejecting = True

                # Toggle the spare LED like a heartbeat
                heartbeat = not heartbeat
                gpio.write(pins.SPARE_LED, heartbeat)

                if check_kill_switch():
                    logger.info("check_kill_switch() = True, opening contactor")
                    gpio.write(pins.CMS_FAULT, True)
                    going = False
                    shutdown = True

                # Schedule next run
                next_run[0.5] = now + 0.5

            ###########################
            # Once a second
            ###########################
            if now >= next_run[1.0]:
                # If not in daemon, print to screen
                if not daemon:
                    print_data(clients)

                ###############################
                # Get CSV data to the log file
                ###############################
                # If any of the clients say we should get a new log
                # file, get a new log file.
                new_log_file = False
                for client in clients:
                    new_log_file = new_log_file or client.new_log_file

                csv_parts = ["{:.1f}".format(now_time)]

                # Get the CSV line from each client, and reset
                # new_log_file flag, as we've gotten the message.
                for client in clients:
                    csv_parts.append(client.csv_line())
                    client.new_log_file = False

                # Send a None over the queue (signal to filewriter
                # to start a new file)
                if new_log_file:
                    try:
                        slow_log_queue.put(None)
                    except queue.Full:
                        exit("File writer queue full. Exiting.")

                # Put the csv data in the logfile
                if len(csv_parts) > 0 and slow_log_queue:
                    try:
                        slow_log_queue.put(','.join(csv_parts))
                    except queue.Full:
                        exit("File writer queue full. Exiting.")

                # Read in the config file to update the tuning coefficients
                try:
                    with open(TUNING_FILE) as f:
                        s = f.read()
                    wc = ast.literal_eval(s)
                except IOError:
                    pass
                else:
                    if wc != last_wc:
                        logger.info("Updating PID tuning with " + str(wc))
                        woodward.set_tunings(wc['Kp'], wc['Ki'], wc['Kd'])
                        woodward.setpoint = wc['setpoint']
                        last_wc = wc

                # Schedule next run
                next_run[1.0] = now + 1.0

            ###########################
            # Once every 5 seconds
            ###########################
            if now >= next_run[5.0]:
                update_gauges(fuel_gauge, battery_gauge)

                # Check for new USB drive
                plugged = usbdrive.plugged()
                if plugged:
                    mounted = usbdrive.mounted()
                    if mounted is None and not ejecting:
                        filewriter.mount_drive = plugged
                        potential_new_measurement_list = True

                    elif ejecting:
                        # if we're already ejecting, don't do anything
                        pass

                    # If the USB changes locations without realizing it
                    # (sometimes happens at engine startup), eject "mounted"
                    # drive (not actually working) and once we've un-
                    # mounted, we'll mount the new location.
                    elif mounted != plugged:
                        filewriter.eject_drive = True

                # If we're ejecting and the drive is gone, turn off light
                if ejecting and not plugged:
                    filewriter.safe_to_remove = False
                    ejecting = False

                # Schedule next run
                next_run[5.0] = now + 5.0

            ###########################
            # Once every 10 seconds
            ###########################
            if now >= next_run[10.0]:
                if watchdog:
                    update_watchdog()

                # Ensure analog and woodward control are running
                if analog.cancelled or woodward.cancelled:
                    logger.error("Missing analog or woodward")
                    going = False
                    exit_code = 1

                # Read in a "measurements.csv" file from the drive and apply
                # it to DeepSea.
                if potential_new_measurement_list:
                    drive = usbdrive.mount_point()
                    if drive:
                        potential_new_measurement_list = False
                        filename = path.join(drive, "measurements.csv")
                        if path.exists(filename):
                            logger.info("Reading new measurement list")
                            mlist = deepsea.read_measurement_description(filename)
                            if set(mlist) != set(deepsea.input_list):
                                deepsea.new_input_list = mlist
                                csv_header = build_csv_header(clients, logger)
                                filewriter.update_csv_header(csv_header)

                # Schedule next run
                next_run[10.0] = now + 10.0

            ###########################
            # Once every minute
            ###########################
            # if now >= next_run[60.0]:
            #
            #     # Schedule next run
            #     next_run[60.0] = now + 60.0

            ###########################
            # Once every hour
            ###########################
            if now >= next_run[3600.0]:
                if time_from_deepsea:
                    set_linux_time()

                # Schedule next run
                next_run[3600.0] = now + 3600.0

            time.sleep(0.01)

        except KeyboardInterrupt:
            logger.info("Dying due to KeyboardInterrupt.")
            going = False
            # Standard exit code when interrupted by Ctrl-C
            # http://tldp.org/LDP/abs/html/exitcodes.html
            exit_code = 130
            close_watchdog()
            stop_threads(threads)

        except SystemExit:
            exception_info = str(sys.exc_info())
            logger.info("Dying due to SystemExit: " + exception_info)
            going = False
            exit_code = 0
            close_watchdog()
            stop_threads(threads)

        except Exception as e:  # Log any other exceptions
            utils.log_exception(logger, e)

    logger.info("Exited while loop.")
    if shutdown:
        logger.info("Calling power_off().")
        power_off()
    logger.info("Calling exit(exit_code).")
    close_watchdog()
    exit(exit_code)

def build_csv_header(clients, logger):
    headers = []
    for c in clients:
        headers.append(c.csv_header())
    if len(headers) == 0:
        logger.error("CSV header returned by clients is blank")
    headers.append("output_woodward")
    csv_header = "linuxtime," + ','.join(headers) + ',id={:x}'.format(MAC_ID0)
    return csv_header

def stop_threads(threads):
    """
    Stop each thread in the list, preparatory to shutdown

    :param threads: A list of AsyncIOThread objects to shutdown
    :return: :const:`None`
    """
    for thread in threads:
        thread.cancel()
        thread.join()

def print_data(clients):
    """
    Print the data for all the threads which get data.

    :param clients: A list of clients with a print_data function
    :return: :const:`None`
    """
    for client in clients:
        client.print_data()
    print('-' * 80)

def update_watchdog():
    """
    Write to the watchdog file, keeping the system from being
    restarted. If we don't write to the watchdog for 60 seconds, the
    system will be restarted.

    :return: :const:`None`
    """
    with open("/dev/watchdog", 'w') as f:
        f.write('\n')

def close_watchdog():
    """
    When we exit, we should shutdown the watchdog daemon politely so as
    not to surprise the user with a reboot.
    """
    logger.info('Closing watchdog...')
    f = open("/dev/watchdog", 'w')
    f.write('V')
    f.close()

def update_gauges(fuel_gauge, battery_gauge):
    """
    Update both the fuel and the battery gauge using data from the
    central data store.

    :param fuel_gauge: GroveLedBar object, the fuel gauge
    :param battery_gauge: GroveLedBar object, the battery gauge
    :return: :const:`None`
    """
    # Update interface gauges
    # See DeepSea_Modbus_manualGenComm.docx, 10.6
    try:
        fuel = data_store[DeepSeaClient.FUEL_LEVEL]
        assert (fuel is not None)
    except KeyError:
        fuel_gauge.set_bar_level(1)
    except AssertionError:
        fuel_gauge.set_bar_level(1)
    else:
        #fuel /= 10  # Scale to 10
        scaled_fuel = (fuel + 5)//10
        fuel_gauge.set_bar_level(scaled_fuel)

    # See DeepSea_Modbus_manualGenComm.docx, 10.6 (#199)
    try:
        battery_charge = data_store[DeepSeaClient.BATTERY_LEVEL]
        # TODO maybe replace this with our analog value
        assert (battery_charge is not None)
    except KeyError:
        battery_gauge.set_bar_level(1)
    except AssertionError:
        battery_gauge.set_bar_level(1)
    else:
        # Scale the range from 269 to 304 to 0-10
        scaled_battery_charge = (battery_charge - 266)//3
        battery_gauge.set_bar_level(scaled_battery_charge)

def check_kill_switch():
    """
    Check whether we are to poweroff now.

    :return: Boolean, whether to poweroff.
    """
    try:
        val = data_store[DeepSeaClient.VIRTUAL_LED_2]
    except KeyError:
        val = None

    if val:
        return True
    else:
        return False

def set_linux_time():
    """
    Set the Linux time from the DeepSea time.

    :return: :const:`None`
    """
    t = data_store[DeepSeaClient.TIME]
    if t is not None:
        s = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(t))
        subprocess.call(['timedatectl', 'set-time', s])

def power_off():
    """
    Shut down the system immediately.

    :return: :const:`None`
    """
    #subprocess.call(["poweroff"])
    logger.info(str(subprocess.check_output("poweroff", stderr=subprocess.STDOUT)))

def blink_leds(fuel_gauge, batt_gauge):
    """
    Do a blinking LED show at startup

    :return: :const:`None`
    """
    for i in range(11):
        fuel_gauge.set_bar_level(i)
        batt_gauge.set_bar_level(i)
        gpio.write(pins.USB_LED, i % 2)
        gpio.write(pins.SPARE_LED, i % 2)
        gpio.write(pins.DISK_ACT_LED, (i + 1) % 2)
        gpio.write(pins.PID_LED, (i + 1) % 2)
        time.sleep(0.1)
    # Turn them all off
    gpio.write(pins.USB_LED, 0)
    gpio.write(pins.PID_LED, 0)
    gpio.write(pins.DISK_ACT_LED, 0)
    gpio.write(pins.SPARE_LED, 0)


"""2750 수 정렬하기"""

# n개의 숫자가 주어진다
n = int(input())

# 숫자를 담을 리스트
num = []

# n개의 숫자를 받는다
for _ in range(n):
    temp = int(input())
    num.append(temp)

# 정렬 함수
num.sort()

# 차례대로 출력
for i in range(n):
    print(num[i])


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
import os

import tasks

import taskpool2

import argparse

class InvalidArgs(Exception):
    pass

def use_pool2():

    try:
        parse_arguments()
    except InvalidArgs as e:
        print("Exception Error: \r\n\r\n{}".format(e))
        sys.exit(-1)

    with open(args.fl, "a+") as fp:
        tp = taskpool2.taskpool2(num=30, output=fp, retry=args.retry)
        tp.add_task(taskpool2.TaskUrlDownload(args.url))
        tp.run()

def use_pool():

    try:
        parse_arguments()
    except InvalidArgs as e:
        print("Exception Error: \r\n\r\n{}".format(e))
        sys.exit(-1)

    tp = tasks.TaskPool(num = 20, fl=args.fl)
    tp.task_append(tasks.TaskPageDownload(args.url))
    tp.start()

def parse_arguments():

    desc="""
    Story downloader, by taowuwen@gmail.com version 1.0
    """
    parser = argparse.ArgumentParser(description=desc)

    parser.add_argument('-a', '--url', action='store', dest='url')
    parser.add_argument('-o', '--output', action='store', dest='fl', default="/tmp/story.txt")
    parser.add_argument('-r', '--retry', action='store', dest='retry', default=10, type=int)
    parser.add_argument('-v', '--version', action='version', version="%(prog)s 1.0")

    global args

    args = parser.parse_args(sys.argv[1:])
    if not args.url:
        parser.print_help()
        raise InvalidArgs("ERROR, Download URL should be supplied")

# cmd url filename
if '__main__' == __name__:
#    use_pool()
    use_pool2()


from biohub.core.tasks.exceptions import TaskInstanceNotExists
from biohub.core.tasks.result import AsyncResult

class TaskPayload(object):
    """
    A task payload carries information related to a specific task instance,
    including task_id, arguments, options, etc.
    """

    __slots__ = ['task_name', 'task_id', 'args', 'kwargs', 'options',
                 'packed_data', '_async_result']

    def __init__(self, task_name, task_id, args, kwargs, options):
        self.task_name = task_name
        self.task_id = task_id
        self.args = args
        self.kwargs = kwargs or {}
        self.options = options
        self.packed_data = (task_name, task_id, args, kwargs, options)
        self._async_result = AsyncResult(task_id)

    def store(self):
        """
        To store the information into redis.
        """
        self._async_result._set_payload(self.packed_data)

    @classmethod
    def from_packed_data(cls, packed_data):
        """
        A factory function to create a payload from a tuple.
        """
        return cls(*packed_data)

    @classmethod
    def from_task_id(cls, task_id):
        """
        A factory function to fetch task payload through a given task_id.
        """
        packed_data = AsyncResult(task_id).payload

        if packed_data is None:
            raise TaskInstanceNotExists(task_id)

        return cls.from_packed_data(packed_data)