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

import isodate
import json

class Stack(object):

    def __init__(self):
        self.items = {}
        self.itemsList = []
        self.current = None

    def isEmpty(self):
        return len(self.itemsList) == 0

    def isEmptyMain(self):
        return len(self.items.keys()) == 0

    def size(self):
        return len(self.itemsList)

    def push(self, item, userid):
        if item not in self.items.keys():
            title = youtube.getTitle(item)
            duration = youtube.getDuration(item)
            if title and duration:
                self.itemsList.append(item)
                self.items[item]={}
                self.items[item]['name'] = title
                self.items[item]['userid'] = userid
                self.items[item]['duration'] = int(
                    isodate.parse_duration(duration).total_seconds())
                self.items[item]['opinions'] = { 'like': [], 'dislike': [] }
                thumbnail = youtube.getThumbnail(item)
                if thumbnail:
                    self.items[item]['thumbnail'] = thumbnail
                else:
                    self.items[item]['thumbnail'] = '/static/img/blank.png'
                return True
            else:
                return False
        else:
            return False

    def getName(self, item):
        if item in self.items.keys():
            return self.items[item]['name']
        else:
            return None

    def getUsername(self, item):
        if item in self.items.keys():
            return self.items[item]['userid']
        else:
            return None

    def getTime(self, item):
        if item in self.items.keys():
            return self.items[item]['duration']
        else:
            return None

    def getCurrent(self):
        return self.current

    def setOpinion(self, opinion, userid):
        anotherOpinion = 'dislike' if opinion == 'like' else 'like'
        if userid not in self.items[self.current]['opinions'][opinion]:
            self.items[self.current]['opinions'][opinion].append(userid)
            try:
                self.items[self.current]['opinions'][
                    anotherOpinion].remove(userid)
            except ValueError:
                pass
            return True
        else:
            return False

    def getOpinions(self):
        if self.current:
            return self.items[self.current]['opinions']
        else:
            return None

    def delete(self, item, delete = True, msg = None):
        if item in self.itemsList:
            self.itemsList.remove(item)
        if item in self.items.keys():
            if msg is None:
                if delete:
                    msg = 'Трек %s удален из очереди' % str(self.getName(item).encode('utf-8'))
                else:
                    opinion = self.getOpinions()
                    msg = 'Трек %s отыграл, лайков: %s, дизлайков: %s' % (str(self.getName(item).encode('utf-8')), str(len(opinion['like'])), str(len(opinion['dislike'])))
            sendMsg({
                'type' : 'chat',
                'action':'getMsg',
                'sender':'system',
                'name':'system',
                'msg': msg})
            self.items.pop(item, None)
        return None

    def first(self):
        if not self.isEmpty():
            return self.itemsList[0]
        else:
            return None

    def last(self):
        if not self.isEmpty():
            return self.itemsList[len(self.itemsList) - 1]
        else:
            return None

    def get(self, admin = False):
        data = {}
        for i in enumerate(self.itemsList):
            _data = {
                'item':         i[1],
                'name':         self.items[i[1]]['name'],
                'duration':     self.items[i[1]]['duration'],
                'thumbnail':    self.items[i[1]]['thumbnail']}
            if admin:
                _data['userid'] = self.items[i[1]]['userid']
            data[i[0]] = json.dumps(_data)
        return json.dumps(data)

    def pop(self, disliked = False):
        global currenttime
        global radio
        if disliked:
            userid = self.getUsername(self.current)
            if userid:
                radio['ustack'].appendDislike(userid, self.current)
        if not self.isEmptyMain():
            self.delete(self.current, False)
        if not self.isEmpty():
            self.current = self.itemsList.pop(0)
        else:
            self.current = None
        currenttime = 0
        return None


import pygame
from pygame.locals import *
from pygame.rect import *
import pyc

size = width, height = 800,600
screen = pygame.display.set_mode(size)

rect1 = Rect(50,50,50,75)
rect2 = Rect(75,100,75,75)

speed = [2,8]
speed0 = [7,2]

clock = pygame.time.Clock()

pygame.init()

running =True
while running :
    clock.tick(60)
    for ev in pygame.event.get():
        if ev.type == QUIT :
            running = False

    rect1.move_ip(speed)
    rect2.move_ip(speed0)

    if rect1.left < 0:
        speed[0] *= -1
    if rect2.left < 0:
        speed0[0] *= -1
    if rect1.right > width :
        speed[0] *= -1
    if rect2.right > width :
        speed0[0] *= -1
    if rect1.top < 0:
        speed[1] *= -1
    if rect2.top < 0 :
        speed0[1] *= -1
    if rect1.bottom > height :
        speed[1] *= -1
    if rect2.bottom > height :
        speed0[1] *= -1

    screen.fill(pyc.GRAY)
    pygame.draw.rect(screen,pyc.GREEN, rect1)
    pygame.draw.ellipse(screen,pyc.BLUE,rect2)
    pygame.display.flip()

pygame.quit()


from PyQt5.QtCore import Qt, QPointF
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QGraphicsRectItem

from urh import constants

class ROI(QGraphicsRectItem):
    def __init__(self, *args, fillcolor, parent=None):
        self.padding = 0
        if len(args) == 0:
            super().__init__(parent)
        elif len(args) == 1:
            super().__init__(args[0], parent)
        elif len(args) == 4:
            x0 = args[0]
            y0 = args[1]
            w = args[2]
            h = args[3]
            ymin = y0 + self.padding * h
            roi_height = (1 - 2 * self.padding) * h
            super().__init__(x0, ymin, w, roi_height, parent)

        self.finished = False
        self.selected_edge = None
        """:type: int """
        self.resizing = False

        self.setBrush(fillcolor)
        self.setPen(QColor(Qt.transparent))
        self.setOpacity(constants.SELECTION_OPACITY)

    @property
    def is_empty(self) -> bool:
        return self.width == 0

    @property
    def width(self):
        return self.rect().width()

    @width.setter
    def width(self, value):
        if value == self.width:
            return

        r = self.rect()
        r.setWidth(value)
        self.setRect(r)

    @property
    def height(self):
        return self.rect().height()

    @height.setter
    def height(self, value):
        if value == self.height:
            return

        r = self.rect()
        r.setHeight(value)
        self.setRect(r)

    @property
    def x(self):
        return self.rect().x()

    def setX(self, p_float):
        if p_float == self.x:
            return

        r = self.rect()
        r.setX(p_float)
        self.setRect(r)

    @property
    def start(self):
        if self.width < 0:
            return self.x + self.width
        else:
            return self.x

    @start.setter
    def start(self, value):
        self.setX(value)

    @property
    def end(self):
        if self.width < 0:
            return self.x
        else:
            return self.x + self.width

    @end.setter
    def end(self, value):
        self.width = value - self.start

    @property
    def y(self):
        return self.rect().y()

    def setY(self, p_float):
        if p_float == self.y:
            return

        r = self.rect()
        r.setY(p_float)
        self.setRect(r)

    def is_in_roi(self, pos: QPointF):
        x1 = self.rect().x()
        x2 = x1 + self.rect().width()
        y1 = self.rect().y()
        y2 = y1 + self.rect().width()

        if x1 < pos.x() < x2 and y1 < pos.y() < y2:
            return True

        return False

    def get_selected_edge(self, pos: QPointF, width_view: float):
        """
        Bestimmt auf welcher Ecke der ROI der Mauszeiger gerade ist.
        0 = links, 1 = rechts

        :param pos: In die Szene gemappte Position des Mauszeigers
        """
        x1 = self.rect().x()
        x2 = x1 + self.rect().width()
        y1 = self.rect().y()
        y2 = y1 + self.rect().height()
        x = pos.x()
        y = pos.y()

        if x1 - 0.025 * width_view < x < x1 + 0.025 * width_view and y1 < y < y2:
            self.selected_edge = 0
            return 0

        if x2 - 0.025 * width_view < x < x2 + 0.025 * width_view and y1 < y < y2:
            self.selected_edge = 1
            return 1

        self.selected_edge = None
        return None

    def clear(self):
        self.width = 0
        self.resizing = False
        self.selected_edge = None
        self.finished = False


from __future__ import absolute_import, division, print_function
import torch

def _make_arg_str(arg):
    arg = str(arg)
    too_big = len(arg) > 15 or "\n" in arg
    return "..." if too_big else arg

def _extract_act_pos(acts, x=None, y=None):
    shape = acts.shape
    x = shape[3] // 2 if x is None else x
    y = shape[4] // 2 if y is None else y
    return acts[: ,:, :, y:y+1, x:x+1]

def _T_handle_batch(T, batch=None):
    def T2(name):
        t = T(name)
        if isinstance(batch, int):
            return t[:,batch:batch+1]
        else:
            return t

    return T2

def linconv_reshape(x,ref):
    #reshapes x to shape of y where x is shape (c) or (b,c) and y is either shape (b,c) or (b,c,h,w)
    if x.dim() == 1: x = x.unsqueeze(0)
    while x.dim() < ref.dim():
        x = x.unsqueeze(dim=-1)
    return x

def orthogonal_proj(x,direction):
    if isinstance(direction,int):
        v = torch.zeros(x.shape[1])
        v[direction] = 1.
    else:
        v = torch.tensor(direction)/torch.norm(direction)
    v = v.to(x.device)
    dot = (x * linconv_reshape(v,x)).sum(dim=1).unsqueeze(1)
    proj = dot * linconv_reshape(v,dot)
    orth_proj = x - linconv_reshape(proj,x)
    return orth_proj


import pickle
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

with open('/home/abhishek/Documents/project/data/tfim_hv1_N10_J11.pickle', 'rb') as data:
	temp=pickle.load(data)

dt=temp[0]
mz=temp[1]
S_en=temp[2]
sc=temp[3]
l_fl=temp[4]
bi_fl=temp[5]

avg_m_z = mz.mean(axis=0)
S = S_en.mean(axis=0)
avg_s_c = sc.mean(axis=0)
l = l_fl.mean(axis=0)
b_fl = bi_fl.mean(axis=0)

plt.subplot(5,1,1)
plt.plot(dt, avg_m_z)
plt.xticks([50,100,150,200], " ")
#plt.yticks([0.6,0.4,0.2,0,-0.2])
plt.ylabel(r"$\langle m_z \rangle$", fontsize=18)
plt.subplot(5,1,2)
plt.plot(dt, S)
plt.xticks([50,100,150,200], " ")
plt.ylabel(r"$S(t)$", fontsize=18)
plt.subplot(5,1,3)
plt.plot(dt, b_fl)
plt.xticks([50,100,150,200], " ")
plt.ylabel(r"$\mathcal{F}$", fontsize=18)
plt.subplot(5,1,4)
plt.plot(dt, avg_s_c)
plt.xticks([50,100,150,200], " ")
plt.ylabel(r"$\langle s_c \rangle$", fontsize=18)
plt.subplot(5,1,5)
plt.plot(dt, l)
plt.xticks([0,50,100,150,200,250], [0,50,r"$\tau$",150,r"$2\tau$",250])
#plt.yticks([0,-0.2,-0.4,-0.6,-0.8,-1])
plt.ylabel(r"$l(t)$", fontsize=18)
plt.xlabel(r"$t$", fontsize=18)
plt.subplots_adjust(hspace=.4)
plt.show()


"""Functions that display the results of Rosetta ResidueSelectors in PyMOL"""
from collections import namedtuple
import logging
from pymol import cmd
import pyrosetta.distributed.packed_pose as packed_pose
from pyrosetta.rosetta.protocols.rosetta_scripts import XmlObjects
from .utils import (
    pymol_to_rosetta,
    rosetta_to_pymol,
    pymol_selection_to_residue_selector,
)

