import shutil
import os
import re
from pathlib import Path

from .log import logger, is_debug
from .dwhrepo import repo
from .snowflake import sf
from .release import release
from .sql import print_sql, sql_meta, get_diff_sql, statement_cleanup
from .utils import get_file_contents
from .config import config

class Model():
    """Handles model .sql definitions."""

    MODEL_DIR    = config.read_config('model_dir', default='model')
    EXTENSIONS   = re.compile(r'.*(\.sql)|(\.vw)|(\.tbl)$', re.I)
    DIFF_DIR     = ".diff"

    def __init__(self):
        self.sf_safe_branch  = repo.get_sf_safe_branch()

    def prepare_release_candidate(self, force):
        """Prepares a release candidate file (if missing)."""
        repo.assert_repo()
        commit_hash = release.get_base_commit(self.sf_safe_branch)
        release.check_release_dir_clean(base_commit=commit_hash)

        files = repo.get_changed_files(index=commit_hash,
                prefix=Model.MODEL_DIR)

        if len(files) == 0:
            logger.info(f"No changes in {Model.MODEL_DIR} dir to prepare release candidate "
                    "file. Preparing empty file.")

        if force:
            logger.info("Not checking if release candidate file was changed due to --force.")
        else:
            release.check_release_candidate()

        branch = repo.get_branch()

        release_candidate_sql = f"--.Release candidate file, branch: {branch}\n\n"
        for change in files.values():
            release_candidate_sql += Model._change_into_release_entry(change, commit_hash)

        release.save_release_candidate_file(release_candidate_sql, branch)
        logger.debug("Release candidate file contents:\n" + release_candidate_sql)

    def deploy_release(self, dry_run=True):
        release_sql = release.prepare_release_file()
        deploy_sql = release.release_file_to_sql(release_sql)

        if is_debug():
            print_sql(deploy_sql)
        if dry_run:
            if not is_debug():
                print_sql(deploy_sql)
            logger.info("Skipping SQL execution due to --dry-run.")
            return

        sf.perform_release(deploy_sql, self.sf_safe_branch)
        release.save_release(release_sql)

        pass

    def clone_production(self, force):
        """Clones production database into new db named after branch name."""
        sf.clone_production(self.sf_safe_branch, force)

    def compare_sf_git(self, branch=None):
        """Compares Snowflake and current branch DDLs."""

        if branch is None:
            branch = self.sf_safe_branch

        git_ddls = self.get_all_ddls()
        sf_ddls = sf.get_all_objects(branch)

        logger.info("| {:_^39.39} | {:_^11.11} | {:_^30.30} | {:_^16.16} |".format(
           'object name', 'type', 'GIT file name', 'last change on SF'))

        for name in sorted(git_ddls.keys() | sf_ddls.keys()):
            o_name = git_ddls.get(name, sf_ddls.get(name))[0]
            o_type = git_ddls.get(name, sf_ddls.get(name))[1]
            o_file = git_ddls.get(name, (None, None, '! MISSING !'))[2][-30:]
            o_date = sf_ddls.get(name, (None, None, None))[2]
            o_date = f"{o_date:%Y-%m-%d %H:%M}" if o_date else '! MISSING !'

            logger.info(f"| {o_name:<39.39} | {o_type:<11.11} | {o_file:^30.30} | {o_date:^16.16} |")

    def compare_single_file(self, filename, branch=None):
        if branch is None:
            branch = self.sf_safe_branch
        if not self.EXTENSIONS.search(filename):
            logger.info(f"{filename} is not a SQL file. Running global comparison.")
            self.compare_sf_git(branch=branch)
            return

        o_name, o_type, easy_ddl, git_ddl = sql_meta(filename)
        sf_ddl = sf.get_ddl(branch, o_type, o_name)

        if not os.path.exists(self.DIFF_DIR):
            os.makedirs(self.DIFF_DIR)
        sf_filename = os.path.join(self.DIFF_DIR, os.path.basename(filename))
        with open(sf_filename, 'w') as sf_file:
            sf_file.write("-- Snowflake definition --\n")
            sf_file.write(statement_cleanup(sf_ddl))

        print_sql(git_ddl)
        print_sql(sf_ddl)

    def get_all_ddls(self):
        ddls = {}
        for f in Path(self.MODEL_DIR).rglob('*'):
            if self.EXTENSIONS.search(str(f)):
                o_name, o_type, easy_ddl, sql = sql_meta(str(f))
                ddls[(o_type + '#' + o_name).upper()] = (o_name, o_type, str(f))
        return ddls

    @staticmethod
    def _change_into_release_entry(change, commit_hash):
        """Converts a git.change of a file into a release candidate entry (string)."""
        change_type = change.change_type
        filename = change.a_path if change_type == 'D' else change.b_path
        if change_type != 'D':
            o_name, o_type, easy_ddl, sql = sql_meta(filename)

        if change_type == 'D':
            # dropped file/object
            return (f"--.File was removed and *will not* be included in the release.\n"
                    f"-- [{change_type}] NOT_INCLUDED:{filename}\n\n"
                    f"   You have to include a DROP statement to properly sync database state:\n"
                    f"   {release.HERE_STMT}\n\n")
        elif change_type == 'R':
            if easy_ddl:
                return (f"--.File with {o_type} definition was renamed and will be included in the release.\n"
                        f"-- [{change_type}] INCLUDED:{filename}\n\n"
                        f"   If you renamed the object, remember to drop the old one:\n"
                        f"   DROP {o_type} <<OLD_NAME>>; {release.HERE_STMT}\n\n")
            # rename table or stream
            return (f"--.File with {o_type} definition was renamed and *will not* be included in the release.\n"
                    f"-- [{change_type}] NOT_INCLUDED:{filename}\n\n"
                    f"   You may need to include an ALTER {o_type} RENAME statement to properly sync database state:\n"
                    f"   ALTER {o_type} <<OLD_NAME>> RENAME {o_name}; {release.HERE_STMT}\n\n")
        elif change_type == 'A':
            # add new object
            return Model._new_file_into_release_entry(change_type, easy_ddl, filename, o_name, o_type, sql)
        elif change_type == 'M':
            if easy_ddl:
                # modification / non table/stream
                return (f"--.File was changed and will be included in the release.\n"
                        f"--.You can change the order of the INCLUDE: statement below.\n"
                        f"-- [{change_type}] INCLUDED:{filename}\n\n")
            # modification / table/stream
            sql_diff = repo.get_file_diff(commit_hash, filename)
            return (f"--.File was changed but *will not be* included in the release.\n"
                    f"-- [{change_type}] NOT_INCLUDED:{filename}\n"
                    f"{sql_diff}\n"
                    f"   You may need to include an ALTER {o_type} statement to properly sync database state:\n"
                    +(f"   SELECT 1/IFF(COUNT(*)>0, 0, 1) FROM {o_name}; -- this will fail if stream is non empty\n" if o_type == 'STREAM' else '')
                    + f"   ALTER {o_type} {o_name} {release.HERE_STMT};\n\n")
        else:
            return (f"--.I don't understand this change and it it *will not* be included in the release.\n"
                    f"-- [{change_type}] NOT_INCLUDED:{filename}\n\n"
                    f"   You have to manually apply changes made in file listed above.\n"
                    f"   {release.HERE_STMT}\n\n")
    @staticmethod
    def _new_file_into_release_entry(change_type, easy_ddl, filename, o_name, o_type, sql):
        if easy_ddl:
            return (f"--.File was added and will be included in the release.\n"
                    f"--.You can change the order of the INCLUDE: statements below.\n"
                    f"-- [{change_type}] INCLUDED:{filename}\n\n")

        try:
            ddl = sf.get_ddl(repo.get_branch(), o_type, o_name)
        except RuntimeError as e:
            if 'does not exist' not in str(e):
                raise
            return (f"--.File with {o_type} definition was added and {o_name} does not exist on the server.\n"
                    f"--.It will be included in the release.\n"
                    f"--.You can change the order of the INCLUDE: statements below.\n"
                    f"-- [{change_type}] INCLUDED:{filename}\n\n")

        logger.warning(f"New CREATE {o_type} definition found in {filename}, but {o_name} already exists on the server.")
        sql_diff = get_diff_sql(ddl, sql, f"{o_type} {o_name} definition on the server",
                f"{o_type} {o_name} from {filename}")

        return (f"--.File with {o_type} definition was added but {o_name} *exists* on the server.\n"
                f"-- [{change_type}] NOT_INCLUDED:{filename}\n"
                f"{sql_diff}\n"
                f"   Double check if {o_type} definition on the server matches file contents. {release.HERE_STMT}\n"
                f"   SELECT '{o_type} {o_name} already exists on the server';\n\n")

model = Model()


#!/usr/bin/python

import argparse
import colorama
from colorama import Fore, Back, Style
import emoji
import os
import random
import yaml

colorama.init(autoreset=True)
bgcolors = [Back.RED, Back.GREEN, Back.YELLOW, Back.BLUE, Back.MAGENTA, Back.CYAN]
emojis = [':thumbs_up:', ':v:', ':revolving_hearts:', ':sparkling_heart:', ':laughing:',
          ':blush:', ':grinning:', ':stuck_out_tongue:', ':stuck_out_tongue_closed_eyes:',
          ':star2:', ':smile_cat:', ':heart_eyes_cat:', ':monkey_face:', ':hibiscus:',
          ':tulip:', ':balloon:', ':white_check_mark:', ':heart_decoration:',
          ':ice_cream:', ':icecream:', ':birthday:', ':ribbon:', ':gift:', ':rabbit:',
          ':baby_chick:', ':panda_face:', ':bear:', ':dog:', ':joy_cat:']

def get_options():
    parser = argparse.ArgumentParser()
    parser.add_argument('--config', help='a configuration file in YAML format')
    args = parser.parse_args()

    options = {'name': '',
               'count': 20,
               'operands': range(2, 10),
               'addition_range': range(101,1000),
               'operations': ['mul', 'div'],
               'bigmulmaxop1': 999,
               'bigmulmaxop2': 9}

    if args.config:
        with open(args.config, 'r') as ymlfile:
            cfg = yaml.safe_load(ymlfile)

        if 'name' in cfg:
            options['name'] = cfg['name']
        if 'count' in cfg:
            options['count'] = int(cfg['count'])
        if 'operands' in cfg:
            options['operands'] = cfg['operands']
        if 'bigmulmaxop1' in cfg:
            options['bigmulmaxop1'] = int(cfg['bigmulmaxop1'])
        if 'bigmulmaxop2' in cfg:
            options['bigmulmaxop2'] = int(cfg['bigmulmaxop2'])
        if 'operations' in cfg:
            options['operations'] = cfg['operations']

    return options

def addition(addition_range):
    operands = [random.choice(addition_range), random.choice(addition_range)]
    answer = operands[0] + operands[1]
    problem = '%s\n+ %s\n  ___\n' % (str(operands[0]).rjust(5), str(operands[1]).rjust(3))
    get_and_check_solution(problem, answer)

def subtraction(addition_range):
    bigger = random.choice(addition_range)
    smaller = random.choice(range(1, bigger))
    answer = bigger - smaller
    problem = '%s\n- %s\n  ___' % (str(bigger).rjust(5), str(smaller).rjust(3))
    get_and_check_solution(problem, answer)

def multiplication(operands1, operands2):
    operands = [random.choice(operands1), random.choice(operands1)]
    product = operands[0] * operands[1]
    first = random.choice([0,1])
    second = 0 if first == 1 else 1

    variable = random.choice([0,4])
    if variable == 0:
        answer = operands[first]
        problem = '? X %d = %d' % (operands[second], product)
    elif variable == 1:
        answer = operands[second]
        problem = '%d X ? = %d' % (operands[first], product)
    else:
        answer = product
        problem = '%d X %d = ?' % (operands[first], operands[second])

    get_and_check_solution(problem, answer)

