import unittest
from unittest.mock import call, create_autospec

from opyoid import PerLookupScope, Provider, ProviderBinding, SelfBinding, SingletonScope, ThreadScope
from opyoid.bindings import BindingRegistry, FromInstanceProvider, ProviderBindingToProviderAdapter
from opyoid.bindings.registered_binding import RegisteredBinding
from opyoid.exceptions import IncompatibleAdapter, NoBindingFound, NonInjectableTypeError
from opyoid.injection_context import InjectionContext
from opyoid.injection_state import InjectionState
from opyoid.providers import ProviderCreator
from opyoid.scopes.thread_scoped_provider import ThreadScopedProvider
from opyoid.target import Target

class MyType:
    pass

# mypy: disable-error-code="attr-defined"
class TestProviderBindingToProviderAdapter(unittest.TestCase):
    def setUp(self):
        self.adapter = ProviderBindingToProviderAdapter()
        self.state = InjectionState(
            create_autospec(ProviderCreator, spec_set=True),
            create_autospec(BindingRegistry, spec_set=True),
        )
        self.provider = create_autospec(Provider, spec_set=True)
        self.instance = MyType()
        self.provider.get.return_value = self.instance
        self.provider_provider = create_autospec(Provider, spec_set=True)
        self.provider_provider.get.return_value = self.provider
        self.mock_scope_provider = create_autospec(Provider, spec_set=True)
        self.scope = PerLookupScope()
        self.mock_scope_provider.get.return_value = self.scope
        self.context = InjectionContext(Target(MyType), self.state)

    def test_create_returns_provider_from_provider_instance_binding(self):
        provider = self.adapter.create(RegisteredBinding(ProviderBinding(MyType, self.provider)), self.context)

        instance = provider.get()
        self.assertIs(instance, self.instance)
        self.assertEqual([], self.state.provider_creator.get_provider.call_args_list)

    def test_create_provider_from_provider_class_binding(self):
        self.state.provider_creator.get_provider.side_effect = [
            self.provider_provider,
            self.mock_scope_provider,
        ]

        provider = self.adapter.create(RegisteredBinding(ProviderBinding(MyType, Provider)), self.context)

        instance = provider.get()
        self.assertIs(instance, self.instance)
        self.assertEqual(
            [
                call(self.context.get_child_context(Target(Provider))),
                call(self.context.get_child_context(Target(SingletonScope))),
            ],
            self.state.provider_creator.get_provider.call_args_list,
        )

    def test_create_named_provider(self):
        self.state.provider_creator.get_provider.side_effect = [
            self.provider_provider,
            self.mock_scope_provider,
        ]

        context = InjectionContext(Target(MyType, "my_name"), self.state)
        provider = self.adapter.create(
            RegisteredBinding(ProviderBinding(MyType, Provider, named="my_name")),
            context,
        )

        instance = provider.get()
        self.assertIs(instance, self.instance)
        self.assertEqual(
            [
                call(context.get_child_context(Target(Provider, "my_name"))),
                call(context.get_child_context(Target(SingletonScope))),
            ],
            self.state.provider_creator.get_provider.call_args_list,
        )

    def test_create_scoped_provider(self):
        self.state.provider_creator.get_provider.side_effect = [
            self.provider_provider,
            FromInstanceProvider(ThreadScope()),
        ]

        provider = self.adapter.create(
            RegisteredBinding(ProviderBinding(MyType, Provider, scope=ThreadScope)),
            self.context,
        )

        instance = provider.get()
        self.assertIs(instance, self.instance)
        self.assertEqual(
            [
                call(self.context.get_child_context(Target(Provider))),
                call(self.context.get_child_context(Target(ThreadScope))),
            ],
            self.state.provider_creator.get_provider.call_args_list,
        )
        self.assertIsInstance(provider, ThreadScopedProvider)

    def test_non_injectable_scope_raises_exception(self):
        self.state.provider_creator.get_provider.side_effect = [
            self.provider_provider,
            NoBindingFound(),
        ]

        with self.assertRaises(NonInjectableTypeError):
            self.adapter.create(RegisteredBinding(ProviderBinding(MyType, Provider)), self.context)

    def test_other_binding_raises_exception(self):
        with self.assertRaises(IncompatibleAdapter):
            self.adapter.create(RegisteredBinding(SelfBinding(MyType)), self.context)


arr= [
[0, 0, 1, 0, 0],
[0, 1, 1, 1, 1],
[0, 0, 1, 1, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 0],
]
N = 5
# 연결된(상하좌우로) 1의 갯수 찾기
# 횡 우선 탐색하다가 1 발견하면 1 연결된거 보고 보고, 하면서 쭉 갈것임.
queue = []          # 리스트지만... 맨 뒤에 넣고 앞에서 뺄꺼니까.. queue라고 합시다.
# 2차원 배열에서 각 요소가 노드 이므로... 모든 정점에 대해서 방문표시
visited= [[0]*N for _ in range(N)]

for i in range(N):
    for j in range(N):
        if arr[i][j]:
            # 여기에서 bfs 시작
            queue.append((i,j))
            # 또는 한개씩 2개 넣기
            # queue.append(i)
            # queue.append(j)
            visited[i][j] = 1       # 방문했음 표시
            # 현재위치에서 갈 수 있는 모든 경로를 탐색
            # 경로를 발견하면 저장
            # 이후에 경로를 발견한 순서대로 방문(deQueue)
            cnt = 0         # 방문할 때 마다 cnt를 증가시키려고
            while queue:    #큐에 저장된 노드를 방문하는 작업을 반복(큐에 저장값이 있다면 계속 반복)
                # 현재 위치
                ci, cj = queue.pop(0)  # 먼저 발견한 순서대로 방문(현재 i, 현재 j를 받음)
                cnt += 1    # 방문할 때 마다 cnt를 증가시킴
                for di, dj in ([(-1,0),(1,0),(0,-1),(0,1)]):
                    ni, nj = ci + di, cj + dj           # next (i, j)
                    # 정상 범위 안에 있으면서,
                    if 0<= ni < N and 0<= nj < N:
                        # 1이고, 방문하지도 않았으면, 방문할 노드에 추가
                        if arr[ni][nj] == 1 and not visited[ni][nj]:
                            queue.append((ni, nj))
                            visited[ni][nj] = visited[ci][cj] + 1   # 현재 위치에서 갈 수 있는 경로
            print(cnt)
            print('여러번 실행될걸요?ㅋㅋㅋㅋㅋㅋ')


import socket
from _thread import *

server = socket.gethostbyname(socket.gethostname())
port = 5555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
    s.bind((server, port))
    print('Server started, waiting for connection')

except socket.error as e:
    print(e)

def threaded_client(conn):
    print(f'[Connected] New connection established')
    connected = True
    while connected:
        data = conn.recv(2048).decode()
        print(f'[Recived] {data}')
        reply = ''
        if data:
            reply = data
        if not data:
            connected = False

        conn.send(str.encode(reply))
        print(f'[Sent] {reply}')
    conn.close()

def start():
    s.listen()
    while True:
        conn, addr = s.accept()
        start_new_thread(threaded_client, (conn,))

start()


from os import path
import sys
sys.stdin=open("input.txt","r")
def DFS(v): #노드번호 v
    global cnt
    if v==n: #종착지점
        cnt+=1
        for x in path:
            print(x, end=' ')
        print() #줄바꿈
    else:
        for i in range(1, n+1): #n가지로 가지를 뻗음
            if g[v][i]==1 and ch[i]==0:
                ch[i]=1
                path.append(i)
                DFS(i)
                path.pop() #뒤로 back했을 때는 pop해서 빼주기
                ch[i]=0 #check 풀어주기

if __name__=="__main__":
    n, m=map(int, input().split()) #n: node number, m: line nubmer
    g=[[0]*(n+1) for _ in range(n+1)]
    ch=[0]*(n+1) #visited
    for i in range(m):
        a, b = map(int,input().split())
        g[a][b]=1 #방향그래프
        cnt = 0
        path=[]
        path.append(1)
        ch[1]=1 #방문했음
        DFS(1) #1번 노드로 넘어감
        print(cnt)


# 3-1 영상의 덧셈
# h(x,y) = f(x,y)+g(x,y)
import numpy as np
from scipy import signal, misc
import matplotlib.pyplot as plt

#Image Read
aero=misc.imread('image/aero2.bmp')
hole=misc.imread('image/hole.bmp')
lena=misc.imread('image/lena_256.bmp')

#Overflow 방지
aero2 = np.float32(aero)
hole2 = np.float32(hole)
lena2 = np.float32(lena)

im_new1 = np.uint8(np.where(lena2+aero2>255,255,lena2+aero2))
im_new2 = np.uint8(np.where(lena2+hole2>255,255,lena2+hole2))

plt.subplot(2,3,1), plt.imshow(aero), plt.gray(), plt.title('AERO Image'), plt.axis('off')
plt.subplot(2,3,2), plt.imshow(lena), plt.gray(), plt.title('ADD Result'), plt.axis('off')
plt.subplot(2,3,3), plt.imshow(im_new1), plt.gray(), plt.title('AERO Image'), plt.axis('off')
plt.subplot(2,3,4), plt.imshow(lena), plt.gray(), plt.title('LENA Image'), plt.axis('off')
plt.subplot(2,3,5), plt.imshow(hole), plt.gray(), plt.title('HOLE Image'), plt.axis('off')
plt.subplot(2,3,6), plt.imshow(im_new2), plt.gray(), plt.title('ADD Result'), plt.axis('off')
plt.show()


def add_student_record(position):
    # Ask the user for the student details
    name = input("Enter student name: ")
    age = input("Enter student age: ")
    grade = input("Enter student grade: ")

    thisdict = {
    "brand": "Ford",
    "model": "Mustang",
    "year": 1964
    }

    # Open the file in append mode
    with open("student_records.txt", "a") as file:
        # Write the student details to the file
        file.write(f"{name},{age},{grade}\n")

    print("Student record added successfully.")

    # Open the file for both reading and writing
    with open('student_records.txt', 'r+') as file:
        # Read the existing data into a list
        lines = file.readlines()

        # Create a new student record
        new_student = 'Jane Doe, 123456, Computer Science\n'

        # Insert the new student record at the 2nd position in the list
        # lines.insert(1, new_student)
        lines.insert(1, thisdict)

        # Move the file pointer to the beginning of the file
        file.seek(0)

        # Write the modified data back to the file
        file.writelines(lines)

add_student_record(2)


import pytest
from lesson26.hometask.pages.dynamic_properties import DynamicPropertiesPage

@pytest.mark.usefixtures('chrome')
class TestDynamicProperties:
    """На сторінці https://demoqa.com/dynamic-properties зробити 3 тести"""
    def test_enable_after_btn(self):
        """Переконується що кнопка "Enable after" вмикається"""
        button = 'enableAfter'
        page = DynamicPropertiesPage(self.driver)
        page.open_page()
        assert page.is_button_enabled(button)

    def test_color_change_btn(self):
        """Переконується що колір напису на кнопці "Color change" змінюється"""
        button = 'colorChange'
        page = DynamicPropertiesPage(self.driver)
        page.open_page()
        assert page.has_button_color_changed(button)

    def test_visible_after_btn(self):
        """Переконується, що кнопка "Visible after" з'являється на сторінці"""
        button = 'visibleAfter'
        page = DynamicPropertiesPage(self.driver)
        page.open_page()
        assert page.is_button_visible(button)


"""
С помощью регулярных выражений выведите из многострочного текста все
строки, имеющие расширения графических файлов.
"""
import re

text = '''Примеры расширений файлов:
wald.jpeg
wow.mp4
book.txt
forest.png
fox.tiff
wood.pdf
hub.gif
small.zip
sound.mp3
'''

l = list(text.split(' '))
res = re.findall(r'\w+\.(?:png|gif|tiff|jpeg)', text)
for i in res:
    print(i)