logger = logging.getLogger("pymol_rosetta_utils.selectors")
PDBAtomID = namedtuple("PDBAtomID", "resi chain name")

def _apply_residue_selector_and_show_as_sticks(
    selector, pose, label="selected_residues"
):
    """Apply a residue selector to a pose and show the selected residues in sticks."""
    residues = selector.apply(pose)
    sele = []
    for pos, val in enumerate(residues, start=1):
        if not val:
            continue
        # this will fail on insertion codes because rosetta only returns
        # residue numbers and chainIDs
        resno, chain = pose.pdb_info().pose2pdb(pos).split()
        sele.append("(resi {} and chain {})".format(resno, chain))
    cmd.select(label, "+".join(sele))
    cmd.show("sticks", label)
    return residues

def _hbond_pdb(hbond, pose):
    """Convert donor and acceptor atom ids to PDB numbering and return a tuple
    in the form of (donor, acceptor).
    """
    (don_res, don_chain), don_atm = (
        pose.pdb_info().pose2pdb(hbond.don_res()).split(),
        pose.residue(hbond.don_res()).atom_name(hbond.don_hatm()).strip(),
    )

    (acc_res, acc_chain), acc_atm = (
        pose.pdb_info().pose2pdb(hbond.acc_res()).split(),
        pose.residue(hbond.acc_res()).atom_name(hbond.acc_atm()).strip(),
    )

    return PDBAtomID(don_res, don_chain, don_atm), PDBAtomID(
        acc_res, acc_chain, acc_atm
    )

def show_interface_residues(pymol_obj_name, grp1, grp2):
    """Show interface residues between two selections."""
    wpose = packed_pose.to_pose(pymol_to_rosetta(pymol_obj_name))
    objs = XmlObjects.create_from_string(
        f"""
<RESIDUE_SELECTORS>
    {pymol_selection_to_residue_selector(grp1, name="grp1", pose=wpose)}
    {pymol_selection_to_residue_selector(grp2, name="grp2", pose=wpose)}
    <InterfaceByVector name="interface" grp1_selector="grp1" grp2_selector="grp2"/>
</RESIDUE_SELECTORS>
"""
    )
    logger.debug(objs)
    _apply_residue_selector_and_show_as_sticks(
        objs.get_residue_selector("interface"), wpose, label="interface_residues"
    )

def show_hydrogen_bonds(pymol_obj_name, include_bb_bb=True, selection="all"):
    """Show hydrogen bonds between two selections."""
    wpose = packed_pose.to_pose(pymol_to_rosetta(pymol_obj_name))
    # update the PyMOL object to include all hydrogens
    rosetta_to_pymol(wpose, pymol_obj_name)

    objs = XmlObjects.create_from_string(
        f"""
<RESIDUE_SELECTORS>
    {pymol_selection_to_residue_selector(selection, name="selector", pose=wpose)}
    <HBond name="hbonds" residue_selector="selector" include_bb_bb="{include_bb_bb}" scorefxn="REF2015"/>
</RESIDUE_SELECTORS>
"""
    )
    logger.debug(objs)

    # show sticks for selected residues
    selected_residues = _apply_residue_selector_and_show_as_sticks(
        objs.get_residue_selector("hbonds"), wpose, label="hbond_residues"
    )

    # hide non-polar hydrogens
    cmd.hide("everything", "(h. and (e. c extend 1))")

    # get all hbonds in pose
    for i, hbond in enumerate(
        wpose.get_hbonds(exclude_bb=(not include_bb_bb)).hbonds(), start=1
    ):
        if (
            not selected_residues[hbond.don_res()]
            or not selected_residues[hbond.acc_res()]
        ):
            continue
        # get the residues and atom names involved in the hbond
        don, acc = _hbond_pdb(hbond, wpose)
        # draw dashed line to indicate hbond
        cmd.distance(
            f"hb_{i}",
            f"(resi {don.resi} and chain {don.chain} and name {don.name})",
            f"(resi {acc.resi} and chain {acc.chain} and name {acc.name})",
        )
        cmd.hide("labels", f"hb_{i}")
    # group all of the hbonds together in a collapsable list
    cmd.group("hbonds", "hb_*")


# -*- coding: utf-8 -*-
from flask import Flask, jsonify, request, Response
from flask_sqlalchemy import SQLAlchemy
import datetime
from flask_marshmallow import Marshmallow
from flask_cors import CORS
from sqlalchemy import asc, desc
import config

app = Flask(__name__, static_folder='./static', static_url_path='/')
CORS(app)

app.config["SQLALCHEMY_DATABASE_URI"] = config.alchemy_uri()
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

db = SQLAlchemy(app)
ma = Marshmallow(app)

# Table명
class Articles(db.Model):
    id = db.Column(db.Integer, primary_key=True, nullable=False, autoincrement=True)
    title = db.Column(db.String(200), nullable=False)
    description = db.Column(db.String(1000), nullable=False)
    price = db.Column(db.Integer, nullable=False)
    dateCreated = db.Column(db.DateTime, default=datetime.datetime.now, nullable=False)

    def __init__(self, title, description, price):
        self.title = title
        self.description = description
        self.price = price

class ArticleSchema(ma.Schema):
    class Meta:
        fields = ('id', 'title', 'description', 'price', 'dateCreated')

article_schema = ArticleSchema()
articles_schema = ArticleSchema(many=True)

@app.before_first_request
def init_db():
    db.create_all()

@app.route('/')
def index():
    return app.send_static_file('index.html')

@app.route('/api/advertisement', methods=['GET'])
def get_sort_articles():
    # sortby True = desc / False = asc
    # 시간이 갈수록 큰 값
    field = request.args.get('field', "dateCreated", type=str)
    sort = request.args.get('sort', "True", type=str)
    per_page = request.args.get('page', 10, type=int)
    page = request.args.get('index', 0, type=int)

    # print(field, sort)

    total = Articles.query.count()
    all_articles = Articles.query.order_by(asc(field)).limit(per_page).offset(page*per_page)

    if sort == "True":
        all_articles = Articles.query.order_by(desc(field)).limit(per_page).offset(page*per_page)

    results = articles_schema.dump(all_articles)
    return jsonify({
        'articles': results,
        'pagination': {
            'total': total,
            'page_index': page,
            'per_page': per_page,
            'pages': float(total / per_page),
        }
    })

@app.route('/api/advertisement/detail', methods=['GET'])
def post_details():
    article = Articles.query.get(request.args.get("id"))
    return article_schema.jsonify(article)

@app.route('/api/advertisement', methods=['POST'])
def add_article():
    title = request.json['title']
    description = request.json['description']
    price = request.json['price']

    # 공백이 들어간다면 backend에서 에러 처리
    if (not title.strip()) or (not description.strip()) or (not str(price).strip()):
        # return "Record not found", 400
        return article_schema.jsonify({"dateCreated": "None"})

    try:
        int(price)
    except:
        return article_schema.jsonify({"dateCreated": "Integer"})

    articles = Articles(title, description, price)
    db.session.add(articles)
    db.session.commit()
    return article_schema.jsonify(articles)

@app.route('/api/advertisement', methods=['PUT'])
def update_article():
    article = Articles.query.get(request.args.get("id"))

    title = request.json['title']
    description = request.json['description']
    price = request.json['price']

    if (not title.strip()) or (not description.strip()) or (not str(price).strip()):
        print("error")
        return article_schema.jsonify({"dateCreated": "None"})

    try:
        int(price)
    except:
        return article_schema.jsonify({"dateCreated": "Integer"})

    article.title = title
    article.description = description
    article.price = price

    db.session.commit()
    return article_schema.jsonify(article)

@app.route('/api/advertisement', methods=['DELETE'])
def article_delete():
    article = Articles.query.get(request.args.get("id"))
    db.session.delete(article)
    db.session.commit()
    return article_schema.jsonify(article)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)


import sys
sys.stdin = open("../test/max_diff.txt")
import itertools
test_num = int(input())
test_list = list(map(int, input().split()))

sorted_list = list(itertools.permutations(test_list, test_num))
len_list = list()
pre_val = None
ans_list = list()
for tuple in sorted_list:
    for index in range(len(tuple)):
        if index > 0:
            len_list.append(tuple[index]-pre_val)
            pre_val = tuple[index]
        else:
            pre_val = tuple[index]
    abs_len_list = list(map(abs, len_list))
    len_list = []
    list_sum = sum(abs_len_list)
    ans_list.append(list_sum)
ans = max(ans_list)
print(ans)


from __future__ import absolute_import
import math
from threading import Thread

from chaco.default_colormaps import jet
from traits.api import HasTraits, Bool, Float, Instance, Button
from traitsui.api import View, UItem, HGroup, VGroup

# ============= standard library imports ========================
import time
from numpy import zeros, ogrid

# ============= local library imports  ==========================
from pychron.graph.graph import Graph

# from pychron.lasers.pattern.dragonfly_pattern import dragonfly, DragonFlyPattern
from pychron.lasers.pattern.pattern_executor import CurrentPointOverlay
from pychron.mv.lumen_detector import LumenDetector

class LM:
    def __init__(self):
        self.stage_manager = SM()

class SM:
    pxpermm = 23

    def __init__(self):
        self.lumen_detector = LumenDetector()

    def update_axes(self):
        pass

    def moving(self, **kw):
        return False

    def find_target(self):
        return self.lumen_detector.find_target(self.frame)

    def find_best_target(self):
        return self.lumen_detector.find_best_target(self.frame)

class Controller:
    def linear_move(self, *args, **kw):
        pass

class SeekTester(HasTraits):
    cx = Float(1)
    cy = Float(1)
    width = Float(2)
    height = Float(2)
    radius = Float(0.5)
    src_graph = Instance(Graph)
    pos_graph = Instance(Graph)

    start_button = Button
    stop_button = Button
    pxpermm = Float(23)
    alive = Bool

    def _start(self):
        self.alive = True

        lm = LM()

        frm = self._frame(0, 0)
        lm.stage_manager.frame = frm

        t = Thread(target=self._dragon, args=(lm,))
        t.setDaemon(True)
        t.start()

        t = Thread(target=self._run, args=(lm,))
        t.setDaemon(True)
        t.start()

    def _stop(self):
        self.alive = False

    def _dragon(self, lm):
        pattern = DragonFlyPattern()
        controller = Controller()

        st = time.time()
        plot = self.src_graph.plots[1]
        dragonfly(st, pattern, lm, controller, plot, self._cp)

    def _run(self, lm):
        cnt = 0
        p = self.src_graph.plots[0]
        while self.alive:
            x, y = self._get_xy(cnt)
            frm = self._frame(x, y)
            p.data.set_data("imagedata", frm)
            lm.stage_manager.frame = frm
            time.sleep(0.25)
            cnt += 1

    def _get_xy(self, cnt):
        # x, y = self.cx * self.pxpermm, self.cy * self.pxpermm
        # x, y = 0, 0
        # x += cnt * 0.01
        # y += cnt * 0.01

        x = 0.3 * math.cos(math.radians((15 * cnt) % 360))
        y = 0.3 * math.sin(math.radians((15 * cnt) % 360))
        # print 'xy {},{}'.format(int(x * self.pxpermm), int(y * self.pxpermm))
        return x, y

    def _frame(self, ox, oy):
        cx, cy = self.width / 2.0, self.height / 2.0
        cx += ox
        cy += oy

        cx, cy = self.pxpermm * cx, self.pxpermm * cy
        # cx, cy = self.cx * self.pxpermm, self.cy * self.pxpermm
        src = zeros((int(self.width * self.pxpermm), int(self.height * self.pxpermm)))
        radius = int(self.radius * self.pxpermm)
        y, x = ogrid[-radius:radius, -radius:radius]
        index = x**2 + y**2 <= radius**2

        src[cy - radius : cy + radius, cx - radius : cx + radius][index] = 255
        return src

    def traits_view(self):
        src = HGroup(UItem("src_graph", style="custom"))
        bgrp = HGroup(UItem("start_button"), UItem("stop_button", enabled_when="alive"))
        pgrp = VGroup(UItem("pos_graph", style="custom"))
        v = View(
            VGroup(
                bgrp,
                src,
                # pgrp
            ),
            resizable=True,
        )
        return v

    def _start_button_fired(self):
        self._start()

    def _stop_button_fired(self):
        self._stop()

    def _src_graph_default(self):
        g = Graph()
        p = g.new_plot(padding_top=10)
        p.data.set_data(
            "imagedata", zeros((self.height * self.pxpermm, self.width * self.pxpermm))
        )
        p.img_plot("imagedata", colormap=jet)

        p = g.new_plot(padding_bottom=10)
        p.data.set_data(
            "imagedata", zeros((self.height * self.pxpermm, self.width * self.pxpermm))
        )
        p.img_plot("imagedata", colormap=jet)

        return g

    def _pos_graph_default(self):
        g = Graph()
        p = g.new_plot()
        s, p = g.new_series()
        cp = CurrentPointOverlay(component=s)
        s.overlays.append(cp)
        self._cp = cp
        return g