def big_multiplication(operands1, operands2):
    operands = [random.choice(operands1), random.choice(operands2)]
    answer = operands[0] * operands[1]
    problem = '%s\nX %s\n  ___' % (str(operands[0]).rjust(5), str(operands[1]).rjust(3))
    get_and_check_solution(problem, answer)

def zeroes_multiplication(operands):
    operands = [random.choice(operands), random.choice(range(1, 11))]
    operands[0] = operands[0] * (10 ** random.choice(range(0, 3)))
    operands[1] = operands[1] * (10 ** random.choice(range(0, 3)))
    answer = operands[0] * operands[1]
    problem = '%d X %d = ?' % (operands[0], operands[1])
    get_and_check_solution(problem, answer)

def division(operands):
    operands = [random.choice(operands), random.choice(range(1, 11))]
    product = operands[0] * operands[1]
    first = random.choice([0,1])
    second = 0 if first == 1 else 1

    answer = operands[second]
    problem = '%d : %d = ?\t' % (product, operands[first])
    get_and_check_solution(problem, answer)

def division_remainder(operands):
    operands = [random.choice(operands), random.choice(range(1, 11))]
    product = operands[0] * operands[1]
    first = random.choice([0,1])
    second = 0 if first == 1 else 1
    remainder = random.choice(range(0, operands[first]))
    product += remainder
    problem = '%d : %d = %d\tRemainder: ?' % (product, operands[first], operands[second])
    get_and_check_solution(problem, remainder)

def fraction_string(whole_number, numerator, denominator):
    filled = u'\u25AE'
    unfilled = u'\u25AF'

    s = ""
    for i in range(0, whole_number):
        for j in range(0, denominator):
            s = s + filled
        s = s + '  '

    for i in range(0, numerator):
        s = s + filled
    for i in range(0, denominator - numerator):
        s = s + unfilled

    return s

def fraction_identify():
    whole_number = random.choice(range(1, 5))
    denominator = random.choice(range(2, 10))
    numerator = random.choice(range(1, denominator))
    filled = u'\u25AE'
    unfilled = u'\u25AF'

    problem = fraction_string(whole_number, numerator, denominator)

    get_and_check_solution(problem, '%s %s/%s' % (whole_number, numerator, denominator), answer_type=str)

def fraction_conversion():
    whole_number = random.choice(range(1, 5))
    denominator = random.choice(range(2, 10))
    numerator = random.choice(range(1, denominator))
    improper_numerator = (whole_number * denominator) + numerator
    to_improper = random.choice([0, 1])

    print(fraction_string(whole_number, numerator, denominator))

    if to_improper == 1:
        get_and_check_solution('%d %d/%d = ?' % (whole_number, numerator, denominator), '%s/%s' % (improper_numerator, denominator), answer_type=str)
    else:
        get_and_check_solution('%d/%d = ?' % (improper_numerator, denominator), '%s %s/%s' % (whole_number, numerator, denominator), answer_type=str)

def get_and_check_solution(problem, answer, answer_type=int):
    attempt = -1
    while attempt != answer:
        attempt = input(random.choice(bgcolors) + problem + Style.RESET_ALL + '\n')
        try:
            attempt = answer_type(attempt)
        except:
            attempt = -1

        if attempt != answer:
            print('')

def main():
    options = get_options()
    i = 0
    while i < int(options['count']):
        op = random.choice(options['operations'])

        if op == 'add':
            addition(options['addition_range'])
        elif op == 'sub':
            subtraction(options['addition_range'])
        elif op == 'mul':
            multiplication(options['operands'], range(1, 11))
        elif op == 'bigmul':
            big_multiplication(range(2,options['bigmulmaxop1']), range(2,options['bigmulmaxop2']))
        elif op == 'zeroesmul':
            zeroes_multiplication(options['operands'])
        elif op == 'div':
            division(options['operands'])
        elif op == 'devrem':
            division_remainder(options['operands'])
        elif op == 'fracident':
            fraction_identify()
        elif op == 'fracconv':
            fraction_conversion()
        else:
            continue

        print(emoji.emojize(random.choice(emojis), use_aliases=True) +
            ' ' + str(int(options['count']) - i - 1) + ' left\n')
        i = i + 1

    print('Great job ' + options['name'] + '!!!')

if __name__ == "__main__":
    main()


from typing import List

class Solution:
    """
    problem statement : https://leetcode.com/problems/find-peak-element/
    self-written solution with linear time complexity O(n)
    """

    def findPeakElement(self, nums: List[int]) -> int:
        # Initialising maximum to first element in the list
        maxima = nums[0]
        output = 0
        for i in range(1, len(nums[1:]) + 1):
            if nums[i] > maxima:
                maxima = nums[i]
                output = i
        return output

if __name__ == "__main__":
    print(Solution().findPeakElement(nums=[1,2]))


from fastapi import FastAPI, status
# from starlette import status #上面的status继承自这

app = FastAPI()

#post
@app.post("/items/", status_code=201)
async def create_item(name: str):
    return {"name": name}

#get
@app.get("/items2/", status_code=201)
async def create_item2(name: str):
    return {"name": name}

#
@app.post("/items3/", status_code=status.HTTP_404_NOT_FOUND)#不一定写数字,也定义了意思常量
async def create_item3(name: str):
    print('HTTP_404:', status.HTTP_404_NOT_FOUND)
    return {"name": name}

#
@app.get("/i/", status_code=status.HTTP_404_NOT_FOUND)
async def i(name: str):
    print('HTTP_404:', status.HTTP_404_NOT_FOUND)
    return {"name": name}

if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)

D_响应状态码与错误处理/d016_响应状态码.py


import importlib
import torch.utils.data
from torch.utils.data._utils.collate import default_collate
import numpy as np

from data.base_dataset import BaseDataset
from tools.utils import get_vprint

def find_dataset_using_name(dataset_name):
    # Given the option --dataset [datasetname],
    # the file "datasets/datasetname_dataset.py"
    # will be imported.
    dataset_filename = "data." + dataset_name + "_dataset"
    datasetlib = importlib.import_module(dataset_filename)

    # In the file, the class called DatasetNameDataset() will
    # be instantiated. It has to be a subclass of BaseDataset,
    # and it is case-insensitive.
    dataset = None
    target_dataset_name = dataset_name.replace('_', '') + 'dataset'
    for name, cls in datasetlib.__dict__.items():
        if name.lower() == target_dataset_name.lower() \
           and issubclass(cls, BaseDataset):
            dataset = cls

    if dataset is None:
        raise ValueError(f"In {dataset_filename}.py, there should be a subclass of BaseDataset "
                         f"with class name that matches {target_dataset_name} in lowercase.")

    return dataset

def create_dataset(opt, phase='train', fold=None, from_vid=False, load_vid=False, verbose=True):
    dataset = find_dataset_using_name(opt.dataset)
    instance = dataset(opt, phase=phase, fold=fold, from_vid=from_vid, load_vid=load_vid, verbose=verbose)
    file_type = "video" if from_vid else "img"
    load_type = "video" if load_vid else "img"
    vprint = get_vprint(verbose)
    fold_str = f"-{fold}" if fold is not None else ""
    vprint(f"Creation of dataset [{type(instance).__name__}-{phase}{fold_str}] of size {len(instance)} "
           f"loading {load_type} data from {file_type} data")
    return instance

def create_dataloader(dataset, batch_size, num_workers, is_train):
    dataloader = torch.utils.data.DataLoader(
        dataset,
        batch_size=batch_size,
        shuffle=is_train,
        num_workers=num_workers,
        drop_last=is_train,
        worker_init_fn=lambda _: np.random.seed(),
        collate_fn=custom_collate_fn
    )
    return dataloader

def custom_collate_fn(batch):
    input_dict = {}
    elem = batch[0]
    for key in elem:
        if key in ["img", "mask_img", "flow_img", "layout"] and elem[key].ndim == 4:
            input_dict[key] = torch.cat([d[key] for d in batch], dim=0)
        else:
            input_dict[key] = default_collate([d[key] for d in batch])
    return input_dict


from flask import g, flash

from bluecat.api_exception import PortalException
import config.default_config as config
from bluecat.util import safe_str

def get_acls(**kwargs):
    """
    Retrieve all ACLs from default configuration
    :return: All ACLs in default configuration
    """
    # Use the default result template to store results
    result = []

    # Retrieve the configuration object
    try:
        configuration = g.user.get_api().get_configuration(config.default_configuration)
    except PortalException as e:
        g.user.logger.error('%s' % e, msg_type=g.user.logger.EXCEPTION)
        flash('Configuration %s could not be retrieved from the Gateway configuration' % config.default_configuration)
        return result

    # Retrieve list of ACLs from configuration
    acls = configuration.get_children_of_type('ACL')

    # Loop through ACLs appending to result dictionary
    for acl in acls:
        result.append((acl.get_id(), safe_str(acl.get_name())))

    return result


# -*- coding: utf-8 -*-
"""
Created on Fri Jan 10 12:56:54 2020

@author: -
"""

#######################################################################

# Moving Average Forecasting

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pandas_datareader as pdr

stock_hist = pdr.get_data_yahoo('ORCL', start = '2015-01-01')
# get rid of Adj Close
stock_hist = stock_hist.drop('Adj Close', axis=1)
# round to 2 decimal places
stock_hist = round(stock_hist,2)

# create 5 day average
# stock_hist['5-day'] = stock_hist['Close'].rolling(5).mean()

# print(stock_hist)

# this assumes you aready know the closing price which we do not
# so we have to use shift()
# roll forecast foward one period.
stock_hist['5-day'] = stock_hist['Close'].rolling(5).mean().shift()

# print(stock_hist)

# plot 5-day alongside close.
plt.plot(stock_hist['Close'][-120:])
plt.plot(stock_hist['5-day'][-120:])

# so we are off a little since the end of the graph does not line up

# put in error measure
# Mean Absolute Deviation
stock_hist['MAD'] = np.abs(stock_hist['Close'] - stock_hist['5-day'])

print('Mean Absolute Deviation')
print(stock_hist['MAD'].mean())
# this shows how much you are off in dollars positive or negative

# account for the scaling of the data we are using
# Mean Absolute Percent Error
stock_hist['MAPE'] = stock_hist['MAD'] / stock_hist['Close']
print('Mean Absolute Percent Error')
print(stock_hist['MAPE'].mean())

# Mean Square Error
# this resembles the variance and therefore the std dev
stock_hist['MSE'] = stock_hist['MAD'] ** 2
print('Mean Square Error')
print(stock_hist['MSE'].mean())
# This is the square as the name implies

MSE = stock_hist['MSE'].mean()

RMSE = np.sqrt(MSE)
print('Relative Mean Square Error')
print(RMSE)

# go through with 10 day and see if you get better error measures.
# rolling(5) -> rolling(10)


# SI 206 Final Project- Covid API
# Name: Sarah Whitman

import json
import unittest
import os
import requests
import matplotlib
import sqlite3

#functions
def get_countries_from_api():
    url = "https://covid-api.mmediagroup.fr/v1/vaccines"
    r = requests.get(url)
    data = r.text
    dict_list = json.loads(data)

    country_list = list(dict_list.keys())
    #print(country_list)
    #print(len(country_list))
    return country_list

#get continent
def get_continents_from_api():
    url = "https://covid-api.mmediagroup.fr/v1/vaccines"
    r = requests.get(url)
    data = r.text
    dict_list = json.loads(data)

    continents_list = []
    for country_key in dict_list:
        try:
            continent = dict_list[country_key]["All"]["continent"]
            continents_list.append(continent)
        except KeyError:
            continents_list.append("N/A")
    #print(continents_list)
    #print(len(continents_list))
    return continents_list