# Time:  O(n)
# Space: O(n)

# Given an array of integers, return indices of the two numbers
# such that they add up to a specific target.
#
# You may assume that each input would have exactly one solution.
#
# Example:
# Given nums = [2, 7, 11, 15], target = 9,
#
# Because nums[0] + nums[1] = 2 + 7 = 9,
# return [0, 1].

class Solution:
    def twoSum(self, nums, target):
        rem = dict()

        for i, num in enumerate(nums):
            if nums[i] in rem:
                return [i, rem[nums[i]]]
            else:
                rem[target - nums[i]] = i

print(Solution().twoSum([2,7,11,15], 9))
print(Solution().twoSum([3,2,4], 6))
print(Solution().twoSum([3,3], 6))


from django.urls import path
# from django.views.decorators.cache import cache_page
from .views import (
    HomeNewsView,
    CategoriesView,
    NewsDeatilView,
    CreateNewsView,
    DeletePostView,
    DeleteListNewsView,
    UpdatePostView,
    AboutMeView,
    contact_me,
    like_news,
    NewsOfferCreate,
    ListNewsOfferView,
    ListCommentsNewsView,
    UpdateCommentView,
    favorite_news_add_remove,
    FavoritesNewsView,
)

urlpatterns = [
    # path('', cache_page(60)(HomeNewsView.as_view()),  name='home',),
    path('', HomeNewsView.as_view(),  name='home',),
    path(
        'category/<int:category_id>',
        CategoriesView.as_view(), name='category',
    ),
    path(
        'news/<int:pk>',
        NewsDeatilView.as_view(), name='view_news',
    ),
    path(
        'news/delete-post/',
        DeleteListNewsView.as_view(), name='list_delete_posts',
    ),
    path(
        'news/<int:pk>/delete',
        DeletePostView.as_view(), name='delete_post',
    ),
    path(
        'news/<int:pk>/update',
        UpdatePostView.as_view(), name='update_post',
    ),
    path(
        'news/create_news/',
        CreateNewsView.as_view(), name='create',
    ),
    path(
        'news/about_me/',
        AboutMeView.as_view(), name='about_me',
    ),
    path(
        'news/contact_with_me/',
        contact_me, name='contact',
    ),
    path(
        'news/like_news/',
        like_news, name='like_news',
    ),
    path(
        'news/offer_news/',
        NewsOfferCreate.as_view(), name='offer_news',
    ),
    path(
        'news/offer_list_news/',
        ListNewsOfferView.as_view(), name='offer_list_news',
    ),
    path(
        'news/list_comment_moder/',
        ListCommentsNewsView.as_view(), name='list_comment_moder',
    ),
    path(
        'news/<int:pk>/update_comment',
        UpdateCommentView.as_view(), name='update_comment',
    ),
    path(
        'news/favorite_news/',
        favorite_news_add_remove, name='favorite_news',
    ),
    path(
        'news/my_favorite_news/',
        FavoritesNewsView.as_view(), name='my_favorite_news',
    )
]


from torch.utils.data import DataLoader, IterableDataset
import os
import numpy as np
import cv2
import numpy.random as random

class Videos(IterableDataset):
    def __init__(self, datadir, t=50, batch_size=49):
        self.datadir = datadir
        self.t = t
        self.batch_size = batch_size

    def __iter__(self):
        directory = os.path.abspath(self.datadir)
        cache = {}
        # random = np.random.RandomState(42)
        for episode in os.listdir(directory):
            vid = cv2.VideoCapture(os.path.join(directory, episode, 'video.avi'))
            wid = int(vid.get(3))
            hei = int(vid.get(4))
            framenum = int(vid.get(7))
            npvid = np.zeros((framenum, hei, wid, 3), dtype=np.uint8)
            i = 0
            a = True
            while vid.isOpened() and a:
                a, b = vid.read()
                if a:
                    npvid[i] = b
                i += 1
            vid.release()
            del vid
            data = np.load(os.path.join(directory, episode, 'data.npz'))
            data = {k: data[k] for k in data.keys()}
            data['image'] = npvid
            cache[episode] = data
            keys = list(cache.keys())
        self.cache = list(cache.values())
        self.lens = [len(o['action']) for o in self.cache]
        while True:
            for index in random.choice(len(keys), self.batch_size, replace=False):
                episode = cache[keys[index]]
                if self.t:
                    total = len(next(iter(episode.values())))
                    available = total - self.t
                    if available < 1:
                        continue
                    index = int(random.randint(0, available))
                    episode = {k: v[index: index + self.t] for k, v in episode.items()}
                    episode['image'] = np.transpose(episode['image'].astype(np.float32) / 255., (0, 3, 1, 2))
                    episode['position'] = episode['position'][:, 1:4].astype(np.float32)
                    episode['image'] = episode['image'][..., 16:-16]
                yield episode

def get_loader(datadir, n_jobs=10, t=50, batch_size=16):
    return DataLoader(Videos(datadir, t=t, batch_size=batch_size), batch_size=batch_size, num_workers=n_jobs)


# vim: fdm=indent
'''
author:     Fabio Zanini
date:       25/01/21
content:    Reconstruct genealogies of large clones and infer rankings
'''
import os
import sys
import argparse
import pickle
import numpy as np
import pandas as pd