if __name__ == "__main__":
    s = SeekTester()
    s.configure_traits()
# ============= EOF =============================================


"""Tests the functions in metadata.py"""

import pytest

from quantum_heom import metadata as meta
from quantum_heom.quantum_system import QuantumSystem

@pytest.mark.parametrize(
    'sites, interactions, dynamics',
    [(2, 'spin-boson', 'local dephasing lindblad'),
     (2, 'spin-boson', 'global thermalising lindblad'),
     (2, 'spin-boson', 'local thermalising lindblad'),
     (2, 'spin-boson', 'HEOM')])
def test_integrate_trace_distance_zero(sites, interactions, dynamics):

    """
    Tests that the integrated trace distance of a system with
    respect to itself is zero.
    """

    qsys = QuantumSystem(sites=sites, interaction_model=interactions,
                         dynamics_model=dynamics)

    assert meta.integrate_trace_distance([qsys], qsys) == [0]


# stage 8
import sqlite3

db = sqlite3.connect('Login.db')

print("Connection Established");

cur = db.cursor()

cur.execute("SELECT * FROM users ")

for row in cur:

    print("{} : {}".format(row[0],row[1]))

db.commit()

print("Total {} Changes in the DB".format(db.total_changes))

db.close()


from django.shortcuts import render, redirect
from hotel.models import Room, OrderRoom
from django.utils import timezone
from datetime import datetime

def search_room(request):
    if not request.GET:
        return render(request, "search_room.html")
    datetime(year=2021, month=12, day=9, hour=23, tzinfo=timezone.get_default_timezone())
    start_date = request.GET.get("start_date")
    start_date = datetime.strptime(start_date, "%Y-%m-%d")
    start_date = start_date.astimezone(timezone.get_current_timezone())
    end_date = request.GET.get("end_date")
    end_date = datetime.strptime(end_date, "%Y-%m-%d")
    end_date = end_date.astimezone(timezone.get_current_timezone())
    return redirect("search-room")


from flask import Flask, render_template, redirect, jsonify, request
from sqlalchemy import create_engine
from sqlalchemy.ext.automap import automap_base
from flask_sqlalchemy import SQLAlchemy
import os
import time

file_path = os.path.abspath(os.getcwd()) + "/bb_app/db/belly_button_biodiversity.sqlite"

# engine = create_engine("sqlite:///db/belly_button_biodiversity.sqlite") or create_engine(os.environ.get('DATABASE_URL', ''))
# engine = create_engine('sqlite:///'+ file_path) or os.environ.get('DATABASE_URL', '') #for flask
# print(engine)

app = Flask(__name__)

# app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', '') or "sqlite:///db/belly_button_biodiversity.sqlite"
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + file_path or os.environ.get('DATABASE_URL', '')
print('app.config is set')

db = SQLAlchemy(app)

db.metadata.bind = db.engine
db.metadata.reflect(db.engine)

Base = automap_base(metadata=db.metadata)
Base.prepare()

Samples_metadata = Base.classes.samples_metadata
Samples = Base.classes.samples
Otu = Base.classes.otu

@app.route("/")
def home():
    return render_template("index.html")

@app.route('/names')
def get_names():
    # from functions import find_col_names # for local hosting only
    from bb_app.functions import find_col_names # for flask app
    names = find_col_names(db.engine, 'samples')

    return jsonify(names)

@app.route('/otu')
def get_otu():

    bact_tuples = db.session.query(Otu.lowest_taxonomic_unit_found).all()
    bacteries = []
    for b_tuple in bact_tuples:
        for bact in b_tuple:
            bacteries.append(bact)
    #bacteries = [bact for b_tuple in bact_tuples for bact in b_tuple]

    return jsonify(bacteries)

@app.route('/metadata/<sample>')
def metaData_sample(sample):
    # from functions import metasample # for local hosting only
    from bb_app.functions import metasample # for flask app
    metaData = metasample(db.engine, sample)

    return jsonify(metaData)

@app.route('/wfreq/<sample>')
def washing_frequency(sample):

    # from functions import find_col_names # for local hosting only
    from bb_app.functions import find_col_names

    if sample in find_col_names(db.engine, 'samples'):
        form_sample = int(sample[3:])
        frequency = int(db.session.query(Samples_metadata.WFREQ).\
        filter(Samples_metadata.SAMPLEID == form_sample).all()[0][0])

        return jsonify(frequency)

    else:
        return f'There is no sample named {sample} in our dataset'

@app.route('/samples/<sample>')
def otu_value(sample):
    # from functions import find_col_names # for local hosting only
    from bb_app.functions import find_col_names

    if sample in find_col_names(db.engine, 'samples'):
        fetch = db.engine.execute(f'select "{sample}", otu_id from samples where "{sample}" > 0 order by "{sample}" desc' ).fetchall()
        val, ids = zip(*fetch)
        values_otu = [dict(otu_ids=list(ids), sample_values=list(val))]

        return jsonify(values_otu)

    else:
        return f'There is no sample named {sample} in our dataset'

# check if data can be entered to db (terrible code)
@app.route("/enter", methods=["GET", "POST"])
def enter():
    if request.method == "POST":

        SAMPLEID = int(request.form['SAMPLEID'])
        EVENT = request.form['EVENT']
        ETHNICITY = request.form['ETHNICITY']
        GENDER = request.form['GENDER']
        AGE = int(request.form['AGE'])
        WFREQ = int(request.form['WFREQ'])
        BBTYPE = request.form['BBTYPE']
        LOCATION = request.form['LOCATION']
        COUNTRY012 = request.form['COUNTRY012']
        ZIP012 = int(request.form['ZIP012'])
        COUNTRY1319 = request.form['COUNTRY1319']
        ZIP1319 = int(request.form['ZIP1319'])
        DOG = request.form['DOG']
        CAT = request.form['CAT']
        IMPSURFACE013 = int(request.form['IMPSURFACE013'])
        NPP013 = int(float(request.form['NPP013']))
        MMAXTEMP013 = int(float(request.form['MMAXTEMP013']))
        PFC013 = int(float(request.form['PFC013']))
        IMPSURFACE1319 = int(request.form['IMPSURFACE1319'])
        NPP1319 = int(float(request.form['NPP1319']))
        MMAXTEMP1319 = int(float(request.form['MMAXTEMP1319']))
        PFC1319 = int(float(request.form['PFC1319']))

        sample_data = Samples_metadata(SAMPLEID=SAMPLEID, EVENT=EVENT, ETHNICITY=ETHNICITY, GENDER=GENDER,\
        AGE=AGE, WFREQ=WFREQ, BBTYPE=BBTYPE, LOCATION=LOCATION, COUNTRY012=COUNTRY012, ZIP012=ZIP012,\
        COUNTRY1319=COUNTRY1319, ZIP1319=ZIP1319, DOG=DOG, CAT=CAT, IMPSURFACE013=IMPSURFACE013, NPP013=NPP013,\
        MMAXTEMP013=MMAXTEMP013, PFC013=PFC013, IMPSURFACE1319=IMPSURFACE1319, NPP1319=NPP1319, MMAXTEMP1319=MMAXTEMP1319, PFC1319=PFC1319)

        db.session.add(sample_data)

        # time.sleep(5)

        db.session.commit()

        return redirect('/', code=302)

    return render_template("form.html")

if __name__ == "__main__":
    # app.jinja_env.auto_reload = True
    # app.config['TEMPLATES_AUTO_RELOAD'] = True
    # app.run(debug=True)
    app.run()


import streamlit as st
import numpy as np
import pandas as pd
from PIL import Image
import time

st.title("Streamlit 入門")

st.write("DataFrame")

df = pd.DataFrame({"1列目": [1, 2, 3, 4], "2列目": [10, 20, 30, 40]})
st.table(df)

# markdownの表示
st.write("Markdown")
"""
# 章
## 節
### 項

```python
import streamlit as st
import numpy as np
import pandas as pd
```
"""

# プログレスバーの表示
st.write("progress bar")
"Start!"
latest_iteration = st.empty()
bar = st.progress(0)
for i in range(100):
    latest_iteration.text(f"Iteration {i + 1}")
    bar.progress(i + 1)
    time.sleep(0.2)
"Finish!"

# グラフの表示
st.write("graph")
left_column, right_column = st.columns(2)
df_chart = pd.DataFrame(np.random.rand(20, 3), columns=["a", "b", "c"])

left_column.table(df_chart)
right_column.line_chart(df_chart)
right_column.bar_chart(df_chart)

# 地図の表示
st.write("map")
df_map = pd.DataFrame(
    np.random.rand(100, 2) / [50, 50] + [35.69, 139.70], columns=["lat", "lon"]
)
st.map(df_map)

# 画像読み込み
st.write("Display Image")

if st.checkbox("Show image"):
    img = Image.open("sample.jpg")
    expander = st.expander("画像を開く")
    expander.image(img, caption="Ikuta Erika", use_column_width=True)

# select, text box
st.write("form sidebar")
st.sidebar.write("Interactive Widgets")
option = st.sidebar.selectbox("あなたが好きな数字を教えてください", list(range(1, 10)))
"あなたの好きな数字は", option, "です"

option = st.sidebar.text_input("あなたの趣味を教えてください。")
"あなたの趣味: ", option

condition = st.sidebar.slider("あなたの今の調子は?", 0, 100, 50)
"コンディション: ", condition


# COSC 482: Homework #4
# Kalyn Howes
#
# This program is to get some experience with the GLSL shading language syntax and command library.
# The program is built on the StrangeShader example from the class. Make the following changes to the
# StrangeShader example.
#
# 3.14.22

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GL.shaders import *
from Shader import *
import pygame
import numpy as np
import ctypes
from PIL import Image
import glm
import random
import time

from Box import *
from Axes2D import *
from Polygon import *

