import os
import torch
import string
import argparse

import numpy as np

from pingouin import mwu
from transformers import (BartForConditionalGeneration,
                          BartTokenizer,
                          MBartTokenizer,
                          MBart50TokenizerFast,
                          MBartForConditionalGeneration)

from eval_util import read_jsonl, get_final_index, compute_perplexity, count_distance_in_subwords, make_bar_plot, \
    make_density_plot

MBART_TABLE = {'en': 'en_XX',
               'de': 'de_DE',
               'fr': 'fr_FR',
               'ru': 'ru_RU'}

LANG2PRON = {'de': {'er': 'male', 'sie': 'female', 'es': 'neutral'},
             'fr': {'il': 'male', 'elle': 'female', 'ils': 'male', 'elles': 'female'},
             'ru': {'oн': 'male', 'oнa': 'female', 'oнo': 'neutral'}}

def _score_translation(src_sentence, tgt_sentence):
    """ Computes perplexity of contrastive translations """
    # Score target sequence conditioned on the input
    src = tokenizer(src_sentence, return_tensors='pt')
    with tokenizer.as_target_tokenizer():
        tgt = tokenizer(tgt_sentence, return_tensors='pt').input_ids

    # Do a forward pass
    with torch.no_grad():
        model_out = model(input_ids=src.input_ids.to(device),
                          attention_mask=src.attention_mask.to(device),
                          labels=tgt.to(device))
    # Extract probabilities
    tgt_input_ids = torch.squeeze(tgt).detach().cpu().numpy().tolist()
    model_logits = torch.squeeze(model_out.logits)
    tgt_probs = model_logits.softmax(axis=-1).detach().cpu().numpy().tolist()
    token_probabilities = [tgt_probs[probs_row][tok_id] for probs_row, tok_id in enumerate(tgt_input_ids)]
    return compute_perplexity(token_probabilities)

def evaluate_models(json_file_path, out_dir):
    """ Checks model performance on the challenge data. """

    # Read-in data
    samples = read_jsonl(json_file_path)

    # Compute accuracy and track input features that may be indicative of the model using heuristics
    num_correct, num_incorrect, num_correct_pairs, num_incorrect_pairs = 0, 0, 0, 0

    gender_counts = {'reference_true': {v: 0 for v in PRON2GEN.values()},
                     'reference_false': {v: 0 for v in PRON2GEN.values()},
                     'model_preference': {v: 0 for v in PRON2GEN.values()},
                     'model_rejection': {v: 0 for v in PRON2GEN.values()}}

    ref_gender_counts_per_position = {'first': {v: 0 for v in PRON2GEN.values()},
                                      'second': {v: 0 for v in PRON2GEN.values()}}  # for correct translation only

    position_counts = {'reference_true': {'first': 0, 'second': 0},
                       'reference_false': {'first': 0, 'second': 0},
                       'model_preference': {'first': 0, 'second': 0},
                       'model_rejection': {'first': 0, 'second': 0}}

    token_distance = \
        {'reference_true': dict(), 'reference_false': dict(), 'model_preference': dict(), 'model_rejection': dict()}
    # This is intended to estimate the "influence" of the trigger phrases
    ppl_changes_trigger = {'same_choice': list(), 'both_right': list(), 'both_wrong': list()}
    # This is intended to estimate the "influence" of the target pronoun
    ppl_changes_pronoun = {'correct': list(), 'incorrect': list()}

    contrastive_pair_ppl = list()
    contrastive_pair_successes = list()
    for sample_id, sample in enumerate(samples):

        # Report
        print('Checking sample {:d}'.format(sample_id))
        if (sample_id - 1) > 0 and (sample_id - 1) % 100 == 0:
            print('Processed {:d} samples'.format(sample_id - 1))

        src = sample['sentence']
        tgt1 = sample['translation1']
        tgt2 = sample['translation2']
        tgt1_ppl = _score_translation(src, tgt1)
        tgt2_ppl = _score_translation(src, tgt2)
        score_pair = [tgt1_ppl, tgt2_ppl]
        label_pair = [int(int(sample['answer']) == 1), int(int(sample['answer']) == 2)]

        # Identify filler gender in both translations
        try:
            gen_pair = [PRON2GEN[samples[sample_id]['pronoun1']], PRON2GEN[samples[sample_id]['pronoun2']]]
        except KeyError:
            gen_pair = [None, None]
        true_ref_gen = gen_pair[label_pair.index(max(label_pair))]
        false_ref_gen = gen_pair[label_pair.index(min(label_pair))]

        # Establish the relative position of the correct referent
        sentence_tokens = [tok.strip(string.punctuation) for tok in sample['sentence'].split()]
        if int(sample['answer']) == 1:
            true_referent_is_first = get_final_index(sentence_tokens, sample['referent1_en']) < \
                                     get_final_index(sentence_tokens, sample['referent2_en'])
        else:
            true_referent_is_first = get_final_index(sentence_tokens, sample['referent2_en']) < \
                                     get_final_index(sentence_tokens, sample['referent1_en'])
        if true_referent_is_first:
            position_counts['reference_true']['first'] += 1
            position_counts['reference_false']['second'] += 1
            if true_ref_gen is not None:
                ref_gender_counts_per_position['first'][true_ref_gen] += 1
                ref_gender_counts_per_position['second'][false_ref_gen] += 1
        else:
            position_counts['reference_true']['second'] += 1
            position_counts['reference_false']['first'] += 1
            if true_ref_gen is not None:
                ref_gender_counts_per_position['first'][false_ref_gen] += 1
                ref_gender_counts_per_position['second'][true_ref_gen] += 1

        # Measure sub-word distance
        distance_pair = \
            [count_distance_in_subwords(sample['sentence'], sample['referent1_en'], 'it', None, None, None, tokenizer),
             count_distance_in_subwords(sample['sentence'], sample['referent2_en'], 'it', None, None, None, tokenizer)]

        # Check model preferences
        if score_pair[0] == score_pair[1]:
            num_incorrect += 1
            contrastive_pair_successes.append(0)
        else:
            min_ppl_id = score_pair.index(min(score_pair))
            correct_id = label_pair.index(max(label_pair))

            # Track model accuracy
            if min_ppl_id == correct_id:
                num_correct += 1
                contrastive_pair_successes.append(1)
            else:
                num_incorrect += 1
                contrastive_pair_successes.append(0)

            # Track model perplexity for the preferred translation
            contrastive_pair_ppl.append((min_ppl_id == correct_id, score_pair[min_ppl_id]))

            # Track heuristics
            # Gender
            if true_ref_gen is not None:
                gender_counts['reference_true'][gen_pair[correct_id]] += 1
                gender_counts['reference_false'][gen_pair[abs(1 - correct_id)]] += 1
                gender_counts['model_preference'][gen_pair[min_ppl_id]] += 1
                gender_counts['model_rejection'][gen_pair[abs(1 - min_ppl_id)]] += 1

            # Relative referent position
            if true_referent_is_first:
                pref_key, rej_key = ('first', 'second') if min_ppl_id == correct_id else ('second', 'first')
            else:
                pref_key, rej_key = ('second', 'first') if min_ppl_id == correct_id else ('first', 'second')
            position_counts['model_preference'][pref_key] += 1
            position_counts['model_rejection'][rej_key] += 1

            # Sub-word distance

            # Measure sub-word distance
            for key, tpl_id in [('reference_true', correct_id), ('reference_false', abs(1 - correct_id)),
                                ('model_preference', min_ppl_id), ('model_rejection', abs(1 - min_ppl_id))]:
                if token_distance[key].get(distance_pair[tpl_id], None) is None:
                    token_distance[key][distance_pair[tpl_id]] = 0
                token_distance[key][distance_pair[tpl_id]] += 1

            # Track perplexity changes within the sample
            ppl_diff = abs(score_pair[0] - score_pair[1])
            ppl_key = 'correct' if min_ppl_id == correct_id else 'incorrect'
            ppl_changes_pronoun[ppl_key].append(ppl_diff)

        # Track perplexity changes across samples
        if sample_id % 2 == 1:
            if len(contrastive_pair_ppl) == 2:
                if (contrastive_pair_ppl[0][0] is True) and (contrastive_pair_ppl[1][0] is True):
                    ppl_key = 'both_right'
                elif (contrastive_pair_ppl[0][0] is False) and (contrastive_pair_ppl[1][0] is False):
                    ppl_key = 'both_wrong'
                else:
                    ppl_key = 'same_choice'
                ppl_changes_trigger[ppl_key].append(
                    abs(contrastive_pair_ppl[0][1] - contrastive_pair_ppl[1][1]))
            contrastive_pair_ppl = list()

        # Update pair counts
        if sample_id % 2 == 1:
            if 0 not in contrastive_pair_successes:
                num_correct_pairs += 1
            else:
                num_incorrect_pairs += 1
            contrastive_pair_successes = list()

    # Report
    if not os.path.exists(out_dir):
        os.makedirs(out_dir)
    sorted_gen = sorted(list(PRON2GEN.values()))
    gen2num = {p: p_id + 1 for p_id, p in enumerate(sorted_gen)}
    print('=' * 20)
    print('# of SAMPLES with lower perplexity assigned to the CORRECT option: {:d}'.format(num_correct))
    print('# of SAMPLES with lower perplexity assigned to the INCORRECT option: {:d}'.format(num_incorrect))
    print('# of PAIRS were resolved correctly: {:d}'.format(num_correct_pairs))
    print('# of PAIRS were resolved incorrectly: {:d}'.format(num_incorrect_pairs))
    print('Accuracy, SAMPLES: {:.4f}'.format(num_correct / (num_correct + num_incorrect)))
    print('Accuracy, PAIRS: {:.4f}'.format(num_correct_pairs / (num_correct_pairs + num_incorrect_pairs)))

    print('=' * 20)
    print('--- MODEL HEURISTICS ---')
    print('Total gender counts for CORRECT referents: male: {:d} | female: {:d} | neutral: {:d}'.format(
        gender_counts['reference_true'].get('male', 0), gender_counts['reference_true'].get('female', 0),
        gender_counts['reference_true'].get('neutral', 0)))
    print('Total gender counts for model-PREFERRED referents: male: {:d} | female: {:d} | neutral: {:d}'.format(
        gender_counts['model_preference'].get('male', 0), gender_counts['model_preference'].get('female', 0),
        gender_counts['model_preference'].get('neutral', 0)))
    print('Total gender counts for INCORRECT referents: male: {:d} | female: {:d} | neutral: {:d}'.format(
        gender_counts['reference_false'].get('male', 0), gender_counts['reference_false'].get('female', 0),
        gender_counts['reference_false'].get('neutral', 0)))
    print('Total gender counts for model-REJECTED referents: male: {:d} | female: {:d} | neutral: {:d}'.format(
        gender_counts['model_rejection'].get('male', 0), gender_counts['model_rejection'].get('female', 0),
        gender_counts['model_rejection'].get('neutral', 0)))
    # Compare correlation
    print('-' * 5)
    print('Gender correlations for references (MWU):')
    x, y = list(), list()
    for cat, var in [('reference_true', x), ('reference_false', y)]:
        for key in gender_counts[cat].keys():
            var += [gen2num[key]] * gender_counts[cat][key]
    print(mwu(x, y, tail='two-sided'))
    print('Gender correlations for model choices (MWU):')
    x, y = list(), list()
    for cat, var in [('model_preference', x), ('model_rejection', y)]:
        for key in gender_counts[cat].keys():
            var += [gen2num[key]] * gender_counts[cat][key]
    print(mwu(x, y, tail='two-sided'))
    # Plot
    make_bar_plot(gender_counts, 'target pronoun gender', 'frequency', sorted_gen, out_dir, 'gender_counts')

    print('-' * 10)
    print('Referent position for CORRECT referents: first {:d} | second {:d}'.format(
        position_counts['reference_true']['first'], position_counts['reference_true']['second']))
    print('Referent position for model-PREFERRED references: first {:d} | second {:d}'.format(
        position_counts['model_preference']['first'], position_counts['model_preference']['second']))
    print('Referent position for INCORRECT referents: first {:d} | second {:d}'.format(
        position_counts['reference_false']['first'], position_counts['reference_false']['second']))
    print('Referent position for model-REJECTED references: first {:d} | second {:d}'.format(
        position_counts['model_rejection']['first'], position_counts['model_rejection']['second']))
    print('   Referent gender per referent position:')
    for loc in ref_gender_counts_per_position.keys():
        print('   {:s}:'.format(loc))
        for gen in ref_gender_counts_per_position[loc].keys():
            print('      {:s} : {:d}'.format(gen, ref_gender_counts_per_position[loc][gen]))
    # Compare correlation
    print('-' * 5)
    print('Position correlations for references (MWU):')
    x, y = list(), list()
    for cat, var in [('reference_true', x), ('reference_false', y)]:
        for key in position_counts[cat].keys():
            var += [int(key == 'first') + 1] * position_counts[cat][key]
    print(mwu(x, y, tail='two-sided'))
    print('Position correlations for model choices (MWU):')
    x, y = list(), list()
    for cat, var in [('model_preference', x), ('model_rejection', y)]:
        for key in position_counts[cat].keys():
            var += [int(key == 'first') + 1] * position_counts[cat][key]
    print(mwu(x, y, tail='two-sided'))
    # Plot
    make_bar_plot(
        position_counts, 'relative referent position', 'frequency', ['first', 'second'], out_dir, 'position_counts')

    print('-' * 10)
    print('# of sub-words between the pronoun and its referent for the CORRECT source interpretation:')
    flattened_list = list()
    for key in token_distance['reference_true'].keys():
        flattened_list += [key] * token_distance['reference_true'][key]
    print('mean: {:.4f} | std: {:.4f}'.format(np.mean([flattened_list]), np.std(flattened_list)))
    print('-' * 5)
    print('# of sub-words between the pronoun and its referent for the interpretation PREFERRED by the model:')
    flattened_list = list()
    for key in token_distance['model_preference'].keys():
        flattened_list += [key] * token_distance['model_preference'][key]
    print('mean: {:.4f} | std: {:.4f}'.format(np.mean([flattened_list]), np.std(flattened_list)))
    print('-' * 5)
    print('# of sub-words between the pronoun and its referent for the INCORRECT source interpretation:')
    flattened_list = list()
    for key in token_distance['reference_false'].keys():
        flattened_list += [key] * token_distance['reference_false'][key]
    print('mean: {:.4f} | std: {:.4f}'.format(np.mean([flattened_list]), np.std(flattened_list)))
    print('-' * 5)
    print('# of sub-words between the pronoun and its referent for the interpretation REJECTED by the model:')
    flattened_list = list()
    for key in token_distance['model_rejection'].keys():
        flattened_list += [key] * token_distance['model_rejection'][key]
    print('mean: {:.4f} | std: {:.4f}'.format(np.mean([flattened_list]), np.std(flattened_list)))
    # Compare correlation
    print('-' * 5)
    print('Distance correlations for references (MWU):')
    x, y = list(), list()
    for cat, var in [('reference_true', x), ('reference_false', y)]:
        for key in token_distance[cat].keys():
            var += [key] * token_distance[cat][key]
    print(mwu(x, y, tail='two-sided'))
    print('Distance correlations for model choices (MWU):')
    x, y = list(), list()
    for cat, var in [('model_preference', x), ('model_rejection', y)]:
        for key in token_distance[cat].keys():
            var += [key] * token_distance[cat][key]
    print(mwu(x, y, tail='two-sided'))
    # Plot
    token_distance_plot = {'reference_true': token_distance['reference_true'],
                           'model_preference': token_distance['model_preference']}
    make_density_plot(token_distance_plot, ['category', '# sub-words'], out_dir, 'token_distance')

    # ACROSS both samples in each PAIR
    print('-' * 10)
    print('Perplexity difference when triggers are ignored (count, mean, std): {:d} | {:.4f} | {:.4f}'.format(
        len(ppl_changes_trigger['same_choice']), np.mean(ppl_changes_trigger['same_choice']),
        np.std(ppl_changes_trigger['same_choice'])))
    print('Perplexity difference when both predictions are correct (count, mean, std): {:d} | {:.4f} | {:.4f}'.format(
        len(ppl_changes_trigger['both_right']),
        np.mean(ppl_changes_trigger['both_right']), np.std(ppl_changes_trigger['both_right'])))
    print('Perplexity difference when both predictions are incorrect (count, mean, std): {:d} | {:.4f} | {:.4f}'.format(
        len(ppl_changes_trigger['both_wrong']), np.mean(ppl_changes_trigger['both_wrong']),
        np.std(ppl_changes_trigger['both_wrong'])))
    # Compare correlations
    print('MWU: same_choice - both_right')
    print(mwu(ppl_changes_trigger['same_choice'], ppl_changes_trigger['both_right'], tail='two-sided'))
    print('MWU: same_choice - both_wrong')
    print(mwu(ppl_changes_trigger['same_choice'], ppl_changes_trigger['both_wrong'], tail='two-sided'))
    print('MWU: both_right - both_wrong')
    print(mwu(ppl_changes_trigger['both_right'], ppl_changes_trigger['both_wrong'], tail='two-sided'))
    # Plot
    make_density_plot(ppl_changes_trigger, ['category', 'PPl difference'], out_dir, 'ppl_difference_trigger')

    # WITHIN each SAMPLE
    print('-' * 10)
    print('Perplexity difference for correct translation choice (count, mean, std): {:d} | {:.4f} | {:.4f}'.format(
        len(ppl_changes_pronoun['correct']), np.mean(ppl_changes_pronoun['correct']),
        np.std(ppl_changes_pronoun['correct'])))
    print('Perplexity difference for incorrect translation choice (count, mean, std): {:d} | {:.4f} | {:.4f}'.format(
        len(ppl_changes_pronoun['incorrect']), np.mean(ppl_changes_pronoun['incorrect']),
        np.std(ppl_changes_pronoun['incorrect'])))
    # Compare correlations
    print('MWU: correct - incorrect')
    print(mwu(ppl_changes_pronoun['correct'], ppl_changes_pronoun['incorrect'], tail='two-sided'))
    # Plot
    make_density_plot(ppl_changes_pronoun, ['category', 'PPl difference'], out_dir, 'ppl_difference_pronoun')

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--json_file_path', type=str, required=True,
                        help='path to the JSON file containing the contrastive samples')
    parser.add_argument('--checkpoint_dir', type=str, default=None,
                        help='path to the directory containing checkpoint files of the evaluated model')
    parser.add_argument('--out_dir', type=str, required=True,
                        help='path to the output directory')
    parser.add_argument('--model_type', type=str, choices=['bart', 'mbart50'],
                        help='Model type to evaluate')
    parser.add_argument('--use_multi', action='store_true',
                        help='Whether to use a multilingual language model; if disabled, uses a monolingual target '
                             'language model')
    parser.add_argument('--use_cpu', action='store_true', help='Whether to use the CPU')
    parser.add_argument('--tgt_lang', type=str, choices=['de', 'fr', 'ru'],
                        help='Target language of the challenge set; ONLY AFFECTS THE ANSWERS, as the context and '
                             'question are always presented in English')
    args = parser.parse_args()

    # Select relevant pronouns
    PRON2GEN = LANG2PRON[args.tgt_lang]

    # Assign checkpoints (change model size by changing checkpoint names)
    if args.model_type == 'bart':
        if args.use_multi:
            model_type = MBartForConditionalGeneration
            tokenizer_type = MBartTokenizer
        else:
            assert args.tgt_lang == 'en', 'Configuration not supported!'
            model_type = BartForConditionalGeneration
            tokenizer_type = BartTokenizer
    else:
        # mBART-50
        model_type = MBartForConditionalGeneration
        tokenizer_type = MBart50TokenizerFast

    # Load models and tokenizers
    if args.model_type != 'mbart50':
        assert args.checkpoint_dir is not None, 'Model checkpoint must be specified for models other than MBART50'
        tokenizer = tokenizer_type.from_pretrained(args.checkpoint_dir)
        model = model_type.from_pretrained(args.checkpoint_dir)
    else:
        model = model_type.from_pretrained('facebook/mbart-large-50-one-to-many-mmt')
        tokenizer = tokenizer_type.from_pretrained('facebook/mbart-large-50-one-to-many-mmt',
                                                   src_lang=MBART_TABLE['en'], tgt_lang=MBART_TABLE[args.tgt_lang])

    device = 'cpu' if args.use_cpu else 'cuda:0'
    model.to(device)

    evaluate_models(args.json_file_path, args.out_dir)