def get_ppl_vax_from_api():
    url = "https://covid-api.mmediagroup.fr/v1/vaccines"
    r = requests.get(url)
    data = r.text
    dict_list = json.loads(data)
    vax_list = []
    for country_key in dict_list:
        vaxxed = dict_list[country_key]["All"]["people_vaccinated"]
        vax_list.append(vaxxed)
    #print(vax_list)
    #print(len(vax_list))
    return vax_list

def get_life_ex_from_api():
    url = "https://covid-api.mmediagroup.fr/v1/vaccines"
    r = requests.get(url)
    data = r.text
    dict_list = json.loads(data)
    life_ex_list = []
    for country_key in dict_list:
        try:
            cur_life_ex = dict_list[country_key]["All"]["life_expectancy"]
            life_ex_list.append(cur_life_ex)
        except KeyError:
            life_ex_list.append("N/A")
    #print(life_ex_list)
    #print(len(life_ex_list)
    return life_ex_list

def create_full_dictionary():
    country_list = get_countries_from_api()
    continents_list = get_continents_from_api()
    vaxxed_list = get_ppl_vax_from_api()
    life_exp_list = get_life_ex_from_api()
    tuples_list = []
    for i in range(len(country_list)):
        tup = (country_list[i], vaxxed_list[i], life_exp_list[i], continents_list[i])
        tuples_list.append(tup)
    #print(tuples_list)

    data_dictionary = {}
    sub_dict_list = []
    country_id = 0
    for tup in tuples_list:
        sub_dict = {}
        sub_dict["people_vaccinated"] = tup[1]
        sub_dict["life_expectancy"] = tup[2]
        sub_dict["continent"] = tup[3]
        sub_dict["country_id"] = country_id
        sub_dict_list.append(sub_dict)
        country_id +=1
    #print(sub_dict_list)

    for i in range(len(country_list)):
        country = tuples_list[i][0]
        data_dictionary[country] = sub_dict_list[i]
    print(data_dictionary)
    return data_dictionary

#set up the database
def setUpDatabase(db_name):
    path = os.path.dirname(os.path.abspath(__file__))
    conn = sqlite3.connect(path+'/'+db_name)
    cur = conn.cursor()
    return cur, conn

#create the table for continents and ids
def create_continents_table(cur, conn, data_dictionary):
    continent_list = []
    for country in data_dictionary.keys():
        continent = data_dictionary[country]["continent"]
        if continent not in continent_list:
            continent_list.append(continent)

    #cur.execute("DROP TABLE IF EXISTS Continents")
    cur.execute("CREATE TABLE IF NOT EXISTS Continents (id INTEGER PRIMARY KEY, continent TEXT)")
    count = 0

    for i in range(len(continent_list)):
        cur.execute("INSERT OR IGNORE INTO Continents (id, continent) VALUES (?,?)",(i,continent_list[i]))

    conn.commit()

#create the table for country, cases, deaths, continent_id
def create_covid_info_table(cur, conn, data_dictionary):
    #cur.execute("DROP TABLE IF EXISTS CovidInfo")
    cur.execute("CREATE TABLE IF NOT EXISTS CovidInfo (country_id INTEGER PRIMARY KEY, country TEXT UNIQUE, people_vaccinated INTEGER, life_expectancy INTEGER, continent_id INTEGER)")
    count = 0
    for country in data_dictionary:
        name = country
        vaxxed = data_dictionary[country]["people_vaccinated"]
        life_exp = data_dictionary[country]["life_expectancy"]
        continent_name = data_dictionary[country]["continent"]
        country_id = data_dictionary[country]["country_id"]

        cur.execute("SELECT id FROM Continents WHERE continent = ?", (continent_name,))
        continent_ids = cur.fetchall()
        for cont in continent_ids:
            continent_id = cont[0]
        cur.execute("INSERT OR IGNORE INTO CovidInfo (country_id, country, people_vaccinated, life_expectancy, continent_id) VALUES (?,?,?,?,?)", (country_id, name, vaxxed, life_exp, continent_id))
        if cur.rowcount == 1:
            count += 1
            if count == 25:
                break
    #cur.execute("SELECT * FROM CovidInfo")

    conn.commit()

class TestCases(unittest.TestCase):
    def test_get_countries_from_api(self):
        country_list = get_countries_from_api()
        self.assertEqual(len(country_list), 193)

    def test_get_continents_from_api(self):
        continent_list = get_continents_from_api()
        self.assertEqual(len(continent_list), 193)

    def test_get_ppl_vax_from_api(self):
        vax_list = get_ppl_vax_from_api()
        self.assertEqual(len(vax_list), 193)

    def test_get_life_ex_from_api(self):
        life_ex_list = get_life_ex_from_api()
        self.assertEqual(len(life_ex_list), 193)

    def test_create_full_dictionary(self):
        data_dictionary = create_full_dictionary()
        self.assertEqual(len(data_dictionary), 193)
        self.assertEqual(list(data_dictionary.keys())[2], "Algeria")
        self.assertEqual(data_dictionary["Cambodia"]["continent"], "Asia")

def main():
    #print("This is main")
    get_countries_from_api()
    get_continents_from_api()
    get_ppl_vax_from_api()
    get_life_ex_from_api()

    data_dictionary = create_full_dictionary()

    cur, conn = setUpDatabase("CovidInfo.db")
    create_continents_table(cur, conn, data_dictionary)
    create_covid_info_table(cur, conn, data_dictionary)
    conn.close()

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


"""This file includes the memory structure for the bot. The core memory structure is simply a dictionary with
embeddings as the keys and summaries as the values. When searching for a memory, a string is input, for which
an embedding is generated. The system then returns the n most similar summaries that are within a range and
have not been used in the current conversation."""

from transformers import AutoTokenizer, AutoModel
import torch
import numpy as np

'''LT memory is essentially a dictionary that uses embeddings as keys and summaries as values.'''
class LTMemory_System():
    def __init__(self):
        self.tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
        self.model = AutoModel.from_pretrained("bert-base-uncased")
        self.lt_memory = dict() #hash -> summary
        self.keys = dict() #hash -> embedding

    def generate_embedding(self, doc_string): #input: document string, output: numerical embeddings
        inputs = self.tokenizer(doc_string, padding=True, truncation=True, return_tensors="pt")
        with torch.no_grad():
            outputs = self.model(**inputs)
        embeddings = outputs.last_hidden_state.mean(dim=1)
        return np.array(embeddings)

    def add_memory(self, summary): #input: summary string
        embedding = self.generate_embedding(summary)
        hashed = hash(embedding.tostring())
        self.lt_memory[hashed] = summary
        self.keys[hashed] = embedding

    def access_memory(self, embedding): #input: numerical embedding; output: summary
        return self.lt_memory[hash(embedding.tostring())]

    def get_closest_memories(self, embedding, k=3): #input: embedding; output: k closest summaries, k closest embeddings
        distances = []
        for i, embedding_2 in enumerate(self.keys.keys()):
            dist = self.euclidean_distance(embedding, embedding_2)
            distances.append((embedding_2, dist))

        distances.sort(key=lambda x: x[1])

        k_closest_indices = [x[0] for x in distances[:k]]

        return [self.lt_memory[embedding] for embedding in k_closest_indices], [embedding for embedding in k_closest_indices]

    def euclidean_distance(self, arr1, arr2):
        return np.linalg.norm(arr1 - arr2)

    def to_string(self):
        output = ""
        for key, value in self.lt_memory.items():
            output += f"{key}: {value}\n"
        return output


from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()

__all__ = ['CoreInstance', 'get_division', 'get_release']

class Meta(Base):
    __tablename__ = 'meta'

    meta_id = Column(Integer, primary_key=True)
    meta_key = Column(String)
    meta_value = Column(String)

    def __repr__(self):
        return "<Meta(meta_id='%s',meta_key='%s', meta_value='%s')>" % (
            self.meta_id, self.meta_key, self.meta_value)

Session = sessionmaker()

class CoreInstance:

    __division = None
    __release = None

    def __init__(self, url, timeout=3600):
        self.engine = create_engine(url, pool_recycle=timeout, echo=False)
        Session.configure(bind=self.engine)

    def __get_meta_value(self, meta_key):
        s = Session()
        try:
            meta = s.query(Meta).filter(Meta.meta_key == meta_key).first()
            return meta.meta_value
        finally:
            s.close()

    @property
    def division(self):
        if self.__division is None:
            self.__division = self.__get_meta_value('species.division')
        return self.__division

    @property
    def release(self):
        if self.__release is None:
            self.__release = self.__get_meta_value('schema_version')
        return self.__release

def get_division(src_uri, tgt_uri, db_type):
    uri = src_uri
    if db_type == "variation" or db_type == "funcgen":
        uri = tgt_uri.replace("_variation_", "_core_").replace("_funcgen_","_core_")
    inst = CoreInstance(uri)
    division_meta = inst.division
    division = str(division_meta).replace('Ensembl','')
    return division.lower()

def get_release(src_uri):
    inst = CoreInstance(src_uri)
    return int(inst.release)


import torch
import torch.nn as nn
from torch.autograd import Variable

import mlflow
import mlflow.pytorch

class RNN(nn.Module):
    def __init__(self, i_size, h_size, n_layers, o_size):
        super(RNN, self).__init__()

        self.rnn = nn.LSTM(
            input_size=i_size,
            hidden_size=h_size,
            num_layers=n_layers
        )
        self.out = nn.Linear(h_size, o_size)

    def forward(self, x, h_state):
        r_out, hidden_state = self.rnn(x, h_state)

        hidden_size = hidden_state[-1].size(-1)
        r_out = r_out.view(-1, hidden_size)
        outs = self.out(r_out)

        return outs, hidden_state

def train_mlmodel(x_train, y_train, parameters):
    rnn = RNN(parameters['INPUT_SIZE'], parameters["HIDDEN_SIZE"], parameters['NUM_LAYERS'], parameters['OUTPUT_SIZE'])
    optimizer = torch.optim.Adam(rnn.parameters(), lr=parameters['learning_rate'])
    criterion = nn.MSELoss()
    hidden_state = None

    mlflow.set_experiment(parameters['EXP_NAME'])
    with mlflow.start_run(run_name=parameters['RUN_NAME']) as run:
        for epoch in range(parameters['num_epochs']):
            inputs = Variable(torch.from_numpy(x_train).float())
            labels = Variable(torch.from_numpy(y_train).float())
            output, hidden_state = rnn(inputs, hidden_state)
            loss = criterion(output.view(-1), labels)
            optimizer.zero_grad()
            # torch.autograd.set_detect_anomaly(True)
            loss.backward(retain_graph=True)
            optimizer.step()

            print('epoch{}, loss{}'.format(epoch, loss.item()))
            mlflow.log_metric("epoch "+ str(epoch), loss.item())
        mlflow.log_param('loss_type', 'MSELoss')
        mlflow.log_param('test_data_ratio', parameters['test_data_ratio'])
        mlflow.log_param('num_train_iter', parameters['num_train_iter'])
        mlflow.log_param('learning_rate', parameters['learning_rate'])
        mlflow.log_param('INPUT_SIZE', parameters['INPUT_SIZE'])
        mlflow.log_param('HIDDEN_SIZE', parameters['HIDDEN_SIZE'])
        mlflow.log_param('NUM_LAYERS', parameters['NUM_LAYERS'])
        mlflow.log_param('OUTPUT_SIZE', parameters['OUTPUT_SIZE'])
        mlflow.log_param('num_epochs', parameters['num_epochs'])
        mlflow.pytorch.log_model(rnn, 'model')
    mlflow.end_run()
    return rnn