class GraphicsEngine():
    # "Addresses" for OpenGL constructs.
    VAO = 0
    Buffer = 0
    vPosition = 0
    vColor = 1
    mode = GL_FILL

    ScreenBounds = [-1, 1, -1, 1]

    # Constructor
    def __init__(self):
        # Load shaders and compile shader programs.
        try:
            shader = Shader()
            self.shaderProgram = shader.loadShadersFromFile("AspectRatioVert.glsl", "StrangeFrag.glsl")
        except Exception as err:
            for i in range(len(err.args)):
                print(err.args[i])
            raise Exception(err)

        self.setProjectionMatrices(pygame.display.get_surface().get_size())

        glUseProgram(self.shaderProgram)
        self.shadernumLoc = glGetUniformLocation(self.shaderProgram, "shadernum")
        self.timeLoc = glGetUniformLocation(self.shaderProgram, "time")

        # Set clear/background color to black.
        glClearColor(0, 0, 0, 1)

        # Create and load the objects.
        self.box = Box()
        self.starttime = time.time()

    # Turn on shader, clear screen, draw axes and boxes, swap display buffers.
    def update(self):
        glUseProgram(self.shaderProgram)
        glClear(GL_COLOR_BUFFER_BIT)
        glPolygonMode(GL_FRONT_AND_BACK, self.mode)

        now = time.time()
        runtime = now - self.starttime
        glUniform1f(self.timeLoc, runtime)

        self.box.draw()

        self.printOpenGLErrors()

    def setShaderNum(self, num):
        glUseProgram(self.shaderProgram)
        glUniform1i(self.shadernumLoc, num)

    # Set mode to fill.
    def setFill(self):
        self.mode = GL_FILL

    # Set mode to line.
    def setLine(self):
        self.mode = GL_LINE

    # Set mode to point.
    def setPoint(self):
        self.mode = GL_POINT

    def setProjectionMatrices(self, size):
        self.setProjectionMatrix(size, self.shaderProgram, "Projection")

    # Set and load the projection matrix to the graphics card.
    def setProjectionMatrix(self, size, prog, name):
        w, h = size

        # if width > height create a matrix to map scene to [-a, a] X [-1, 1]
        # if height > width create a matrix to map scene to [-1, 1] X [-a, a]
        # glm.ortho creates the scaling matrix.
        if w > h:
            aspratio = w / h
            ProjectionMatrix = glm.ortho(-aspratio, aspratio, -1, 1)
            self.ScreenBounds = [-aspratio, aspratio, -1, 1]
        else:
            aspratio = h / w
            ProjectionMatrix = glm.ortho(-1, 1, -aspratio, aspratio)
            self.ScreenBounds = [-1, 1, -aspratio, aspratio]

        # print(ProjectionMatrix)
        # print(self.ScreenBounds)

        # Load Projection Matrix to the projection matrix in the shader.
        glUseProgram(prog)
        projLoc = glGetUniformLocation(prog, name)
        glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm.value_ptr(ProjectionMatrix))

    # Dump screen buffer data to raw pixels and convert to PIL Image object.
    def getScreenImage(self):
        viewport = glGetIntegerv(GL_VIEWPORT)
        glReadBuffer(GL_FRONT)
        pixels = glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE)
        image = Image.frombytes("RGB", (viewport[2], viewport[3]), pixels)
        image = image.transpose(Image.FLIP_TOP_BOTTOM)
        return image

    # Print out any errors in the OpenGL error queue.
    def printOpenGLErrors(self):
        errCode = glGetError()
        while errCode != GL_NO_ERROR:
            errString = gluErrorString(errCode)
            print("OpenGL Error: ", errString, "\n")
            errCode = glGetError()


#!/usr/bin/env python3

import datetime
import json
import logging
import time
from pathlib import Path

import coloredlogs
import torch
from omegaconf import OmegaConf
from tqdm import tqdm

import utils
from datasets.cc_dataset import create_dataset
from datasets.cmc_dataset import CLEVRMultiChangeDataset
from datasets.original_cmc_dataset import CaptionDataset
from models import MCCFormer

logger = logging.getLogger(__name__)

def main() -> None:
    # load configuration
    cfg = utils.load_configs()

    # prepare output directory
    output_dir = Path(cfg.output_dir)
    output_dir.mkdir(exist_ok=True, parents=True)
    OmegaConf.save(cfg, output_dir.joinpath("config.yaml"))

    # logger
    utils.create_logger(output_dir)
    logger = logging.getLogger(__name__)
    coloredlogs.install(level="INFO", logger=logger)
    logger.info(OmegaConf.to_yaml(cfg))

    # set device
    device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
    cpu_device = torch.device("cpu")

    # Data loading code
    logger.info("Creating datasets and data loaders")
    if cfg.data.dataset == "rcc_dataset":
        test_dataset, test_loader = create_dataset(
            Path.cwd().joinpath("data"),
            "test",
            batch_size=1,
            seq_per_img=1,
            num_workers=cfg.data.num_workers,
        )
        num_tokens = test_dataset.vocab_size
        max_seq_length = test_dataset.max_seq_length

    elif cfg.data.dataset == "original_cmc_dataset":
        max_seq_length = 99
        with Path.cwd().joinpath(cfg.data.path, "WORDMAP_{}.json".format(cfg.data.data_name)).open(
            "r"
        ) as f:
            vocab = json.load(f)
        idx_to_word = {v: k for k, v in vocab.items()}
        num_tokens = len(vocab)

        test_dataset = CaptionDataset(
            Path.cwd().joinpath(cfg.data.path),
            cfg.data.data_name,
            "TEST",
            cfg.data.captions_per_image,
            "MOSCC",
        )
        test_loader = torch.utils.data.DataLoader(
            test_dataset,
            batch_size=1,
            shuffle=False,
            num_workers=cfg.data.num_workers,
            drop_last=False,
        )

    elif cfg.data.dataset == "cmc_dataset":
        max_seq_length = 99
        with Path.cwd().joinpath(cfg.data.vocab_path).open("r") as f:
            vocab = json.load(f)
        target_transform = utils.Word2Id(max_seq_length, vocab)
        idx_to_word = {v: k for k, v in vocab.items()}
        num_tokens = len(vocab)

        test_dataset = CLEVRMultiChangeDataset(
            Path.cwd().joinpath(cfg.data.path),
            split="test",
            use_feature=True,
            choose_one_caption=True,
            img_transform=None,
            target_transform=target_transform,
        )

        test_loader = torch.utils.data.DataLoader(
            test_dataset,
            batch_size=1,
            shuffle=False,
            num_workers=cfg.data.num_workers,
            drop_last=False,
        )
    logger.info("Length of test dataset: {}".format(len(test_dataset)))

    # prepare model
    logger.info("Creating model")
    model = MCCFormer(
        encoder_type=cfg.model.encoder_type,
        num_tokens=num_tokens,
        feature_dim=cfg.data.feature_dim,
        encoder_dim=cfg.model.encoder_dim,
        encoder_nhead=cfg.model.encoder_nhead,
        encoder_transformer_layer_num=cfg.model.encoder_transformer_layer_num,
        decoder_nhead=cfg.model.decoder_nhead,
        decoder_transformer_layer_num=cfg.model.decoder_transformer_layer_num,
        pe_type=cfg.model.pe_type,
        max_len=max_seq_length,
    )
    model.to(device)
    model.eval()

    # load pre-trained model
    if cfg.resume is None:
        exit()
    checkpoint = torch.load(Path.cwd().joinpath(cfg.resume), map_location="cpu")
    model.load_state_dict(checkpoint["model"])

    # predict captions
    result_captions_pos = []
    result_captions_neg = []
    start_time = time.time()
    with torch.no_grad():
        for i, data in enumerate(tqdm(test_loader)):
            if cfg.data.dataset == "rcc_dataset":
                (
                    d_feature,
                    n_feature,
                    q_feature,
                    targets,
                    neg_targets,
                    _,
                    _,
                    _,
                    _,
                    d_img_paths,
                    ncs_img_paths,
                    sc_feats,
                ) = data
                d_feature = d_feature.to(device)
                n_feature = n_feature.to(device)
                q_feature = q_feature.to(device)

                outputs_pos = model(d_feature, q_feature)
                caption_pos = utils.decode_seq(
                    outputs_pos.squeeze().to(cpu_device).tolist(), test_dataset.idx_to_word
                )
                image_id = d_img_paths[0].split("_")[-1]
                result_captions_pos.append({"caption": caption_pos, "image_id": image_id})

                outputs_neg = model(d_feature, n_feature)
                caption_neg = utils.decode_seq(outputs_neg[0].tolist(), test_dataset.idx_to_word)
                result_captions_neg.append({"caption": caption_neg, "image_id": image_id + "_n"})

            elif cfg.data.dataset == "original_cmc_dataset":
                if i % cfg.data.captions_per_image != 0:
                    continue

                d_feature, q_feature, target, _, _ = data
                d_feature = d_feature.to(device)
                q_feature = q_feature.to(device)

                output = model(d_feature, q_feature, start_idx=vocab["<start>"])
                output = output.squeeze().to(cpu_device).tolist()
                output = utils.decode_seq(
                    output,
                    idx_to_word,
                    start_idx=vocab["<start>"],
                    end_idx=vocab["<end>"],
                    pad_idx=vocab["<pad>"],
                )

                result_captions_pos.append({"caption": output, "image_id": i + 1})

            elif cfg.data.dataset == "cmc_dataset":
                d_feature, q_feature, target = data
                d_feature = d_feature.to(device)
                q_feature = q_feature.to(device)

                output = model(d_feature, q_feature, start_idx=vocab["<start>"])
                output = output.squeeze().to(cpu_device).tolist()
                output = utils.decode_seq(
                    output,
                    idx_to_word,
                    start_idx=vocab["<start>"],
                    end_idx=vocab["<end>"],
                    pad_idx=vocab["<pad>"],
                )

                result_captions_pos.append({"caption": output, "image_id": i + 1})

    total_time = time.time() - start_time
    total_time_str = str(datetime.timedelta(seconds=int(total_time)))
    logger.info("Test time {}".format(total_time_str))

    # save results
    with output_dir.joinpath("sc_results.json").open("w") as f:
        json.dump(result_captions_pos, f)
    with output_dir.joinpath("nsc_results.json").open("w") as f:
        json.dump(result_captions_neg, f)

if __name__ == "__main__":
    main()


from io import StringIO

f = StringIO()

f.write('hello\n')
f.write('code')

print(f.getvalue())

f2 = StringIO('Hello!\nHi!\nGoodbye!')
while True:
    s = f2.readline().strip()
    if s == '':
        break
    print(s)


from walkers_positions import walkers_positions

positions = walkers_positions

"""
Created on Sunday 28th February 2021

@author: joel pendleton & xudongke
"""

# imports
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
from scipy.ndimage import gaussian_filter

# start counter
counter = 0

# Number of persons e.g. sweeps over 6400 10000
Nps = [6400, 10000]
# fraction of infected
sicks = [0.005, 0.01, 0.02]
# coughing or not e.g. none once/hour twice/hour
Pcoughs = [0, 1 / 3600, 2 / 3600]
# possibility to investigate superemitters
superswitch = [0]
# walking speed
Upaves = [0.01, 0.1, 0.5, 1]
# ventilation timescale in seconds
taus = [100]
# diffusivity including aerosol mixing due to turbulence
Ds = [0.05]
# mask effectivity
mask_effs_out = [0, 0.6, 0.9]
mask_effs_in = [0, 0.3, 0.5]
# far-UVC susceptibility constant [cm2 mJ−1]
Zs = [0, 4.1]
# fraction of asymptomatic
asymptomatics = [0.2, 0.4]
# fever fraction in symptomatic
fevers = [0.34, 0.45, 0.88]
# use of Non-contact Infrared thermometers (NCIT)
NCITs = [0, 1]
# effectivity of Non-contact Infrared thermometers (NCIT)
NCIT_effs = [0.82]