import torchvision.transforms as transforms
from .. import constants
from ..util import max_vector_magnitude, log_vector, exp_vector

def create_transformer(img_size=(224,224), mean_std=None, aug=False):
    augmentations = []
    if aug:
        augmentations = [
            transforms.RandomHorizontalFlip(p=0.5),
            transforms.RandomAffine(degrees=0, translate=(0.1,0.1)),
        ]
    normalizations = []
    if mean_std is not None:
        normalizations = [transforms.Normalize(*mean_std)]
    return transforms.Compose([
        transforms.Resize(img_size),
        *augmentations,
        transforms.ToTensor(),
        *normalizations
    ])

class Normalizer:
    def __init__(self, dash_enabled=None, delta_mag=0, enemy_mag=0, negative_dash=False, log=False):
        self.dash_enabled = dash_enabled
        self.dash_cooldown = 2
        self.dash_length = 10
        self.max_health = 100
        self.max_bullets = 5
        self.delta_mag = delta_mag
        self.enemy_mag = enemy_mag
        self.n = 0
        self.negative_dash = negative_dash
        self.log = log

    def fit(self, df):
        dash_enabled = None
        delta_mag = 0
        enemy_mag = 0

        if "dash_enabled" in df.columns:
            dash_enabled = bool(df.iloc[-1]["dash_enabled"])

        if constants.last_movements[0] in df.columns:
            delta_mag = max(max_vector_magnitude(df[constants.last_movements]), max_vector_magnitude(df[constants.deltas]))
        else:
            delta_mag = max_vector_magnitude(df[constants.deltas])
        if constants.enemy_positions[0] in df.columns:
            enemy_mag = max_vector_magnitude(df[constants.enemy_positions], log=self.log)

        n = len(df)

        self.dash_enabled = self.dash_enabled if not dash_enabled else True
        self.delta_mag = max(self.delta_mag, delta_mag)
        self.enemy_mag = max(self.enemy_mag, enemy_mag)
        self.n += n

    def get_dash_enabled(self, df, dash_enabled=None):
        if dash_enabled is None:
            dash_enabled = self.dash_enabled
        if dash_enabled is None:
            if "dash_enabled" in df.columns:
                dash_enabled = bool(df.iloc[-1]["dash_enabled"])
            else:
                dash_enabled = True
        return dash_enabled

    def transform(self, df, dash_enabled=None):
        dash_enabled = self.get_dash_enabled(df, dash_enabled=dash_enabled)

        df = df.copy()

        if dash_enabled or not self.negative_dash:
            df["dash_cooldown"] /= self.dash_cooldown
            df["dash"] /= self.dash_length

        healths = [x for x in df.columns if "health" in x]
        df[healths] /= self.max_health
        df["bullets"] /= self.max_bullets

        if constants.last_movements[0] in df.columns:
            df[constants.deltas+constants.last_movements] /= self.delta_mag
        else:
            df[constants.deltas] /= self.delta_mag

        if constants.enemy_positions[0] in df.columns:
            pos = df[constants.enemy_positions]
            if self.log:
                pos = log_vector(pos)
            #print(df[constants.enemy_positions].shape, pos.shape)
            df[constants.enemy_positions] = pos / self.enemy_mag
        return df

    def inverse_transform(self, df):
        dash_enabled = self.get_dash_enabled(df, dash_enabled=dash_enabled)

        df = df.copy()

        if dash_enabled or not self.negative_dash:
            if "dash_cooldown" in df.columns:
                df["dash_cooldown"] *= self.dash_cooldown
            if "dash" in df.columns:
                df["dash"] *= self.dash_length

        if "health" in df.columns:
            healths = [x for x in df.columns if "health" in x]
            df[healths] *= self.max_health
        if "bullets" in df.columns:
            df["bullets"] *= self.max_bullets

        if constants.last_movements[0] in df.columns:
            df[constants.deltas+constants.last_movements] *= self.delta_mag
        else:
            df[constants.deltas] *= self.delta_mag

        if constants.enemy_positions[0] in df.columns:
            pos = df[constants.enemy_positions]
            if self.log:
                pos = exp_vector(pos)
            df[constants.enemy_positions] = pos * self.enemy_mag
        return df