# -*- coding: utf-8 -*-

import os
import configparser
# from scrapy import log
from scrapy.http import Request, Response
from scrapy import signals

import tweepy

class Twitter:
    def __init__(self, *args, **kwargs):
        super(Twitter, self).__init__(*args, **kwargs)
        self.config_file = str(os.path.dirname(os.path.abspath(__file__)) + "/config.ini")
        if os.path.exists(self.config_file):
            self.config = configparser.ConfigParser()
            self.config.read(self.config_file, "utf-8")

class TwitterUserTimelineRequest(Request):
    def __init__(self, *args, **kwargs):
        auth = kwargs.pop("auth", None)
        spider = kwargs.pop("spider", None)
        self.oauth = tweepy.OAuthHandler(auth["CONSUMER_KEY"], auth["CONSUMER_SECRET"])
        self.oauth.set_access_token(auth["ACCESS_TOKEN"], auth["ACCESS_TOKEN_SECRET"])
        super(TwitterUserTimelineRequest, self).__init__('https://twitter.com', dont_filter=True, **kwargs)

class TwitterUserTimelineResponse(Response):
    def __init__(self, *args, **kwargs):
        auth = kwargs.pop("auth", None)
        self.api = tweepy.API(auth,wait_on_rate_limit=True)
        super(TwitterUserTimelineResponse, self).__init__('https://twitter.com', *args, **kwargs)


from __future__ import division

import argparse
import chainer
import importlib

import numpy as np
import pytest
import torch

from espnet.asr.pytorch_backend.asrtts import Reporter
from espnet.nets.pytorch_backend.e2e_asrtts import TacotronRewardLoss
from espnet.nets.pytorch_backend.nets_utils import pad_list

def make_arg(**kwargs):
    defaults = dict(
        elayers=4,
        subsample="1_2_2_1_1",
        etype="vggblstm",
        eunits=100,
        eprojs=100,
        dtype="lstm",
        dlayers=1,
        dunits=300,
        atype="location",
        aheads=4,
        awin=5,
        aconv_chans=10,
        aconv_filts=100,
        mtlalpha=0.5,
        lsm_type="",
        lsm_weight=0.0,
        sampling_probability=0.0,
        adim=320,
        dropout_rate=0.0,
        dropout_rate_decoder=0.0,
        nbest=5,
        beam_size=3,
        penalty=0.5,
        maxlenratio=1.0,
        minlenratio=0.0,
        ctc_weight=0.2,
        streaming_min_blank_dur=10,
        streaming_onset_margin=2,
        streaming_offset_margin=2,
        verbose=2,
        char_list=[u"あ", u"い", u"う", u"え", u"お"],
        outdir=None,
        ctc_type="warpctc",
        sym_space="<space>",
        sym_blank="<blank>",
        sortagrad=0,
        grad_noise=False,
        context_residual=False,
        use_speaker_embedding=True,
        expected_loss="tts",
        alpha=0.5,
        n_samples_per_input=5,
        policy_gradient=True,
        sample_scaling=0.1,
        generator="tts",
        rnnloss=None,
        update_asr_only=True
    )
    defaults.update(kwargs)
    return argparse.Namespace(**defaults)

def make_tts_args(**kwargs):
    defaults = dict(
        use_speaker_embedding=False,
        spk_embed_dim=None,
        embed_dim=512,
        elayers=1,
        eunits=512,
        econv_layers=3,
        econv_filts=5,
        econv_chans=512,
        dlayers=2,
        dunits=1024,
        prenet_layers=2,
        prenet_units=256,
        postnet_layers=5,
        postnet_filts=5,
        postnet_chans=512,
        output_activation=None,
        atype="location",
        adim=512,
        aconv_chans=32,
        aconv_filts=15,
        cumulate_att_w=True,
        use_batch_norm=True,
        use_concate=True,
        dropout=0.5,
        zoneout=0.1,
        reduction_factor=1,
        threshold=0.5,
        maxlenratio=5.0,
        minlenratio=0.0,
        use_cbhg=False,
        spc_dim=None,
        cbhg_conv_bank_layers=8,
        cbhg_conv_bank_chans=128,
        cbhg_conv_proj_filts=3,
        cbhg_conv_proj_chans=256,
        cbhg_highway_layers=4,
        cbhg_highway_units=128,
        cbhg_gru_units=256,
        use_masking=True,
        bce_pos_weight=1.0,
        use_guided_attn_loss=False,
        guided_attn_loss_sigma=0.4,
    )
    defaults.update(kwargs)
    return argparse.Namespace(**defaults)

def prepare_inputs(mode, ilens=[150, 100], olens=[4, 3], is_cuda=False):
    np.random.seed(1)
    assert len(ilens) == len(olens)
    xs = [np.random.randn(ilen, 40).astype(np.float32) for ilen in ilens]
    ys = [np.random.randint(1, 5, olen).astype(np.int32) for olen in olens]
    ilens = np.array([x.shape[0] for x in xs], dtype=np.int32)
    embs = torch.from_numpy(np.random.randn(2, 128)).float().to(torch.device('cpu'))

    if mode == "chainer":
        if is_cuda:
            xp = importlib.import_module('cupy')
            xs = [chainer.Variable(xp.array(x)) for x in xs]
            ys = [chainer.Variable(xp.array(y)) for y in ys]
            ilens = xp.array(ilens)
            embs = [chainer.Variable(xp.array(e)) for e in embs]
        else:
            xs = [chainer.Variable(x) for x in xs]
            ys = [chainer.Variable(y) for y in ys]
        return xs, ilens, ys, embs

    elif mode == "pytorch":
        ilens = torch.from_numpy(ilens).long()
        xs_pad = pad_list([torch.from_numpy(x).float() for x in xs], 0)
        ys_pad = pad_list([torch.from_numpy(y).long() for y in ys], -1)
        embs = torch.from_numpy(np.random.randn(2, 128)).float().to(torch.device('cpu'))
        if is_cuda:
            xs_pad = xs_pad.cuda()
            ilens = ilens.cuda()
            ys_pad = ys_pad.cuda()
            embs = embs.cuda()
        return xs_pad, ilens, ys_pad, embs
    else:
        raise ValueError("Invalid mode")

@pytest.mark.parametrize(
    "module, etype, atype, dtype", [
        ('espnet.nets.pytorch_backend.e2e_asrtts', 'blstmp', 'location', 'lstm'),
    ]
)
def test_model_trainable_and_decodable(module, etype, atype, dtype):
    args = make_arg(etype=etype, atype=atype, dtype=dtype)
    if "pytorch" in module:
        batch = prepare_inputs("pytorch", is_cuda=False)
    else:
        batch = prepare_inputs("chainer", is_cuda=False)

    m = importlib.import_module(module)
    tts_args = make_tts_args(spk_embed_dim=128, use_speaker_embedding=True)
    loss_fn = TacotronRewardLoss(None, idim=5, odim=40, train_args=tts_args, reporter=Reporter())
    asr_model = m.E2E(40, 5, args)
    model = m.E2E(40, 5, args, predictor=asr_model, asr2tts=True, loss_fn=loss_fn, rnnlm=None)
    attn_loss = model(*batch)[0]
    attn_loss.backward()  # trainable

    with torch.no_grad(), chainer.no_backprop_mode():
        in_data = np.random.randn(100, 40)
        model.recognize(in_data, args, args.char_list)  # decodable
        if "pytorch" in module:
            batch_in_data = [np.random.randn(100, 40), np.random.randn(50, 40)]
            model.recognize_batch(batch_in_data, args, args.char_list)  # batch decodable

# @pytest.mark.skipif(torch.cuda.device_count() < 2, reason="multi gpu required")
# @pytest.mark.parametrize("module", ["espnet.nets.pytorch_backend.e2e_asrtts"])
# def test_model_trainable_gpu(module):
#    ngpu = 1
#    args = make_arg()
#    m = importlib.import_module(module)
#    device_ids = list(range(ngpu))
#    tts_args = make_tts_args(spk_embed_dim=128, use_speaker_embedding=True)
#    loss_fn = TacotronRewardLoss(None, idim=5, odim=40, train_args=tts_args, reporter=Reporter())
#    asr_model = m.E2E(40, 5, args)
#    model = m.E2E(40, 5, args, predictor=asr_model, asr2tts=True, loss_fn=loss_fn, rnnlm=None)
#    if "pytorch" in module:
#        model = torch.nn.DataParallel(model, device_ids)
#        batch = prepare_inputs("pytorch", is_cuda=True)
#        model.cuda()
#        loss = 1. / ngpu * model(*batch)[0]
#        loss.backward(loss.new_ones(ngpu))  # trainable


import glob
import setuptools
from os.path import basename, splitext

with open("README.md", "r", encoding="utf8") as fh:
    long_description = fh.read()