###################################################
# System dimensions
###################################################
Nx = 20
Ny = 22
#  meters 20m*10m
Lx = 20
Ly = 22
# spacing
dx = Lx / Nx
dy = Ly / Ny

# reference for indices
radius = Nx/(2*Lx)
x = np.arange(0,Nx+1)
y = np.arange(0,Ny+1)
y2d, x2d=np.meshgrid(y,x)
# each element contains list of neighbour indices
indices_array = np.zeros((Ny+1,Nx+1),dtype=object)
# area of neighbours
area_array = np.zeros((Ny+1,Nx+1))
# create neighbour indices for each position

for x0 in x:
    for y0 in y:
        array = np.zeros_like(x2d)
        array[np.where(np.sqrt((x2d-x0)**2+(y2d-y0)**2)<radius)]=1
        # boundary conditions
        if x0<radius:
            array[:,0]=0
        if x0>Lx-radius-1:
            array[:,-1]=0
        if y0<radius:
            array[0,:]=0
        if y0>Ly-radius-1:
            array[-1,:]=0
        indices_array[y0,x0]=np.where(array==1)
        area_array[y0,x0]=len(indices_array[y0,x0])

###################################################
# UV field intensity
###################################################
# grid for intensity field
x_field = np.arange(0,Nx+1,dx)
y_field = np.arange(0,Ny+1,dy)
x2d_field,y2d_field=np.meshgrid(x_field,y_field)
# position of UV lamp
x0_field = x_field[int(len(x_field)/2)]
y0_field = y_field[int(len(y_field)/2)]

# far-UVC maximum intensity [mJ cm-2 s-1]
Ep_0 = 0.0014

denominator = ((x2d_field-x0_field)**2+(y2d_field-y0_field)**2)
denominator = np.where(denominator <= 0, 1, denominator)

# far-UVC intensity field
Ep = Ep_0/denominator
# apply Gaussian filter with sigma=4
Ep = gaussian_filter(Ep, 4)

###################################################
# Parameters selection
###################################################
aaa = 0
# 2% of infected people
bbb = 2
# 2 coughs per hour
ccc = 2
ddd = 0
eee = 2
fff = 0
ggg = 0
# mask eff out 60%
hhh_out = 1
# mask eff in 30%
hhh_in = 1
# with UV light
iii = 1
# 40% asymptomatic
jjj = 1
# 45% fever in symptomatic
kkk = 1
# do not use NCIT
lll = 0
mmm = 0

# total number of people
Np = Nps[aaa]
# fraction of sick persons
sick_fraction = sicks[bbb]
# symptomatic fraction
symptomatic = 1 - asymptomatics[jjj]
# do not use NCIT
if NCITs[lll] == 0:
    # total number of infected people
    total_sick = round(Np * sick_fraction)
# use NCIT
else:
    total_sick = round(Np * sick_fraction * (1 - symptomatic * fevers[kkk] * NCIT_effs[mmm]))

# number of people in the room, assume 100 rooms
N = int(Np / 100)
# Hypergeometric distribution
rv = stats.hypergeom(Np, total_sick, N)
# sick of people in room
N_sicks = np.arange(0, N)
pmf_sick = rv.pmf(N_sicks)
# sick of people in room with nonzero probability
N_sicks = N_sicks[np.round(pmf_sick * 100) != 0]
print(f'possible number of infected people in room: {N_sicks}')
# choose the highest number of sick people in room
N_sick = N_sicks[-1]
# you can pick the fraction how many emit more than others
superemitter = 0.1
super_sick = superswitch[ddd] * max(1, round(superemitter * N_sick));
# sp = 0 -> healthy sp=1 -> sick
sp = np.zeros(N)
sp[0:N_sick] = 1
# super emitter
se = np.zeros(N)
se[np.where(sp == 1)][0:super_sick] = 1
# the healthy persons gain a dose
# i.e. number of aerosols
dose = np.zeros(N)

# velocity of each individual
Upave = Upaves[eee]
# timescale [s] of removing aerosols upwards due to ventilation
tau = taus[fff]
# m^2/s  diffusivity in x,y plane direction due to turbulence
D = Ds[ggg]
# mask effectivity
mask_eff_out = mask_effs_out[hhh_out]
mask_eff_in = mask_effs_in[hhh_in]
# UV light: 0 if not, 1 if yes
Z = Zs[iii]

# concentration, assume zerogradient bc's
C = np.zeros((Ny+1, Nx+1))

# source term in units [# of particles / 0.01 m^3 ]
S = np.zeros((Ny+1, Nx+1))

simuTime = 2000  # seconds
dt = 1  # seconds
simuSteps = round(simuTime / dt)

###################################################
# parameters of sick individuals
###################################################
# lambda aerosols [1/s] e.g. 5 means 5 per second into control volume
lambdanormal = 5 * (1 - mask_eff_out)

# how many particles come from a single cough, assume this is
# immediately spread to the control volume during dt
lambdacough = 40000 * (1 - mask_eff_out)

# how many m^3 you inhale in a second, here 20 l per 60 sec
Vinh = 0.001 * 20 / 60
# volume in which the droplets locate
Vvol = area_array * dx * dy * 1
# Here. e.g. 1 cough per 3600 sec; then during dt probability dt*Pcough
Pcough = Pcoughs[ccc]

# PDF that accumulates the dose
# PDF = np.zeros((1,1+lambdacough*100))
aveinf = []
maxinf = []
aveC = []
Np = 20

# run single simulation with fixed parameters
for k in range(0, simuSteps):

    # zero source term
    S = 0 * S

    for s in range(0, Np):

        xp = positions[s, k, 0]
        yp = positions[s, k, 1]

        # make person coordinate an integer
        xpint = int(xp)
        ypint = int(yp)
        # sick persons generate lambda*dt particles per volume during dt
        if sp[s] == 1:

            S[ypint, xpint] += (
                        lambdanormal * dt + se[s] * lambdanormal * 9 * dt) / area_array[ypint, xpint]
            # coughing occurs at probablity Pcough*dt
            if np.random.random() < Pcough * dt:
                S[xpint, ypint] += lambdacough / area_array[ypint, xpint]
        # healthy individuals accumulate a dose
        else:

            dose[s] += np.sum(C[ypint, xpint]) *(Vinh/Vvol[ypint,xpint])*dt*(1-mask_eff_in)

    # diffusion equation with source and sink terms for aerosol concentration
    # following the paper using expl.Euler and CD2 method (finite difference)
    C = C + dt * D * (np.roll(C, 1, axis=0) + np.roll(C, -1, axis=0) + np.roll(C, 1, axis=1) + np.roll(C, -1,
                                            axis=1) - 4 * C) / dx ** 2
    # hard walls boundary conditions
    C[0, :] = 0
    C[-1, :] = 0
    C[:, 0] = 0
    C[:, -1] = 0
    # [C] number of aerosols in the control volume
    C = C + S - dt * C / tau - Z * Ep * C

    if k % 100 == 0:
        plt.clf()
        plt.plot(xp, yp, '.')
        plt.title('Walkers in a public place')
        plt.xlabel('x [m]')
        plt.ylabel('y [m]')
        plt.xlim(0, Lx)
        plt.ylim(0, Ly)
        plt.gca().set_aspect('equal', adjustable='box')
        plt.pause(1)

        plt.clf()
        plt.imshow(C / 1000, extent=[0, Lx, 0, Ly])
        plt.title('Number of aerosols per liter')
        plt.xlabel('x [m]')
        plt.ylabel('y [m]')
        plt.colorbar()
        plt.gca().set_aspect('equal', adjustable='box')
        plt.pause(1)

        # append dose and concentration
        aveinf.append(np.mean(dose[sp == 0]))
        maxinf.append(np.max(dose))
        aveC.append(np.mean(C))

np.savetxt(f'data_{aaa}_{bbb}_{ccc}_{ddd}_{eee}_{fff}_{ggg}_{hhh_out}_{hhh_in}_{iii}_{jjj}_{kkk}_{lll}_{mmm}.txt'
           , np.column_stack((aveinf, maxinf, aveC)))


import argparse
import copy
import os
import shutil
from datetime import datetime
from pathlib import Path

import yaml
from easydict import EasyDict

from .stuff import set_deterministic
from .tg_logger import TelegramLogger

def parse_args():
    parser = argparse.ArgumentParser(description="Pipeline")
    parser.add_argument("config_file", type=str, help="path to config file")
    parser.add_argument(
        "--checkpoints_dir", type=str, default=None, help="models are saved here"
    )
    parser.add_argument(
        "--no_tg",
        action="store_true",
        help="send train information to telegram after training",
    )

    parser.add_argument(
        "--debug", action="store_true", help="Turns off logging and checkpointing"
    )
    return parser.parse_args()

def setup_experiment():
    args = parse_args()
    cfg = load_config(args.config_file)
    experiment = dict(args=args, cfg=cfg)

    set_deterministic(cfg.defaults.seed)

    if args.debug:
        args.no_tg = True

    if not args.no_tg:
        tg_logger = TelegramLogger()
        experiment["tg_logger"] = tg_logger

    if args.checkpoints_dir is None:
        checkpoints_name = extract_config_name(args.config_file)
        checkpoints_name = checkpoints_name + datetime.now().strftime("_%B%d_%H:%M:%S")
        args.checkpoints_dir = "checkpoints/" + checkpoints_name

    checkpoints_dir = Path(args.checkpoints_dir)
    if not args.debug:
        checkpoints_dir.mkdir(parents=True, exist_ok=True)
        shutil.copyfile(args.config_file, checkpoints_dir / "config.yml")

    return experiment

def load_config(config_path):
    with open(config_path, "r") as fid:
        config = yaml.load(fid, Loader=yaml.FullLoader)
    config = EasyDict(config)
    return config

def extract_config_name(config_path):
    config_name = os.path.split(config_path)[-1]
    return config_name.replace(".yml", "")

def update_config(cfg, stage_cfg):
    cfg = copy.deepcopy(cfg)

    for component_name, component_cfg in stage_cfg.items():

        if component_name in ("lightning", "dataloader"):
            # Update changes
            for k, v in component_cfg.items():
                cfg[component_name][k] = v

        elif component_name == "datasets":
            for dataset_cfg in component_cfg.list:

                # Find index of dataset which will be changed
                idx_dataset_to_replace = -1
                for i in range(len(cfg.datasets)):
                    if cfg.datasets.list[i].id == dataset_cfg.id:
                        idx_dataset_to_replace = i
                        break

                # Update components of dataset_cfg
                for k, v in dataset_cfg.items():
                    cfg.datasets.list[idx_dataset_to_replace][k] = v

        elif component_name == "model":
            # model.{task}.heads[target_name].criterion
            for task_name, stage_task_cfg in component_cfg.items():
                for stage_head_cfg in stage_task_cfg.heads:

                    target_name = stage_head_cfg.target

                    # Find index of head
                    idx_head = -1
                    for i in range(len(cfg.model[task_name].heads)):
                        if cfg.model[task_name].heads[i].target == target_name:
                            idx_head = i
                            break

                    # Replace criterion
                    cfg.model[task_name].heads[
                        idx_head
                    ].criterion = stage_head_cfg.criterion

        elif component_name in ("optimizer", "scheduler"):
            # Replace original component with new
            cfg[component_name] = copy.deepcopy(component_cfg)

        else:
            raise KeyError(
                f"Component {component_name} can't be replaced during training."
            )

    return cfg