from django.shortcuts import render, get_object_or_404, redirect
from django.http import HttpResponseRedirect, HttpResponse
from .models import Project, Category, Expense
from django.views.generic import CreateView
from django.utils.text import slugify
from .forms import ExpenseForm
import json

def project_list(request):
    project_list = Project.objects.all()
    return render(request, "budget/project-list.html", {"project_list": project_list})

def project_detail(request, project_slug):
    project = get_object_or_404(Project, slug=project_slug)

    if request.method == "GET":
        category_list = Category.objects.filter(project=project)
        return render(
            request,
            "budget/project-detail.html",
            {
                "project": project,
                "expense_list": project.expenses.all(),
                "category_list": category_list,
            },
        )

    elif request.method == "POST":
        # request.POST has a dictionary-like object containing all HTTP POST params
        # providing that the request contains the form data
        form = ExpenseForm(request.POST)

        # If is_valid returns False, we go back to the form template with the previous values populated.
        if form.is_valid():
            # When is_valid returns True, we can access validated data in cleaned_data
            title = form.cleaned_data["title"]
            amount = form.cleaned_data["amount"]
            category_name = form.cleaned_data["category"]

            category = get_object_or_404(Category, project=project, name=category_name)

            Expense.objects.create(
                project=project, title=title, amount=amount, category=category
            )

    elif request.method == "DELETE":
        try:
            # this will raise when id is not passed into client.delete()
            id = json.loads(request.body)["id"]
            expense = Expense.objects.get(id=id)
            expense.delete()
        except Exception as e:
            print("[DELETE:project_detail]", e)
            return HttpResponse(status=404)

        return HttpResponse(status=204)

    return redirect(project)

class ProjectCreateView(CreateView):
    model = Project
    template_name = "budget/add-project.html"
    fields = ("name", "budget")

    def form_valid(self, form):
        self.object = form.save()

        categories = self.request.POST.get("categoriesString").split(",")
        for category in categories:
            Category.objects.create(
                project=Project.objects.get(id=self.object.id), name=category
            )

        return redirect(self.object)