setuptools.setup(
    name="createflaskapp",
    version="1.2",
    license="MIT",
    author="Ivan Sakal",
    author_email="sakalivan4@gmail.com",
    description="Package for initializing a flask project structure",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/isakal/create-flask-app",
    classifiers=[
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.6",
        "Programming Language :: Python :: 3.7",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires=">=3.6",
    package_dir={"": "src"},
    packages=setuptools.find_packages("src"),
    py_modules=[splitext(basename(path))[0] for path in glob.glob('src/*.py')],
    include_package_data=True,
    # package_data={"": [".flake8"]},
    install_requires=[
        "Click>=7",
        "animation>=0.0.6",
        "termcolor>=1.1.0"
    ],
    entry_points={
        "console_scripts": ["create-flask-app=create_flask_app.cli:create_project"]
    }
)


from django.core.management.base import BaseCommand, CommandError
from expert_system.utils import find_closest_request, timeit

class Command(BaseCommand):
    help = "Поиск самого похожего запроса в базе данных"

    def add_arguments(self, parser):
        parser.add_argument("user_request", type=str, help="Пользовательский запрос")

    @timeit
    def handle(self, *args, **options):
        closest_request = find_closest_request(options["user_request"])
        if closest_request is None:
            raise CommandError("Не удалось найти похожий запрос")
        self.stdout.write(
            self.style.SUCCESS(
                f'Наиболее похожий запрос на "{options["user_request"]}" - "{closest_request.request}" и '
                f'ответ: "{closest_request.text.text}".'
            )
        )


import requests
from django.views.generic import ListView, DetailView, UpdateView, CreateView, DeleteView, TemplateView, FormView, View
from .models import *
from django.shortcuts import render
from django.core.paginator import Paginator  # импортируем класс, позволяющий удобно осуществлять постраничный вывод
from .filters import PostFilter  # импортируем недавно написанный фильтр
from .forms import PostForm, CatForm
from django.shortcuts import redirect
from django.contrib.auth.models import Group
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.mail import send_mail
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
from django.db.models.signals import ModelSignal
from datetime import datetime, date, time
from django.core.cache import cache
import logging
from django.utils.translation import gettext as _  # импортируем функцию для перевода
from django.http import HttpResponse
# class NewsListN(ListView):
#     model = Post
#     template_name = 'news.html'
#     context_object_name = 'post'
#     queryset = Post.objects.filter(noa='N')
#
#     # class NewsListPost(ListView):
#     #     model = Post
#     #     template_name = 'news.html'
#     #     context_object_name = 'post'
#     #     queryset = News.objects.order_by('-id').filter(noa='A')
#
#
# class DetailNew(DetailView):
#     model = Post
#     template_name = 'new.html'
#     context_object_name = 'new'
#     queryset = Post.objects.filter(noa='N')

# logger = logging.getLogger(__name__)

custom_create_signal = ModelSignal(use_caching=True)
custom_update_signal = ModelSignal(use_caching=True)

class NewsListN(ListView):
    model = Post
    template_name = 'news_list.html'
    context_object_name = 'post'
    queryset = Post.objects.filter(noa='N')
    ordering = ['-id']
    paginate_by = 15  # поставим постраничный вывод в один элемент
    # form_class = PostForm

    def get_filter(self):
        return PostFilter(self.request.GET, queryset=super().get_queryset())

    def get_queryset(self):
        return self.get_filter().qs

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context['filter'] = self.get_filter()
        return context

class NewsDetailView(DetailView):
    template_name = 'news_detail.html'
    queryset = Post.objects.all()

    # def get_object(self, *args, **kwargs):
    #     # obj = cache.get(f'post-{self.kwargs["pk"]}', None)
    #
    #     # if not obj:
    #     obj = super().get_object(queryset=kwargs['queryset'])
    #         # cache.set(f'post-{self.kwargs["pk"]}', obj)
    #     return obj

class NewsCreateView(LoginRequiredMixin, PermissionRequiredMixin,  CreateView):
    template_name = 'news_create.html'
    form_class = PostForm
    permission_required = ('news.add_post',)

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.author = Author.objects.get_or_create(name=self.request.user)[0]
        # user = self.request.user
        all_post_author = self.object.author.post_set.all() # Добавили все посты автора
        count_today_post = 0
        for post in all_post_author:
            if post.author == self.object.author:
                time_delta = datetime.now().date() - post.time_in.date()
                if time_delta.total_seconds() < 86400:
                    count_today_post += 1
        if count_today_post < 3:

            self.object.save()
        else:
            return self.handle_no_permission()
        category = Category.objects.get(pk=self.request.POST['category'])
        self.object.category.add(category)
        custom_create_signal.send(sender=Post, instance=self.object, created=True)

        return super().form_valid(form)
        # text = self.object.text
        # heading = self.object.heading
        # if user.subscribe_category == category:
        #     html_content = render_to_string(
        #         'sub_new_post.html',
        #         {
        #             'user': user,
        #             'category': category,
        #             'heading': heading,
        #             'text': text
        #         }
        #     )
        #
        #     msg = EmailMultiAlternatives(
        #         subject=f'Новая статья в категории: {heading}!',
        #         from_email='murik0525@yandex.ru',
        #         to=['murik0525@yandex.ru'],
        #     )
        #     msg.attach_alternative(html_content, 'text/html')
        #     msg.send()

# дженерик для редактирования объекта
class NewsUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    template_name = 'news_create.html'
    form_class = PostForm
    permission_required = ('news.change_post',)

    def dispatch(self, request, *args, **kwargs):
        user = request.user
        author = Author.objects.get(name=user)
        if not author.post_set.filter(pk=kwargs.get('pk')).exists():
            return self.handle_no_permission()
        return super().dispatch(request, *args, **kwargs)

    # метод get_object мы используем вместо queryset, чтобы получить информацию об объекте, который мы собираемся редактировать
    def get_object(self, **kwargs):
        id = self.kwargs.get('pk')
        return Post.objects.get(pk=id)

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.author = Author.objects.get_or_create(name=self.request.user)[0]
        # user = self.request.user
        self.object.save()
        category = Category.objects.get(pk=self.request.POST['category'])
        self.object.category.add(category)
        custom_update_signal.send(sender=Post, instance=self.object, created=False)
        return super().form_valid(form)

# дженерик для удаления товара
class NewsDeleteView(LoginRequiredMixin, DeleteView):
    template_name = 'news_delete.html'
    queryset = Post.objects.all()
    success_url = '/news/'

    def dispatch(self, request, *args, **kwargs):
        user = request.user
        author = Author.objects.get(name=user)
        if not author.post_set.filter(pk=kwargs.get('pk')).exists():
            return self.handle_no_permission()
        return super().dispatch(request, *args, **kwargs)

class ProfileView(LoginRequiredMixin, TemplateView):
    template_name = 'profile.html'

    def dispatch(self, request, *args, **kwargs):
        user = request.user
        gr = Group.objects.get(name='common')
        if user.is_authenticated:
            gr.user_set.add(user)
            return super().dispatch(request, *args, **kwargs)
        return self.handle_no_permission()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['is_not_authors'] = not self.request.user.groups.filter(name='authors').exists()
        return context

@login_required
def upgrade_me(request):
    user = request.user
    premium_group = Group.objects.get(name='authors')
    if not request.user.groups.filter(name='authors').exists():
        premium_group.user_set.add(user)
        Author.objects.create(name=user)
    return redirect('/')

class SubscribeCategory(FormView):
    form_class = CatForm
    template_name = 'category.html'
    success_url = '/news/'

    def form_valid(self, form):
        user = self.request.user
        print(user.subscribe_category)
        user.subscribe_category = Category.objects.get(pk=self.request.POST['category'])
        user.save()
        html_content = render_to_string(
            'subscribe_created.html',
            {
                'user': user,
            }
        )

        msg = EmailMultiAlternatives(
            subject='Подписка оформлена!',
            from_email='murik0525@yandex.ru',
            to=[user.email],
        )
        msg.attach_alternative(html_content, 'text/html')
        msg.send()
        return super().form_valid(form)

# Create your views here.

class Index(View):
    def get(self, request):
        string = _('Hello world')

        return HttpResponse(string)


from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.shortcuts import render
from .models import Ordenes
from .forms import OrdenesForm, UpdateOrdenesForm
from django.views.generic.edit import UpdateView
from django.contrib import messages
from django.views.generic.detail import DetailView
from django.views.generic import DeleteView
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from django.contrib.messages.views import SuccessMessageMixin
from datetime import date
from .filters import OrdenesFilter, HistoryFilter
from django.db.models import Sum, Max
from operator import sub
from Stock.models import StockMovimientos,Stock

def ListarEntregadosView(request):
    Model_one = Ordenes.objects.all().filter(estado='Completato')

    myFilter = OrdenesFilter(request.GET, queryset=Model_one)
    paginator = Paginator(myFilter.qs, 10)
    page = request.GET.get('page1')
    try:
        pub = paginator.page(page)
    except PageNotAnInteger:
        pub = paginator.page(1)
    except EmptyPage:
        pub = paginator.page(paginator.num_pages)

    myFilter = OrdenesFilter(request.GET, queryset=Model_one)

    context = {'Model_one': Model_one, 'pub': pub, "myFilter": myFilter}
    return render(request, 'ordenes/listarEntregados.html', context)

def dashboard(request):

    # todo crear entregados por mes

    # variables globales para pasar a dashboard
    totalUsado = StockMovimientos.objects.values("nombre__nombre").filter(tipo_de_movimiento=False).annotate(Sum("cantidad"))
    totalprod = Ordenes.objects.values_list("producto__nombre").exclude(cantidadEntregada=None).annotate(cantidad=Sum('cantidad_recibida')).order_by('producto')
    totalprodentregados = Ordenes.objects.values_list("producto__nombre").exclude(cantidadEntregada=None).annotate(cantidad=Sum('cantidadEntregada')).order_by('producto')
    totalprodentregados2 = Ordenes.objects.all().exclude(cantidadEntregada=None).annotate(cantidad=Sum("cantidadEntregada"))
    #funciones para recuperar datos a mostrar

    totalUsadoetiq = []
    totalUsadocant = []
    for i in totalUsado:
        totalUsadoetiq.append(i["nombre__nombre"])
        totalUsadocant.append(i["cantidad__sum"])

    productos1 = []
    for i in totalprod:
        if totalprod[0] != None:
            productos1.append(i[1])
        else:
            productos1.append(0)

    productos2 = []
    listatitulos = []
    for i in totalprodentregados:
        if i[1] != None:
            listatitulos.append(i[0])

            productos2.append(i[1])
        else:
            listatitulos.append(i[0])
            productos2.append(0)

    total = list(map(int.__sub__,productos2,productos1))

    context = {"total": total,"etiquetas":listatitulos,"totalProdEntr":totalprodentregados2,"totalUsadoEtiq":totalUsadoetiq,"totalUsadoCant":totalUsadocant}
    return render(request, 'ordenes/dashboard.html', context)

class CreateOrdenView(SuccessMessageMixin, CreateView):
    form_class = OrdenesForm
    template_name = 'ordenes/crearOrden.html'

    def get_success_url(self):
        return reverse_lazy('listarOrden')

    def form_valid(self, form):
        formulario = form.save(commit=False)

        if formulario.estado == 'Entregado':
            formulario.fecha_entrega_real = date.today()
        else:
            formulario.fecha_entrega_real = None
        formulario.usuarios = self.request.user
        messages.success(self.request, '¡¡¡ Orden %s creada correctamente !!!' % (formulario.producto))
        return super().form_valid(form)

def ListViewOrden(request):
    ordenes = Ordenes.objects.filter(estado='Entregado')
    historial = Ordenes.history.all()
    # ----------------------------------------------- graficas----------------------------------
    totalprod = Ordenes.objects.values_list("producto__nombre").annotate(cantidad=Sum('cantidad_recibida')).order_by('producto')
    totalprodentregados = Ordenes.objects.values_list("producto__nombre").annotate(cantidad=Sum('cantidadEntregada')).order_by('producto')
    totalfechasentregadas = Ordenes.objects.values_list("fecha_entrega_real", 'producto__nombre', 'cantidadEntregada').order_by('producto')
    listaTodos = []
    listaproductos = []
    listaEtiquetas = []

    for i in totalfechasentregadas:
        if i[0] != None:
            listaTodos.append(i)

    print(listaTodos)

    for i in totalprodentregados:
        if i[1] != None:
            listaproductos.append(i[1])
        else:
            listaproductos.append(0)

        listaEtiquetas.append(i[0])
    productos1 = []
    etiquetas = []

    for i in totalprod:
        if totalprod[0] != None:
            productos1.append(i[1])
        else:
            productos1.append(0)
        etiquetas.append(i[0])
    fuera = ("Completato", "Entregado")

    Model_one = Ordenes.objects.exclude(estado__in=fuera).order_by('fecha_entrega_estimada')
    total = Model_one.count
    myFilter = OrdenesFilter(request.GET, queryset=Model_one)
    paginator = Paginator(myFilter.qs, 10)
    page = request.GET.get('page1')
    try:
        pub = paginator.page(page)
    except PageNotAnInteger:
        pub = paginator.page(1)
    except EmptyPage:
        pub = paginator.page(paginator.num_pages)

    myFilter = OrdenesFilter(request.GET, queryset=Model_one)
    comparar = date.today()
    fechasAcomparar = []
    for i in Model_one:
        fechasAcomparar.append(str(abs(comparar - i.fecha_entrega_estimada).days) + " dias" + " " + str(i.orden))

    print(fechasAcomparar)
    context = {'pub': pub, 'myFilter': myFilter, 'listatodos': listaTodos, 'listaproductos': listaproductos, 'listaetiquetas': listaEtiquetas, 'productos1': productos1, 'etiquetas': etiquetas, 'Total': total, 'Model_one': Model_one, 'Ordenes': ordenes,
               'History': historial}
    return render(request, 'ordenes/ListarOrden.html', context)

def ListHistorialView(request):
    porOrden = Ordenes.history.values_list("orden").annotate(cantidad=Sum('history_id'))

    orden = []
    historial = []
    for i in porOrden:
        historial.append(i[1])
        orden.append(i[0])

    Model_one = Ordenes.history.all().order_by('history_id')
    total = Model_one.count
    paginator = Paginator(Model_one, 10)
    page = request.GET.get('page1')
    try:
        Model_one = paginator.page(page)
    except PageNotAnInteger:
        Model_one = paginator.page(1)
    except EmptyPage:
        Model_one = paginator.page(paginator.num_pages)

    context = {'Model_one': Model_one, 'total': total, 'orden': orden, 'historial': historial}
    return render(request, 'ordenes/history.html', context)

class DetailOrdenView(DetailView):
    form_class = OrdenesForm
    model = Ordenes
    template_name = 'ordenes/detailOrden.html'

class DeleteOrdenView(DeleteView):
    model = Ordenes

    def get_success_url(self):
        success_message = '¡¡¡ Producto eliminado correctamente !!!'
        messages.success(self.request, (success_message))
        return reverse_lazy('listarOrden')

class UpdateOrdenView(UpdateView):
    form_class = UpdateOrdenesForm
    model = Ordenes
    template_name = 'ordenes/updateOrden.html'

    def get_success_url(self):
        return reverse_lazy('listarOrden')

    def form_invalid(self, form):
        print("errrrrorororororo")
        print(form)
        return super().form_invalid(form)

    def form_valid(self, form):
        formulario = form.save(commit=False)
        from Productos.models import Productos

        print(formulario)  # 3
        print(form)

        hola = Productos.objects.get(id=formulario.producto.id)

        print(hola)

        if (hola.telaio == None):
            print("Aca estoy pero no tengo que hacer nada")
            Productos.objects.filter(id=formulario.producto.id).update(telaio=formulario.telaio)
            formulario.telaio = formulario.cantidad_recibida / formulario.telaio

        else:
            pass

        if formulario.estado == 'Completato':
            formulario.fecha_entrega_real = date.today()
            messages.success(self.request, "¡¡¡ L'ordine %s è stato consegnato !!!" % (formulario.orden))

        else:
            formulario.fecha_entrega_real = None
            messages.success(self.request, "¡¡¡ L'ordine %s è stato aggiornato correttamente !!!" % (formulario.orden))

        formulario.usuarios = self.request.user

        return super().form_valid(form)


"""Utility functions for FarCry6 test script"""
import os
import cv2

# path relative to script
script_dir = os.path.dirname(os.path.realpath(__file__))
images_dir = os.path.join(script_dir, "images")
dir16x9 = os.path.join(images_dir, "16x9")
dir16x10 = os.path.join(images_dir, "16x10")

templates = {
    "options": {
        "16x10": cv2.imread(os.path.join(dir16x9, "options_menu_1080.png"), cv2.IMREAD_UNCHANGED),
        "16x9": cv2.imread(os.path.join(dir16x9, "options_menu_1080.png"), cv2.IMREAD_UNCHANGED)
    },
    "benchmark": {
        "16x10": cv2.imread(os.path.join(dir16x9, "benchmark_1080.png"), cv2.IMREAD_UNCHANGED),
        "16x9": cv2.imread(os.path.join(dir16x9, "benchmark_1080.png"), cv2.IMREAD_UNCHANGED)
    },
    "header": {
        "16x10": cv2.imread(os.path.join(dir16x9, "results_header_1080.png"), cv2.IMREAD_UNCHANGED),
        "16x9": cv2.imread(os.path.join(dir16x9, "results_header_1080.png"), cv2.IMREAD_UNCHANGED)
    },
}

def get_resolution():
    """Stub: Return resolution"""
    return 0,0


import torch
import glob
import os

def load_wts(model, checkpoint_path):
    ckpt = torch.load(checkpoint_path)
    wts = ckpt['model']

    state = {}
    for k, v in wts.items():
        if k.startswith('module.'):
            k = k.replace('module.','')
        state[k] = v

    model.load_state_dict(state)
    return model


import copy
from pyaudio import PyAudio, paInt16
from threading import Thread
import numpy as np
import sys

class AudioAnalyzer(Thread):
    SAMPLING_RATE = 48000
    CHUNK_SIZE = 1024
    BUFFER_TIMES = 50
    ZERO_PADDING = 3
    NUM_HPS = 3

    NOTE_NAMES = ['Do', 'Do#', 'Re', 'Re#', 'Mi', 'Fa', 'Fa#', 'Sol', 'Sol#', 'La', 'La#', 'Si']

    def __init__(self, queue, *args, **kwargs):
        Thread.__init__(self, *args, **kwargs)

        self.queue = queue
        self.buffer = np.zeros(self.CHUNK_SIZE * self.BUFFER_TIMES)
        self.hanning_window = np.hanning(len(self.buffer))
        self.running = False

        try:
            self.audio_object = PyAudio()
            self.stream = self.audio_object.open(format=paInt16,
                                                 channels=1,
                                                 rate=self.SAMPLING_RATE,
                                                 input=True,
                                                 output=False,
                                                 frames_per_buffer=self.CHUNK_SIZE)
        except Exception as e:
            sys.stderr.write('Error: Line {} {} {}\n'.format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e))
            return

    @staticmethod
    def frequency_to_number(freq, a4_freq):
        if freq == 0:
            sys.stderr.write("Error: No hay frecuencia, el sistema no reconoce la entrada de audio\n")
            return 0
        return 12 * np.log2(freq / a4_freq) + 69

    @staticmethod
    def number_to_frequency(number, a4_freq):
        return a4_freq * 2.0**((number - 69) / 12.0)

    @staticmethod
    def number_to_note_name(number):
        return AudioAnalyzer.NOTE_NAMES[int(round(number) % 12)]

    @staticmethod
    def frequency_to_note_name(frequency, a4_freq):
        number = AudioAnalyzer.frequency_to_number(frequency, a4_freq)
        note_name = AudioAnalyzer.number_to_note_name(number)
        return note_name

    def run(self):
        self.running = True

        while self.running:
            try:
                data = self.stream.read(self.CHUNK_SIZE, exception_on_overflow=False)
                data = np.frombuffer(data, dtype=np.int16)

                self.buffer[:-self.CHUNK_SIZE] = self.buffer[self.CHUNK_SIZE:]
                self.buffer[-self.CHUNK_SIZE:] = data

                magnitude_data = abs(np.fft.fft(np.pad(self.buffer * self.hanning_window,
                                                       (0, len(self.buffer) * self.ZERO_PADDING),
                                                       "constant")))
                magnitude_data = magnitude_data[:int(len(magnitude_data) / 2)]
                magnitude_data_orig = copy.deepcopy(magnitude_data)
                for i in range(2, self.NUM_HPS+1, 1):
                    hps_len = int(np.ceil(len(magnitude_data) / i))
                    magnitude_data[:hps_len] *= magnitude_data_orig[::i]

                frequencies = np.fft.fftfreq(int((len(magnitude_data) * 2) / 1),
                                             1. / self.SAMPLING_RATE)

                for i, freq in enumerate(frequencies):
                    if freq > 60:
                        magnitude_data[:i - 1] = 0
                        break

                self.queue.put(round(frequencies[np.argmax(magnitude_data)], 2))

            except Exception as e:
                sys.stderr.write('Error: Line {} {} {}\n'.format(sys.exc_info()[-1].tb_lineno, type(e).__name__, e))

        self.stream.stop_stream()
        self.stream.close()
        self.audio_object.terminate()