"""
Asserto exception hierarchy.
    * ActualTypeError
"""
import typing

from .handlers import Handler

class ActualTypeError(TypeError):
    """Raised when type error problems occur with the actual value"""

class ExpectedTypeError(TypeError):
    """Raised when type error problems occur with the expected value"""

class DynamicCallableWithArgsError(TypeError):
    """
    Raised when a dynamic lookup via `attr_is` returns a callable that expects arguments.
    Asserto currently only supports 0-arg callables as part of its dynamic lookup and
    invocations.
    """

class UnsupportedHandlerTypeError(ValueError):
    """Raised when the actual value passed to a handler is not suitable for it to handle."""

    def __init__(self, handler: typing.Type[Handler], method: str, value: typing.Any) -> None:
        super().__init__(f"`{handler.__name__}` cannot accept type: {type(value)} when calling: {method}")


# Licensed under a 3-clause BSD style license - see LICENSE.rst
import matplotlib.pyplot as plt

__all__ = [
    "plot_spectrum_datasets_off_regions",
    "plot_npred_signal",
]

def plot_spectrum_datasets_off_regions(
    datasets, ax=None, legend=None, legend_kwargs=None, **kwargs
):
    """Plot the off regions of spectrum datasets.

    Parameters
    ----------
    datasets : `~gammapy.datasets.Datasets` or list of `~gammapy.datasets.SpectrumDatasetOnOff`
        List of spectrum on-off datasets.
    ax : `~astropy.visualization.wcsaxes.WCSAxes`
        Axes object to plot on.
    legend : bool
        Whether to add/display the labels of the off regions in a legend. By default True if
        ``len(datasets) <= 10``.
    legend_kwargs : dict
        Keyword arguments used in `matplotlib.axes.Axes.legend`. The ``handler_map`` cannot be
        overridden.
    **kwargs : dict
        Keyword arguments used in `gammapy.maps.RegionNDMap.plot_region`. Can contain a
        `~cycler.Cycler` in a ``prop_cycle`` argument.

    Notes
    -----
    Properties from the ``prop_cycle`` have maximum priority, except ``color``,
    ``edgecolor``/``color`` is selected from the sources below in this order:
    ``kwargs["edgecolor"]``, ``kwargs["prop_cycle"]``, ``matplotlib.rcParams["axes.prop_cycle"]``
    ``matplotlib.rcParams["patch.edgecolor"]``, ``matplotlib.rcParams["patch.facecolor"]``
    is never used.

    Examples
    --------
    Plot without legend and with thick circles::

        plot_spectrum_datasets_off_regions(datasets, ax, legend=False, linewidth=2.5)

    Plot to visualise the overlap of off regions::

        plot_spectrum_datasets_off_regions(datasets, ax, alpha=0.3, facecolor='black')

    Plot that cycles through colors (``edgecolor``) and line styles together::

        plot_spectrum_datasets_off_regions(datasets, ax, prop_cycle=plt.cycler(color=list('rgb'), ls=['--', '-', ':']))  # noqa: E501

    Plot that uses a modified `~matplotlib.rcParams`, has two legend columns, static and
    dynamic colors, but only shows labels for ``datasets1`` and ``datasets2``. Note that
    ``legend_kwargs`` only applies if it's given in the last function call with ``legend=True``::

        plt.rc('legend', columnspacing=1, fontsize=9)
        plot_spectrum_datasets_off_regions(datasets1, ax, legend=True, edgecolor='cyan')
        plot_spectrum_datasets_off_regions(datasets2, ax, legend=True, legend_kwargs=dict(ncol=2))
        plot_spectrum_datasets_off_regions(datasets3, ax, legend=False, edgecolor='magenta')
    """
    from matplotlib.legend_handler import HandlerPatch, HandlerTuple
    from matplotlib.patches import CirclePolygon, Patch

    if ax is None:
        ax = plt.subplot(projection=datasets[0].counts_off.geom.wcs)

    legend = legend or legend is None and len(datasets) <= 10
    legend_kwargs = legend_kwargs or {}
    handles, labels = [], []

    prop_cycle = kwargs.pop("prop_cycle", plt.rcParams["axes.prop_cycle"])

    for props, dataset in zip(prop_cycle(), datasets):
        plot_kwargs = kwargs.copy()
        plot_kwargs["facecolor"] = "None"
        plot_kwargs.setdefault("edgecolor")
        plot_kwargs.update(props)

        dataset.counts_off.plot_region(ax, **plot_kwargs)

        # create proxy artist for the custom legend
        if legend:
            handle = Patch(**plot_kwargs)
            handles.append(handle)
            labels.append(dataset.name)

    if legend:
        legend = ax.get_legend()
        if legend:
            handles = legend.legendHandles + handles
            labels = [text.get_text() for text in legend.texts] + labels

        handles = [(handle, handle) for handle in handles]
        tuple_handler = HandlerTuple(ndivide=None, pad=0)

        def patch_func(
            legend, orig_handle, xdescent, ydescent, width, height, fontsize
        ):
            radius = width / 2
            return CirclePolygon((radius - xdescent, height / 2 - ydescent), radius)

        patch_handler = HandlerPatch(patch_func)

        legend_kwargs.setdefault("handletextpad", 0.5)
        legend_kwargs["handler_map"] = {Patch: patch_handler, tuple: tuple_handler}
        ax.legend(handles, labels, **legend_kwargs)

    return ax

def plot_npred_signal(
    dataset,
    ax=None,
    model_names=None,
    region=None,
    **kwargs,
):
    """
    Plot the energy distribution of predicted counts of a selection of models assigned to a dataset.

    The background and the sum af all the considered models predicted counts are plotted on top of individual
    contributions of the considered models.

    Parameters
    ----------
    dataset : an instance of `~gammapy.datasets.MapDataset`
        The dataset from which to plot the npred_signal.
    ax : `~matplotlib.axes.Axes`
        Axis object to plot on.
    model_names : list of str
        The list of models for which the npred_signal is plotted. Default is None.
        If None, all models are considered.
    region: `~regions.Region` or `~astropy.coordinates.SkyCoord`
        Region used to reproject predicted counts. Default is None.
        If None, use the full dataset geometry.
    **kwargs : dict
        Keyword arguments to pass to `~gammapy.maps.RegionNDMap.plot`.

    Returns
    -------
    axes : `~matplotlib.axes.Axes`
        Axis object
    """

    npred_not_stack = dataset.npred_signal(
        model_names=model_names, stack=False
    ).to_region_nd_map(region)
    npred_background = dataset.npred_background().to_region_nd_map(region)

    if ax is None:
        ax = plt.gca()

    npred_not_stack.plot(ax=ax, axis_name="energy", **kwargs)
    if npred_not_stack.geom.axes["models"].nbin > 1:
        npred_stack = npred_not_stack.sum_over_axes(["models"])
        npred_stack.plot(ax=ax, label="stacked models")
    npred_background.plot(ax=ax, label="background", **kwargs)

    ax.set_ylabel("Predicted counts")
    ax.legend()

    return ax


import numpy as np

def smooth_array_fft_np(a, keep_frac=(0.1,0.2,0.2,0.2), nbatch=0, array_only=True):
# a = a[:20]
    s = a.shape
    dim = len(keep_frac)
    axes = list(range(nbatch,nbatch+dim))
    a_f = np.fft.fftn(a, axes=axes)
    for i in range(dim):
        nkeep = int(s[nbatch+i]*keep_frac[i])
        a_f[(slice(None),)*(nbatch+i) + (slice(nkeep+1,-nkeep if nkeep>0 else s[nbatch+i]),)] = 0
        # print(f'debug i {i} nkeep {nkeep} slice {(slice(None),)*nbatch + (slice(nkeep+1,-nkeep),)}')
    ap = np.fft.ifftn(a_f, axes=axes).real
    # print('FT shape', a_f.shape, "out shape", ap.shape)
    print('FFT smoothing RMSE', np.sqrt(np.mean((a-ap)**2)), 'MAE', np.mean(np.abs(a-ap)))
    if array_only:
        return ap
    else:
        freq = np.stack(np.meshgrid(*[np.fft.fftfreq(i) for i in s[nbatch:nbatch+dim]], sparse=False, indexing='ij'), -1)
        # print(f'freq shape {freq.shape}')
        return ap, a_f, freq

def derivative_fft_np(a_f, freq, dx_index, axes=(1,2,3,4)):
    return np.fft.ifftn(2j*np.pi*a_f* freq[None,...,dx_index,None], axes=axes).real

def gradient_fft_np(a_f, freq, dx_indices, axes=(1,2,3,4)):
    return np.fft.ifftn(2j*np.pi*a_f* freq[None,...,dx_indices], axes=axes).real

def laplacian_fft_np(a_f, freq, dx_indices, axes=(1,2,3,4)):
    return np.fft.ifftn(-(2*np.pi)**2 *a_f* np.sum(freq[None,...,dx_indices]**2,axis=-1,keepdims=True), axes=axes).real

if __name__ == '__main__':
    # a = np.load('/g/g90/zhou6/data/LJ20new/valid.npy')
    # smooth_array_fft_np(a, nbatch=1)
    if False:
        print('testing derivative')
        import matplotlib.pyplot as plt
        t, x = np.mgrid[-10:11, -21:22]
        # a = np.stack([t**2*x, np.exp(-t/5)*x**2, np.exp(-t/5)*x**3, np.exp(-t/15)*np.sin(x**2/10), np.cos(-np.sqrt(t)/0.5)*np.sin(x**2/40)],0)
        a = np.stack([np.sin(t*0.9), np.cos(x*0.7), np.exp(-(t**2*0.05 + x**2*0.013 + t*x*0.018)), np.exp((t*1.5-x*0.9)/15), np.cos(-t*0.7-x*0.2)],0)
        dim=2
        a = (a/np.linalg.norm(a,axis=(1,2),keepdims=True))[..., None]
        a+= np.random.randn(*a.shape)*2e-3
        # dadt_analytic = np.stack([2*(t-10)*x, (-1/5)*np.exp(-t/5)*x**2, (-1/5)*np.exp(-t/5)*x**3, (-1/15)*np.exp(-t/15)*np.sin(x**2/10), np.sin(np.sqrt(t)/0.5)*(-1/np.sqrt(t)/0.25)*np.sin(x**2/40)],0)[..., None]
        ap, a_f, freq = smooth_array_fft_np(a, keep_frac=(0.2,0.2), nbatch=1, array_only=False)
        # dadt_diff = a[:,1:]-a[:,:-1]
        # dadt_diff = np.concatenate([dadt_diff[:,:1], (dadt_diff[:,1:]+dadt_diff[:,:-1])/2, dadt_diff[:,-1:]],1)
        dadt_diff = (np.roll(a,-1,1)-np.roll(a,1,1))/2
        lapl_diff = np.roll(a,-1,2)+np.roll(a,1,2)-2*a
        # dadt_fft = np.fft.ifftn(1j*((2*np.pi)**(dim/2))*a_f* freq[None,...,0,None], axes=(1,2)).real
        dadt_fft = derivative_fft_np(a_f, freq, 0, axes=(1,2))
        lapl_fft = laplacian_fft_np(a_f, freq, slice(1,2), axes=(1,2))
        print(f'da/dt diff {np.sqrt(np.mean((dadt_diff-dadt_fft)**2))}')
        fig, axs = plt.subplots(8,len(a))
        for i in range(len(a)):
            axs[0,i].matshow(a[i,...,0])
            axs[0,i].set_axis_off()
            axs[1,i].matshow(ap[i,...,0])
            axs[1,i].set_axis_off()
            axs[2,i].matshow(dadt_diff[i,...,0])
            axs[2,i].set_axis_off()
            axs[3,i].matshow(dadt_fft[i,...,0])
            axs[3,i].set_axis_off()
            axs[4,i].matshow(np.abs(a_f[i,...,0])**0.15)
            axs[4,i].set_axis_off()
            axs[5,i].scatter(dadt_fft[i].ravel(), dadt_diff[i].ravel())
            # axs[5,i].set_axis_off()
            axs[6,i].matshow(lapl_diff[i,...,0])
            axs[6,i].set_axis_off()
            axs[7,i].matshow(lapl_fft[i,...,0])
            axs[7,i].set_axis_off()
        plt.show()

    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument('arr', type=str, default='', help='input array')
    parser.add_argument('-o', type=str, default='', help='output array')
    parser.add_argument('--tkeep', type=float, default=0.2, help='how many temporal Fourier components to keep')
    parser.add_argument('--skeep', type=float, default=0.2, help='how many spatial Fourier components to keep')
    args = parser.parse_args()
    a = np.load(args.arr)
    dim = a.ndim-2
    ap = smooth_array_fft_np(a, keep_frac=(args.tkeep,)+((args.skeep,)*(dim-1)), nbatch=1, array_only=True)
    if args.o:
        np.save(args.o, ap)