"""empty message

Revision ID: 3e45ffb8236d
Revises: 9ec2cd7f9f5d
Create Date: 2021-05-07 10:34:44.523301

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = '3e45ffb8236d'
down_revision = '9ec2cd7f9f5d'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('posts', sa.Column('author_id', sa.Integer(), nullable=True))
    op.drop_constraint('posts_ibfk_1', 'posts', type_='foreignkey')
    op.create_foreign_key(None, 'posts', 'users', ['author_id'], ['id'])
    op.drop_column('posts', 'author')
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('posts', sa.Column('author', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True))
    op.drop_constraint(None, 'posts', type_='foreignkey')
    op.create_foreign_key('posts_ibfk_1', 'posts', 'users', ['author'], ['id'])
    op.drop_column('posts', 'author_id')
    # ### end Alembic commands ###


import discord
from discord.ext import commands
import random
from discord.utils import get
import pickle
import re

class Common(commands.Cog, name="기본"):
    """
    솔린디 봇의 기본 명령어들입니다
    """

    def __init__(self, app):
        self.app = app

    @commands.command(help="설정한 숫자의 범위 안에서 랜덤한 숫자를 하나 뽑습니다", usage="`!randomnumber/rn <숫자 1> <숫자 2>`")
    async def rn(self, ctx, num1, num2):
        try:
            picked = random.randint(int(num1), int(num2))
            await ctx.send(f'뽑힌 숫자는 **{str(picked)}** 입니다')
        except IndexError:
            await ctx.send("무슨 숫자를 뽑을지 알려주세요")
        except ValueError:
            await ctx.channel.send("정수를 입력해주세요")
        except ZeroDivisionError:
            await ctx.channel.send("0으로 나눌 수 없습니다")

    @commands.command(name="도움말", help="도움말을 출력합니다.")
    async def help_command(self, ctx, func=None):
        cog_list = ["기본","관리자", "음악"]
        if func is None:
            embed = discord.Embed(title="VGS Bot 도움말", description="접두사는 `?` 입니다.", color=0x00ffd8)  # Embed 생성
            for x in cog_list:  # cog_list에 대한 반복문
                cog_data = self.app.get_cog(x)  # x에 대해 Cog 데이터를 구하기
                command_list = cog_data.get_commands()  # cog_data에서 명령어 리스트 구하기
                embed.add_field(name=x, value=" ".join([c.name for c in command_list]), inline=True)  # 필드 추가
            await ctx.send(embed=embed)  # 보내기
        else:
            command_notfound = True  # 이걸 어떻게 쓸지 생각해보세요!
            for _title, cog in self.app.cogs.items():  # title, cog로 item을 돌려주는데 title은 필요가 없습니다.
                if not command_notfound:  # False면
                    break  # 반복문 나가기
                else:  # 아니면
                    for title in cog.get_commands():  # 명령어를 아까처럼 구하고 title에 순차적으로 넣습니다.
                        if title.name == func:  # title.name이 func와 같으면
                            cmd = self.app.get_command(title.name)  # title의 명령어 데이터를 구합니다.
                            embed = discord.Embed(title=f"명령어 : {cmd}", description=cmd.help, color=0x00ffd8)  # Embed 만들기
                            await ctx.send(embed=embed)  # 보내기
                            command_notfound = False
                            break  # 반복문 나가기
                        else:
                            command_notfound = True
            if command_notfound:  # 명령어를 찾지 못하면
                if func in cog_list:  # 만약 cog_list에 func가 존재한다면
                    cog_data = self.get_cog(func)  # cog 데이터 구하기
                    command_list = cog_data.get_commands()  # 명령어 리스트 구하기
                    embed = discord.Embed(title=f"카테고리 : {cog_data.qualified_name}",
                                          description=cog_data.description, color=0x00ffd8)  # 카테고리 이름과 설명 추가
                    embed.add_field(name="명령어들",
                                    value=", ".join([c.name for c in command_list]))  # 명령어 리스트 join
                    await ctx.send(embed=embed)  # 보내기
                else:
                    await ctx.send("그런 이름의 명령어나 카테고리는 없습니다.")  # 에러 메시지

def setup(app):
    app.add_cog(Common(app))


"""
DQAS for QFT QEM circuit design, deprecated DQAS implementation
"""

import sys

sys.path.insert(0, "../")

from functools import partial
import cirq
import numpy as np
import tensorflow as tf
from tensorcircuit.applications.vags import qft_qem_vag
from tensorcircuit.applications.dqas import (
    set_op_pool,
    DQAS_search,
    verbose_output,
)

def main_3():
    qft_3 = partial(qft_qem_vag, n=3)

    set_op_pool([cirq.X, cirq.Y, cirq.Z, cirq.I, cirq.T, cirq.S])
    DQAS_search(
        qft_3,
        nnp_initial_value=tf.zeros([6, 6]),
        p=6,
        prethermal=0,
        batch=32,
        verbose=False,
        epochs=30,
    )

def main_4():
    qft_4 = partial(qft_qem_vag, n=4)

    set_op_pool(
        [
            cirq.I,
            cirq.X,
            cirq.Y,
            cirq.Z,
            cirq.H,
            cirq.rx(np.pi / 3),
            cirq.rx(np.pi * 2.0 / 3),
            cirq.rz(np.pi / 3),
            cirq.rz(np.pi * 2.0 / 3),
            cirq.S,
            cirq.T,
        ]
    )
    DQAS_search(
        qft_4,
        nnp_initial_value=tf.zeros([12, 11]),
        p=12,
        prethermal=0,
        batch=32,
        verbose=False,
        verbose_func=verbose_output,
        epochs=6,
    )

if __name__ == "__main__":
    # main_3()
    main_4()


from ..message_class import *
from ..message_id import *
from ..payload import *
from ..message import *

flags = Bitfield(1, (
    BitfieldEntry("timeBase", 0),
    BitfieldEntry("utc", 1),
    BitfieldEntry("raim", slice(2, 4)),
    )
)

refInfo = Bitfield(1, (
    BitfieldEntry("timeRefGnss", slice(0, 4)),
    BitfieldEntry("utcStandard", slice(4, 8)),
    )
)

payload_description = Fields(
    ("towMS", U4),
    ("towSubMS", U4),
    ("qErr", I4),
    ("week", U2),
    ("flags", flags),
    ("refInfo", refInfo)
)

description = MessageDescription(
    message_class=TIM,
    message_id=MessageId("TP", b"\x01"),
    payload_description=Options(
        Empty,
        payload_description
    )
)


from __future__ import division, print_function, absolute_import
# noinspection PyUnresolvedReferences
from six.moves import range

from scipy.stats import rv_discrete
import numpy as np

__all__ = ['nonuniform', 'gibbs']

# noinspection PyMethodOverriding,PyPep8Naming
class nonuniform_gen(rv_discrete):
    """A nonuniform discrete random variable.

    %(before_notes)s

    %(example)s

    .. note::
        Adapted from Matlab:

        | Project: `Probabilistic Modeling Toolkit for Matlab/Octave <https://github.com/probml/pmtk3>`_.
        | Copyright (2010) Kevin Murphy and Matt Dunham
        | License: `MIT <https://github.com/probml/pmtk3/blob/5fefd068a2e84ae508684d3e4750bd72a4164ba0/license.txt>`_

    """
    def _argcheck(self, a):
        self.a = a
        return abs(a.sum() - 1) <= np.finfo(np.float16).eps

    def _pmf(self, x, a):
        # port discreteLogprob
        raise NotImplementedError

    def _ppf(self, q, a):
        raise NotImplementedError

    def _stats(self, a):
        raise NotImplementedError

    # noinspection PyArgumentList
    def _rvs(self, a):
        r = np.random.rand()
        if self._size is not None:
            r = np.random.rand(self._size)
        s = np.zeros(self._size, dtype=np.int32)

        cum_prob = np.cumsum(a.ravel())

        if self._size is None:
            cum_prob2 = cum_prob[0:-1]
            s = np.sum(r > cum_prob2)
        else:
            n = a.size
            if n < self._size:
                for i in range(n - 1):
                    s += r > cum_prob[i]
            else:
                cum_prob2 = cum_prob[0:-1]
                for i in range(self._size):
                    # noinspection PyTypeChecker
                    s[i] = np.sum(r[i] > cum_prob2)

        return s

nonuniform = nonuniform_gen(name='nonuniform', longname='A discrete non-uniform '
                            '(random integer)')

# noinspection PyMethodOverriding,PyPep8Naming
class gibbs_gen(rv_discrete):
    """A Gibbs distributed discrete random variable.

    %(before_notes)s

    Notes
    -----
    The probability mass function for `gibbs` is::

                        exp(a/t)
        gibbs.pmf(x) = ------------
                       sum(exp(a/t)

    %(example)s

    """
    def _argcheck(self, t):
        """Default check for correct values on args and keywords.

        Returns condition array of 1's where arguments are correct
        and 0's where they are not.

        """
        return t >= 0

    def _nonzero(self, k, t):
        return k == k

    def _pmf(self, a, t):
        values = np.exp(a / t)

        # noinspection PyTypeChecker
        if np.any(t <= np.finfo(np.float16).eps):
            max_value = max(a)
            values = np.asarray([val if val == max_value else 0. for val in a])
        return values / np.sum(values)

    def _ppf(self, a, t):
        raise NotImplementedError

    def _stats(self, t):
        raise NotImplementedError

gibbs = gibbs_gen(name='gibbs', longname='Gibbs distribution '
                  '(random integer)')


"""
Overview:

Bubble sort is a O(n^2) sorting algorithm where it iterates
through an array and checks if two elements in array are
greater than each other.

"""

def bubbleSort(array):
	# Create Flag to keep track of whether or not it's sorted
	sortedC = False

	while not sortedC:  # If the array is not sorted keep running while flag is false
		sortedC = True  # The Array is sorted if no swap occurs
		for i in range(1, len(array)):  # Iterate from 2nd ele to last
			prev = array[i-1]  # temp variables so simpler
			curr = array[i]
			if prev > curr:
				array[i-1], array[i] = array[i], array[i-1]  # Swap elements if condition
				sortedC = False	 # array isn't sorted so reset flag to restart loop
	return array

res = bubbleSort([1,3,1,4,2,6,1,8])
print(res)


#!/home/saeed/Programs/miniconda3/bin/python

import obspy as obs

"""

# Extract station information from dlsv files.

"""
inv = input("\n\n+++ Enter dataless file name:\n")
inv = obs.read_inventory(inv)

stations = []

with open('dataless.dat', 'w') as f:

    for net in inv:

        for station in net:

            if station.code not in stations:

                stations.append(station.code)

                f.write('%2s %4s %7.3f %7.3f %5d\n'%(net.code, station.code,
                        station.longitude, station.latitude, station.elevation))


import time
import os
from .logger import logger
from .notifier import CrowdAiNotifier
import threading
import uuid

class NoClientInteractionError(Exception):
    pass

class InteractionVerifier:
    __last_request = None
    __time_out = None
    __instance_id = None

    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super().__new__(cls)
            cls.instance.start()
        return cls.instance

    def __init__(self):
        # timeout in seconds or client <-> server interaction
        self.__time_out = int(os.getenv('CS_INTERACTION_TIMEOUT', 180))
        self.__instance_id = uuid.uuid1()
        logger.info('client <-> server interaction verifier id: %s', self.__instance_id)

    def start(self):
        self.__last_request = time.time()
        Caller()
        logger.info('Client <-> Server interaction monitor started...')

    def mark(self):
        self.__last_request = time.time()

    def verify(self):
        now = time.time()
        duration = now - self.__last_request
        if duration > self.__time_out:
            logger.error('Client has not sent any requests to to the server for more than %ss', duration)
            CrowdAiNotifier.no_client_interaction()
            raise NoClientInteractionError(
                "Client has not sent any requests to to the server for more than {}s ".format(duration)
            )

class Caller:

    def __init__(self):
        # interval in seconds to check client <-> server interaction
        self.__cs_interaction_verifier = InteractionVerifier()
        self.__interval = int(os.getenv('CS_INTERACTION_CHECK_INTERVAL', 5))
        thread = threading.Thread(target=self.run, args=())
        thread.daemon = True
        thread.start()

    def run(self):
        while True:
            self.__cs_interaction_verifier.verify()
            time.sleep(self.__interval)


#!/usr/bin/env python

import argparse
import subprocess
import sys
import yaml

def parse_args(args):
    description = """\
Partial implementation of "helmfile sync" in Python. This will run the
same Helm commands that "helmfile sync" would run. Use --dry-run to
print the list of commands.

helmfile selectors (allows selective partial deployment) are not
implemented, nor are any other commands or arguments. Use the proper
Helmfile if you require that
"""
    p = argparse.ArgumentParser(description=description)
    p.add_argument('-f', '--file', default='helmfile.yaml', help='Helmfile')
    p.add_argument('--dry-run', action='store_true', help='Dry run')
    return p.parse_args(args)

def load_config(helmfile):
    with open(helmfile) as f:
        y = list(yaml.load_all(f))
    if len(y) != 1:
        raise ValueError('Expected one YAML document, found %d' % len(y))
    y = y[0]
    if 'releases' not in y:
        raise ValueError('Expected releases in helmfile')
    return y

def get_helm_command(r):
    command = [
        'helm',
        'upgrade',
        '--install',
        r['name'],
        r['chart'],
    ]
    if 'version' in r:
        command.extend(['--version', r['version']])
    if 'namespace' in r:
        command.extend(['--namespace', r['namespace']])
    for v in r['values']:
        command.extend(['--values', v])
    return command

def main(args):
    cfg = load_config(args.file)
    commands = [get_helm_command(r) for r in cfg['releases']]
    for c in commands:
        print(' '.join(c))
        if not args.dry_run:
            subprocess.check_call(c)

if __name__ == '__main__':
    args = parse_args(sys.argv[1:])
    main(args)


import torch
from torch import nn
import numpy as np
import time
# import wandb
from data_preprocess import Utils
from sklearn.model_selection import TimeSeriesSplit
from torch.utils.data import DataLoader

class GRU(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim):
        super(GRU, self).__init__()
        self.gru = nn.GRU(input_dim, hidden_dim)
        self.linear = nn.Linear(hidden_dim, output_dim)
        self.logistic = nn.Sigmoid()

        self.has_features = False

        self.train_window = 20
        self.test_window = 1

        self.epochs = 1
        self.optimizer = None
        self.loss_function = None
        self.model_name = None
        self.need_train = None
        self.k_fold = 5

        self.device = None

    def forward(self, input_seq):
        gru_out, hidden = self.gru(input_seq)
        out = self.linear(hidden)
        out = self.logistic(out)
        return out

    def set_params(self, has_features, train_window, test_window, epoch, optimizer,
                   loss_function, model_name, k_fold, device):
        # 属性
        # self.need_train = need_train
        self.has_features = has_features
        self.train_window = train_window
        self.test_window = test_window
        self.epochs = epoch
        self.optimizer = optimizer
        self.loss_function = loss_function
        self.model_name = model_name
        self.k_fold = k_fold
        self.device = device

    @staticmethod
    def predict_value_nf(self, model, seq):
        predicted_value = []
        begin_time = time.time()
        value = model(seq)
        end_time = time.time()
        infer_time = end_time - begin_time
        value = value.to(self.device)
        predicted_value.append(value)
        predicted_value = torch.Tensor(predicted_value)
        return predicted_value.view(-1, 1), infer_time

    def train_model_nf(self, model: torch.nn.Module, train_X: torch.Tensor, train_Y: torch.Tensor):
        time_start = time.time()
        model = model.to(self.device)
        loss_function = self.loss_function.to(self.device)
        model.train()
        for i in range(self.epochs):
            sum_loss = 0.0
            for data, label in zip(train_X, train_Y):
                self.optimizer.zero_grad()
                data, label = data.to(self.device), label.to(self.device)
                value = model(data)
                each_loss = loss_function(value, label)
                sum_loss = sum_loss + each_loss.item()
                each_loss.backward()
                # wandb.log({"sum_loss": sum_loss})
                # loss = Variable(loss.data, requires_grad=True)
                # loss.requires_grad_(True)
                self.optimizer.step()

            if i % 10 == 1:
                print(f'epoch: {i:3} loss: {sum_loss:10.8f}')
        print(f'epoch: {i:3} loss: {sum_loss:10.10f}')
        # 模型保存
        time_end = time.time()
        torch.save(model.state_dict(), f'./MODEL/GRU/{self.model_name}.pt')
        print('time cost', time_end - time_start, 's')

    def train_model_with_batches(self, model, dataset, batch_size):
        time_start = time.time()
        model = model.to(self.device)
        loss_function = self.loss_function.to(self.device)
        model.train()

        data_loader = DataLoader(dataset, batch_size=batch_size, shuffle=False)
        for i in range(self.epochs):
            sum_loss = 0.0
            for batch_data, batch_label in data_loader:
                self.optimizer.zero_grad()
                batch_data, batch_label = batch_data.to(self.device), batch_label.to(self.device)
                length = batch_data.shape[0]
                batch_data = batch_data.view(-1, length, 1)  # GRU的输入第二维度是batch_size，注意可能会多个余数
                batch_value = model(batch_data)
                batch_value = batch_value.view(length, 1, 1)
                batch_loss = loss_function(batch_value, batch_label)
                sum_loss += batch_loss.item()
                batch_loss.backward()
                self.optimizer.step()

            if i % 10 == 1:
                print(f'epoch: {i:3} loss: {sum_loss / len(data_loader):10.3f}')
            else:
                print(f'epoch: {i:3} loss: {sum_loss / len(data_loader):10.3f}')

        # 模型保存
        time_end = time.time()
        torch.save(model.state_dict(), f'./MODEL/GRU/{self.model_name}.pt')
        print('time cost: {:.3f} s'.format(time_end - time_start))

    def eval_GRU_nf(self, model: torch.nn.Module, test_set: np.ndarray):
        train_window: int = self.train_window
        time_start: float = time.time()
        model.eval()
        # model = model.cpu()
        pred_value: list = []
        t_sum: float = 0.0
        with torch.no_grad():
            for test_idx in range(len(test_set) - train_window):
                test_seq: torch.FloatTensor = torch.FloatTensor(test_set[test_idx: test_idx + train_window, :]).reshape((-1, 1))
                test_seq = test_seq.to(self.device)
                pred, t = self.predict_value_nf(self, model, test_seq)
                t_sum = t + t_sum
                pred_value.append(pred[-1, :])
        time_end: float = time.time()
        print('average cost time per inference: {:.3f} s'.format(t_sum / len(pred_value)))
        print('time cost: {:.3f} s'.format(time_end - time_start))
        return pred_value

    def eval_GRU(self, model, test_set, features, feature_dim):
        time_start = time.time()
        model.eval()
        # model = model.cpu()
        test_window = self.test_window
        train_window = self.train_window
        pred_value = []
        with torch.no_grad():
            for test_idx in range(len(test_set) - train_window):
                test_seq = torch.FloatTensor(test_set[test_idx: test_idx + train_window, :]).reshape((-1, feature_dim))
                pred = self.predict_value(self, model, test_seq, features)
                pred_value.append(pred[-1, :])
        time_end = time.time()
        print('time cost: {:.3f} s'.format(time_end - time_start))
        return pred_value


import solution
import utils

class GC(solution.Solution):

    def _read(self, f):
        return utils.read_fasta(f)

    def solve(self, data):
        max_gc_id = None
        max_gc = 0

        for id_, dna in data:
            gc = sum([1 for i in dna if i == utils.CYTOSINE or i == utils.GUANINE]) * 1. / len(dna)
            if gc > max_gc:
                max_gc_id = id_
                max_gc = gc

        return max_gc_id, max_gc * 100

    def _write(self, f, answer):
        f.write('{}\n{}'.format(answer[0][1:], '%.6f' % answer[1]))


class Solution:
    def numRescueBoats(self, people: List[int], limit: int) -> int:
        start, end = 0, len(people) - 1

        people.sort()
        boats = 0

        while start <= end:
            if people[start] + people[end] <= limit:
                start += 1
            boats += 1
            end -= 1
        return boats


from flask import Flask, request, abort
import os
import products_db

app = Flask(__name__)

@app.errorhandler(products_db.ValidationError)
def handle_validation_error(e):
    return {"ok": False}, 400

@app.post("/products")
def post_products():
    products = request.json
    products_db.set_products(products)
    return {"ok": True}

@app.get("/products")
def get_products():
    return products_db.get_products()

@app.post("/products/<string:sku>")
def post_product(sku):
    product = request.json
    product['sku'] = sku
    products_db.upsert_product(product)
    return {"ok": True}

@app.get("/products/<string:sku>")
def get_product(sku):
    product = products_db.get_product(sku)
    if not product:
        abort(404)
    return product

if __name__ == '__main__':
    products_db.init(os.path.join(os.path.dirname(__file__), "data", "db.sqlite"))
    app.run()


def leiaInt(msg):
    ok = False
    valor = 0
    while True:
        n = str(input(msg))
        if n.isnumeric():
            valor = int(n)
            ok = True
        else:
            print('\033[1;31mVALOR INVÁLIDO TENTE NOVAMENTE!!\33[m')
        if ok:
            break
    return valor

def leiaDinheiro(msg):
    valido = False
    while not valido:
        entrada = str(input(msg)).replace(',', '.')
        if entrada.isalpha() or entrada.strip() == '':
            print(f'\033[0;31mERRO: \"{entrada}\" NÃO É VALIDO!!\033[m')
        else:
            valido = True
            return float(entrada)

def contador(*num):
    cont = 0
    cont2 = 1
    while True:
        valor = float(input(f'{cont2}º valor? ').replace(',', '.'))
        cont2 += 1
        if valor == 0:
            break
        cont += valor
    return cont

def lin():
    print('-'*60)

#Programa principal
from datetime import datetime
data_atual = datetime.now()
data_em_texto = data_atual.strftime('%d-%m-%Y')
ano = data_atual.strftime("%Y")
print(ano)

#Código refatorado em 14/09/2022
#Lista com valores para o café

cafe = ["cafe", 55.00, "infantil", 27.50, "vinho", 10.90] #Valores dos produtos do café
print('-'*46)
print('\033[1;31mCAFÉ COLONIAL DIA V 2.0'.center(50))
print(f'{data_em_texto}\033[m'.center(50))
print('-'*46)
try:
    n1 = leiaInt(f'\033[1;32m Digite a Quantidade de cafés Uni. R$ {cafe[1]}0? ')
    n2 = leiaInt(f'\033[1;32m Quantidade de cafés infantil Uni R$ {cafe[3]}0? ')
    n3 = leiaInt(f'\033[1;32m Quantas taças de vinho Uni. R$ {cafe[5]}0 ? ')
except:
    print('Houve um erro na execução do programa :(')
try:
    outros = soma1 = 0
    while True:
        outros = leiaDinheiro('Mais alguma coisa (FINALIZAR..000>>)? ')
        if outros == 0:
            break
        soma1 += outros
except:
    print('\033[1;31mHouve um erro de digitação de Valor :(\033[m')
soma = (n1 * cafe[1]) + (n2 * cafe[3]) + (n3 * cafe[5]) + soma1
print(f'\033[1;31mO valor total da comanda é R$ {soma:.2f}\033[m')
valor = leiaDinheiro('Valor recebido: R$ ')
troco = (valor - soma)
print(f'\033[1;32m O valor do troco é R$ {troco:.2f}')


import telebot
from telebot import types
from django.core.management.base import BaseCommand

from user.models import User

bot = telebot.TeleBot("You Bot Token")

class Command(BaseCommand):
    help = 'Run the Telegram bot'

    def handle(self, *args, **options):
        @bot.message_handler(commands=['start'])
        def handle_start(message: types.Message):
            telegram_id = message.from_user.id
            if not User.objects.filter(telegram_id= telegram_id):
                User.objects.create(telegram_id=telegram_id, username=message.from_user.username)
            bot.reply_to(message, f"Welcome to your Django integrated Telegram bot: {message.from_user.username}!")

        @bot.message_handler(commands=['contact'])
        def handle_contact(message):
            keyboard = types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
            contact_button = types.KeyboardButton(text="Share Contact", request_contact=True)
            keyboard.add(contact_button)
            bot.send_message(message.chat.id, "Please provide your contact information.", reply_markup=keyboard)

        @bot.message_handler(content_types=['contact'])
        def get_contact(message: types.Message):
            phone_number = message.contact.phone_number
            User.objects.filter(telegram_id=message.from_user.id).update(phone_number=phone_number)
            bot.reply_to(message, f"Phone number updated: {phone_number}", reply_markup=types.ReplyKeyboardRemove())

        bot.polling()


import random
import time
from pazaak.game import cards
from pazaak.game.cards import PazaakCard
from pazaak.errors import GameLogicError, GameOverError
from pazaak.game.players import PazaakPlayer
from pazaak.enums import GameRule, GameStatus, Turn
from pazaak.data_structures.hash_tables import MultiSet
from pazaak.bases import Serializable, Recordable
from pazaak.utilities.functions import first_true

_HAND_SIZE = 4
_MAX_MODIFIER = GameRule.MAX_MODIFIER.value
_WINNING_SCORE = GameRule.WINNING_SCORE.value
_FILLED_TABLE_THRESHOLD = GameRule.MAX_CARDS_ON_TABLE.value

class PazaakGame(Serializable, Recordable):
    def __init__(self, initial_pool: [PazaakCard], hand_size=_HAND_SIZE, max_modifier=_MAX_MODIFIER):
        Recordable.__init__(self)
        self._hand_size = hand_size
        self._max_modifier = max_modifier

        opponent_cards = cards.random_cards(self._hand_size, positive_only=False, bound=5)
        opponent_hand = self._draw_hand(opponent_cards)
        player_hand = self._draw_hand(initial_pool)

        # making the opponent's hand a hash table adds some efficiency gain -- see self._get_opponent_move()
        self._opponent = PazaakPlayer(opponent_hand, Turn.OPPONENT.value, _hand_container_type=MultiSet)
        self._player = PazaakPlayer(player_hand, Turn.PLAYER.value)
        self._turn = Turn.PLAYER
        self._is_over = False

    @property
    def player(self) -> PazaakPlayer:
        return self._player

    @property
    def opponent(self) -> PazaakPlayer:
        return self._opponent

    @property
    def turn(self) -> Turn:
        return self._turn

    @property
    def is_over(self) -> bool:
        return self._is_over

    def _players(self) -> (PazaakPlayer,):
        """
        Returns a tuple of the players in the game.
        """
        return (self.player, self.opponent)

    def _game_status_from_player(self, player: PazaakPlayer) -> GameStatus:
        """
        Given a player, return the GameStatus corresponding to them.
        """
        table = {
            self.player: GameStatus.PLAYER_WINS,
            self.opponent: GameStatus.OPPONENT_WINS
        }

        if player not in table:
            raise ValueError('received unexpected player {0}'.format(player))

        return table[player]

    def start(self) -> None:
        """
        Begins a console-based version of Pazaak.
        The player goes first.
        """
        self._print_player_game(self.player)
        self._print_player_game(self.opponent)
        status = GameStatus.GAME_ON
        switch = {
            Turn.PLAYER: self.player,
            Turn.OPPONENT: self.opponent
        }

        while not status:
            try:
                turn = self._turn
                current_player = switch[turn]
                move = self._get_move(current_player)
                status = self.end_turn(turn, move)
                self._print_player_game(current_player, show_hand=True)
                time.sleep(0.5)

            except GameOverError as e:
                status = str(e)
                break

        if not status:
            status = self.winner()
        print('Winner: {0}!'.format(status))

    def end_turn(self, turn: Turn, move: PazaakCard) -> GameStatus:
        """
        Given a turn and a move, updates the game for the specified player.
        If the player is already standing, no move will be made.
        Automatically switches self._turn.
        Calculates and returns the game's updated status.
        """
        switch = {
            Turn.PLAYER: self.player,
            Turn.OPPONENT: self.opponent
        }
        player = switch[turn]
        opposite_turn = Turn.opposite_turn(self._turn)
        status = GameStatus.GAME_ON

        if player.is_standing or player.forfeited:
            status = self.winner()

        else:
            previous_score = player.score
            player.placed.append(move)
            new_score = player.score + move.modifier

            if new_score == _WINNING_SCORE:
                player.stand()

            # ending a turn with a score over 20 is an automatic loss
            if previous_score > _WINNING_SCORE and new_score > _WINNING_SCORE:
                status = GameStatus.from_turn(opposite_turn)
            else:
                player.score = new_score
                status = self.winner()

        self._turn = opposite_turn
        return status

    def choose_from_hand(self, player: PazaakPlayer, card_index: int) -> PazaakCard:
        """
        Chooses and returns the index of the card from the player's hand.
        Removes that card from the player's hand.
        Note that card_index is expected to be 0-based, but will 1-based from the player's UI.
        """
        container_type = type(player.hand)
        if not hasattr(container_type, 'pop'):
            raise GameLogicError('custom hand container type {0} for {1} has no "pop" method'.format(container_type, player))

        if card_index > len(player.hand):
            raise GameLogicError('hand-card index {0} out of bounds for {1}'.format(card_index, player))

        return player.hand.pop(card_index)

    def winner(self) -> GameStatus:
        criteria = (self._forfeited, self._outscored, self._filled_table)
        invoker = lambda f: f()
        results = map(invoker, criteria)

        status = first_true(results, default=GameStatus.GAME_ON)
        self._is_over = status != GameStatus.GAME_ON

        self._update_records(status)

        return status

    def _forfeited(self) -> GameStatus:
        forfeited_player = first_true(self._players(), lambda player: player.forfeited)
        # for now, the only person that can forfeit is the player
        return GameStatus.GAME_ON if forfeited_player is None else GameStatus.PLAYER_FORFEIT

    def _outscored(self) -> GameStatus:
        """
        Determines if any player has won by outscore.
        Outscoring happens when both players are standing - the one with the highest score <= 20 wins.
        Returns the applicable GameStatus.
        """
        status = None

        if all(player.is_standing for player in self._players()):
            if self.player.score == self.opponent.score:
                status = GameStatus.TIE
            else:
                winning_player = max(self._players(), key=lambda player: (player.score <= _WINNING_SCORE, player.score))
                status = self._game_status_from_player(winning_player)

        else:
            status = GameStatus.GAME_ON

        return status

    def _filled_table(self) -> GameStatus:
        """
        Determines if any player has won by filling the table.
        Filling the table happens when has placed 9 cards without going bust, and still has a score under 20.
        This is an automatic win.
        Returns the applicable GameStatus.
        :return:
        """
        results = {self._game_status_from_player(player): self._player_filled_table(player) for player in self._players()}
        return first_true(results, predicate=lambda status: results[status], default=GameStatus.GAME_ON)

    def _player_filled_table(self, player: PazaakPlayer) -> bool:
        return len(player.placed) >= _FILLED_TABLE_THRESHOLD and player.score <= _WINNING_SCORE

    def _update_records(self, status: GameStatus) -> None:
        if status == GameStatus.PLAYER_WINS:
            self.player.record.wins += 1
            self.opponent.record.losses += 1
        elif status in (GameStatus.OPPONENT_WINS, GameStatus.PLAYER_FORFEIT):
            self.player.record.losses += 1
            self.opponent.record.wins += 1
        elif status == GameStatus.TIE:
            self.player.record.ties += 1
            self.opponent.record.ties += 1

    def _get_move(self, player: PazaakPlayer) -> PazaakCard:
        if player.is_standing:
            return PazaakCard.empty()

        table = {
            self.player: self._get_player_move,
            self.opponent: self._get_opponent_move
        }

        if player not in table:
            raise ValueError('received unexpected player {0}'.format(player))

        method = table[player]
        return method()

    def _get_player_move(self) -> PazaakCard:
        """
        Prompts the player for their next move.
        Applies to the console-based game only.
        """
        prompt = ''
        if self.player.hand:
            cards_in_hand = len(self.player.hand)
            range = str(cards_in_hand) if cards_in_hand == 1 else '1-{0}'.format(cards_in_hand)
            prompt = '[e]nd turn, [s]tand, or use a card from your hand [{0}]: '.format(range)
        else:
            prompt = '[e]nd turn or [s]tand: '

        response = input(prompt)
        response = response.strip().upper()
        move = PazaakCard.empty()

        if response.isnumeric():
            number = int(response)
            if 1 <= number <= len(self.player.hand):
                move = self.choose_from_hand(self.player, number - 1)
            else:
                print('Invalid number, choose again')
                return self._get_player_move()

        elif response == 'S':
            self.player.stand()

        elif response == 'Q':
            self.player.forfeit()

        else:
            move = cards.random_card(positive_only=True, bound=self._max_modifier)

        return move

    def _get_opponent_move(self) -> PazaakCard:
        """
        Returns the opponent's next move.
        There's some limited intelligence here:
        1) if their score is higher than the player's score (but under 20), AND the player is standing,
           then the opponent will stand (causing the them to win).
        2) if the opponent has a card in their hand that, when played, will get their score to 20,
           then they'll play it.

        Otherwise, they'll just draw a random card.
        """
        card = None
        value_needed_to_win = _WINNING_SCORE - self.opponent.score
        card_needed_to_win = PazaakCard.empty() if value_needed_to_win == 0 else PazaakCard(_WINNING_SCORE - self.opponent.score)
        player_stood_too_early = self.player.is_standing and \
                                 ((self.player.score <= self.opponent.score <= _WINNING_SCORE) or \
                                  (self.player.score > _WINNING_SCORE and self.opponent.score <= _WINNING_SCORE))

        if self.opponent.score == _WINNING_SCORE or player_stood_too_early:
            self.opponent.stand()
            card = PazaakCard.empty()

        elif card_needed_to_win in self.opponent.hand:
            self.opponent.hand.remove(card_needed_to_win)
            card = card_needed_to_win

        elif self.opponent.score > _WINNING_SCORE:
            # if their score is over 20,
            # find a card from their hand that will maximize their score under 20
            card_needed = max(self.opponent.hand, key=lambda card: self.opponent.score + card.modifier <= _WINNING_SCORE)
            self.opponent.hand.remove(card_needed)
            card = card_needed

        else:
            card = cards.random_card(positive_only=True, bound=self._max_modifier)

        return card

    def _print_player_game(self, player: PazaakPlayer, show_hand=True) -> None:
        hand_repr = '| {0} |'.format(' | '.join([card.parity() if show_hand else 'X' for card in player.hand]))
        divider_size = len(hand_repr)
        pronoun = 'You' if player is self.player else 'Opponent'
        print('{0}: {1}'.format(pronoun, player.score))

        if not player.is_standing:
            print('-' * divider_size)
            print(', '.join([card.parity() for card in player.placed]))
            print('-' * divider_size)
            print(hand_repr)
            print('-' * divider_size)

        print()

    def _draw_hand(self, pool: [PazaakCard]) -> [PazaakCard]:
        """
        Return a list of PazaakCards representing a player's "hand".
        A hand is a set of cards that the player can use instead of a random draw.
        Example - if the hand has a +3 card, and player's current score is 17,
        play the +3 card to make 20.
        """
        return random.sample(pool, self._hand_size)

    def key(self) -> str:
        raise GameLogicError('PazaakGame object should not be a context key')

    def context(self) -> dict:
        return {
            Turn.PLAYER: self.player,
            Turn.OPPONENT: self.opponent,
        }

if __name__ == '__main__':
    pool = cards.random_cards(10, positive_only=False, bound=5)
    game = PazaakGame(pool)
    game.start()


import time

try:
    import boto3
except BaseException:
    boto3 = None

from .model import parse_verbosity
from .util import retry
from . import logs

class SQSQueue(object):

    def __init__(self, name, verbose=10, receive_timeout=300,
                 retry_time=10, region_name=None):
        assert boto3 is not None
        self._client = boto3.client('sqs', region_name=region_name)

        create_q_response = self._client.create_queue(
            QueueName=name)

        self._queue_url = create_q_response['QueueUrl']
        self.logger = logs.getLogger('SQSQueue')
        if verbose is not None:
            self.logger.setLevel(parse_verbosity(verbose))
        self._name = name
        self.logger.info('Creating SQS queue with name ' + name)
        self.logger.info('Queue url = ' + self._queue_url)

        self._receive_timeout = receive_timeout
        self._retry_time = retry_time

    def get_name(self):
        return self._name

    def clean(self, timeout=0):
        while True:
            msg = self.dequeue(timeout=timeout)
            if not msg:
                break

    def enqueue(self, msg):
        self.logger.debug("Sending message {} to queue with url {} "
                          .format(msg, self._queue_url))
        self._client.send_message(
            QueueUrl=self._queue_url,
            MessageBody=msg)

    def has_next(self):
        raise NotImplementedError(
            'Using has_next with distributed queue ' +
            'such as pubsub will bite you in the ass! ' +
            'Use dequeue with timeout instead')

        no_tries = 3
        for _ in range(no_tries):
            response = self._client.receive_message(
                QueueUrl=self._queue_url)

            if 'Messages' not in response.keys():
                time.sleep(5)
                continue
            else:
                break

        msgs = response.get('Messages', [])

        for m in msgs:
            self.logger.debug('Received message {} '.format(m['MessageId']))
            self.hold(m['ReceiptHandle'], 0)

        return any(msgs)

    def dequeue(self, acknowledge=True, timeout=0):
        wait_step = 1
        for waited in range(0, timeout + wait_step, wait_step):
            response = self._client.receive_message(
                QueueUrl=self._queue_url)
            msgs = response.get('Messages', [])
            if any(msgs):
                break
            elif waited == timeout:
                return None
            else:
                self.logger.info(
                    ('No messages found, sleeping for {} ' +
                     ' (total sleep time {})').format(wait_step, waited))
                time.sleep(wait_step)

        msgs = response['Messages']

        if not any(msgs):
            return None

        retval = msgs[0]

        if acknowledge:
            self.acknowledge(retval['ReceiptHandle'])
            self.logger.debug("Message {} received and acknowledged"
                              .format(retval['MessageId']))

            return retval['Body']
        else:
            self.logger.debug("Message {} received, ack_id {}"
                              .format(retval['MessageId'],
                                      retval['ReceiptHandle']))
            return (retval['Body'], retval['ReceiptHandle'])

    def acknowledge(self, ack_id):
        retry(lambda: self._client.delete_message(
            QueueUrl=self._queue_url,
            ReceiptHandle=ack_id),

            sleep_time=10, logger=self.logger)

    def hold(self, ack_id, minutes):
        self._client.change_message_visibility(
            QueueUrl=self._queue_url,
            ReceiptHandle=ack_id,
            VisibilityTimeout=int(minutes * 60))

    def delete(self):
        self._client.delete_queue(QueueUrl=self._queue_url)


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import Select
import time
import re

ontologyElement = {}

def runQuery(browser):
#    runOk = browser.find_element(By.ID, "yui-gen5-button")
    runOk = browser.find_element(By.ID, "yui-gen9-button")
    runOk.click()

def pickQueryType(browser, queryTypeList):
    runQuery = browser.find_element(By.ID, "runBox")
    runQuery.click()

    if len(queryTypeList) > 0:
        for queryType in queryTypeList:
            print (queryType)
            currentDivElement = browser.find_element(By.ID, queryType)
            print (currentDivElement.get_attribute('value'))
            currentElement = currentDivElement.find_element(By.TAG_NAME, 'input')
            print (currentElement.get_attribute('value'))
            currentElement.click()

# Open each of the Ontology tree nodes until you get to the desired element
def traverseOntology(browser, nodeStrings):
    global currentElement
    nodeCnt = 0
    for currentNode in nodeStrings:
        print ('Current Node: ' , currentNode)
        #Find all the visible concepts
        '''
        try:
            element = WebDriverWait(browser, 30).until(
                EC.presence_of_element_located((By.CLASS_NAME, "sdxDefaultCONCPT")))
                #EC.presence_of_element_located((By.ID, "myDynamicElement")))
        finally:
            print('Still not visible')
        '''

        sdxConcepts = browser.find_elements(By.CLASS_NAME, "sdxDefaultCONCPT")

        #Add them to a dictionary
        print('Add more nodes...');
        for sdxConcept in sdxConcepts:
            print("sdxConcepts: %s" % sdxConcept.text)
            ontologyElement[sdxConcept.text] = sdxConcept
        #Find the concept that corresponds to your 1st click open it
        print('Open...', currentNode)
        currentElement = ontologyElement[currentNode]
        if ( nodeCnt < len(nodeStrings)):
            currentElement.click()
        nodeCnt = nodeCnt + 1
        time.sleep(5) #webdriver wait does not seem to be working
    #return the last element
    return currentElement

# Open each of the Ontology tree nodes until you get to the desired element
def findValueByExclusion(browser):
    global currentElement
    elementCnt = 0
    tagElements = browser.find_elements(By.TAG_NAME, "tr")

    #Add them to a dictionary
    print('Add more nodes...');
    for tagElement in tagElements:
        print("tagElement Text: %s" % tagElement.text)
'''
        ontologyElement[sdxConcept.text] = sdxConcept
        #Find the concept that corresponds to your 1st click open it
        print('Open...', currentNode)
        currentElement = ontologyElement[currentNode]
        if ( nodeCnt < len(nodeStrings)):
            currentElement.click()
        nodeCnt = nodeCnt + 1
        time.sleep(5) #webdriver wait does not seem to be working
    #return the last element
    return currentElement
'''

# Find the first numerical text
def findValueByNumberOnly(browser, tag_name):
    global currentElement
    elementCnt = 0
    tagElements = browser.find_elements(By.TAG_NAME, tag_name)

    #Add them to a dictionary
    print('Add more nodes...');
    for tagElement in tagElements:
        print("tagElement Text: %s" % tagElement.text)
        if tagElement.text.isnumeric() == True:
            return int(tagElement.text)
    return -1

# use regular expression on innerhtml to find what you are looking for
# This is used because the use of ids and tags is pretty inconsistent
# in the interface
def findValuesByRegularExpression(browser, regExpressions):
    #print ('Element: ' , browser.get_attribute('innerHTML'))
    theText = browser.get_attribute('innerHTML')
    for regExpression in regExpressions:
        print ('Reg Ex: ' ,regExpression)
        value = findValueByRegularExpression(theText, regExpression, 1)
        print ('Value: ' , value)

def findValueByRegularExpression(theText, regularExpression, matchGroup):
    #print ('Element: ' , browser.get_attribute('innerHTML'))
    #print ('Reg Ex: ' ,regularExpression)
    match = re.search(regularExpression, theText )
    if match:
        print('Match: ', match.group(matchGroup))
        return match.group(matchGroup)
    return -1 #NO MATCH

'''
    #Add them to a dictionary
    print('Add more nodes...');
    for tagElement in tagElements:
        print("tagElement Text: %s" % tagElement.getElementName())
        match = re.search(regularExpression, tagElement.getText())
        if match:
            print('Match: ', tagElement.text)
    return -1
'''

browser = webdriver.Chrome()
browser.implicitly_wait(10) # seconds
#browser.get('https://i2b2.act.pitt.edu/webclient/')
browser.get('https://dbmi-ncats-test02.dbmi.pitt.edu/webclient/')
print("Done waiting")
browser.find_element_by_id("loginusr").send_keys(Keys.CONTROL, "a")
browser.find_element_by_id("loginusr").send_keys('username')
browser.find_element_by_id("loginpass").send_keys(Keys.CONTROL, "a")
browser.find_element_by_id("loginpass").send_keys('passwd'+ Keys.RETURN)
nodeStrings = ['ACT Demographics','Race','Asian']
time.sleep(5)

#Drag term to panel
currentNode = traverseOntology(browser, nodeStrings)
queryPanel1 = browser.find_element(By.ID, "QPD1")
ActionChains(browser).drag_and_drop(currentNode, queryPanel1).perform()

#infoQueryStatusText
#Number of patients for 'query name'
#patient_count:

# Select Query Topic
#queryTopicSelect = Select(browser.find_element(By.ID, "queryTopicSelect"))
#queryTopicSelect.select_by_visible_text("Test Pitt Query")

#Run query popup
'''value PATIENT_GENDER_COUNT_XML id crcDlgResultOutputPATIENT_GENDER_COUNT_XML
PATIENT_VITALSTATUS_COUNT_XML
PATIENT_RACE_COUNT_XML
PATIENT_AGE_COUNT_XML
'''
queryTypeList = ['crcDlgResultOutputPATIENT_GENDER_COUNT_XML',
                 'crcDlgResultOutputPATIENT_VITALSTATUS_COUNT_XML',
                 'crcDlgResultOutputPATIENT_RACE_COUNT_XML',
                 'crcDlgResultOutputPATIENT_AGE_COUNT_XML']
pickQueryType(browser, queryTypeList)

#Name Query
runQuery(browser)

# try to find the answer
time.sleep(60)
answer = browser.find_element(By.ID, "chart0")
print(answer.find_element_by_tag_name("tr").text)
findValueByExclusion(answer)
answerNumber = findValueByNumberOnly(answer, 'tr')
print('Query Result',answerNumber)
showQueryStatus = browser.find_element(By.ID, "infoQueryStatusText")
#print('showQueryStatus: ', showQueryStatus.get_attribute('innerHTML'))
#endDateMillsecElem = browser.find_element(By.ID, "endDateMillsecElem")
#print('endDateMillsecElem: ', endDateMillsecElem.get_attribute('innerHTML'))

time.sleep(60)
#findValueByRegularExpression(showQueryStatus, 'div', 'Compute Time: (\w*)')
regExprs = ('Compute Time: (\w*)','patient_count: <font color=\"#0000dd\">(\d*)')
findValuesByRegularExpression(showQueryStatus, regExprs)

'''
#drop Asian on 1st query panel
asian = ontologyElement['Asian']
queryPanel1 = browser.find_element(By.ID, "QPD1")
ActionChains(browser).drag_and_drop(asian, queryPanel1).perform()

# Select Query Topic
queryTopicSelect = Select(browser.find_element(By.ID, "queryTopicSelect"))
queryTopicSelect.select_by_visible_text("Test Pitt Query")

#Run query
runQuery = browser.find_element(By.ID, "runBox")
runQuery.click()
#runOk = browser.find_element(By.ID, "yui-gen5-button")
runOk = browser.find_element(By.ID, "yui-gen9-button")
runOk.click()
'''
# Run Query

#    sdxConcept.click()
#demographics = browser.find_element(By.ID, "ONT_TID-1")
#demographics.click()
#race = browser.find_element(By.ID, "ONT_TID-99")
#race.click()
#asian = browser.find_element(By.ID, "ONT_TID-103")

#ActionChains(browser).drag_and_drop(asian, queryPanel1).perform()

#for sdxConcept in sdxConcepts:
#    print("Value is: %s" % sdxConcept.get_attribute("value"))
#    sdxConcept.click()
'''
WebElement element = browser.findElement(By.name("source"));
WebElement target = browser.findElement(By.name("target"));

(new Actions(browser)).dragAndDrop(element, target).perform();
'''

'''
browser.find_element_by_name('loginForm').send_keys('test')

browser.switch_to.frame('_yuiResizeMonitor')
browser.find_element_by_id('loginusr').send_keys('test')

browser.find_element_by_class_name("input")
browser.find_element_by_id("loginusr").send_keys('username')
browser.find_element_by_id ('ID').send_keys('password')
browser.find_element_by_id('submit').click()

elem = browser.findElement(By.id("uname"));
#elem = browser.find_element_by_name('uname')  # Login
elem.send_keys('username' + Keys.RETURN)
elem = browser.find_element_by_name('input#loginpass')  # Login
elem.send_keys('password' + Keys.RETURN)
elem = browser.find_element_by_name('input')  # Login
elem.send_keys(Keys.RETURN)
'''
#browser.quit()
'''
male
250 icd9
e13 icd10
36 icd9p
03 icd10p
1012974 cpt
va med 161 acetam
loinc 2345-7
visit 2 days
inc e13 exc 250
01/01/2014 e08-e13 exclude 250 no date
male all breakdowns
retired 71010
'''

''' Make Methods
 Read in json that describes the test
--select
--breakdown
--set date
--set exclude
--add to more that one panel
--login
'''


import logging
from typing import Any
from typing import Callable

import requests
from requests import Response
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# fmt: off
# isort: off
# pylint: disable=unused-import
# Keep these imports so that our monkey patch of mailjet_rest allows
# its code to use `requests.exception` and get `RequestException`
# from this module.
from requests import RequestException
import requests.exceptions as exceptions
# pylint: enable=unused-import
# isort: on
# fmt: on

from pcapi import settings

logger = logging.getLogger(__name__)

REQUEST_TIMEOUT_IN_SECOND = 10

def _wrapper(request_func: Callable, method: str, url: str, log_at_error_level=True, **kwargs: Any) -> Response:
    timeout = kwargs.pop("timeout", REQUEST_TIMEOUT_IN_SECOND)
    try:
        response = request_func(method=method, url=url, timeout=timeout, **kwargs)
    except Exception as exc:
        # If the URL is not controlled by us, there is probably no
        # reason to send the error to Sentry. Logging an INFO message
        # is enough if we ever need to debug.
        if log_at_error_level:
            logger_method = logger.exception
        else:
            logger_method = logger.info
        logger_method("Call to external service failed with %s", exc, extra={"method": method, "url": url})
        raise exc
    else:
        logger.info(
            "External service called",
            extra={
                "url": response.url,
                "statusCode": response.status_code,
                "duration": response.elapsed.total_seconds(),
            },
        )

    return response

def get(url: str, **kwargs: Any) -> Response:
    with Session() as session:
        return session.request(method="GET", url=url, **kwargs)

def post(url: str, **kwargs: Any) -> Response:
    with Session() as session:
        return session.request(method="POST", url=url, **kwargs)

def put(url: str, **kwargs: Any) -> Response:
    with Session() as session:
        return session.request(method="PUT", url=url, **kwargs)

def delete(url: str, **kwargs: Any) -> Response:
    with Session() as session:
        return session.request(method="DELETE", url=url, **kwargs)

class _SessionMixin:
    def request(self, method: str, url: str, *args: Any, **kwargs: Any) -> Response:
        return _wrapper(super().request, method, url, *args, **kwargs)

class Session(_SessionMixin, requests.Session):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Only sets a retry strategy for safe verbs
        safe_retry_strategy = Retry(total=3, allowed_methods=["HEAD", "GET", "OPTIONS"])
        unsafe_retry_strategy = Retry(total=3)
        safe_adapter = HTTPAdapter(max_retries=safe_retry_strategy)
        unsafe_adapter = HTTPAdapter(max_retries=unsafe_retry_strategy)
        self.mount("https://www.demarches-simplifiees.fr", safe_adapter)
        if settings.JOUVE_API_DOMAIN:
            self.mount(settings.JOUVE_API_DOMAIN, safe_adapter)
        self.mount("https://api.mailjet.com", unsafe_adapter)


"""Evaluate the one-scale performance on MSCOCO dataset"""
import os
import argparse
import logging
import cv2
import matplotlib.pyplot as plt
import time
import warnings
import datetime
import numpy as np
import json
import torch
import torchvision
from pycocotools.coco import COCO
from pycocotools.cocoeval import COCOeval
import config
import data
import transforms
import models
import logs
from visualization import show
import decoder
from utils.util import AverageMeter

try:
    from apex.parallel import DistributedDataParallel as DDP
    from apex.fp16_utils import *
    from apex import amp
    import apex.optimizers as apex_optim
    from apex.multi_tensor_apply import multi_tensor_applier
except ImportError:
    raise ImportError(
        "Please install apex from https://www.github.com/nvidia/apex to run this example.")

# os.environ['CUDA_VISIBLE_DEVICES'] = "1"  # choose the available GPUs

LOG = logging.getLogger(__name__)

ANNOTATIONS_TRAIN = 'data/link2COCO2017/annotations/person_keypoints_train2017.json'
ANNOTATIONS_VAL = 'data/link2COCO2017/annotations/person_keypoints_val2017.json'
IMAGE_DIR_TRAIN = 'data/link2COCO2017/train2017'
IMAGE_DIR_VAL = 'data/link2COCO2017/val2017'

ANNOTATIONS_TESTDEV = 'data/link2COCO2017/annotations_trainval_info/image_info_test-dev2017.json'
ANNOTATIONS_TEST = 'data/link2COCO2017/annotations_trainval_info/image_info_test2017.json'
IMAGE_DIR_TEST = 'data/link2COCO2017/test2017/'

def evaluate_cli():
    parser = argparse.ArgumentParser(
        # __doc__: current module's annotation (or module.a_function's annotation)
        description=__doc__,
        # --help text with default values, e.g., gaussian threshold (default: 0.1)
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    logs.cli(parser)
    models.net_cli(parser)
    decoder.decoder_cli(parser)

    parser.add_argument('--dump-name',  # TODO: edit this name each evaluation
                        default='hourglass104_focal_l2_instance_l1_sqrt_epoch_77__distmax40_640_input_1scale_flip_hmpoff_gamma2_thre004',
                        type=str, help='detection file name')

    parser.add_argument('--dataset', choices=('val', 'test', 'test-dev'), default='val',
                        help='dataset to evaluate')
    parser.add_argument('--batch-size', default=8, type=int,
                        help='batch size')
    parser.add_argument('--long-edge', default=640, type=int,
                        help='long edge of input images')
    parser.add_argument('--fixed-height', action='store_true', default=False,
                        help='resize input images to the fixed height of long_edge')
    parser.add_argument('--flip-test', action='store_true', default=False,
                        help='flip augmentation during testing')
    parser.add_argument('--cat-flip-offset', action='store_true', default=False,
                        help='offset flip merge of increasing to 4D vector space')
    parser.add_argument('--loader-workers', default=8, type=int,
                        help='number of workers for data loading')
    parser.add_argument('--all-images', default=False, action='store_true',
                        help='run over all images irrespective of catIds')

    parser.add_argument('--resume', '-r', action='store_true', default=False,
                        help='resume from checkpoint')
    parser.add_argument('--checkpoint-path', '-p',
                        default='link2checkpoints_storage',
                        help='folder path checkpoint storage of the whole pose estimation model')
    parser.add_argument('--show-detected-poses', action='store_true', default=False,
                        help='show the final results')

    group = parser.add_argument_group('apex configuration')
    group.add_argument("--local_rank", default=0, type=int)
    # full precision O0  # mixture precision O1 # half precision O2
    group.add_argument('--opt-level', type=str, default='O2')
    group.add_argument('--keep-batchnorm-fp32', type=str, default=None)
    group.add_argument('--loss-scale', type=str, default=None)  # '1.0'
    # todo: channel last may lead to 22% speed up however not obvious here
    #  channels Last memory format is implemented for 4D NCWH Tensors only.
    group.add_argument('--channels-last', default=False, action='store_true',
                       help='channel last may lead to 22% speed up')
    group.add_argument('--print-freq', '-f', default=10, type=int, metavar='N',
                       help='print frequency (default: 10)')

    # args = parser.parse_args(
    #     '--checkpoint-whole link2checkpoints_storage/PoseNet_18_epoch.pth --resume --no-pretrain'.split())
    args = parser.parse_args()

    if args.dataset == 'val':
        args.image_dir = IMAGE_DIR_VAL
        args.annotation_file = ANNOTATIONS_VAL
    elif args.dataset == 'test':
        args.image_dir = IMAGE_DIR_TEST
        args.annotation_file = ANNOTATIONS_TEST
    elif args.dataset == 'test-dev':
        args.image_dir = IMAGE_DIR_TEST
        args.annotation_file = ANNOTATIONS_TESTDEV
    else:
        raise Exception

    if args.dataset in ('test', 'test-dev') and not args.all_images:
        print('force to use --all-images for this dataset because catIds are unknown')
        args.all_images = True

    return args

def run_images():
    result_keypoints = []
    result_image_ids = []

    print(f"\nopt_level = {args.opt_level}")
    print(f"keep_batchnorm_fp32 = {args.keep_batchnorm_fp32}")
    print(f"CUDNN VERSION: {torch.backends.cudnn.version()}\n")

    torch.backends.cudnn.benchmark = True
    # print(vars(args))
    args.pin_memory = False
    if torch.cuda.is_available():
        args.pin_memory = True

    args.world_size = 1

    if args.fixed_height:
        try:
            assert args.batch_size == 1
        except AssertionError:
            warnings.warn(f'forcibly fix the height of the input rgb_img to '
                          f'{args.long_edge: d} and set batch_size=1"')
            args.batch_size = 1

        preprocess_transformations = [
            transforms.NormalizeAnnotations(),
            # transforms.RescaleRelative(scale_factor=1),  # original input
            transforms.RescaleHighAbsolute(args.long_edge),
            transforms.RightDownPad(args.max_stride),
        ]
    else:
        LOG.info('you resize the longer edge of the input rgb_img to %d ', args.long_edge)
        preprocess_transformations = [
            transforms.NormalizeAnnotations(),
            transforms.RescaleLongAbsolute(args.long_edge),
            transforms.CenterPad(args.long_edge),
        ]

    preprocess_transformations += [
        transforms.ImageTransform(torchvision.transforms.ToTensor()),
        transforms.ImageTransform(
            torchvision.transforms.Normalize(mean=config.data_mean,
                                             std=config.data_std)),
    ]
    preprocess = transforms.Compose(preprocess_transformations)

    dataset = data.CocoKeypoints(
        args.image_dir,
        annFile=args.annotation_file,
        preprocess=preprocess,
        all_persons=True,  # we do not know if people are exitst in each rgb_img of test-dev
        all_images=args.all_images,
    )
    data_loader = torch.utils.data.DataLoader(
        dataset, batch_size=args.batch_size,
        pin_memory=args.pin_memory,
        num_workers=args.loader_workers,
        collate_fn=data.collate_images_anns_meta)

    model, _ = models.model_factory(args)

    model.cuda()  # .to(memory_format=torch.channels_last)

    if args.resume:
        model, _, start_epoch, best_loss, _ = models.networks.load_model(
            model, args.checkpoint_whole, optimizer=None, resume_optimizer=False,
            drop_layers=False, load_amp=False)

    processor = decoder.decoder_factory(args)

    # Initialize Amp.  Amp accepts either values or strings for the optional override arguments,
    # for convenient interpretation with argparse.
    # make processor as Module (rewrite forward method) and wrap it 测试后发现没有明显加速效果
    [model] = amp.initialize([model],  # , processor
                             opt_level=args.opt_level,
                             keep_batchnorm_fp32=args.keep_batchnorm_fp32,
                             loss_scale=args.loss_scale)

    model.eval()

    batch_time = AverageMeter()
    end = time.time()  # Notice: CenterNet 和 pifpaf 应该没有包含数据加载的时间，所以确认一下这个计时，考虑换个位置
    for batch_idx, (images, annos, metas) in enumerate(data_loader):

        images = images.cuda(non_blocking=True)  # .to(memory_format=memory_format)

        if args.flip_test:
            images = torch.cat((images, torch.flip(images, [-1])))  # images tensor shape = (N, 3, H, W)

        with torch.no_grad():
            outputs = model(images)  # outputs of multiple headnets

        # post-processing for generating individual poses
        batch_poses = processor.generate_poses(
            outputs,
            flip_test=args.flip_test,
            cat_flip_offs=args.cat_flip_offset
        )

        # #########################################################################
        # ############# inverse the keypoint into the original rgb_img space ############
        # #########################################################################
        for index, (image_poses, image_meta) in enumerate(zip(batch_poses, metas)):
            subset = preprocess.annotations_inverse(image_poses, image_meta)
            batch_poses[index] = subset  # numpy array [M * [ 17 * [x, y, v, s, limb_score, ind]]]

            image_id = image_meta['image_id']

            # #########################################################################
            # ############# collect the detected person poses and rgb_img ids ###########
            # #########################################################################
            result_image_ids.append(image_id)
            # last dim of subset: [x, y, v, s, limb_score, ind]
            subset[:, :, :2] = np.around(subset[:, :, :2], 2)
            for i, person in enumerate(subset.astype(float)):
                keypoints_list = []
                v = []
                for xyv in person[:, :3]:
                    v.append(xyv[2])
                    keypoints_list += [
                        xyv[0], xyv[1], 1 if xyv[0] > 0 or xyv[1] > 0 else 0
                    ]

                result_keypoints.append({
                    'image_id': image_id,
                    'category_id': 1,  # person category
                    'keypoints': keypoints_list,
                    'score': sum(v) / len(v),
                    #  the criterion of person pose score
                    #  we actually did at decoder.group.GreedyGroup._delete_sort
                })

            # force at least one annotation per rgb_img following PIFPAF
            # but make no difference to the result
            if not len(subset):
                result_keypoints.append({
                    'image_id': image_id,
                    'category_id': 1,
                    'keypoints': np.zeros((17 * 3,)).tolist(),
                    'score': 0.01,
                })

        if args.show_detected_poses:
            image_poses = batch_poses[0]

            image_path = metas[0]['image_path']
            orig_img = cv2.imread(image_path)
            rgb_img = cv2.cvtColor(orig_img, cv2.COLOR_BGR2RGB)
            skeleton = processor.skeleton
            keypoint_painter = show.KeypointPainter(
                show_box=False,
                # color_connections=True, linewidth=5,
            )
            with show.image_canvas(rgb_img,
                                   # output_path + '.keypoints.png',
                                   show=True,
                                   # fig_width=args.figure_width,
                                   # dpi_factor=args.dpi_factor
                                   ) as ax:
                keypoint_painter.keypoints(ax, image_poses[:, :, :3], skeleton=skeleton)

        if batch_idx % args.print_freq == 0:
            # to_python_float incurs a host<->device sync
            torch.cuda.synchronize()
            batch_time.update((time.time() - end) / args.print_freq)
            end = time.time()

            print('==================> Epoch: [{0}][{1}/{2}]\t'
                  'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
                  'Speed {3:.3f} ({4:.3f}) <================ \t'.format(
                0, batch_idx, len(data_loader),
                args.world_size * args.batch_size / batch_time.val,
                args.world_size * args.batch_size / batch_time.avg,
                batch_time=batch_time))

    return result_keypoints, result_image_ids

def validation(annFile, dump_name, dataset):
    prefix = 'person_keypoints'

    dataDir = 'data/link2COCO2017'

    print(annFile)
    cocoGt = COCO(annFile)

    resFile = '%s/results/%s_%s_%s_results.json'
    resFile = resFile % (dataDir, prefix, dataset, dump_name)
    print('======================>')
    print('The path of detected keypoint file is: ', resFile)
    os.makedirs(os.path.dirname(resFile), exist_ok=True)

    results_keypoints, validation_ids = run_images()

    json.dump(results_keypoints, open(resFile, 'w'))

    # ####################  COCO Evaluation ################
    cocoDt = cocoGt.loadRes(resFile)
    cocoEval = COCOeval(cocoGt, cocoDt, iouType='keypoints')
    cocoEval.params.imgIds = validation_ids  # only part of the person images are evaluated
    cocoEval.evaluate()
    cocoEval.accumulate()
    cocoEval.summarize()
    return cocoEval

if __name__ == '__main__':
    log_level = logging.INFO  # logging.DEBUG
    # set RootLogger
    logging.basicConfig(
        level=log_level,
    )

    global best_loss, args
    best_loss = float('inf')
    args = evaluate_cli()

    print(args.dump_name)   # todo: 添加 NN inference 和 decoding time记录
    eval_result_original = validation(args.annotation_file,
                                      dump_name=args.dump_name,
                                      dataset=args.dataset)
    print('\nEvaluation finished!')


#jawaban no 1
def remove_outlier(data):
    dataSorted = sorted(data)
    mid = len(data) // 2
    data1 = dataSorted[0 : mid]
    data3 = dataSorted[-mid: ]
    if (len(data1) % 2 != 0):
        q1 = data1[len(data1)//2]
    else:
        q1 = (data1[len(data1)//2] + (data1[(len(data1)//2)-1])) / 2
    if (len(data3) % 2 != 0):
        q3 = data3[len(data3)//2]
    else:
        q3 = (data3[len(data3)//2] + (data3[(len(data3)//2)-1])) / 2
    IQR = q3 - q1
    lower_limit = q1 - (1.5*IQR)
    upper_limit = q3 + (1.5*IQR)
    newdata = []
    for item in data:
        if(item > lower_limit and item < upper_limit):
            newdata.append(item)
    print('data asli adalah {}'.format(data))
    print('data setelah di sort {}'.format(dataSorted))
    print('setengah data pertama {}'.format(data1))
    print('setengah data kedua {}'.format(data3))
    print('upper limit adalah {}'.format(upper_limit))
    print('lower limit adalah {}'.format(lower_limit))
    print('data yang tidak outlier adalah = {}'.format(newdata))

remove_outlier([71, 70, 73, 70, 70, 69, 70, 72, 71, 300, 71, 69])

#jawaban no 2
def count_vowel(words):
    jumlah_vowel = 0
    vowel = 'aiueo'
    for item in words:
        if(item.lower() in vowel):
            jumlah_vowel += 1
    print(jumlah_vowel)

count_vowel('budi pergi ke pasar')

#jawaban no 3
def given(num_list):
    new_list = []
    for item in num_list:
        for element in item:
            new_list.append(element)
            new_list.sort()
    print(new_list)

given([[3, 2, 1], [4, 6, 5], [], [9, 7, 8]])

#jawaban no 4
def countwords(words):
    wordlist = words.split(' ')
    count_dict = {}
    for item in wordlist:
        if(item in count_dict.keys()):
            count_dict[item] += 1
        else:
            count_dict[item] = 1
    for key, value in count_dict.items():
        print("Jumlah kata '{}' ada sebanyak {}".format(key.capitalize() , value))

countwords('jangan jangan kamu adalah aku')

1st Exam - Python Fundamental/pembahasan.py


import tensorflow as tf
from tensorflow import keras
from keras import initializers
from keras.layers import Dense

class TS_Model(keras.Model):
    def __init__(self, m_i, m_h, m_o, seed=42, special_init=True):
        super().__init__()
        tf.random.set_seed(seed)
        if special_init:
            init = initializers.RandomUniform(minval=-1, maxval=1)
            kwargs = {'kernel_initializer': init,
                      'bias_initializer': init}
        else:
            kwargs = {}

        self.m_i = m_i
        self.h_lay = Dense(m_h,
                           activation='relu',
                           **kwargs)
        self.out_lay = Dense(m_o,
                             **kwargs)

    def call(self, x):
        x = self.h_lay(x)
        return self.out_lay(x)