if __name__ == "__main__":
    from analizer.threading_helper import ProtectedList
    import time

    q = ProtectedList()
    a = AudioAnalyzer(q)
    a.start()

    while True:
        q_data = q.get()
        if q_data is not None:
            print("loudest frequency:", q_data, "nearest note:", a.frequency_to_note_name(q_data, 440))
            time.sleep(0.02)


from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

from .forms import CustomUserCreationForm, CustomUserChangeForm
from .models import *

class CustomUserAdmin(UserAdmin):
    add_form = CustomUserCreationForm
    form = CustomUserChangeForm
    model = CustomUser
    list_display = ("email",#"resident_type",
    "emailVerified",
    "is_staff", "is_active",
    )
    list_filter = ("email", "is_staff", "is_active",)
    fieldsets = (
        (None, {"fields": ("email", "password")}),
        ("Permissions", {"fields": ("is_staff", "is_active", "groups", "user_permissions")}),
    )
    # add_fieldsets = (
    #     (None, {
    #         "classes": ("wide",),
    #         "fields": (
    #             "email", "password1", "password2", "is_staff",
    #             "is_active", "groups", "user_permissions"
    #         )}
    #     ),
    # )
    search_fields = ("email",)
    ordering = ("email",)

admin.site.register(CustomUser)#, CustomUserAdmin)
admin.site.register(ResidenceType)
admin.site.register(StatusOfResidence)
admin.site.register(Profession)
admin.site.register(Profile)
admin.site.register(UserDocuments)
admin.site.register(TermsAndConditions)
admin.site.register(IntendedUseOfAccount)
admin.site.register(Ekyc)
# admin.site.register(AppVersion)
# admin.site.register(PostalCode)
admin.site.register(EkycType)
@admin.register(PostalCode)
class PostalCodeAdmin(admin.ModelAdmin):
    list_display=[k.name  for k in PostalCode._meta.fields]
# admin.site.register(CurrencyRate)
# @admin.register(CurrencyRate)
class CurrencyRateAdmin(admin.ModelAdmin):
    # list_display=["name","created_at","updated_at"]
    list_display=[k.name  for k in CurrencyRate._meta.fields]
    # list_display=[k for k in CurrencyRate._meta.get_fields()]
    # list_dispaly=('sell')#(k for k in CurrencyRate._meta.get_fields())
    list_filter = ('name','buy','sell', 'created_at','updated_at',)
    # list_display=['name','buy','sell', 'created_at','updated_at',]
    search_fields = ("name",'iso3')
admin.site.register(CurrencyRate,CurrencyRateAdmin)
# admin.site.register(ProfileDocuments)
@admin.register(ProfileDocuments)
class ProfileDocumentsAdmin(admin.ModelAdmin):
    # date_hierarchy = 'pub_date'
    list_display = ['id','user', 'created_at','updated_at','front_img_preview','back_img_preview','tilted_preview','blink_preview']

admin.site.register(ProvinceDistricts)

class BannersAdmin(admin.ModelAdmin): # new
    readonly_fields = ['img_preview']
    list_display = ['title', 'img_preview']
admin.site.register(Banners,BannersAdmin)
admin.site.site_header='Clone RPS Remit'

class CountryAdmin(admin.ModelAdmin):
    list_display=["img_preview","country","continent"]

admin.site.register(Country,CountryAdmin)
admin.site.register(TransactionType)
@admin.register(Transactions)

class Transactions(admin.ModelAdmin):
    list_display=[k.name  for k in Transactions._meta.fields]


from selenium import webdriver

class WebDriverFactory:

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

    def getWebDriverInstance(self):

        base_url = "https://www.amazon.com"
        if self.browser == "iexplorer":
            driver = webdriver.Ie()
        elif self.browser == "firefox":
            driver = webdriver.Firefox()
        elif self.browser == "chrome":
            driver = webdriver.Chrome()
        else:
            driver = webdriver.Chrome()

        driver.implicitly_wait(3)
        driver.maximize_window()
        driver.get(base_url)
        return driver


import json
from enum import Enum

import pyperclip
from textual import on
from textual.app import ComposeResult
from textual.containers import Horizontal, Vertical
from textual.css.query import NoMatches
from textual.events import Click
from textual.reactive import reactive
from textual.widget import Widget
from textual.widgets import Input, LoadingIndicator, Static

from oterm.app.prompt import PromptWidget
from oterm.ollama import OllamaLLM

class Author(Enum):
    USER = "me"
    OLLAMA = "ollama"