from typing import List

import mopyx
import oaas

from adhesive_event_debugger.core import ui_thread

class Event:
    def __init__(self,
                 *,
                 event_id: str,
                 task_id: str,
                 task_name: str) -> None:
        self.event_id = event_id
        self.task_id = task_id
        self.task_name = task_name

class EventGenerator:
    def __init__(self,
                 *,
                 task_id: str,
                 task_name: str) -> None:
        self.task_id = task_id
        self.task_name = task_name

@mopyx.model
class Model:
    def __init__(self):
        self.event_generators: List[EventGenerator] = []
        self.active_events: List[Event] = []

instance = Model()

@oaas.service("adhesive-events")
class EventGenerators:
    @ui_thread
    @mopyx.action
    def register_event_generator(self, task_id, task_name) -> None:
        instance.event_generators.append(EventGenerator(
            task_id=task_id,
            task_name=task_name,
        ))

    @ui_thread
    @mopyx.action
    def register_active_event(self, event_id, task_id, task_name) -> None:
        instance.active_events.append(Event(
            event_id=event_id,
            task_id=task_id,
            task_name=task_name,
        ))

    def is_event_active(self, event_id) -> bool:
        for event in instance.active_events:
            if event.event_id == event_id:
                return True

        return False


from datetime import date
from decimal import Decimal

import httpx

from currency_exchange.database.repositories import ExchangeRateRepository
from currency_exchange.enums import Currency
from currency_exchange.exceptions import (
    ExchangeRateRecordDoesNotExist,
    ExchangeRateUnavailable,
)
from currency_exchange.services.nbp_api import NBPApiService

class CurrencyExchangeService:
    def __init__(self, exchange_rate_repository: ExchangeRateRepository, nbp_api_service: NBPApiService):
        self.exchange_rate_repository = exchange_rate_repository
        self.nbp_api_service = nbp_api_service

    async def _get_exchange_rate(self, rate_date: date, currency: Currency) -> Decimal:
        try:
            exchange_rate = await self.exchange_rate_repository.get_exchange_rate(rate_date, currency)
            if exchange_rate.rate is None:
                raise ExchangeRateUnavailable()
            return exchange_rate.rate
        except ExchangeRateRecordDoesNotExist:
            try:
                rate = await self.nbp_api_service.get_exchange_rate(rate_date, currency)
            except ExchangeRateUnavailable:
                # if exchange rate is unavailable for specific date then insert null value to database
                await self.exchange_rate_repository.insert_exchange_rate(rate_date, currency, None)
                raise
            except httpx.HTTPError as err:
                # if api call failed raise exception, but don't save null value of the exchange rate
                raise ExchangeRateUnavailable() from err
            await self.exchange_rate_repository.insert_exchange_rate(rate_date, currency, rate)
        return rate

    async def exchange(self, amount: float, in_currency: Currency, out_currency: Currency, exchange_date: date) -> float:
        if in_currency == Currency.PLN:
            exchange_rate = await self._get_exchange_rate(exchange_date, out_currency)
            return float(Decimal(amount) / exchange_rate)
        if out_currency == Currency.PLN:
            exchange_rate = await self._get_exchange_rate(exchange_date, in_currency)
            return float(Decimal(amount) * exchange_rate)
        raise ValueError("in_currency or out_currency argument has to be PLN.")


from collections.abc import Iterator
import json
from typing import Any, Callable
from .RenderedNode import RenderedNode

CALLABLE_KEY = "__dh_cbid"
OBJECT_KEY = "__dh_obid"
ELEMENT_KEY = "__dh_elem"

class NodeEncoder(json.JSONEncoder):
    """
    Encode the node in JSON. Store any replaced objects and callables in their respective arrays.
    - RenderedNodes in the tree are replaced with a dict with property `ELEMENT_KEY` set to the name of the element, and props set to the props key.
    - callables in the tree are replaced with an object with property `CALLABLE_KEY` set to the index in the callables array.
    - non-serializable objects in the tree are replaced wtih an object with property `OBJECT_KEY` set to the index in the objects array.
    """

    _callable_id_prefix: str
    """
    Prefix to use for callable ids. Used to ensure callables used in stream are unique.
    """

    _callables: list[Callable]
    """
    List of callables parsed out of the document
    """

    _callable_id_dict: dict[int, int]
    """
    Dictionary from a callables id to the index in the callables array.
    """

    _objects: list[Any]
    """
    List of objects parsed out of the document
    """

    _object_id_dict: dict[int, int]
    """
    Dictionary from an objects id to the index in the objects array.
    """

    def __init__(self, *args, callable_id_prefix: str = "cb", **kwargs):
        """
        Create a new NodeEncoder.

        Args:
            *args: Arguments to pass to the JSONEncoder constructor
            callable_id_prefix: Prefix to use for callable ids. Used to ensure callables used in stream are unique.
            **kwargs: Args to pass to the JSONEncoder constructor
        """
        super().__init__(*args, **kwargs)
        self._callable_id_prefix = callable_id_prefix
        self._callables = []
        self._callable_id_dict = {}
        self._objects = []
        self._object_id_dict = {}

    def default(self, node: Any):
        if isinstance(node, RenderedNode):
            return self._convert_rendered_node(node)
        elif callable(node):
            return self._convert_callable(node)
        else:
            try:
                return super().default(node)
            except TypeError:
                # This is a non-serializable object. We'll store a reference to the object in the objects array.
                return self._convert_object(node)

    @property
    def callables(self) -> list[Callable]:
        return self._callables

    @property
    def objects(self) -> list[Any]:
        return self._objects

    def _convert_rendered_node(self, node: RenderedNode):
        result = {ELEMENT_KEY: node.name}
        if node.props is not None:
            result["props"] = node.props
        return result

    def _convert_callable(self, cb: callable):
        callable_id = id(cb)
        callable_index = self._callable_id_dict.get(callable_id, len(self._callables))
        if callable_index == len(self._callables):
            self._callables.append(cb)
            self._callable_id_dict[callable_id] = callable_index

        return {
            CALLABLE_KEY: f"{self._callable_id_prefix}{callable_index}",
        }

    def _convert_object(self, obj: Any):
        object_id = id(obj)
        object_index = self._object_id_dict.get(object_id, len(self._objects))
        if object_index == len(self._objects):
            self._objects.append(obj)
            self._object_id_dict[object_id] = object_index

        return {
            OBJECT_KEY: object_index,
        }


import os
import requests
import pandas as pd
import json

data = requests.get(
     'https://resultados.tse.jus.br/oficial/ele2022/544/dados-simplificados/br/br-c0001-e000544-r.json')
json_data = json.loads(data.content)
tempo = 60
candidato=[]
partido = []
votos=[]
porcentagem=[]
pa=json_data['pst']
os.system('cls')

for informacoes in json_data['cand']:

    candidato.append(informacoes['nm'])
    votos.append(informacoes['vap'])
    porcentagem.append(informacoes['pvap'])

df_eleicao = pd.DataFrame(list(zip(candidato,votos,porcentagem)),columns=['Candidato','N° Votos','Porcentagem'])
print("Porcentagem das urnas apuradas: ",pa,"%")
print(df_eleicao)


from django.http import Http404
from rest_framework.permissions import DjangoObjectPermissions, SAFE_METHODS

class BaseObjectPermission(DjangoObjectPermissions):
    """
    Similar to `DjangoObjectPermissions`, but adding 'view' permissions.
    """
    perms_map = {
        'GET': ['%(app_label)s.view_%(model_name)s'],
        'OPTIONS': ['%(app_label)s.view_%(model_name)s'],
        'HEAD': ['%(app_label)s.view_%(model_name)s'],
        'POST': ['%(app_label)s.add_%(model_name)s'],
        'PUT': ['%(app_label)s.change_%(model_name)s'],
        'PATCH': ['%(app_label)s.change_%(model_name)s'],
        'DELETE': ['%(app_label)s.delete_%(model_name)s'],
    }

class ObjectPermission(BaseObjectPermission):
    def has_object_permission(self, request, view, obj):
        # authentication checks have already executed via has_permission
        if view.get_permission_object():
            obj = view.get_permission_object()
            model_cls = obj._meta.model
        else:
            model_cls = self._get_queryset(view)
        perms = self.get_required_object_permissions(request.method, model_cls)
        user = request.user
        if not user.has_perms(perms, obj):
            # If the user does not have permissions we need to determine if
            # they have read permissions to see 403, or not, and simply see
            # a 404 response.

            if request.method in SAFE_METHODS:
                # Read permissions already checked and failed, no need
                # to make another lookup.
                raise Http404

            read_perms = self.get_required_object_permissions('GET', model_cls)
            if not user.has_perms(read_perms, obj):
                raise Http404
            # Has read permissions.
            return False
        return True

    def has_permission(self, request, view):
        # Workaround to ensure DjangoModelPermissions are not applied
        # to the root view when using DefaultRouter.
        if getattr(view, '_ignore_model_permissions', False):
            return True

        if not request.user or (
           not request.user.is_authenticated and self.authenticated_users_only):
            return False

        if view.get_permission_object():
            model_cls = view.get_permission_object()._meta.model
        else:
            queryset = self._queryset(view)
            model_cls = queryset.model
        perms = self.get_required_permissions(request.method, model_cls)
        return request.user.has_perms(perms)


# Purpose: Pre-processing daily CMIP5 GCM 500 hPa geopotential height data and classification
#          of Central European circulation types with the cost733class software

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
#                                                                                #
# Project:  Practicum MeteoSwiss/ETH Zurich                                                     #
#           Frequency and Persistence of Central European Circulation Types                     #
# My Name:  Maurice Huguenin-Virchaux                                                           #
# My Email: hmaurice@student.ethz.ch                                                            #
# Date:     11.12.2018, 16:16 CET                                                               #
#                                                                                #
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #

# preamble
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from netCDF4 import Dataset
import numpy as np
import matplotlib.pyplot as plt
from cdo import *
cdo = Cdo()
import os
from datetime import datetime
import sys
#cdo.debug = True

variable = 'zg'
method = 'GWT'
classes = '10'