def translate_column(df, col):
    from Bio.Seq import translate
    aas = []
    for i, seq in enumerate(df[col]):
        seq = seq.replace('.', '')
        for rf in range(3):
            seq_rf = seq[rf:]
            seq_rf = seq_rf[:(len(seq_rf) // 3) * 3]

            try:
                aa = translate(seq_rf)
            except:
                continue

            n_stops = aa.count('*')
            if n_stops == 0:
                break
        else:
            print(f'WARNING: in sequence {i}, all reading frames have problems!')
            aa = ''

        aas.append(aa)
    return aas

def pad_sequences(seqs, templates, gap='.'):
    new_seqs = []
    for i, (seq, template) in enumerate(zip(seqs, templates)):
        if seq[0] == gap:
            i_start = len(seq) - len(seq.lstrip(gap))
            seq = template[:i_start] + seq[i_start:]
        if seq[-1] == gap:
            i_end = len(seq.rstrip(gap))
            seq = seq[i_end:] + template[i_end:]
        new_seqs.append(seq)
    return new_seqs

def get_tree_and_rankings(seqs, outgroup_label):
    import subprocess as sp
    import tempfile
    from Bio.Phylo import read as read_tree
    from Bio.SeqIO import parse as parse_seqs

    with tempfile.TemporaryDirectory() as tmpdirname:
        ##if True:
        #tmpdirname = '/home/fabio/Desktop/tmptmp'
        #os.makedirs(tmpdirname, exist_ok=True)

        # Make temporary FASTA file with the sequences
        fn_in = tmpdirname+'/seqs_in.fasta'
        with open(fn_in, 'wt') as fin:
            for name, seq in seqs.items():
                fin.write(f'>{name}\n{seq}\n')

        # Make multiple sequence alignment with MUSCLE
        fn_out = tmpdirname+'/ali_out.fasta'
        sp.run(f'muscle -in {fn_in} -out {fn_out} -diags', shell=True, check=True)

        # Get terminal alignments
        leaves_seqs = list(parse_seqs(fn_out, 'fasta'))

        ## Make phylogenetic tree from MSA
        #fn_tree = tmpdirname+'/tree.nwk'
        #sp.run(f'FastTree -out {fn_tree} {fn_out}', shell=True, check=True)

        # Make phylogeny and infer LBI rankings via Richard's package
        # https://github.com/neherlab/FitnessInference (adapted to Python 3)
        rank_seqs_fdn = '/home/fabio/university/PI/projects/dengue/libraries/FitnessInference'
        rank_seqs_bin = 'rank_sequences.py'
        tmpdir_infer = tmpdirname+'/fitness_inference'
        os.makedirs(tmpdir_infer, exist_ok=True)
        sp.run(
            f'python {rank_seqs_bin} --aln {fn_out} --outgroup {outgroup_label}',
            shell=True, cwd=rank_seqs_fdn, check=True,
            )
        subfdn = [x for x in os.listdir(rank_seqs_fdn) if x.startswith('2021')][0]
        sp.run(f'mv {rank_seqs_fdn}/{subfdn} {tmpdir_infer}/', shell=True, check=True)
        fn_tree = tmpdir_infer+f'/{subfdn}/reconstructed_tree.nwk'
        fn_anc = tmpdir_infer+f'/{subfdn}/ancestral_sequences.fasta'
        fn_rank_int = tmpdir_infer+f'/{subfdn}/sequence_ranking_nonterminals.txt'
        fn_rank_ter = tmpdir_infer+f'/{subfdn}/sequence_ranking_terminals.txt'

        tree = read_tree(fn_tree, 'newick')
        rank_int = pd.read_csv(fn_rank_int, sep='\t', index_col=0)
        rank_ter = pd.read_csv(fn_rank_ter, sep='\t', index_col=0)
        anc_seqs = list(parse_seqs(fn_anc, 'fasta'))

    return {
        'tree': tree,
        'ranking_internal': rank_int,
        'ranking_leaves': rank_ter,
        'ancestral_sequences': anc_seqs,
        'leaves_sequences': leaves_seqs,
        }

if __name__ == '__main__':

    fdn_data = '../../data/datasets/20200809_20kids/vdj/'
    pnames = os.listdir(fdn_data)
    pnames = [x for x in pnames if os.path.isdir(fdn_data+x)]

    pa = argparse.ArgumentParser()
    pa.add_argument('--patient', choices=pnames, action='append')
    pa.add_argument('--regenerate', action='store_true')
    args = pa.parse_args()

    if args.patient is not None:
        pnames = args.patient

    res_all = {}
    for pname in pnames:
        print(f'Patient {pname}')
        fn_res = f'{fdn_data}/{pname}/ranking_LBI.pkl'
        if args.regenerate or not os.path.isfile(fn_res):
            fn_heavy_sequences = f'../../data/datasets/20200809_20kids/vdj/{pname}/filtered_contig_heavy_germ-pass.tsv'
            if not os.path.isfile(fn_heavy_sequences):
                print('Heavy chain file not found')
                continue
            df = pd.read_csv(fn_heavy_sequences, sep='\t')
            df['patient'] = pname
            df['unique_id'] = pname + '-' + df['sequence_id']

            df['sequence_alignment_pad'] = pad_sequences(
                    df['sequence_alignment'],
                    df['germline_alignment'],
                    )

            #df['germline_ali_aa'] = translate_column(df, 'germline_alignment')
            #df['sequence_ali_pad_aa'] = translate_column(df, 'sequence_alignment_pad')
            #df['sequence_aa'] = translate_column(df, 'sequence_alignment')

            res = {}
            # Top 10 clones per patient
            clone_abundances = df['clone_id'].value_counts()[:10]
            # Also limit to clones with 10+ sequences
            clone_abundances = clone_abundances[clone_abundances >= 5]
            nclones = len(clone_abundances)
            print(f'# clones in this individual: {nclones}')
            for clone_id, df_clone in df.groupby('clone_id'):
                if clone_id not in clone_abundances.index:
                    continue
                print(f'Clone: {clone_id}')

                abu = clone_abundances[clone_id]
                if df_clone['germline_alignment'].value_counts()[0] != abu:
                    print(df_clone['germline_alignment'].value_counts())
                    raise ValueError('Clone has multiple germlnes??')

                seqs = df_clone.set_index('unique_id')['sequence_alignment']
                germ_line = f'germline_clone_{clone_id}'
                seqs.loc[germ_line] = df_clone['germline_alignment'].iloc[0]

                print('Get tree and rankings')
                res_clone = get_tree_and_rankings(seqs, outgroup_label=germ_line)

                res[clone_id] = res_clone

            print(f'Saving results for subject {pname} to file')
            with open(fn_res, 'wb') as fout:
                pickle.dump(res, fout)
        else:
            with open(fn_res, 'rb') as fout:
                res = pickle.load(fout)

        res_all[pname] = res

    print('Saving results for all individuals to file')
    fn_res = '../../data/datasets/20200809_20kids/vdj/ranking_LBI.pkl'
    with open(fn_res, 'wb') as fout:
        pickle.dump(res_all, fout)


#!/usr/bin/python
from datetime import datetime
from collections import namedtuple
import sys, os
import gzip
import random, math
from optparse import OptionParser

options = None

## User for Orthology
best_query_taxon_score = {}
## Used for the Paralogy
BestInterTaxonScore = {}
BetterHit = {}

# class SimilarSequenceLine:
# 	def __init__(self, line):
# 		column = line.strip().split('\t')

# 		self.query_id = column[0]
# 		(self.query_taxon, self.query_seq) = column[0].split('|')

# 		self.subject_id = column[1]
# 		(self.subject_taxon,self.subject_seq)  = column[1].split('|')

# 		self.evalue_mant = float(column[2])
# 		self.evalue_exp = int(column[3])

# 		#self.percent_ident = column[4]
# 		self.percent_match = float(column[4])

class SimilarSequenceLine(namedtuple('SimilarSequenceLine', 'query_id,query_taxon,query_seq,subject_id,subject_taxon,subject_seq,evalue_mant,evalue_exp,percent_match')):
	__slots__ = ()
	@classmethod
	def _fromLine(cls, line, new=tuple.__new__, len=len):
		'Make a new SimilarSequenceLine object from a sequence or iterable'
		column = line.strip().split('\t')
		(query_taxon, query_seq) = column[0].split('|')
		(subject_taxon, subject_seq) = column[1].split('|')
		iterable = (column[0], query_taxon, query_seq, column[1], subject_taxon, subject_seq, float(column[2]), int(column[3]), float(column[4]))
		result = new(cls, iterable)
		if len(result) != 9:
			raise TypeError('Expected 9 arguments, got %d' % len(result))
		return result

def readTaxonList(filename):

	taxon_list = []
	taxon_list_file = open(filename)
	for line in taxon_list_file:
		line = line.strip()
		if line:
			taxon_list += [line]
	taxon_list_file.close()
	return taxon_list

def memory_usage_resource():
	import resource
	rusage_denom = 1024.
	if sys.platform == 'darwin':
		# ... it seems that in OSX the output is different units ...
		rusage_denom = rusage_denom * rusage_denom
	mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / rusage_denom
	return round(mem, 0)

def log(s):
	global options
	print >> sys.stderr, s
	if options.logfile:
		l = open(options.logfile, 'a')
		l.write(s+'\n')
		l.close()

def writeStoOutputFiles(s, out_bh_file):
	global best_query_taxon_score, BestInterTaxonScore, options
	try:
		(cutoff_exp, cutoff_mant) = best_query_taxon_score[(s.query_id, s.subject_taxon)]

		if (
			s.query_taxon != s.subject_taxon and
			(s.evalue_exp == 0 or s.evalue_exp < options.evalueExponentCutoff) and
			s.percent_match > options.percentMatchCutoff and
			(s.evalue_mant < 0.01 or s.evalue_exp==cutoff_exp and s.evalue_mant==cutoff_mant)
		   ):
			out_bh_file.write('{0}\t{1}\t{2}\t{3}\n'.format(s.query_seq, s.subject_id, s.evalue_exp, s.evalue_mant))

	except KeyError:
		pass

	if options.outInParalogTempFolder:
		try:
			(cutoff_exp, cutoff_mant) = BestInterTaxonScore[s.query_id]

			if (s.query_taxon == s.subject_taxon and
				s.query_id != s.subject_id and
                (s.evalue_exp== 0 or s.evalue_exp <= options.evalueExponentCutoff) and
				s.percent_match >= options.percentMatchCutoff and
				(s.evalue_mant < 0.01 or s.evalue_exp<cutoff_exp or (s.evalue_exp == cutoff_exp and s.evalue_mant<=cutoff_mant))
			   ):

				# try:
				# 	BetterHit[(s.query_seq, s.subject_seq)] += [(s.evalue_exp, s.evalue_mant)]
				# except KeyError:
				BetterHit[(s.query_seq, s.subject_seq)] = (s.evalue_exp, s.evalue_mant)

		except KeyError:
			# Include the ones with
			if (
				s.query_taxon == s.subject_taxon and
				(options.keepOrthoMCLBug or s.query_id != s.subject_id) and  #### THIS IS an OrthoMCL bug
				(s.evalue_exp == 0 or s.evalue_exp <= options.evalueExponentCutoff) and
				s.percent_match >= options.percentMatchCutoff
			   ):
				# try:
				# 	BetterHit[(s.query_seq, s.subject_seq)] += [(s.evalue_exp, s.evalue_mant)]
				# except KeyError:
				BetterHit[(s.query_seq, s.subject_seq)] = (s.evalue_exp, s.evalue_mant)

if __name__ == '__main__':
	usage = "This is STEP 5.1 of PorthoMCL.\n\nusage: %prog options\n"
	parser = OptionParser(usage)

	parser.add_option("-t", "--taxonlist", dest="taxonlistfile", help="A single column file containing the list of taxon to work with")
	parser.add_option("-x", "--index", dest="index", help="An integer number identifying which taxon to work on [1-size_of_taxon_list]", type='int')

	parser.add_option('-s', '--inSimSeq', dest='inSimSeq', help='Input folder that contains split similar sequences files (ss files)')

	parser.add_option('-b', '--outBestHitFolder', dest='outBestHitFolder', help='folder that will stores Best Hit files (If not set, current folder)')
	parser.add_option('-q', '--outInParalogTempFolder', dest='outInParalogTempFolder', help='folder to generate best InParalogTemp evalue scores (pt files) (required only for Paralogs)')
	parser.add_option("-l", "--logfile", dest="logfile", help="log file (optional, if not supplied STDERR will be used)")

	parser.add_option('', '--evalueExponentCutoff', dest='evalueExponentCutoff', help='evalue Exponent Cutoff (a nebative value, default=-5)', default=-5, type='int')
	parser.add_option('', '--percentMatchCutoff', dest='percentMatchCutoff', help='percent Match Cutoff (integer value, default=50)', default=50, type='int')
	parser.add_option('', '--cacheInputFile', dest='cacheInputFile', help='Cache input file or read it again. (Only use if I/O is very slow)', default=False, action="store_true")
	parser.add_option('', '--keepOrthoMCLBug', dest='keepOrthoMCLBug', help='Keep the OrthoMCL bug in creating Temporary Paralogs files (pt files) where self hits are included', default=False, action="store_true")

	#

	(options, args) = parser.parse_args()

	if len(args) != 0 or not options.taxonlistfile or not options.inSimSeq or not options.index:
		parser.error("incorrect arguments.\n\t\tUse -h to get more information or refer to the MANUAL.md")

	log('{2} | Best Hit | {0} | {1} | {3} | {4} MB | {5}'.format(1, 'reading taxon list', options.index, '', memory_usage_resource(), datetime.now()))
	taxon_list = readTaxonList(options.taxonlistfile)

	if options.index <= 0 or options.index > len(taxon_list):
		log('{2} | Best Hit | {0} | {1} | {3} | {4} MB | {5}'.format('ERROR', 'Error in index', options.index, '', memory_usage_resource(), datetime.now()))
		exit()

	taxon1s = taxon_list[options.index - 1]

	if options.cacheInputFile:
		log('{2} | Best Hit | {0} | {1} | {3} | {4} MB | {5}'.format('OPTION', 'Caching Input files', options.index, taxon1s, memory_usage_resource(), datetime.now()))

	log('{2} | Best Hit | {0} | {1} | {3} | {4} MB | {5}'.format(2, 'Reading similar sequences (ss file)', options.index, taxon1s, memory_usage_resource(), datetime.now()))

	if options.outBestHitFolder and not os.path.exists(options.outBestHitFolder):
		os.makedirs(options.outBestHitFolder)

	if options.outInParalogTempFolder and not os.path.exists(options.outInParalogTempFolder):
		os.makedirs(options.outInParalogTempFolder)

	input_file_cache = []

	with open(os.path.join(options.inSimSeq, taxon1s+'.ss.tsv')) as input_file:
		for line in input_file:

			ss = SimilarSequenceLine._fromLine(line)

			if options.cacheInputFile:
				input_file_cache += [ss]

			if ss.query_taxon != ss.subject_taxon:

				try:
					best_query_taxon_score[(ss.query_id, ss.subject_taxon)] += [(ss.evalue_mant, ss.evalue_exp)]
				except:
					best_query_taxon_score[(ss.query_id, ss.subject_taxon)] = [(ss.evalue_mant, ss.evalue_exp)]

	for (query_id,subject_taxon) in best_query_taxon_score:

		evalues = best_query_taxon_score[(query_id, subject_taxon)]

		min_exp = sys.maxint  #min(evalues, key = lambda t: t[1])

		min_mants = []

		for (evalue_mant, evalue_exp) in evalues:
			if evalue_exp < min_exp:
				min_exp = evalue_exp
				min_mants += [evalue_mant]

			if evalue_mant == 0 and evalue_exp == 0:
				#min_mants += [evalue_mant]
				min_exp = 0
				min_mants = [0]
				break

		best_query_taxon_score[(query_id,subject_taxon)] = (min_exp, min(min_mants))

	if options.outInParalogTempFolder:

		# log('{2} | Best Hit | {0} | {1} | * | {3} MB | {4}'.format(3 , 'Creating bestQueryTaxonScore (q-t file)', options.index, memory_usage_resource(), datetime.now() ))
		# with open(os.path.join(options.outQueryTaxonScoreFolder, taxon1s+'.q-t.tsv'), 'w') as out_file:
		# 	for (query_id,subject_taxon) in sorted(best_query_taxon_score):
		# 		(ev_exp, ev_mant) = best_query_taxon_score[(query_id,subject_taxon)]
		# 		out_file.write('{0}\t{1}\t{2}\t{3}\n'.format(query_id, subject_taxon, ev_exp, ev_mant))

		log('{2} | Best Hit | {0} | {1} | {3} | {4} MB | {5}'.format(3 , 'Creating BestInterTaxonScore Matirx', options.index,taxon1s, memory_usage_resource(), datetime.now() ))

		for (query_id,subject_taxon) in best_query_taxon_score:

			(ev_exp, ev_mant) = best_query_taxon_score[(query_id,subject_taxon)]

			try:
				(min_exp, mants) = BestInterTaxonScore[query_id]

				if min_exp == 0 and mants[0] == 0:
					pass
				elif ev_exp < min_exp:
					BestInterTaxonScore[query_id] = (ev_exp, [ev_mant])
				elif ev_exp == min_exp:
					BestInterTaxonScore[query_id] = (ev_exp, mants+[ev_mant])
			except:
				BestInterTaxonScore[query_id] = (ev_exp, [ev_mant])

		for query_id in BestInterTaxonScore:

			(ev_exp, ev_mants) = BestInterTaxonScore[query_id]
			BestInterTaxonScore[query_id] = (ev_exp, min(ev_mants))

	log('{2} | Best Hit | {0} | {1} | {3} | {4} MB | {5}'.format(4 , 'Creating BestHit file needed for Orthology (bh file)', options.index, taxon1s, memory_usage_resource(), datetime.now() ))

	BestHit = {}

	if not options.outBestHitFolder:
		options.outBestHitFolder = '.'

	out_bh_file = open(os.path.join(options.outBestHitFolder, taxon1s+'.bh.tsv') ,'w')

	if not options.cacheInputFile:
		with open(os.path.join(options.inSimSeq, taxon1s+'.ss.tsv')) as input_file:
			for line in input_file:
				s = SimilarSequenceLine._fromLine(line)
				writeStoOutputFiles(s, out_bh_file)

	else:

		for s in input_file_cache:
			writeStoOutputFiles(s, out_bh_file)

	out_bh_file.close()

	if options.outInParalogTempFolder:
		log('{2} | Best Hit | {0} | {1} | {3} | {4} MB | {5}'.format(5 , 'Creating InParalogTemp file needed for InParalogs (pt file)', options.index, taxon1s, memory_usage_resource(), datetime.now() ))

		out_pt_file = open(os.path.join(options.outInParalogTempFolder, taxon1s+'.pt.tsv') ,'w')

		for (seq1, seq2) in BetterHit:

			if seq1 < seq2:

				(bh1_evalue_exp, bh1_evalue_mant) = BetterHit[(seq1, seq2)]

				try:
					(bh2_evalue_exp, bh2_evalue_mant) =  BetterHit[(seq2, seq1)]
				except:
					continue

				if bh1_evalue_mant < 0.01 or bh2_evalue_mant < 0.01:
					unnormalized_score = (bh1_evalue_exp + bh2_evalue_exp) / -2
				else:
					unnormalized_score = (math.log10(bh1_evalue_mant * bh2_evalue_mant) + bh1_evalue_exp + bh2_evalue_exp) / -2

				out_pt_file.write('{0}\t{1}\t{2}\n'.format(seq1, seq2, unnormalized_score))

		out_pt_file.close()

	log('{2} | Best Hit | {0} | {1} | {3} | {4} MB | {5}'.format(6 , 'Done', options.index, taxon1s, memory_usage_resource(), datetime.now() ))


from world import items

def test_create_item():
    gun = items.Item("Gun", "Weapon", 0, "10", "Gun that shoots")
    assert ("Gun", "Weapon", 0, "10", "Gun that shoots") == (
        gun.name,
        gun.item_type,
        gun.armor,
        gun.damage,
        gun.description,
    )


# Name                           AM    Username
# Ilias Kleftakis                2461  cse32461
# Konstantinos Panagiotis Nakas  2501  cse32501

# This file contains error handling routines.

import sys

class ErrorData:
    filename = ""
    line = 1
    column = 1

    def __init__(self, filename, line, column):
        self.filename = filename
        self.line = line
        self.column = column

    def __repr__(self): # to print nicely
        return "in " + self.filename + ":" + str(self.line) + ":" + str(self.column)

def error(description, errorData, underlineLength):
    print(errorData.filename + ":" + str(errorData.line) + ":" +
            str(errorData.column) + ": ERROR: " + description)
    printLine(errorData)
    printUnderline(errorData, underlineLength)
    print("Please fix the above error and try compiling again. " +
            "Compilation aborted.")
    sys.exit(1)

def printLine(errorData):
    infile = open(errorData.filename, 'r')
    text = infile.readlines()
    print("\t", end = "")
    print(text[errorData.line - 1], end = "")
    infile.close()

def printUnderline(errorData, underlineLength):
    # initial whitespace
    print("\t", end = "")
    for i in range(errorData.column - 1):
        print(" ", end = "")

    # underline characters
    for i in range(underlineLength):
        print("^", end = "")
    print("")


#Functions with output

def format_name(f_name,l_name):

    if f_name == "" or l_name == "":
        return "Any name was inputed"

    f_name = f_name.title()
    l_name = l_name.title()

    # #first_name
    # first_letter = str(f_name[0]).upper()
    # name_rest = str(f_name[1:]).lower()

    # #last name
    # first_letter_l_name = str(l_name[0]).upper()
    # name_rest_l_name= str(l_name[1:]).lower()
    #print(f_name, l_name)
    return f"Your name is {f_name} {l_name}?"

print(format_name(input("Type your first name:"),input('Type your last name:')))


"""Helper functions

Consists of functions to typically be used within templates, but also
available to Controllers. This module is available to both as 'h'.
"""
from pylonsgenshi.helpers import *
from pylons.i18n import _, set_lang, get_lang
import logging

log = logging.getLogger(__name__)

# Don't know why but this import needs to be done after the wrapper
from datetime import date
from paste.deploy.converters import asbool as paste_asbool
# random_pass imports
import string
import random
# check_path_perms imports
import os
import sys
from pwd import getpwuid
from grp import getgrgid
from stat import ST_MODE

def date_from_tstamp(tstamp):
    return date.fromtimestamp(int(tstamp))

def convert_size(size):
    """ Helper function  to convert ISPMan sizes to readable units. """
    return number_to_human_size(int(size)*1024)

def get_nav_class_state(url, request, partial=False):
    """ Helper function that just returns the 'active'/'inactive'
    link class based on the passed url. """
    if partial:
        _url = url_for(
            controller=request.environ['pylons.routes_dict']['controller'],
            action=None,
            id=None
        )
    else:
        _url = url_for(
            controller=request.environ['pylons.routes_dict']['controller'],
            action=request.environ['pylons.routes_dict']['action'],
            id=None
        )

    if url == request.path_info:
        return 'active'
    elif url.startswith(_url) and partial:
        return 'active'
    elif url == _url:
        return 'active'
    else:
        return 'inactive'

def to_unicode(in_obj):
    """ Function to convert whatever we can to unicode."""
    if not in_obj: # or in_obj == '':
        pass
    elif isinstance(in_obj, unicode) or isinstance(in_obj, int):
        return in_obj
    elif isinstance(in_obj, str):
        return unicode(in_obj, 'UTF-8')
    elif isinstance(in_obj, list):
        return [to_unicode(x) for x in in_obj] # if x not in ('', u'', None)]
    elif isinstance(in_obj, dict):
        def conv_to_list(obj):
            if isinstance(obj, str) or isinstance(obj, unicode):
                return [to_unicode(obj)]
            else:
                return to_unicode(obj)
        out_dict = {}
        for key, val in in_obj.iteritems():
            if key == 'mailAlias':
                out_dict[key] = conv_to_list(val)
            elif key == 'mailForwardingAddress':
                out_dict[key] = conv_to_list(val)
            else:
                out_dict[key] = to_unicode(val)
        return out_dict
    else:
        try:
            return to_unicode(dict(in_obj))
        except: # Failed to convert to dict
            pass
        try:
            return to_unicode(list(in_obj))
        except: # Failed to convert to list
            pass
    return in_obj

def remap_user_dict(form_dict, user_dict):
    uid = user_dict['ispmanUserId']
    lengths = {}
    lengths[uid] = {}

    for key, val in form_dict.iteritems():
        if isinstance(val, list):
            # Make shure we're not passing empty mailAlias and/or
            # mailForwardingAddress's
            new_list = to_unicode(val)
            if len(new_list) > 0:
                user_dict[key] = new_list
        else:
            user_dict[key] = to_unicode(val)
    # calculate lenghts
    try:
        lengths[uid]['forwards'] = len(user_dict['mailForwardingAddress'])
    except:
        pass # there are no forwards
    try:
        lengths[uid]['aliases'] = len(user_dict['mailAlias'])
    except:
        pass # there are no aliases

    return lengths, user_dict

def random_pass(alpha, num):
    """
    Returns a human-readble password (say rol86din instead of
    a difficult to remember K8Yn9muL )
    From http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410076
    """
    vowels = ['a','e','i','o','u']
    consonants = [a for a in string.ascii_lowercase if a not in vowels]
    digits = string.digits

    ####utility functions
    def a_part(slen):
        ret = ''
        for i in range(slen):
            if i%2 ==0:
                randid = random.randint(0,20) #number of consonants
                ret += consonants[randid]
            else:
                randid = random.randint(0,4) #number of vowels
                ret += vowels[randid]
        return ret

    def n_part(slen):
        ret = ''
        for i in range(slen):
            randid = random.randint(0,9) #number of digits
            ret += digits[randid]
        return ret

    ###
    fpl = alpha/2
    if alpha % 2 :
        fpl = int(alpha/2) + 1
    lpl = alpha - fpl

    start = a_part(fpl)
    mid = n_part(num)
    end = a_part(lpl)

    return u"%s%s%s" % (start,mid,end)

def asbool(obj):
    try:
        return bool(int(obj))
    except:
        return paste_asbool(obj)

def check_path_perms(path):
    """Function to check a path's permissions.
    Based on recipe found on:
        http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/436211
    """
    path = os.path.abspath(path)

    if not os.access(path, os.F_OK):
        log.error("I'm bailing out! "
                  "%r does not exist. ", path)
        log.error("Please correct the above problems and run again...")
        sys.exit(1)

    path_perms = os.stat(path)
    running_uid = os.getuid()
    running_gid = os.getgid()
    running_uid_name = getpwuid(running_uid)[0]
    running_gid_name = getgrgid(running_gid)[0]
    R_MSK, W_MSK, X_MSK, Z_MSK =   4,   2,   1,   0
    R_STR, W_STR, X_STR, Z_STR = 'r', 'w', 'x', '-'

    def iff( test_, then_, else_ ): # then_, else_ always get evaled so pls be atoms
        if test_:
            return then_
        else:
            return else_

    def mode2str( mode ):
        r, w, x = mode & R_MSK, mode & W_MSK, mode & X_MSK
        return iff( r, R_STR, Z_STR ) + iff( w, W_STR, Z_STR ) + iff( x, X_STR, Z_STR )

    def fullmode2str( mode ):
        u, g, o = mode >> 6 & 0x7, mode >> 3 & 0x7, mode & 0x7
        return mode2str( u ) + mode2str( g ) + mode2str( o )

    if not os.access(path, os.F_OK) or not os.access(path, os.X_OK):
        log.error("I'm bailing out! "
                  "I don't have read access to %r. "
                  "I'm running as '%s(%i):%s(%i)' and directory is\n"
                  "owned by '%s(%i):%s(%i) with perms '%s'.",
                  path,
                  running_uid_name,
                  running_uid,
                  running_gid_name,
                  running_gid,
                  getpwuid(path_perms[4])[0],
                  path_perms[4],
                  getgrgid(path_perms[5])[0],
                  path_perms[5],
                  fullmode2str(path_perms[ST_MODE]))
        log.error("Please correct the above problems and run again...")
        sys.exit(1)


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

# In[1]:

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from plotly.offline import plot
from plotly import graph_objects as  go
from matplotlib import pyplot as plt
from datetime import datetime
from os.path import basename
import numpy as np
import requests
np.seterr(divide='ignore', invalid='ignore')

# In[ ]:

day_mean = 10
today = datetime.now()
#URL =  " https://opendata.ecdc.europa.eu/covid19/casedistribution/csv-{0:%Y}-{0:%m}-{0:%d}.csv" #https://www.ecdc.europa.eu/sites/default/files/documents/COVID-19-geographic-disbtribution-worldwide-{0:%Y}-{0:%m}-{0:%d}.csv".format(today)
#FILE = "/home/lev/Dropbox/ScriptsLCS-Mesura/Coronavirus/LATAM/Data/"+basename(URL)

#with open(FILE, 'wb') as f:
#    f.write(requests.get(URL, allow_redirects=False).content)
#    print('DONE')

#dataglobal = pd.read_csv(FILE)
print (today)

# In[ ]:

dataglobal = pd.read_csv("https://opendata.ecdc.europa.eu/covid19/casedistribution/csv")
dataglobal.columns = ['daterep', 'year_week', 'cases_weekly', 'deaths_weekly', 'countries', 'geoid','gedoid1','pop','continentExp','notification_rate_per_100000_population_14-days']
dataglobal[dataglobal['countries'] == 'Panama']

# In[ ]:

dataglobal['daterep'] =pd.to_datetime(dataglobal.daterep, format = "%d/%m/%Y")

# In[ ]:

# In[ ]:

datalatam = dataglobal[dataglobal['countries'].isin(['Argentina', 'Bolivia', 'Brazil', 'Chile', 'Colombia', 'Costa_Rica', 'Cuba',
                                           'Ecuador', 'Guatemala', 'Honduras', 'Mexico', 'Nicaragua', 'Paraguay', 'Peru', 'Dominican_Republic', 'Uruguay', 'Venezuela'])]
mask = (datalatam['daterep'] > '02/28/2020') & (datalatam['daterep'] <= today.strftime('%m-%d-%Y'))
datalatam = datalatam.loc[mask]

# In[ ]:

datalatam = datalatam[['daterep', 'cases_weekly', 'countries', 'pop','deaths_weekly',]]

# In[ ]:

datalatam[datalatam['countries'] == 'Argentina']

# In[ ]:

idx = pd.date_range('2020-02-28', today.strftime('%Y-%m-%d'))

for rdate in idx:
    for country in ['Argentina', 'Bolivia', 'Brazil', 'Chile', 'Colombia', 'Costa_Rica', 'Cuba',
                                           'Ecuador', 'Guatemala', 'Honduras', 'Mexico', 'Nicaragua', 'Paraguay', 'Peru', 'Dominican_Republic', 'Uruguay', 'Venezuela']:
        dlt = datalatam[datalatam['countries'] == country]
        pop_country = dlt['pop'].iloc[0]
        death_country = dlt['deaths_weekly'].iloc[0]
        if rdate in set(dlt.daterep):
            value = dlt['cases_weekly'].loc[dlt['daterep'] == rdate]
            val = value.values[0]
        else:
            print(country)
            print(rdate)
            df2 = pd.DataFrame({"daterep": [rdate], "cases_weekly": [0], "countries": country, "deaths_weekly": [0], "pop": pop_country})
            datalatam = datalatam.append(df2, ignore_index = True, sort=True)
datalatam[datalatam['countries'] == 'Argentina']

# In[ ]:
# changed

datalatam = datalatam.sort_values(by=['countries', 'daterep'], ascending=True)
datalatam

# In[ ]:

datalatam['cumsum'] = datalatam.groupby(['countries'])['cases_weekly'].cumsum()
datalatam['cumnorm']=(datalatam['cumsum']/datalatam['pop'])*100000
datalatam['cumsumdeath'] = datalatam.groupby(['countries'])['deaths_weekly'].cumsum()
datalatam['cumdeathnorm']=(datalatam['cumsumdeath']/datalatam['pop'])*100000
datalatam['letalidad'] = (datalatam['cumsumdeath']/datalatam['cumsum'])*100
datalatam

# In[ ]:

fig = px.line(datalatam, x="daterep", y="cumsum", color="countries", line_shape = "linear", line_group="countries", hover_name="countries")
#fig.update_traces(textposition='top center')
fig.update_layout(
    title="COVID-19 en LATAM "+today.strftime('%Y-%m-%d'),
    xaxis_title="Fecha",
    yaxis_title="Casos acumulados",
    yaxis_type = "log",
    font=dict(
        family="Courier New, monospace",
        size=14,
        color="#7f7f7f"
    ),
    images= [dict(
                    source="https://raw.githubusercontent.com/sydmizar/datacovid19mx/master/images/csl.png",
                    xref="paper", yref="paper",
                    x=0, y=1,
                    sizex=0.2, sizey=0.4,
                    sizing="stretch",
                    opacity = 0.4,
                    layer="below")],
    annotations=[
            dict(
                text='Fuente: @ECDC_EU Gráfica: CSL UPIITA',
                align='left',
                showarrow=False,
                xref='paper',
                yref='paper',
                x=1,
                y=-0.16,
                bordercolor='black',
                borderwidth=1
            )
        ]
)
fig.show()

# In[ ]:

plot(fig, filename='../LATAM/acumulados_latam.html')

# In[ ]:

fig = px.line(datalatam, x="daterep", y="cumsumdeath", color="countries", line_shape = "linear", line_group="countries", hover_name="countries")
#fig.update_traces(textposition='top center')
fig.update_layout(
    title="COVID-19 en LATAM "+today.strftime('%Y-%m-%d'),
    xaxis_title="Fecha",
    yaxis_title="Decesos acumulados",
    yaxis_type = "log",
    font=dict(
        family="Courier New, monospace",
        size=14,
        color="#7f7f7f"
    ),
    images= [dict(
                    source="https://raw.githubusercontent.com/sydmizar/datacovid19mx/master/images/csl.png",
                    xref="paper", yref="paper",
                    x=0, y=1,
                    sizex=0.2, sizey=0.4,
                    sizing="stretch",
                    opacity = 0.4,
                    layer="below")],
    annotations=[
            dict(
                text='Fuente: @ECDC_EU Gráfica: CSL UPIITA',
                align='left',
                showarrow=False,
                xref='paper',
                yref='paper',
                x=1,
                y=-0.16,
                bordercolor='black',
                borderwidth=1
            )
        ]
)
fig.show()

# In[ ]:

plot(fig, filename='../LATAM/decesosacumulados_latam.html')

# In[ ]:

fig = px.scatter(datalatam, x="daterep", y="letalidad",  color="countries", hover_name="countries") #color="countries", line_shape = "linear", line_group="countries", hover_name="countries")
#fig.update_traces(textposition='top center')
fig.update_layout(
    title="COVID-19 en LATAM "+today.strftime('%Y-%m-%d'),
    xaxis_title="Fecha",
    yaxis_title="Letalidad (decesos/confirmados x100)",
    yaxis_type = "log",
    font=dict(
        family="Courier New, monospace",
        size=14,
        color="#7f7f7f"
    ),
    images= [dict(
                    source="https://raw.githubusercontent.com/sydmizar/datacovid19mx/master/images/csl.png",
                    xref="paper", yref="paper",
                    x=0, y=1,
                    sizex=0.2, sizey=0.4,
                    sizing="stretch",
                    opacity = 0.4,
                    layer="below")],
    annotations=[
            dict(
                text='Fuente: @ECDC_EU Gráfica: CSL UPIITA',
                align='left',
                showarrow=False,
                xref='paper',
                yref='paper',
                x=1,
                y=-0.16,
                bordercolor='black',
                borderwidth=1
            )
        ]
)
fig.show()

# In[ ]:

plot(fig, filename='../LATAM/letalidad_latam.html')

# In[ ]:

fig = px.scatter(datalatam, x="daterep", y="cumnorm", color="countries", hover_name="countries")
#fig.update_traces(textposition='top center')
fig.update_layout(
    title="COVID-19 per 10^5 "+today.strftime('%Y-%m-%d'),
    xaxis_title="Fecha",
    yaxis_title="(Casos acumulados / población) x 10^5",
    yaxis_type = "log",
    #xaxis_type = "log",
    font=dict(
        family="Courier New, monospace",
        size=14,
        color="#7f7f7f"
    ),
    images= [dict(
                    source="https://raw.githubusercontent.com/sydmizar/datacovid19mx/master/images/csl.png",
                    xref="paper", yref="paper",
                    x=0, y=1,
                    sizex=0.2, sizey=0.4,
                    sizing="stretch",
                    opacity = 0.4,
                    layer="below")],
    annotations=[
            dict(
                text='Fuente: @ECDC_EU Gráfica: CSL UPIITA',
                align='left',
                showarrow=False,
                xref='paper',
                yref='paper',
                x=1,
                y=-0.16,
                bordercolor='black',
                borderwidth=1
            )
        ]
)
fig.show()

# In[ ]:

plot(fig, filename='../LATAM/scatter_latam.html')

# In[ ]:

fig = px.scatter(datalatam, x="daterep", y="cumdeathnorm", color="countries", hover_name="countries")
#fig.update_traces(textposition='top center')
fig.update_layout(
    title="Decesos/Pob. per 10^5 "+today.strftime('%Y-%m-%d'),
    xaxis_title="Fecha",
    yaxis_title="(Decesos acumulados / población) x 10^5",
    yaxis_type = "log",
    #xaxis_type = "log",
    font=dict(
        family="Courier New, monospace",
        size=14,
        color="#7f7f7f"
    ),
#fig.update_traces(mode='markers', marker_symbol=diamond),
    images= [dict(
                    source="https://raw.githubusercontent.com/sydmizar/datacovid19mx/master/images/csl.png",
                    xref="paper", yref="paper",
                    x=0, y=1,
                    sizex=0.2, sizey=0.4,
                    sizing="stretch",
                    opacity = 0.4,
                    layer="below")],
    annotations=[
            dict(
                text='Fuente: @ECDC_EU Gráfica: CSL UPIITA',
                align='left',
                showarrow=False,
                xref='paper',
                yref='paper',
                x=1,
                y=-0.16,
                bordercolor='black',
                borderwidth=1
            )
        ]
)
fig.show()

# In[ ]:

plot(fig, filename='../LATAM/mortality_latam.html')


# -*- coding:utf-8 -*-
import jieba
if __name__ == "__main__":
    file_name = 'dict.txt'  # 自定义的词典
    jieba.load_userdict(file_name)
    fname1 = 'D:\大学\毛泽东思想概论\\b站爬虫\第五次\领风者\第七集\去重后\去重后弹幕.csv'
    f = open(fname1 ,encoding='utf-8')
    txt = f.read()  #   读取
    wordlist = jieba.lcut(txt)
    wordfile = 'D:\大学\毛泽东思想概论\\b站爬虫\第五次\领风者\第七集\去重后\弹幕文本清洗.txt'
    with open(wordfile, 'w+', encoding='utf-8') as f:
        for word in wordlist:
            f.write(word)
            if word != '\n':
                f.write(' ')

文本清洗/文本清洗.py


def rprop(val_delta,
          grad,
          initial_stepsize=0.1,
          eta_plus=1.2,
          eta_minus=0.5,
          max_stepsize=50.0,
          min_stepsize=1e-6):
    if not grad:
        return

    val = val_delta[0]
    delta = val_delta[1]

    if delta:
        if grad < 0.:
            if delta < 0.:
                delta *= eta_plus

                if -delta > max_stepsize:
                    delta = -max_stepsize
            else:
                delta *= -eta_minus

                if -delta < min_stepsize:
                    delta = -min_stepsize
        else:
            if delta < 0.:
                delta *= -eta_minus

                if delta < min_stepsize:
                    delta = min_stepsize
            else:
                delta *= eta_plus

                if delta > max_stepsize:
                    delta = max_stepsize
    else:
        if grad < 0.:
            delta = -initial_stepsize
        else:
            delta = initial_stepsize

    val += delta

    val_delta[0] = val
    val_delta[1] = delta


import setuptools

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

setuptools.setup(
    name="pedestrian_movement",
    version="0.0.3",
    author="Michael Hartmann",
    author_email="michael.hartmann@v2c2.at",
    description="Human Locomotion Models",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="",
    project_urls={
        "GitHub": "https://github.com/ga74kud/pedestrian_movement.git",
        "Bug Tracker": "https://github.com/ga74kud/pedestrian_movement.git",
    },
    classifiers=[
        "Programming Language :: Python :: 2.7",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    package_dir={"": "src"},
    install_requires=["matplotlib"],
    packages=setuptools.find_packages(where="src"),
    python_requires=">=2.7",
)


import random

quotes_dict = {"Houston, we have a problem": "Apollo 13",
               "I'll be back": "Terminator",
               "Remember who you are": "The Lion King",
               "I'm the king of the world": "Titanic",
               "There's no place like home": "The Wizard of Oz",
               "May the Force be with you": "Star Wars",
               "Go ahead, make my day": "Dirty Harry",
               "My mama always said life is like a box of chocolates": "Forrest Gump",
               "It's alive! It's alive!": "Frankenstein",
               "Just keep swimming": "Finding Nemo"
               }

questions_amount = int(input(f"Welcome to the Movie Quotes Quiz Game! How many questions "
                             f"would you like to attempt? (up to {len(quotes_dict)}) "))
# if questions_amount > len(quotes_dict):
while questions_amount > len(quotes_dict):
    questions_amount = int(input(f"Error: please enter the number of questions you would like to attempt "
                                 f"up to {len(quotes_dict)} "))

rset = random.sample(list(quotes_dict), questions_amount)

score = 0
counter = 0

for i in rset:
    answer = quotes_dict[f'{i}']
    guess = input(f'Question #{counter + 1} - What movie is this quote from? : \n\t\t"{i}"\n')
    if guess.lower() == answer.lower():
        print("Good job, that's correct!")
        score += 1
    else:
        print(f"Sorry, the correct answer was '{answer}'")

    counter += 1
    if counter == questions_amount:
        break

    print('---------------------------------')

print(f"\nYou finished with a total score of {score} out of {questions_amount}")


from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QGridLayout

from .node import StreamDirection
from .stream_info_group import StreamInfoGroup

class StreamInfoDialog(QDialog):

    def __init__(self, plugin, **kwargs):
        super().__init__(**kwargs)
        self._plugin = plugin

        self.setWindowTitle('AES67 Audio Streams')
        self.setMinimumSize(800, 600)
        self.setLayout(QGridLayout())

        self._sources = StreamInfoGroup(self._plugin, StreamDirection.SOURCE)
        self.layout().addWidget(self._sources, 0, 0)

        self._sinks = StreamInfoGroup(self._plugin, StreamDirection.SINK)
        self.layout().addWidget(self._sinks, 0, 1)

        self._button_box = QDialogButtonBox(parent=self)
        self._button_box.addButton(QDialogButtonBox.Close)
        self._button_box.rejected.connect(self.reject)
        self.layout().addWidget(self._button_box, 1, 0, 1, 2)

    @property
    def sinks(self):
        return self._sinks

    @property
    def sources(self):
        return self._sources

    def open(self, *args, **kwargs):
        super().open(*args, **kwargs)
        self._plugin.poller.add_callback('streams', self.update_local_streams)
        self._plugin.poller.add_callback('remote_sources', self.update_remote_sources)

    def reject(self, *args, **kwargs):
        super().reject(*args, **kwargs)
        self._plugin.poller.remove_callback('streams', self.update_local_streams)
        self._plugin.poller.remove_callback('remote_sources', self.update_remote_sources)

    def update_local_streams(self, stream_definitions):
        if not stream_definitions:
            return
        self._sources.update_local_streams(stream_definitions['sources'])
        self._sinks.update_local_streams(stream_definitions['sinks'])

    def update_remote_sources(self, stream_definitions):
        if not stream_definitions:
            return
        self._sources.update_remote_streams(stream_definitions['remote_sources'])


import json

from flask import request
from flask_restful import Resource
from flask_jwt_extended import jwt_required, get_jwt_identity, get_jwt_claims

from globalinfo.globalutils import transactions, timing, logger
from globalinfo.routeutils import results, error_handler
from productmanagement.product.service.productservice import ProductService

class ProductSearchController(Resource):

    product_service = ProductService()

    @jwt_required
    @timing
    @transactions
    @error_handler
    def get(self):
        '''
            This controller method is to retrieve the product given anysearch criteria

            As of now, it only retrieves the products for each tenant

        '''

        tenant_id = get_jwt_claims()['tenant_id']
        logger.debug(
            'Post method is invoked to retrieve the products for the tenant {0}'.format(tenant_id))
        product = self.product_service.search({}, tenant_id)
        return results(status="success", message="Fetched Product", data=product, format_json=True)

    @jwt_required
    @timing
    @transactions
    @error_handler
    def post(self):
        '''
            This controller method is to retrieve the product given anysearch criteria

            As of now, it only retrieves the products for each tenant
        '''

        tenant_id = get_jwt_claims()['tenant_id']
        logger.debug(
            'Post method is invoked to retrieve the products for the tenant {0}'.format(tenant_id))
        product = self.product_service.search({}, tenant_id)
        return results(status="success", message="Fetched Products", data=product, format_json=True)


import pandas as pd
import numpy as np
import pickle

from tqdm import tqdm

import vtk
from vtk.util.numpy_support import vtk_to_numpy

from glob import glob

def load_vtu(str_file):
    r = vtk.vtkXMLUnstructuredGridReader()

    r.SetFileName(str_file)
    r.Update()

    points = r.GetOutput().GetPoints().GetData()
    np_points = vtk_to_numpy(points)

    phi = r.GetOutput().GetPointData().GetArray(0)
    np_phi = vtk_to_numpy(phi)

    return {'points':np_points, 'phi' : np_phi}

file_list = glob("./*_motor_unit_* idx_muscle_fiber_*_1/t_*.vtu")

df = pd.DataFrame({'file_name' : file_list})

df['muscle_fiber_id'] = df.file_name.map(lambda x: int( x.split(' ')[-1].split('_')[3] ))
df['electrodes']      = df.file_name.map(lambda x: x.split('/')[-1].split('_')[0] == 't')
df['sources']         = df.file_name.map(lambda x: x.split('/')[-1].split('_')[0] == 'sources')
df['time']            = df.file_name.map(lambda x: int(x.split('/')[-1].split('_')[-1].split('.')[0]))

muscle_ids = df.muscle_fiber_id.unique()

muscle_fiber_phi = {}

def import_muscle_data(muscle_id : '[int]', df : 'pd.DataFrame' ) -> 'dict':
    sel = (df.muscle_fiber_id == muscle_id)

    df_local = df[sel & df.electrodes]

    muscle_fiber_phi = {}
    muscle_fiber_phi[muscle_id] = {}

    for t in df_local.time:
        file_selected = df_local.file_name[df_local.time == t]
        assert len(file_selected) == 1 , 'more than one file selected'

        try:
            data_dict = load_vtu( file_selected.item() )
        except :
            import pdb; pdb.set_trace()

        phi    = data_dict['phi']

        muscle_fiber_phi[muscle_id][t] = phi

    return muscle_fiber_phi

def import_electrode_positions(df : 'pd.DataFrame') -> 'nd.array' :
        data_dict = load_vtu( df.file_name[0])

        return data_dict['points']

def sort_time(d):
    time_idx = np.sort([t for t in d])
    return np.array( [ d[t] for t in time_idx ])

iterator = tqdm(map(lambda x : import_muscle_data(x, df), muscle_ids), total = len(muscle_ids))

muscle_fiber_phi = { k: sort_time(v) for d in iterator for k , v in d.items()  }

electtrode_df = pd.DataFrame({'timepoint' : [], 'phi': [], 'electrode_id': [], 'muscle_id' : []})

electrode_positions = import_electrode_positions(df)

for e_id in tqdm( range(len(muscle_fiber_phi[0][0,:])) ):
    for m_id in muscle_fiber_phi:

        df_length = len(muscle_fiber_phi[m_id][:,e_id])

        electtrode_df_m = pd.DataFrame({
            'timepoint':    [t for t in range(len(muscle_fiber_phi[m_id][:,e_id]))]
            , 'phi':          muscle_fiber_phi[m_id][:,e_id]
            , 'muscle_id':    [m_id] * df_length
            , 'electrode_id': [e_id] * df_length
            , 'p_electrode_x' : [electrode_positions[e_id,0]] * df_length
            , 'p_electrode_y' : [electrode_positions[e_id,1]] * df_length
            , 'p_electrode_z' : [electrode_positions[e_id,2]] * df_length
            })

        electtrode_df = pd.concat([electtrode_df, electtrode_df_m], ignore_index = True )

pd.to_pickle(electtrode_df, "./pandas_full_data.pkl")


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Google Nest Python Plugin
#
# Author: Filip Demaertelaere
# Extended by Mark Ruys
#
# Nest Plugin that works with the Google Account.
#
# It is based on the PHP code from https://github.com/gboudreau/nest-api. However only the functions required are ported to the plugin.
# A workaround is required to access the Google Account data. The values of issue_token and cookies are specific to your Google Account.
# To get them, follow these steps (only needs to be done once, as long as you stay logged into your Google Account).
#     Open a Chrome browser tab in Incognito Mode (or clear your cache).
#     Open Developer Tools (View/Developer/Developer Tools).
#     Click on Network tab. Make sure Preserve Log is checked.
#     In the Filter box, enter issueToken
#     Go to https://home.nest.com, and click Sign in with Google. Log into your account.
#     One network call (beginning with iframerpc) will appear in the Dev Tools window. Click on it.
#     In the Headers tab, under General, copy the entire Request URL (beginning with https://accounts.google.com, ending with nest.com). This is your $issue_token.
#     In the Filter box, enter oauth2/iframe
#     Several network calls will appear in the Dev Tools window. Click on the last iframe call.
#     In the Headers tab, under Request Headers, copy the entire cookie value (include the whole string which is several lines long and has many field/value pairs - do not include the Cookie: prefix). This is your $cookies; make sure all of it is on a single line.
#
"""
<plugin key="GoogleNest" name="Nest Thermostat/Protect Google" author="Filip Demaertelaere" version="2.3.0">
    <description>

Instructions

        The values of issue_token and cookies are specific to your Google Account.

        To get them, follow these steps (only needs to be done once, as long as you stay logged into your Google Account).

Open a Chrome browser tab in Incognito Mode (or clear your cache).

Open 'Developer Tools' (View/Developer/Developer Tools).

Click on 'Network' tab. Make sure 'Preserve Log' is checked.

In the 'Filter' box, enter 'issueToken'

Go to 'https://home.nest.com', and click 'Sign in with Google'. Log into your account.

One network call (beginning with 'iframerpc') will appear in the 'Dev Tools' window. Click on it.

In the 'Headers' tab, under 'General', copy the entire 'Request URL' (beginning with https://accounts.google.com, ending with nest.com). This is your $issue_token.

In the 'Filter' box, enter 'oauth2/iframe'.

Several network calls will appear in the 'Dev Tools' window. Click on the last 'iframe' call.

In the 'Headers' tab, under 'Request Headers', copy the entire 'cookie value' (include the whole string which is several lines long and has many field/value pairs - do not include the Cookie: prefix). This is your $cookies; make sure all of it is on a single line.

        You can now close the browser, but DO NOT LOGGED OUT from your Google Nest Account (logging out

        will invalidate the credentials).

    </description>
    <params>
        <param field="Mode1" label="issue_token" width="600px" required="true"/>
        <param field="Mode2" label="cookie" width="600px" required="true"/>
        <param field="Mode5" label="Minutes between update" width="120px" required="true" default="5"/>
        <param field="Mode6" label="Debug" width="120px">
            <options>
                <option label="True" value="Debug"/>
                <option label="False" value="Normal" default="true"/>
            </options>
        </param>
    </params>
</plugin>
"""

#IMPORTS
import sys, os
major,minor,x,y,z = sys.version_info
sys.path.append('/usr/lib/python3/dist-packages')
sys.path.append('/usr/local/lib/python{}.{}/dist-packages'.format(major, minor))
sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
from domoticz_tools import *
import Domoticz
import nest
import threading
import queue
import time
import json

#DEFAULT IMAGE
_IMAGE_NEST_HEATING = 'GoogleNest Nest Heating'
_IMAGE_NEST_HEATING_OFF = 'GoogleNest Nest Heating Off'
_IMAGE_NEST_AWAY = 'GoogleNest Nest Away'
_IMAGE_NEST_ECO = 'GoogleNest Nest Eco'
_IMAGE_NEST_PROTECT = 'GoogleNest Nest Protect'

#DEVICE NAMES
_NEST_HEATING = 'Heating'
_NEST_ECO_MODE = 'Eco Mode'
_NEST_AWAY = 'Away'
_NEST_TEMP_HUM = 'Temp/Hum'
_NEST_HEATING_TEMP = 'Heating Temp'
_NEST_PROTECT = 'Protect'
_NEST_WIND = 'Wind'

################################################################################
# Start Plugin
################################################################################

class BasePlugin:

    def __init__(self):
        self.debug = DEBUG_OFF
        self.runAgain = MINUTE
        self.ErrorLevel = 0
        self.myNest = None
        self.round_temperature = 0
        self.wind_list = []
        self.tasksQueue = queue.Queue()
        self.tasksThread = threading.Thread(name='QueueThread', target=BasePlugin.handleTasks, args=(self,))

    def onStart(self):
        # Set debug level according to user setting
        self.debug = DEBUG_ON if Parameters['Mode6'] == 'Debug' else DEBUG_OFF
        Domoticz.Debugging(self.debug)
        if self.debug == DEBUG_ON:
            DumpConfigToLog(Parameters, Devices)

        # Read technical parameters
        try:
            config = None
            with open('./plugins/GoogleNest/GoogleNest.json') as json_file:
                config = json.load(json_file)
            self.round_temperature = config['RoundTemperature']
        except:
            pass

        # Create images if necessary
        if _IMAGE_NEST_AWAY not in Images:
            Domoticz.Image('Nest Away.zip').Create()
        if _IMAGE_NEST_ECO not in Images:
            Domoticz.Image('Nest Eco.zip').Create()
        if _IMAGE_NEST_HEATING not in Images:
            Domoticz.Image('Nest Heating.zip').Create()
        if _IMAGE_NEST_HEATING_OFF not in Images:
            Domoticz.Image('Nest Heating Off.zip').Create()
        if _IMAGE_NEST_PROTECT not in Images:
            Domoticz.Image('Nest Protect.zip').Create()
        Domoticz.Debug('> Images created')

        # Set all devices as timed out
        TimeoutDevice(Devices, All=True)

        # Create Nest instance
        if not Parameters['Mode1'].startswith('https://accounts.google.com'):
            Domoticz.Error('Hardware setting issue_token must start with https://accounts.google.com.')
        elif not Parameters['Mode1'].endswith('nest.com'):
            Domoticz.Error('Hardware setting issue_token must end with nest.com.')
        else:
            self.myNest = nest.Nest(Parameters['Mode1'], Parameters['Mode2'], float(Parameters['Mode5'].replace(',','.')))
            self.tasksThread.start()
            self.tasksQueue.put({'Action': 'StatusUpdate'})
            self.tasksQueue.put({'Action': 'OutsideWeather'})

        Domoticz.Debug('> Plugin started')

    def onStop(self):
        Domoticz.Debug('> onStop called')

        # Signal queue thread to exit
        self.tasksQueue.put(None)
        self.tasksQueue.join()

        # Wait until queue thread has exited
        Domoticz.Debug('Threads still active: {} (should be 1)'.format(threading.active_count()))
        endTime = time.time() + 70
        while (threading.active_count() > 1) and (time.time() < endTime):
            for thread in threading.enumerate():
                if thread.name != threading.current_thread().name:
                    Domoticz.Debug('Thread {} is still running, waiting otherwise Domoticz will abort on plugin exit.'.format(thread.name))
            time.sleep(1.0)

        Domoticz.Debug('> Plugin stopped')

    def onConnect(self, Connection, Status, Description):
        Domoticz.Debug('> onConnect called, ignored')

    def onMessage(self, Connection, Data):
        Domoticz.Debug('> onMessage called, ignored')

    def onCommand(self, Unit, Command, Level, Hue):
        Domoticz.Debug('> onCommand called: Unit: {} - Command: {} - Level {} - Hue: {}'.format(Unit, Command, Level, Hue))

        for device in self.myNest.device_list:
            info = self.myNest.GetThermostatInformation(device)
            Domoticz.Debug('> {} - {}'.format(info['Where'], Devices[Unit].Name))

            # Set heating temperature
            if DeviceNameBelongsToUnit(info['Where'] + ' ' + _NEST_HEATING_TEMP, Unit):
                self.tasksQueue.put({'Action': 'SetHeatingTemp', 'Device': device, 'Value': Level})

            # Set Away status
            elif DeviceNameBelongsToUnit(_NEST_AWAY, Unit):
                self.tasksQueue.put({'Action': 'SetAway', 'Device': device, 'Value': Command})

            # Set Eco mode
            elif DeviceNameBelongsToUnit(info['Where'] + ' ' + _NEST_ECO_MODE, Unit):
                self.tasksQueue.put({'Action': 'SetEcoMode', 'Device': device, 'Value': Command})

            # Set Heating
            elif DeviceNameBelongsToUnit(info['Where'] + ' ' + _NEST_HEATING, Unit):
                self.tasksQueue.put({'Action': 'SetHeating', 'Device': device, 'Value': Command})

        Domoticz.Debug('Processed {} to {} for unit {}'.format(Command, Level, Unit))

    def onNotification(self, Name, Subject, Text, Status, Priority, Sound, ImageFile):
        Domoticz.Debug('> Notification: {}, {}, {}, {}, {}, {}, {}'.format(
            Name, Subject, Text, Status, Priority, Sound, ImageFile
        ))

    def onDisconnect(self, Connection):
        Domoticz.Debug('> onDisconnect called, ignored')

    def onHeartbeat(self):
        self.runAgain -= 1
        if self.runAgain <= 0:

            # Get Nest Update
            self.tasksQueue.put({'Action': 'StatusUpdate'})
            self.tasksQueue.put({'Action': 'OutsideWeather'})
            if self.ErrorLevel == 5:
                TimeoutDevice(Devices, All=True)
                Domoticz.Error('ERRORLEVEL=5 Unable to get update data from Nest (last error: {}).'.format(self.myNest._nest_access_error))

            # Run again following the period in the settings
            self.runAgain = MINUTE * float(Parameters['Mode5'].replace(',','.'))

    def handleTasks(self):
        try:
            Domoticz.Debug('> Entering tasks handler')
            while True:
                task = self.tasksQueue.get(block=True)
                if task is None:
                    Domoticz.Debug('> Exiting task handler')
                    try:
                        self.myNest.terminate()
                    except AttributeError:
                        pass
                    self.tasksQueue.task_done()
                    break

                Domoticz.Debug('> Handling task: {}.'.format(task['Action']))
                DeviceUpdate = False
                DeviceUpdateRequested = False
                if task['Action'] == 'StatusUpdate':
                    DeviceUpdateRequested = True
                    DeviceUpdate = self.myNest.UpdateDevices()

                elif task['Action'] == 'SetHeatingTemp':
                    DeviceUpdateRequested = True
                    DeviceUpdate = self.myNest.SetTemperature(task['Device'], task['Value']) and self.myNest.UpdateDevices()

                elif task['Action'] == 'SetAway':
                    DeviceUpdateRequested = True
                    Away = True if task['Value'] == 'On' else False
                    DeviceUpdate = self.myNest.SetAway(task['Device'], Away) and self.myNest.UpdateDevices()

                elif task['Action'] == 'SetEcoMode':
                    DeviceUpdateRequested = True
                    Eco = 'manual-eco' if task['Value'] == 'On' else 'schedule'
                    DeviceUpdate = self.myNest.SetEco(task['Device'], Eco) and self.myNest.UpdateDevices()

                elif task['Action'] == 'SetHeating':
                    DeviceUpdateRequested = True
                    Heat = 'heat' if task['Value'] == 'On' else 'off'
                    DeviceUpdate = self.myNest.SetThermostat(task['Device'], Heat) and self.myNest.UpdateDevices()

                elif task['Action'] == 'OutsideWeather':
                    WeatherUpdate = self.myNest.GetOutsideTempHum()
                    if WeatherUpdate:
                        updated_units = self.updateWeather(WeatherUpdate)
                        self.ErrorLevel = 0
                        Domoticz.Debug('> Updated {} units for weather.'.format(updated_units))
                    else:
                        self.ErrorLevel += 1
                        Domoticz.Debug('Unable to get weather data from Nest (last error: {}).'.format(self.myNest._nest_access_error))

                else:
                    Domoticz.Error('> TaskHandler: unknown action code {}'.format(task['Action']))
                    DeviceUpdate = self.myNest.UpdateDevices()

                if DeviceUpdate:
                    updated_units = self.updateNestInfo() + self.updateThermostats() + self.updateProtects()
                    self.ErrorLevel = 0
                    Domoticz.Debug('> Updated {} units for {} device(s)'.format(updated_units, len(self.myNest.device_list) + len(self.myNest.protect_list)))
                else:
                    if DeviceUpdateRequested:
                        self.ErrorLevel += 1
                        Domoticz.Debug('Unable to get update data from Nest (last error: {}).'.format(self.myNest._nest_access_error))

                self.tasksQueue.task_done()
                Domoticz.Debug('> Finished handling task: {}.'.format(task['Action']))

        except Exception as err:
            self.tasksQueue.task_done()
            Domoticz.Error('> General error TaskHandler: {}'.format(err))

    def updateProtects(self):
        updated_units = 0
        for nest_device in self.myNest.protect_list:
            info = self.myNest.GetProtectInformation(nest_device)
            Domoticz.Debug('> {}'.format(json.dumps(info)))
            #Create device if required and allowed
            device_name = info['Where'] + ' ' + _NEST_PROTECT
            unit = FindUnitByNestName(device_name)
            if not unit:
                unit = GetNextFreeUnit(Devices)
                description = CreateDescription(device_name)
                Domoticz.Device(Unit=unit, Name=device_name, Description=description, Type=244, Subtype=73, Switchtype=5, Image=Images[_IMAGE_NEST_PROTECT].ID, Used=1).Create()
            if info['Smoke_status'] or info['Co_status'] or info['Heat_status'] :
                UpdateDevice(Devices, unit, 1, 1, BatteryLevel=int(int(info['Battery_level'])/100))
            else:
                UpdateDevice(Devices, unit, 0, 0, BatteryLevel=int(int(info['Battery_level'])/100))
            updated_units += 1
        return updated_units

    def updateThermostats(self):
        updated_units = 0
        for nest_device in self.myNest.device_list:
            info = self.myNest.GetThermostatInformation(nest_device)
            Domoticz.Debug('> {}'.format(json.dumps(info)))

            #Update NEST HEATING and create device if required
            device_name = info['Where'] + ' ' + _NEST_HEATING
            unit = FindUnitByNestName(device_name)
            if not unit:
                unit = GetNextFreeUnit(Devices)
                description = CreateDescription(device_name)
                Domoticz.Device(Unit=unit, Name=device_name, Description=description, Type=244, Subtype=73, Switchtype=0, Image=Images[_IMAGE_NEST_HEATING].ID, Used=1).Create()
            if info['Heating']:
                UpdateDevice(Devices, unit, 1, 1, Images[_IMAGE_NEST_HEATING].ID)
            else:
                #Update NEST HEATING icon off or on
                if info['Target_mode'] == 'off':
                    UpdateDevice(Devices, unit, 0, 0, Images[_IMAGE_NEST_HEATING_OFF].ID)
                else:
                    UpdateDevice(Devices, unit, 0, 0, Images[_IMAGE_NEST_HEATING].ID)
            updated_units += 1

            #Update NEST ECO MODE and create device if required
            device_name = info['Where'] + ' ' + _NEST_ECO_MODE
            unit = FindUnitByNestName(device_name)
            if not unit:
                unit = GetNextFreeUnit(Devices)
                description = CreateDescription(device_name)
                Domoticz.Device(Unit=unit, Name=device_name, Description=description, Type=244, Subtype=73, Switchtype=0, Image=Images[_IMAGE_NEST_ECO].ID, Used=1).Create()
            if info['Eco']:
                UpdateDevice(Devices, unit, 1, 1)
            else:
                UpdateDevice(Devices, unit, 0, 0)
            updated_units += 1

            #Update NEST TEMP/HUMIDITY and create device if required
            device_name = info['Where'] + ' ' + _NEST_TEMP_HUM
            unit = FindUnitByNestName(device_name)
            if not unit:
                unit = GetNextFreeUnit(Devices)
                description = CreateDescription(device_name)
                Domoticz.Device(Unit=unit, Name=device_name, Description=description, Type=82, Subtype=1, Switchtype=0, Used=1).Create()
            if self.round_temperature:
                temperature = round(info['Current_temperature'] * 2) / 2
            else:
                temperature = info['Current_temperature']
            UpdateDevice(Devices, unit, 0, '%.1f;%.0f;0'%(temperature, info['Humidity']))
            updated_units += 1

            #Update NEST HEATING TEMPERATURE and create device if required
            device_name = info['Where'] + ' ' + _NEST_HEATING_TEMP
            unit = FindUnitByNestName(device_name)
            if not unit:
                unit = GetNextFreeUnit(Devices)
                description = CreateDescription(device_name)
                Domoticz.Device(Unit=unit, Name=device_name, Description=description, Type=242, Subtype=1, Switchtype=0, TypeName=info['Temperature_scale'], Used=1).Create()
            UpdateDevice(Devices, unit, info['Target_temperature'], info['Target_temperature'])
            updated_units += 1

            #Update device for the auto-away of the thermostat
            device_name = info['Where'] + ' ' + _NEST_AWAY
            unit = FindUnitByNestName(device_name)
            if not unit:
                unit = GetNextFreeUnit(Devices)
                description = CreateDescription(device_name)
                Domoticz.Device(Unit=unit, Name=device_name, Description=description, Type=244, Subtype=73, Switchtype=0, Image=Images[_IMAGE_NEST_AWAY].ID, Used=0).Create()
            #Auto_away<0=disabled; Auto_away==0=enabled+home; Auto_away>0=enabled+away
            if info['Auto_away'] > 0:
                UpdateDevice(Devices, unit, 1, 1)
            elif info['Auto_away'] == 0:
                UpdateDevice(Devices, unit, 0, 0)
            updated_units += 1

        return updated_units

    def updateNestInfo(self):
        updated_units = 0
        info = self.myNest.GetNestInformation()
        Domoticz.Debug('> {}'.format(json.dumps(info)))

        #Update NEST AWAY and create device if required
        device_name = _NEST_AWAY
        unit = FindUnitByNestName(device_name)
        if not unit:
            unit = GetNextFreeUnit(Devices)
            description = CreateDescription(device_name)
            Domoticz.Device(Unit=unit, Name=device_name, Description=description, Type=244, Subtype=73, Switchtype=0, Image=Images[_IMAGE_NEST_AWAY].ID, Used=1).Create()
        if info['Away']:
            UpdateDevice(Devices, unit, 1, 1)
        else:
            UpdateDevice(Devices, unit, 0, 0)
        updated_units += 1
        return updated_units

    def updateWeather(self, weather_info):
        updated_units = 0
        Domoticz.Debug('> {}'.format(json.dumps(weather_info)))

        #update Temperature/Humidity and create device if required
        device_name = '{} {}'.format(weather_info['City'], _NEST_TEMP_HUM)
        unit = FindUnitByNestName(device_name)
        if not unit:
            unit = GetNextFreeUnit(Devices)
            description = CreateDescription(device_name)
            Domoticz.Device(Unit=unit, Name=device_name, Description=description, Type=82, Subtype=1, Switchtype=0, Used=1).Create()
        UpdateDevice(Devices, unit, 0, '%.1f;%.0f;0'%(weather_info['Current_temperature'], weather_info['Current_humidity']))
        updated_units += 1

        #update Wind and create device if required
        device_name = '{} {}'.format(weather_info['City'], _NEST_WIND)
        unit = FindUnitByNestName(device_name)
        if not unit:
            unit = GetNextFreeUnit(Devices)
            description = CreateDescription(device_name)
            Domoticz.Device(Unit=unit, Name=device_name, Description=description, Type=86, Subtype=4, Switchtype=0, Used=1).Create()
        wind_km = 1.609344 * weather_info['Current_wind']
        directions = {'N':0, 'NNE':22.5, 'NE':45, 'ENE':67.5, 'E':90, 'ESE':112.5, 'SE':135,'SSE':157.5, 'S':180, 'SSW':202.5, 'SW':225, 'WSW':247.5, 'W':270, 'WNW':292.5, 'NW':315, 'NNW':337.5, 'N':0, 'North':0, 'East':90, 'West':270, 'South':180}
        wind_chill = 13.12 + (0.6215 * weather_info['Current_temperature']) + (-11.37 * wind_km ** 0.16) + (0.3965 * weather_info['Current_temperature'] * wind_km ** 0.16)
        if len(self.wind_list)>10:
            self.wind_list.pop(0)
        self.wind_list.append(wind_km)
        UpdateDevice(Devices, unit, 0, '%.1f;%s;%d;%.1f;%.1f;%.1f'%(directions[weather_info['Wind_direction']], weather_info['Wind_direction'], 10000/3600*wind_km, 10000/3600*max(self.wind_list), weather_info['Current_temperature'], wind_chill))
        updated_units += 1

        return updated_units

global _plugin
_plugin = BasePlugin()

def onStart():
    global _plugin
    _plugin.onStart()

def onStop():
    global _plugin
    _plugin.onStop()

def onConnect(Connection, Status, Description):
    global _plugin
    _plugin.onConnect(Connection, Status, Description)

def onMessage(Connection, Data):
    global _plugin
    _plugin.onMessage(Connection, Data)

def onCommand(Unit, Command, Level, Hue):
    global _plugin
    _plugin.onCommand(Unit, Command, Level, Hue)

def onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile):
    global _plugin
    _plugin.onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile)

def onDisconnect(Connection):
    global _plugin
    _plugin.onDisconnect(Connection)

def onHeartbeat():
    global _plugin
    _plugin.onHeartbeat()

################################################################################
# Specific helper functions
################################################################################

def DeviceNameBelongsToUnit(device_name, Unit):
    needle = '[{}]'.format(device_name).lower()
    return needle in Devices[Unit].Description.lower()

def CreateDescription(tag):
    return 'Do not remove: [{}]'.format(tag)

def FindUnitByNestName(device_name):
    for Unit in Devices:
        if DeviceNameBelongsToUnit(device_name, Unit):
            return Unit

    # For backwards compatibility, scan for device names ending in device_name
    for Unit in Devices:
        Domoticz.Debug('Check {} ends with {}'.format(Devices[Unit].Name, device_name))
        if Devices[Unit].Name.lower().endswith(device_name.lower()):
            descriptions = [] if Devices[Unit].Description == '' else [ Devices[Unit].Description ]
            descriptions += [ CreateDescription(device_name) ]
            Devices[Unit].Update(Description='; '.join(descriptions), nValue=Devices[Unit].nValue, sValue=Devices[Unit].sValue)
            Domoticz.Debug('Updated description to {}'.format('; '.join(descriptions)))
            return Unit
    return None


import unittest
from unittest.mock import ANY, Mock, patch, call
from http.client import HTTPMessage

from pynautobot.core.query import RequestErrorFromException
import pynautobot

host = "http://localhost:8000"

def_kwargs = {
    "token": "abc123",
}

# Keys are app names, values are arbitrarily selected endpoints
# We use dcim and ipam since they have unique app classes
# and circuits because it does not. We don't add other apps/endpoints
# beyond 'circuits' as they all use the same code as each other
endpoints = {
    "dcim": "devices",
    "ipam": "prefixes",
    "circuits": "circuits",
}

class ApiTestCase(unittest.TestCase):
    @patch(
        "requests.sessions.Session.post",
    )
    @patch("pynautobot.api.version", "2.0")
    def test_get(self, *_):
        api = pynautobot.api(host, **def_kwargs)
        self.assertTrue(api)

    @patch(
        "requests.sessions.Session.post",
    )
    @patch("pynautobot.api.version", "2.0")
    def test_sanitize_url(self, *_):
        api = pynautobot.api("http://localhost:8000/", **def_kwargs)
        self.assertTrue(api)
        self.assertEqual(api.base_url, "http://localhost:8000/api")

    @patch("pynautobot.api.version", "2.0")
    def test_verify_true(self, *_):
        api = pynautobot.api("http://localhost:8000/", **def_kwargs)
        self.assertTrue(api)
        self.assertTrue(api.http_session.verify)

    @patch("pynautobot.api.version", "2.0")
    def test_verify_false(self, *_):
        api = pynautobot.api("http://localhost:8000/", verify=False, **def_kwargs)
        self.assertTrue(api)
        self.assertFalse(api.http_session.verify)

class ApiVersionTestCase(unittest.TestCase):
    class ResponseHeadersWithVersion:
        headers = {"API-Version": "1.999"}
        ok = True

    @patch(
        "requests.sessions.Session.get",
        return_value=ResponseHeadersWithVersion(),
    )
    def test_api_version(self, *_):
        with self.assertRaises(ValueError) as error:
            pynautobot.api(host)
        self.assertEqual(
            str(error.exception), "Nautobot version 1 detected, please downgrade pynautobot to version 1.x"
        )

    class ResponseHeadersWithoutVersion:
        headers = {}
        ok = True

    @patch(
        "requests.sessions.Session.get",
        return_value=ResponseHeadersWithoutVersion(),
    )
    def test_api_version_not_found(self, *_):
        api = pynautobot.api(
            host,
        )
        self.assertEqual(api.version, "")

    class ResponseHeadersWithVersion2:
        headers = {"API-Version": "2.0"}
        ok = True

    @patch(
        "requests.sessions.Session.get",
        return_value=ResponseHeadersWithVersion2(),
    )
    def test_api_version_2(self, *_):
        api = pynautobot.api(
            host,
        )
        self.assertEqual(api.version, "2.0")

class ApiStatusTestCase(unittest.TestCase):
    class ResponseWithStatus:
        ok = True

        def json(self):
            return {
                "nautobot-version": "1.3.2",
            }

    @patch(
        "requests.sessions.Session.get",
        return_value=ResponseWithStatus(),
    )
    @patch("pynautobot.api.version", "2.0")
    def test_api_status(self, *_):
        api = pynautobot.api(
            host,
        )
        self.assertEqual(api.status()["nautobot-version"], "1.3.2")

class ApiRetryTestCase(unittest.TestCase):
    class ResponseWithStatus:
        ok = False
        status_code = 429

    @patch("urllib3.connectionpool.HTTPConnectionPool._get_conn")
    def test_api_retry(self, getconn_mock):
        getconn_mock.return_value.getresponse.side_effect = [
            Mock(status=500, msg=HTTPMessage()),
            Mock(status=429, msg=HTTPMessage()),
            Mock(status=200, msg=HTTPMessage()),
        ]

        api = pynautobot.api(
            "http://any.url/",
            retries=2,
        )
        with patch("pynautobot.api.version", "2.0"):
            api.version

        assert getconn_mock.return_value.request.mock_calls == [
            call("GET", "/api/", body=None, headers=ANY),
            call("GET", "/api/", body=None, headers=ANY),
            call("GET", "/api/", body=None, headers=ANY),
        ]

    @patch("urllib3.connectionpool.HTTPConnectionPool._get_conn")
    def test_api_retry_fails(self, getconn_mock):
        getconn_mock.return_value.getresponse.side_effect = [
            Mock(status=500, msg=HTTPMessage()),
            Mock(status=429, msg=HTTPMessage()),
            Mock(status=200, msg=HTTPMessage()),
        ]

        with patch("pynautobot.api.version", "2.0"):
            api = pynautobot.api(
                "http://any.url/",
                retries=1,
            )

        with self.assertRaises(RequestErrorFromException):
            api.version


import os

import eyed3

from app.config import configuration

class Mp3Editor:

    def update_tag_all_under_mp3_home(self):
        files_under_mp3_home = os.listdir(configuration.mp3_home)
        mp3_iterator = filter(lambda f: f.endswith(configuration.endswith), files_under_mp3_home)
        mp3_iterator = sorted(mp3_iterator)

        for mp3 in mp3_iterator:
            mp3_file = eyed3.load(os.path.join(configuration.mp3_home, mp3))
            print(mp3_file)

mp3_editor = Mp3Editor()