class ChatContainer(Widget):
    ollama = OllamaLLM()
    messages: reactive[list[tuple[Author, str]]] = reactive([])
    chat_name: str

    def __init__(
        self,
        *children: Widget,
        db_id: int,
        chat_name: str,
        model: str = "nous-hermes:13b",
        context: list[int] = [],
        messages: list[tuple[Author, str]] = [],
        **kwargs,
    ) -> None:
        super().__init__(*children, **kwargs)

        self.ollama = OllamaLLM(
            model=model, context=context
        )  # We do this to reset the context
        self.chat_name = chat_name
        self.db_id = db_id
        self.messages = messages

    def on_mount(self) -> None:
        self.query_one("#prompt").focus()
        if self.messages:
            message_container = self.query_one("#messageContainer")
            for author, message in self.messages:
                chat_item = ChatItem()
                chat_item.text = message
                chat_item.author = author
                message_container.mount(chat_item)
            message_container.scroll_end()

    @on(Input.Submitted)
    async def on_submit(self, event: Input.Submitted) -> None:
        message = event.value
        input = event.input
        message_container = self.query_one("#messageContainer")

        input.clear()
        input.disabled = True
        self.messages.append((Author.USER, message))
        chat_item = ChatItem()
        chat_item.text = message
        chat_item.author = Author.USER
        message_container.mount(chat_item)

        chat_item = ChatItem()
        chat_item.author = Author.OLLAMA
        message_container.mount(chat_item)
        loading = LoadingIndicator()
        message_container.mount(loading)
        message_container.scroll_end()

        response = ""
        async for text in self.ollama.stream(message):
            response = text
            chat_item.text = text
            message_container.scroll_end()
        self.messages.append((Author.OLLAMA, response))
        loading.remove()
        input.disabled = False
        input.focus()

        # Save to db
        await self.app.store.save_context(  # type: ignore
            id=self.db_id,
            context=json.dumps(self.ollama.context),
        )
        await self.app.store.save_message(  # type: ignore
            chat_id=self.db_id,
            author=Author.USER.value,
            text=message,
        )
        await self.app.store.save_message(  # type: ignore
            chat_id=self.db_id,
            author=Author.OLLAMA.value,
            text=response,
        )

    def compose(self) -> ComposeResult:
        with Vertical():
            yield Static(f"model: {self.ollama.model}", id="info")
            yield Vertical(id="messageContainer")
            yield PromptWidget(id="prompt")

class ChatItem(Widget):
    text: reactive[str] = reactive("")
    author: Author

    @on(Click)
    async def on_click(self, event: Click) -> None:
        pyperclip.copy(self.text)
        widget = self.query_one(".text", Static)
        widget.styles.animate("opacity", 0.5, duration=0.1)
        widget.styles.animate("opacity", 1.0, duration=0.1, delay=0.1)

    def watch_text(self, text: str) -> None:
        try:
            widget = self.query_one(".text", Static)
            if widget:
                widget.update(text)
        except NoMatches:
            pass

    def compose(self) -> ComposeResult:
        """A chat item."""
        with Horizontal(classes=f"{self.author.name} chatItem"):
            yield Static(self.author.value, classes="author")
            yield Static(self.text, classes="text")


import argparse
import sys
from io import StringIO
from unittest import mock

import matplotlib
import matplotlib.pyplot as plt
import pytest

from agenet.plot import main, plot

def test_plot(monkeypatch):
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--num_nodes_const",
        type=int,
        default=2,
        help="Constant value for the number of nodes.",
    )
    parser.add_argument(
        "--active_prob_const",
        type=float,
        default=0.5,
        help="Constant value for the active probability.",
    )
    parser.add_argument(
        "--n_const",
        type=int,
        default=150,
        help="Constant value for the block length.",
    )
    parser.add_argument(
        "--k_const",
        type=int,
        default=100,
        help="Constant value for the update size.",
    )
    parser.add_argument(
        "--P_const",
        type=float,
        default=2 * (10**-3),
        help="Constant value for the power.",
    )
    parser.add_argument(
        "--numevnts",
        type=int,
        default=1000,
        help="The number of events.",
    )
    parser.add_argument(
        "--numruns",
        type=int,
        default=2,
        help="The number of runs.",
    )
    parser.add_argument(
        "--num_nodes_vals",
        nargs="+",
        type=int,
        default=[1, 2, 3, 4, 5],
        help="Values for the number of nodes.",
    )
    parser.add_argument(
        "--active_prob_vals",
        nargs="+",
        type=float,
        default=[0.1, 0.15, 0.2, 0.25],
        help="Values for the active probability.",
    )
    parser.add_argument(
        "--n_vals",
        nargs="+",
        type=int,
        default=[150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250],
        help="Values for the block length.",
    )
    parser.add_argument(
        "--k_vals",
        nargs="+",
        type=int,
        default=[50, 60, 70, 80, 90, 95, 100],
        help="Values for the update size.",
    )
    parser.add_argument(
        "--P_vals",
        nargs="+",
        type=float,
        default=[
            2 * (10**-3),
            3 * (10**-3),
            4 * (10**-3),
            5 * (10**-3),
            10 * (10**-3),
        ],
        help="Values for the power.",
    )
    # Add other necessary arguments to the parser

    # Mock the command-line arguments
    monkeypatch.setattr(
        "sys.argv",
        [
            "test_script.py",
            "--num_nodes_const",
            "2",
            "--active_prob_const",
            "0.5",
            "--n_const",
            "150",
            "--k_const",
            "100",
            "--P_const",
            "0.002",
            "--numevnts",
            "1000",
            "--numruns",
            "2",
            "--num_nodes_vals",
            "1",
            "2",
            "3",
            "4",
            "5",
            "--active_prob_vals",
            "0.1",
            "0.15",
            "0.2",
            "0.25",
            "--n_vals",
            "150",
            "160",
            "170",
            "180",
            "190",
            "200",
            "210",
            "220",
            "230",
            "240",
            "250",
            "--k_vals",
            "50",
            "60",
            "70",
            "80",
            "90",
            "95",
            "100",
            "--P_vals",
            "0.002",
            "0.003",
            "0.004",
            "0.005",
            "0.01",
        ],
    )

    args = parser.parse_args([])

    # Redirect stdout to a StringIO object
    output = StringIO()
    monkeypatch.setattr("sys.stdout", output)

    # Mock the plt.show() function to avoid showing the plot
    with mock.patch.object(plt, "show"):
        plot(args)

    # Get the output
    out = output.getvalue().strip()

matplotlib.use("Agg")  # Use Agg backend to prevent plots from being displayed

def test_main():
    sys.argv = [
        "your_script_name.py",
        "--num_nodes_const",
        "2",
        "--active_prob_const",
        "0.5",
        "--n_const",
        "150",
        "--k_const",
        "100",
        "--P_const",
        "0.002",
        "--numevnts",
        "1000",
        "--numruns",
        "1",
        "--num_nodes_vals",
        "1",
        "2",
        "--active_prob_vals",
        "0.1",
        "0.2",
        "--n_vals",
        "150",
        "160",
        "--k_vals",
        "50",
        "60",
        "--P_vals",
        "0.002",
        "0.003",
    ]
    with mock.patch.object(plt, "show"):
        main()


"""
Filename: arellano_vfi.py

Authors: Chase Coleman, John Stachurski

Solve the Arellano default risk model

References
----------

http://quant-econ.net/py/arellano.html

.. Arellano, Cristina. "Default risk and income fluctuations in emerging
   economies." The American Economic Review (2008): 690-712.

"""
from __future__ import division
import numpy as np
import random
import quantecon as qe
from numba import jit

class Arellano_Economy(object):
    """
    Arellano 2008 deals with a small open economy whose government
    invests in foreign assets in order to smooth the consumption of
    domestic households. Domestic households receive a stochastic
    path of income.

    Parameters
    ----------
    beta : float
        Time discounting parameter
    gamma : float
        Risk-aversion parameter
    r : float
        int lending rate
    rho : float
        Persistence in the income process
    eta : float
        Standard deviation of the income process
    theta : float
        Probability of re-entering financial markets in each period
    ny : int
        Number of points in y grid
    nB : int
        Number of points in B grid
    tol : float
        Error tolerance in iteration
    maxit : int
        Maximum number of iterations
    """

    def __init__(self,
            beta=.953,      # time discount rate
            gamma=2.,       # risk aversion
            r=0.017,        # international interest rate
            rho=.945,       # persistence in output
            eta=0.025,      # st dev of output shock
            theta=0.282,    # prob of regaining access
            ny=21,          # number of points in y grid
            nB=251,         # number of points in B grid
            tol=1e-8,       # error tolerance in iteration
            maxit=10000):

        # Save parameters
        self.beta, self.gamma, self.r = beta, gamma, r
        self.rho, self.eta, self.theta = rho, eta, theta
        self.ny, self.nB = ny, nB

        # Create grids and discretize Markov process
        self.Bgrid = np.linspace(-.45, .45, nB)
        self.mc = qe.markov.tauchen(rho, eta, 3, ny)
        self.ygrid = np.exp(self.mc.state_values)
        self.Py = self.mc.P

        # Output when in default
        ymean = np.mean(self.ygrid)
        self.def_y = np.minimum(0.969 * ymean, self.ygrid)

        # Allocate memory
        self.Vd = np.zeros(ny)
        self.Vc = np.zeros((ny, nB))
        self.V = np.zeros((ny, nB))
        self.Q = np.ones((ny, nB)) * .95  # Initial guess for prices
        self.default_prob = np.empty((ny, nB))

        # Compute the value functions, prices, and default prob
        self.solve(tol=tol, maxit=maxit)
        # Compute the optimal savings policy conditional on no default
        self.compute_savings_policy()

    def solve(self, tol=1e-8, maxit=10000):
        # Iteration Stuff
        it = 0
        dist = 10.

        # Alloc memory to store next iterate of value function
        V_upd = np.zeros((self.ny, self.nB))

        # == Main loop == #
        while dist > tol and maxit > it:

            # Compute expectations for this iteration
            Vs = self.V, self.Vd, self.Vc
            EV, EVd, EVc = (np.dot(self.Py, v) for v in Vs)

            # Run inner loop to update value functions Vc and Vd.
            # Note that Vc and Vd are updated in place.  Other objects
            # are not modified.
            _inner_loop(self.ygrid, self.def_y, self.Bgrid, self.Vd, self.Vc,
                    EVc, EVd, EV, self.Q,
                    self.beta, self.theta, self.gamma)

            # Update prices
            Vd_compat = np.repeat(self.Vd, self.nB).reshape(self.ny, self.nB)
            default_states = Vd_compat > self.Vc
            self.default_prob[:, :] = np.dot(self.Py, default_states)
            self.Q[:, :] = (1 - self.default_prob)/(1 + self.r)

            # Update main value function and distance
            V_upd[:, :] = np.maximum(self.Vc, Vd_compat)
            dist = np.max(np.abs(V_upd - self.V))
            self.V[:, :] = V_upd[:, :]

            it += 1
            if it % 25 == 0:
                print("Running iteration {} with dist of {}".format(it, dist))

        return None

    def compute_savings_policy(self):
        """
        Compute optimal savings B' conditional on not defaulting.
        The policy is recorded as an index value in Bgrid.
        """

        # Allocate memory
        self.next_B_index = np.empty((self.ny, self.nB))
        EV = np.dot(self.Py, self.V)

        _compute_savings_policy(self.ygrid, self.Bgrid, self.Q, EV,
                self.gamma, self.beta, self.next_B_index)

    def simulate(self, T, y_init=None, B_init=None):
        """
        Simulate time series for output, consumption, B'.
        """
        # Find index i such that Bgrid[i] is near 0
        zero_B_index = np.searchsorted(self.Bgrid, 0)

        if y_init is None:
            # Set to index near the mean of the ygrid
            y_init = np.searchsorted(self.ygrid, self.ygrid.mean())
        if B_init is None:
            B_init = zero_B_index
        # Start off not in default
        in_default = False

        y_sim_indices = self.mc.simulate_indices(T, init=y_init)
        B_sim_indices = np.empty(T, dtype=np.int64)
        B_sim_indices[0] = B_init
        q_sim = np.empty(T)
        in_default_series = np.zeros(T, dtype=np.int64)

        for t in range(T-1):
            yi, Bi = y_sim_indices[t], B_sim_indices[t]
            if not in_default:
                if self.Vc[yi, Bi] < self.Vd[yi]:
                    in_default = True
                    Bi_next = zero_B_index
                else:
                    new_index = self.next_B_index[yi, Bi]
                    Bi_next = new_index
            else:
                in_default_series[t] = 1
                Bi_next = zero_B_index
                if random.uniform(0, 1) < self.theta:
                    in_default = False
            B_sim_indices[t+1] = Bi_next
            q_sim[t] = self.Q[yi, Bi_next]

        q_sim[-1] = q_sim[-2] # Extrapolate for the last price
        return_vecs = (self.ygrid[y_sim_indices],
                      self.Bgrid[B_sim_indices],
                      q_sim,
                      in_default_series)

        return return_vecs