# file paths
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
path_hist='/net/atmos/data/cmip5/historical/day/' # input file path 1
path_rcp='/net/atmos/data/cmip5/rcp85/day/'       # input file path 2
# file path for processed files
path_processed='/net/h2o/climphys/hmaurice/Practicum_meteoswiss_output/cost/cmip5/'
# file path for cost output files
path_cost='/net/h2o/climphys/hmaurice/Practicum_meteoswiss_output/cost/cmip5/'

# array with model names and realisations <- first for the CH2018 models only

## CH2018 model list
#a = ['EC-EARTH', 'HadGEM2-ES', 'MPI-ESM-LR', 'MIROC5', 'CanESM2', 'IPSL-CM5A-MR',
#     'NorESM1-M', 'GFDL-ESM2M']; b = ['r1i1p1', 'r2i1p1', 'r3i1p1', 'r12i1p1']

## small model list for testing
a = ['GFDL-ESM2M'];
b = ['r1i1p1']

## all CMIP5 model list
#a = ['ACCESS1-3',       'CanESM2',
#      'CMCC-CMS',      'GFDL-CM3',     'HadGEM2-AO',    'IPSL-CM5A-MR',
#      'MIROC-ESM-CHEM',  'MRI-CGCM3',   'bcc-csm1-1',    'CCSM4',      'CNRM-CM5',
#      'GFDL-ESM2G',  'HadGEM2-CC', 'IPSL-CM5B-LR',  'MPI-ESM-LR',      'MRI-ESM1',
#      'bcc-csm1-1-m',  'CMCC-CESM',   'EC-EARTH',  'GFDL-ESM2M',  'HadGEM2-ES',
#      'MIROC5',        'MPI-ESM-MR',      'NorESM1-M']
#b = ['r1i1p1', 'r2i1p1', 'r3i1p1', 'r4i1p1', 'r12i1p1']

# example filename: zg_day_GFDL-ESM2M_historical_r1i1p1_20010101-20051231.nc
for model in a:                 # loop over all models
    for realisation in b:       # loop over all realisations
        # combine array elements
        s = path_hist + variable + '/' + model + '/' + realisation + '/'
        t = path_rcp + variable + '/' + model + '/' + realisation + '/'
        output_name = 'zg_day_' + model + '_historical_rcp85_' + realisation + '.nc'

        # (1) check if data exists
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # print 'No data' for model realisations that do not exist
        if os.path.isdir(s) == False and os.path.isdir(t) == False or \
           os.path.isdir(s) == True and os.path.isdir(t) == False:
            print('No data for: ' + model + '/' + realisation)
            continue

        starttime = datetime.now() # start stopwatch

        # (2) merge all historical and rcp85 files
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # now use cdo merge for that file path
        cdo.mergetime(input = s + 'zg_day_*', output = path_processed + 'zg_day_' + model +
                      '_' + realisation + '_historical.nc', force = False)
        cdo.mergetime(input = t + 'zg_day_*', output = path_processed + 'zg_day_' + model +
                      '_' + realisation + '_rcp85.nc', force = False)

        # (3) merge newly created hist + rcp85 file into one large file
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        filenames = [i for i in os.listdir(path_processed) if
                     i.startswith('zg_day_' + model + '_' + realisation)]
        print(filenames) # print filenames in console
        cdo.mergetime(input = ' '.join(filenames), output = path_processed + output_name,
                      force = False)
        print('Merging hist + rcp85 data done:')
        print(datetime.now() - starttime) # print time after one iteration

        # (4) subsetting data to reduce size
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        cdo.invertlat(input = '-setlevel,0 -sellevel,50000 -selname,zg -selyear,1960/2099 \
        -sellonlatbox,2.5,20,40.73,52.10 ' + path_processed + output_name,
                      output = output_name[:-3] + '_process.nc', force = False)
        print('Subsetting data done:')
        print(datetime.now() - starttime) # print time after one iteration

        # (5) adjusting time dimension
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        output_name = output_name[:-3] + '_process.nc'
        os.system("ncap2 -O -s " + '"time=time*24+50*365" ' + '-s ' + "'time@units=" +
                  '"hours since 1900-01-01 00:00:00' + '"' + "' " + path_processed +
                  output_name + ' ' + path_processed + output_name.replace('process', 'time'))
                  # cannot use force = False here as system() does not take keyword arguments

        # (6) convert to classic format
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        output_name = output_name.replace('process', 'time')
        os.system('ncks -O --fl_fmt=classic ' + path_processed + output_name + ' ' +
                  path_processed + output_name.replace('time', 'classic'))

        # (7) removing bnds = 2 dimension from the vertical zg dimension
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        output_name = output_name.replace('time', 'classic')
        os.system('ncwa -a bnds ' + path_processed + output_name + ' ' + path_processed +
                  output_name.replace('classic', 'no_bnds'))

        # (8) running cost software and creating output .dat file
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        output_name = output_name.replace('classic', 'no_bnds')
        os.system("cost733class -dat pth:" + path_processed + output_name + " var:" +
                  variable + " -met " + method + " -ncl " + classes + " -cla " +
                  path_processed + output_name[:-3].replace('no_bnds', 'cost') +
                  ".dat" + " -dcol 3  -cnt")

        # (9) removing redundant files
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        os.system('rm -r ' + path_processed + 'zg_day_' + model + '_' + realisation + '_*')
        redundant_names = 'zg_day_' + model + '_historical_rcp85_' + realisation
        os.system('rm -r ' + path_processed + redundant_names + '_classic.nc')
        os.system('rm -r ' + path_processed + redundant_names + '_no_bnds.nc')
        os.system('rm -r ' + path_processed + redundant_names + '_process.nc')
        os.system('rm -r ' + path_processed + redundant_names + '_time.nc')

        print(datetime.now() - starttime) # print time after one iteration

        # (10) post-processing cost output file
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#        output_name = output_name[:-3].replace('no_bnds', 'cost') + '.dat'
#        print(output_name)
#        os.system("awk '{print $4}' " + path_processed + output_name + ' >' +
#                  path_processed + output_name.replace('cost', 'small'))
#        os.system('rm -r ' + path_processed + output_name) # again remove redundant file
        # these 'small' files are then used to adjust leap days and combinedd into one file
        # with date vector (i.e. YYYY MM DD) and all other CMIP5 ensemble member output
        # to combine these files I just use: hmaurice@h2o:~> paste date.dat zg_day_* >data.dat

   # end of loop over realisations
# end of loop over models

sys.exit() # exit script

# (XY) notes here
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


#!/usr/bin/env python3
import dataclasses
from enum import IntEnum, auto
from typing import List

from pymagnitude import Magnitude
from sudachipy import tokenizer, dictionary

class MorphemeMode(IntEnum):
    SURFACE = auto()
    DICTIONARY_FORM = auto()
    READING_FORM = auto()
    PART_OF_SPEECH = auto()

@dataclasses.dataclass
class WordReplacer:
    chive_vectors: Magnitude = dataclasses.field(init=False)
    tokenizer_obj: tokenizer.Tokenizer = dataclasses.field(init=False)
    sudachi_split_mode: tokenizer.Tokenizer.SplitMode = dataclasses.field(init=False)

    def __post_init__(self) -> None:
        # 類語検索にはchiVe<https://github.com/WorksApplications/chiVe>の埋め込み表現を利用する
        self.chive_vectors = Magnitude(
            "https://sudachi.s3-ap-northeast-1.amazonaws.com/chive/chive-1.1-mc90-aunit.magnitude",
            # stream=True,
        )

        self.tokenizer_obj = dictionary.Dictionary().create()

        # 形態素解析はSudachiのMode C（最も単語の結合力が強いモード）で
        self.sudachi_split_mode = tokenizer.Tokenizer.SplitMode.C

    def wakati(
        self, sentence: str, mode: MorphemeMode = MorphemeMode.SURFACE
    ) -> List[str]:
        """Sudachiによる分かち書きの実行

        Parameters
        ----------
        sentence : str

        mode : IntEnum, optional
            , by default 1.
            1: SURFACE, 2: DICTIONARY_FORM, 3: READING_FORM, 4: PART_OF_SPEECH

        Returns
        -------
        List[str]
        """
        tokens = self.tokenizer_obj.tokenize(sentence, self.sudachi_split_mode)
        if mode == MorphemeMode.SURFACE:
            return [m.surface() for m in tokens]
        elif mode == MorphemeMode.DICTIONARY_FORM:
            return [m.dictionary_form() for m in tokens]
        elif mode == MorphemeMode.READING_FORM:
            return [m.reading_form() for m in tokens]
        else:
            return [m.part_of_speech() for m in tokens]

    def normalize(self, word: str) -> str:
        """入力の正規化

        Parameters
        ----------
        word : str

        Returns
        -------
        str
        """
        return self.tokenizer_obj.tokenize(word, self.sudachi_split_mode)[
            0
        ].normalized_form()

    def calc_similarity(self, word: str, topn: int = None) -> List[str]:
        """類似単語を返す

        Parameters
        ----------
        word : str

        topn : int, optional
            , by default None

        Returns
        -------
        List[str]
        """
        return self.chive_vectors.most_similar(
            word, topn=topn, return_similarities=False
        )

    def search_similar_words(
        self,
        input_word: str,
        top_N: int = 10,
        normalization: bool = True,
        allows_other_part_of_speech: bool = False,
    ) -> List[str]:
        """類似単語を返す

        Parameters
        ----------
        input_word : str

        top_N : int, optional
            , by default 10

        normalization : bool, optional
            , by default True. Trueの場合、入力単語の正規化を行う

        allows_other_part_of_speech : bool, optional
            , by default False. Trueの場合、類似単語に品詞違いのものも含める

        Returns
        -------
        List[str]
        """
        if normalization:
            input_word = self.normalize(input_word)

        if allows_other_part_of_speech:  # 品詞問わず置換する場合
            similar_words = self.calc_similarity(input_word, topn=top_N)
        else:  # 同じ品詞のものに絞って置換する場合
            similar_words = []
            input_word_part_of_speech = self.wakati(
                input_word, mode=MorphemeMode.PART_OF_SPEECH
            )[0][0]
            # 類似度が高い順に単語を見ていき、品詞が同じもののみappendする
            for word in self.calc_similarity(input_word, topn=top_N * 5):
                part_of_speech = self.wakati(word, mode=MorphemeMode.PART_OF_SPEECH)[0][
                    0
                ]
                if part_of_speech == input_word_part_of_speech:
                    similar_words.append(word)
                if len(similar_words) == top_N:
                    break
        return similar_words

    def generate_replaced_sentences(
        self, sentence: str, from_word: str, top_N: int = 10, normalization: bool = True
    ) -> List[str]:
        """`sentence` 内の `from_word` を類語で置換した文章のリストを返す

        Parameters
        ----------
        sentence : str

        from_word : str

        top_N : int, optional
            , by default 10

        normalization : bool, optional
            , by default True. Trueの場合、入力単語の正規化を行う

        Returns
        -------
        List[str]
        """
        assert from_word in sentence

        to_word_candidates = self.search_similar_words(
            from_word, top_N=top_N, normalization=normalization
        )
        replaced_sentences = []
        for to_word in to_word_candidates:
            replaced_sentence = sentence.replace(from_word, to_word, 1)
            replaced_sentences.append(replaced_sentence)
        return replaced_sentences

if __name__ == "__main__":
    word_replacer = WordReplacer()
    sentence = "そうだ、京都行こう。"
    print(word_replacer.generate_replaced_sentences(sentence, "京都"))