@jit(nopython=True)
def u(c, gamma):
    return c**(1-gamma)/(1-gamma)

@jit(nopython=True)
def _inner_loop(ygrid, def_y, Bgrid, Vd, Vc, EVc,
                         EVd, EV, qq, beta, theta, gamma):
    """
    This is a numba version of the inner loop of the solve in the
    Arellano class. It updates Vd and Vc in place.
    """
    ny, nB = len(ygrid), len(Bgrid)
    zero_ind = nB // 2  # Integer division
    for iy in range(ny):
        y = ygrid[iy]   # Pull out current y

        # Compute Vd
        Vd[iy] = u(def_y[iy], gamma) + \
                beta * (theta * EVc[iy, zero_ind] + (1 - theta) * EVd[iy])

        # Compute Vc
        for ib in range(nB):
            B = Bgrid[ib] # Pull out current B

            current_max = -1e14
            for ib_next in range(nB):
                c = max(y - qq[iy, ib_next] * Bgrid[ib_next] + B, 1e-14)
                m = u(c, gamma) + beta * EV[iy, ib_next]
                if m > current_max:
                    current_max = m
            Vc[iy, ib] = current_max

    return None

@jit(nopython=True)
def _compute_savings_policy(ygrid, Bgrid, Q, EV, gamma, beta, next_B_index):
    # Compute best index in Bgrid given iy, ib
    ny, nB = len(ygrid), len(Bgrid)
    for iy in range(ny):
        y = ygrid[iy]
        for ib in range(nB):
            B = Bgrid[ib]
            current_max = -1e10
            for ib_next in range(nB):
                c = max(y - Q[iy, ib_next] * Bgrid[ib_next] + B, 1e-14)
                m = u(c, gamma) + beta * EV[iy, ib_next]
                if m > current_max:
                    current_max = m
                    current_max_index = ib_next
            next_B_index[iy, ib] = current_max_index
    return None


import argparse
import glob
import json
import logging
import os
import sys
import time
import urllib.request

logging.basicConfig(stream = sys.stdout, level = logging.INFO, format="%(levelname)s:%(module)s:%(lineno)s: %(message)s")

class MobilecoindJsonClient:
    def __init__(self, base_url):
        if not base_url.endswith("/"):
            base_url += "/"
        self.base_url = base_url

    def request(self, url, data=None):
        req = urllib.request.Request(self.base_url + url)

        if data:
            data = json.dumps(data)
            data_bytes = data.encode("utf-8")

            req.add_header("Content-Type", "application/json; charset=utf-8")
            req.add_header("Content-Length", len(data_bytes))
            response = urllib.request.urlopen(req, data_bytes)
        else:
            response = urllib.request.urlopen(req)

        return json.loads(response.read())

    def get_balance(self, monitor_id, subaddress_index=0):
        response = self.request(f"monitors/{monitor_id}/subaddresses/{subaddress_index}/balance")
        if "balance" not in response:
            raise Exception(f"Invalid response: {response}")
        return int(response["balance"])

    def create_monitor(self, account_key, first_subaddress_index=0, num_subaddresses=1):
        return self.request(f"monitors", {
            "account_key": account_key,
            "first_subaddress": first_subaddress_index,
            "num_subaddresses": num_subaddresses,
        })

    def get_monitor(self, monitor_id):
        return self.request(f"monitors/{monitor_id}")

    def get_ledger_local(self):
        return self.request(f"ledger/local")

    # Takes the json loaded from a private key file, tests if it is mnemnonic or root entropy
    #
    # If it is mnemonic, we pass the mnemonic to `account-key-from-mnemonic` route
    # Otherwise, we hit the `entropy/{root_entropy}` route.
    # Both return Json account key response.
    def account_key_from_json(self, obj):
        if "mnemonic" in obj:
            return self.request("account-key-from-mnemonic", {"mnemonic": obj["mnemonic"]})
        elif "root_entropy" in obj:
            # Take the integer array in obj["root_entropy"], convert it to builtin bytes, then
            # get hex string of that.
            return self.request("entropy/{}".format(bytes(obj["root_entropy"]).hex()))
        else:
            raise Exception("unknown key format", obj)

    def get_public_address(self, monitor_id, subaddress_index=0):
        return self.request(f"monitors/{monitor_id}/subaddresses/{subaddress_index}/public-address")

    def pay_address_code(self, from_monitor_id, from_subaddress_index, to_b58_address, value):
        return self.request(f"monitors/{from_monitor_id}/subaddresses/{from_subaddress_index}/pay-address-code", {
            "receiver_b58_address_code": to_b58_address,
            "value": str(value),
        })

    def tx_status_as_sender(self, tx_info):
        return self.request(f"tx/status-as-sender", tx_info)

    def tx_status_as_receiver(self, monitor_id, receipt):
        return self.request(f"monitors/{monitor_id}/tx-status-as-receiver", receipt)

    def get_utxos(self, monitor_id, subaddress_index=0):
        return self.request(f"monitors/{monitor_id}/subaddresses/{subaddress_index}/utxos")["output_list"]

    def wait_for_monitor_to_sync(self, monitor_id, poll_interval=0.1):
        while True:
            local_ledger = self.get_ledger_local()
            monitor = self.get_monitor(monitor_id)
            if int(monitor["next_block"]) >= int(local_ledger["block_count"]):
                break
            time.sleep(poll_interval)

def load_keys(keys_dir):
    """Load all keys from the keys_dir directory"""

    # When Comparing filenames, make shorter file names compare less than longer filenames,
    # using this key function
    def filename_key(filename):
        return (len(filename), filename);

    return [
        json.load(open(f)) for f in
        sorted(glob.glob(os.path.join(keys_dir, "*.json")), key=filename_key)
    ]

def run_test(mobilecoind_json_url, keys_dir, max_seconds):
    logging.info(f"mobilecoind-json integration test starting with url={mobilecoind_json_url} keys_dir={keys_dir} max_seconds={max_seconds}")
    keys = load_keys(keys_dir)
    if not keys:
        raise Exception(f"No keys found in directory: {keys_dir}")
    logging.info(f"Loaded {len(keys)} keys")

    client = MobilecoindJsonClient(mobilecoind_json_url)

    # Add two monitors and wait for them to sync
    monitor_ids = []
    for i in range(2):
        account_key = client.account_key_from_json(keys[i])
        monitor = client.create_monitor(account_key)
        logging.info(f"{i}: Monitor created: {monitor}, waiting to sync...")
        monitor_id = monitor["monitor_id"]
        client.wait_for_monitor_to_sync(monitor_id)
        balance = client.get_balance(monitor_id)
        logging.info(f"{i}: Monitor synced: balance={balance}")
        monitor_ids.append(monitor_id)

    # Run tests
    test_pay_address_code(client, monitor_ids)
    test_utxos(client, monitor_ids[1])

def test_pay_address_code(client, monitor_ids):
    # Get the balance of both monitors and then transact from one to the other using the pay_address_code endpoint
    balance0 = client.get_balance(monitor_ids[0])
    balance1 = client.get_balance(monitor_ids[1])

    amount = 1
    addr1 = client.get_public_address(monitor_ids[1])["b58_address_code"]
    tx_info = client.pay_address_code(monitor_ids[0], 0, addr1, amount)
    logging.info(f"Tx submitted: {tx_info}")

    # Wait up to 30 seconds for tx to happen
    for _ in range(30):
        new_balance1 = client.get_balance(monitor_ids[1])
        if new_balance1 != balance1:
            break
        time.sleep(1)

    assert new_balance1 == balance1 + amount, f"Balance mismatch: {new_balance1} != {balance1} + {amount}"
    logging.info("Balance check passed")

    # Check the status as the sender
    response = client.tx_status_as_sender(tx_info)
    logging.info(f"tx_status_as_sender: {response}")
    if response["status"] != "verified":
        raise Exception(f"Failed tx_status_as_sender check: {response}")

    # Check the status as the receiver
    response = client.tx_status_as_receiver(monitor_ids[1], tx_info["receiver_tx_receipt_list"][0])
    logging.info(f"tx_status_as_receiver: {response}")
    if response["status"] != "verified":
        raise Exception(f"Failed tx_status_as_receiver check: {response}")

def test_utxos(client, monitor_id):
    # Confirm the balance matches the list of utos
    balance = client.get_balance(monitor_id)
    utxos = client.get_utxos(monitor_id)

    utxo_balance = sum(int(utxo["value"]) for utxo in utxos)
    logging.info(f"balance is {balance}, utxo_balance is {utxo_balance}")
    assert balance == utxo_balance

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("--mobilecoind-json-url",
                        default="http://localhost:9090/",
                        type=str,
                        help="mobilecoind-json host")
    parser.add_argument("--key-dir",
                        type=str,
                        help="Path to directory of account_keys",
                        required=True)
    parser.add_argument("--max-seconds",
                        type=int,
                        default=40,
                        help="Number of seconds to wait for a tx to clean")
    args = parser.parse_args()
    run_test(
        args.mobilecoind_json_url,
        args.key_dir,
        args.max_seconds,
    )


from django.test import TestCase
from ..models import Subject, Category

class CategoryModelTest(TestCase):
    """Tests for Category model."""

    @classmethod
    def setUpTestData(cls):
        Category.objects.create(
            name='Разработка программ',
            slug='develop',
            description='Описание',
            content='Содержание',
            price=5000,
            status=True
        )

    def test_get_absolute_url(self):
        category = Category.objects.get(slug='develop')
        self.assertEqual(category.get_absolute_url(), '/subjects/develop/')

    def test_is_enabled(self):
        category = Category.objects.get(slug='develop')
        self.assertTrue(category.is_enabled())

class SubjectModelTest(TestCase):
    """Tests for Subject model."""

    @classmethod
    def setUpTestData(cls):
        category = Category.objects.create(
            name='Разработка программ',
            slug='develop',
            description='Описание',
            content='Содержание',
            price=5000,
            status=True
        )
        Subject.objects.create(
            name='Django site',
            description='Описание',
            content='Содердание',
            price=5000,
            status=Subject.STATUS_ENABLED,
            category=category
        )

    def test_get_absolute_url(self):
        subject = Subject.objects.get(pk=1)
        self.assertEqual(subject.get_absolute_url(), '/subjects/1/')

    def test_get_create_url(self):
        subject = Subject.objects.get(pk=1)
        self.assertEqual(subject.get_create_url(), '/orders/subject/1/')

    def test_get_status(self):
        subject = Subject.objects.get(pk=1)
        self.assertEqual(subject.status, Subject.STATUS_ENABLED)
        self.assertEqual(subject.get_status(), 'Доступно')

    def test_is_enabled(self):
        subject = Subject.objects.get(pk=1)
        self.assertTrue(subject.is_enabled())