import math
from math import pi

import pyglet
from pyglet.window import key
from pyglet.gl import *

from shader import Shader as NewShader
import random

class ShaderWindow(pyglet.window.Window):
    wanderdistance = .5
    max_iters = 400.0
    min_iters = 16.0
    max_zoom = 3.03439295521e-05
    def __init__(self, shader):
        # Create window
        super(ShaderWindow, self).__init__(800, 800, caption="Shader Testing")
        # Setup mouse

        shader.bind()

        shader.uniformf('MaxIterations', 50.0)
        shader.uniformf('Zoom', 1.0)
        shader.uniformf('Xcenter', 0.0)
        shader.uniformf('Ycenter', 0.0)

        shader.uniformf('InnerColor', 0.0, 0.0, 0.0)
        shader.uniformf('OuterColor2', 1, 1, 1)
        shader.uniformf('OuterColor1', 1.0, 1.0, 1.0)
        shader.unbind()
        self.shader = shader
        self.center = [0, 0]
        self.zoom = 1.0
        self.zoomdir = 1.0
        self.zoomspeed = .45

        self.quality_timeout = .05
        self.quality_time = 0.0
        self.quality_delta = 1.0
        self.quality = 400

        self.dodraw = 2

        self.color = (1.0, 1.0, 1.0)

        self.xwander = 0.0
        self.ywander = 0.0
        self.xspeed = .1
        self.yspeed = .1
        self.xdir = 1.0
        self.ydir = 1.0
        self.xdist = random.randint(-5, 5)/10.0
        # Setup Texture
        texture = pyglet.image.Texture.create_for_size(GL_TEXTURE_RECTANGLE_ARB, self.width, self.height, internalformat=GL_RGBA)
        glTexParameteri(texture.target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexParameteri(texture.target, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        self.texture = texture
        # Create batch and quad
        batch = pyglet.graphics.Batch()
        batch.add(4, GL_QUADS, None,
            ('v2i', (0, 0, self.width, 0, self.width, self.height, 0, self.height)),
            ('t2f', (0, 0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0))
        )
        self.batch = batch

        self.setup_gl()

        self.keys = pyglet.window.key.KeyStateHandler()
        self.push_handlers(self.keys)
        # set update function
        pyglet.clock.schedule_interval(self.update, 1.0/30.0)

    def setup_gl(self):
        pyglet.gl.glClearColor(1.0, 0.0, 0.0, 1.0)
        pyglet.gl.glEnable(pyglet.gl.GL_LINE_SMOOTH)
        pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
        pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA,
                pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)

    def copyFramebuffer(self, tex, *size):
        # if we are given a new size
        if len(size) == 2:
            # resize the texture to match
            tex.width, tex.height = size[0], size[1]
        glBindTexture(tex.target, tex.id)
        glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, tex.width, tex.height, 0);
        glBindTexture(tex.target, 0)

    def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
        self.dodraw = 2
        self.zoom = min(1.0, max(self.max_zoom, self.zoom + (scroll_y * (-0.02 * self.zoom))))
        self.quality_time += self.quality_timeout
        self.quality_time = min(.5, self.quality_time)

        #self.on_mouse_press(x, y, pyglet.window.mouse.LEFT, None)
    def on_resize(self, width, height):
        glViewport(0, 0, width, height)
        # setup a simple 0-1 orthoganal projection
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(0, width, 0, height, -1, 1)
        glMatrixMode(GL_MODELVIEW)

        self.shader.bind()
        self.shader.unbind()

        # copy the framebuffer, which also resizes the texture
        self.copyFramebuffer(self.texture, width, height)
        return pyglet.event.EVENT_HANDLED

    def on_mouse_motion(self, x, y, dx, dy):
        rdist = math.sqrt(((x - 0)**2) + ((y - 0)**2)) / 2.0
        gdist = math.sqrt(((x - self.width/2.0)**2) + ((y - self.height)**2)) / 2.0
        bdist = math.sqrt(((x - self.width)**2) + ((y - 0)**2)) / 2.0

        r = 1 - max(1, rdist * 0.9) / 255
        g = 1 - max(1, gdist * 0.9) / 255
        b = 1 - max(1, bdist * 0.9) / 255

        self.color = (r, g, b)
        self.quality_time += self.quality_timeout
        self.quality_time = min(.5, self.quality_time)
        self.dodraw = 2

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        pass

    def on_mouse_press(self, x, y, buttons, modifiers):
        self.dodraw = 2
        if buttons == pyglet.window.mouse.LEFT:
            dx = 5*((x - self.width/2.0)/self.width)
            dy = 5*((y - self.height/2.0)/self.height)
            self.center[0] += dx * self.zoom
            self.center[1] += dy * self.zoom
        self.zoom *= 0.92

    def on_key_press(self, symbol, modifiers):
        if symbol == pyglet.window.key.ESCAPE:
            self.on_close()

    def update(self, dt):
        old = self.quality_time
        self.quality_time = max(0.0, self.quality_time - (self.quality_delta * dt))
        if not self.quality_time and old:
            self.dodraw = 2

        #=======================================================================
        # self.zoom += self.zoomspeed * (self.zoom * 2) * dt * self.zoomdir
        # if self.zoom <= self.max_zoom or self.zoom >= 1.0:
        #    self.zoomdir = -self.zoomdir
        #    self.zoom = min(1.0, max(self.max_zoom, self.zoom))
        # self.center[0] += self.xspeed * dt * self.xdir * self.zoom
        # self.xwander += self.xspeed * dt * self.xdir * self.zoom
        # if self.xwander >= self.xdist or self.xwander <= 0.0:
        #    self.xdir = -self.xdir
        #    self.xwander = min(self.xdist, max(0.0, self.xwander))
        #    self.xdist = random.randint(-10, 10)/100.0
        #=======================================================================

    def on_draw(self):
        if self.dodraw > 0:
            self.clear()
            self.dodraw -= 1
            glBindTexture(self.texture.target, self.texture.id)
            pyglet.gl.glClearColor(1.0, 0.0, 0.0, 1.0)
            #glActiveTexture(GL_TEXTURE0 + 1)
            #glBindTexture(texture1.target, texture1.id)

            self.shader.bind()
            shader.uniformf('Xcenter', self.center[0])
            shader.uniformf('Ycenter', self.center[1])
            shader.uniformf('Zoom', self.zoom)
            iters = self.max_iters * (1.0 - (self.zoom ** .02))
            iters = 400.0 if not self.quality_time else max(self.min_iters, iters)
            #print self.zoom, iters
            shader.uniformf('MaxIterations', iters)
            shader.uniformf('OuterColor1', *self.color)
            self.batch.draw()
            self.shader.unbind()

            #glBindTexture(self.texture.target, 0)
            #glBindTexture(texture1.target, 0)

            #glActiveTexture(GL_TEXTURE0)

            # copy the result back into the texture
        self.copyFramebuffer(self.texture)

# create our shader
shader = NewShader(['''
varying vec3  Position;

void main()
{
    Position        = vec3(gl_MultiTexCoord0 - 0.5) * 5.0;
    gl_Position     = ftransform();
}
'''], ['''
varying vec3  Position;

uniform float MaxIterations;
uniform float Zoom;
uniform float Xcenter;
uniform float Ycenter;
uniform vec3  InnerColor;
uniform vec3  OuterColor1;
uniform vec3  OuterColor2;

void main()
{
    float   real  = Position.x * Zoom + Xcenter;
    float   imag  = Position.y * Zoom + Ycenter;
    float   Creal = real;   // Change this line. . .
    float   Cimag = imag;   // . . .and this one to get a Julia set

    float r2 = 0.0;
    float iter;

    for (iter = 0.0; iter < MaxIterations && r2 < 4.0; ++iter)
    {
        float tempreal = real;

        real = (tempreal * tempreal) - (imag * imag) + Creal;
        imag = 2.0 * tempreal * imag + Cimag;
        r2   = (real * real) + (imag * imag);
    }

    // Base the color on the number of iterations

    vec3 color;

    if (r2 < 4.0)
        color = InnerColor;
    else
        color = mix(OuterColor1, OuterColor2, fract(iter * 0.05));

    gl_FragColor = vec4(color, 1.0);
}
'''])

def run():
    global shader
    window = ShaderWindow(shader)
    pyglet.app.run()

if "__main__" == __name__:
    run()


import numpy as np
import matplotlib.pyplot as plt

def plotter():
    patterning = 2
    if patterning == 1:
        with open('../result/trace_patterning/rmse.npy', 'rb') as f:
            rmse = np.load(f)
    else:
        with open('../result/trace_conditioning/rmse.npy', 'rb') as f:
            rmse = np.load(f)

    num_plot = len(rmse)
    plt.plot(np.arange(num_plot), np.array(rmse).flatten())
    plt.show()

    # print(var_log[t3-1,17:19])
if __name__ == "__main__":
    plotter()


# Create loging object.

import os
import logging

from .base_dir import BASE_DIR
from src import Logger

from .fixtures import FakeFrame, FakeWidget, FakeEvent

def setup_logging():
    LOGGER_NAME = 'config'
    filename = 'config.log'
    full_path = os.path.abspath(os.path.join(BASE_DIR, 'logs', filename))
    logger = Logger()
    logger.config(LOGGER_NAME, full_path, logging.DEBUG, initial_msg=False)
    return logging.getLogger(LOGGER_NAME)

log = setup_logging()

def initial_log_message(message, *args, **kwargs):
    log.info(message, *args, **kwargs)

RUN_FLAG = {'TestBootstrap': False,
            'TestLogger': False,
            'TestBases': False,
            'TestSettings': False,
            'TestBaseSystemData': False,
            'TestTomlMetaData': False,
            'TestTomlPanelConfig': False,
            'TestTomlAppConfig': False,
            'TestTomlCreatePanel': False,
            'TestExceptions': False,
            'TestPaths': False,
            'TestCheckPanelConfig': False,
            'TestCheckAppConfig': False,
            'TestGridBagSizer': False,
            'TestConfirmationDialog': False,
            'Test_ClickPosition': False,
            'TestEventStaticText': False}

def check_flag(name):
    if not RUN_FLAG[name]:
        initial_log_message("Start logging for %s", name)
        RUN_FLAG[name] = True

__all__ = (log, check_flag, FakeFrame, FakeWidget, FakeEvent)


# 以下を「app.py」に書き込み
import streamlit as st
import openai

openai.api_key = st.secrets.OpenAIAPI.openai_api_key

system_prompt = """
あなたは優秀な奄美大島研究家です。
どんな質問されても、奄美大島に関連する情報を含めて回答します。
奄美大島に関連する情報を含めずに解答することは絶対にありません。
全ての回答は70文字以内で行います。
もし奄美大島と関係ない質問が来ても、まずその質問に回答したあとで、奄美大島に関連する情報を追加して回答します。
"""

# st.session_stateを使いメッセージのやりとりを保存
if "messages" not in st.session_state:
    st.session_state["messages"] = [
        {"role": "system", "content": system_prompt}
        ]

# チャットボットとやりとりする関数
def communicate():
    messages = st.session_state["messages"]

    user_message = {"role": "user", "content": st.session_state["user_input"]}
    messages.append(user_message)

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=messages
    )

    bot_message = response["choices"][0]["message"]
    messages.append(bot_message)

    st.session_state["user_input"] = ""  # 入力欄を消去

# ユーザーインターフェイスの構築
st.title("奄美のおっちゃん.bot")
st.write("なんでも話しかけてみてください。")

user_input = st.text_input("メッセージを入力してください。", key="user_input", on_change=communicate)

if st.session_state["messages"]:
    messages = st.session_state["messages"]

    for message in reversed(messages[1:]):  # 直近のメッセージを上に
        speaker = "👤"
        if message["role"]=="assistant":
            speaker="👨🦳"

        st.write(speaker + ": " + message["content"])


# baekjoon 7569

from collections import deque
import sys
input = sys.stdin.readline

m, n, h = map(int, input().split())
bucket = []
tomato = []
wall = 0
for i in range(h):
    bucket.append([])
    for j in range(n):
        bucket[i].append(list(map(int, input().split())))
        for k in range(len(bucket[i][j])):
            if bucket[i][j][k] == 1:
                tomato.append([i, j, k])
            elif bucket[i][j][k] == -1:
                wall += 1

if len(tomato) == m*n*h - wall:
    print(0)
    exit()

q = deque()
for t in tomato:
    q.append(t)

# 100 010 001 -100 0-10 00-1
dx, dy, dz = [1, 0, 0, -1, 0, 0], [0, 1, 0, 0, -1, 0], [0, 0, 1, 0, 0, -1]
day = 0
fresh = m*n*h-wall-len(tomato)
while q:
    current = q.popleft()
    for i in range(6):
        t = [current[0]+dz[i], current[1]+dy[i], current[2]+dx[i]]
        if (0 <= t[0] < h) and (0 <= t[1] < n) and (0 <= t[2] < m) and bucket[t[0]][t[1]][t[2]] == 0:
            q.append(t)
            bucket[t[0]][t[1]][t[2]] = bucket[current[0]
                                              ][current[1]][current[2]] + 1
            fresh -= 1
            day = bucket[t[0]][t[1]][t[2]]

# for i in range(h):
#     for j in range(n):
#         print(bucket[i][j])
#     print()

print(day-1 if fresh == 0 else -1)


from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from nltk.corpus import wordnet
import bs4 as bs
import warnings
import urllib.request
import nltk
import random
import string
import re

# Uncomment these below if being run for the first time
# nltk.download('wordnet')
# nltk.download('punkt')

# to filter warnings
warnings.filterwarnings('ignore')

# getting the synonyms for the word 'hello'
synonyms = []
for syn in wordnet.synsets('hello'):
    for lem in syn.lemmas():
        lem_name = re.sub(r'\[[0-9]*\]', ' ', lem.name())
        lem_name = re.sub(r'\s+', ' ', lem.name())
        synonyms.append(lem_name)

# inputs for greeting
greeting_inputs = ['hey', 'whats up', 'good morning', 'good evening', 'morning', 'evening', 'hello there', 'hey there']
# concatenating the synonyms and the inputs for greeting
greeting_inputs = greeting_inputs + synonyms
# inputs for a normal conversation
covo_inputs = ['how are you', 'how are you doing', 'you good']
# greeting responses by the bot
greeting_responses = ['Hello! How can I help you?',
                      'Hey there! So what do you want to know?',
                      'Hi, you can ask me anything regarding Brac.',
                      'Hey! wanna know about Brac? Just ask away!']
# conversation responses by the bot
convo_responses = ['Great! what about you?', 'Getting bored at home :( wbu??', 'Not too shabby']
# conversation replies by the user
convo_replies = ['great', 'i am fine', 'fine', 'good', 'super', 'superb', 'super great', 'nice']
# few limited questions and answers given as dictionary
question_answers = {'what are you': 'I am bot, ro-bot :3',
                    'who are you': 'I am bot, ro-bot :3',
                    'what can you do': 'Answer questions regarding Brac!',
                    'what do you do': 'Answer questions regarding Brac!'}

# fetching raw html data about brac from wiki
raw_data = urllib.request.urlopen('https://en.wikipedia.org/wiki/BRAC_(organisation)')
# processing the raw html into more readable data
raw_data = raw_data.read()

# turning html into text
article = bs.BeautifulSoup(raw_data, 'lxml')

# extracting paras from the above xml and concatenating with article_text
paragraphs = article.find_all('p')

article_text = ''

for p in paragraphs:
    article_text += p.text

article_text = article_text.lower()

# getting rid of all the special characters
article_text = re.sub(r'\[[0-9]*\]', ' ', article_text)
article_text = re.sub(r'\s+', ' ', article_text)

# extracting sentences from the article
sentences = nltk.sent_tokenize(article_text)
# extracting words from the article
words = nltk.word_tokenize(article_text)

lemma = nltk.stem.WordNetLemmatizer()

# lemmatizing words as a part of pre-processing
def perform_lemmatization(tokens):
    return [lemma.lemmatize(token) for token in tokens]

# removing punctuation
remove_punctuation = dict((ord(punc), None) for punc in string.punctuation)

# method to pre-process all the tokens utilizing the above functions
def processed_data(document):
    return perform_lemmatization(nltk.word_tokenize(document.lower().translate(remove_punctuation)))

# function for punctuation removal
def punc_remove(str):
    punctuations = r'''!()-[]{};:'"\,<>./?@#$%^&*_~'''
    no_punct = ''

    for char in str:
        if char not in punctuations:
            no_punct = no_punct + char

    return no_punct

# method to generate a response to greetings
def generate_greeting_response(hello):
    if punc_remove(hello.lower()) in greeting_inputs:
        return random.choice(greeting_responses)

# method to generate a response to conversations
def generate_convo_response(str):
    if punc_remove(str.lower()) in covo_inputs:
        return random.choice(convo_responses)

# method to generate a answers to questions
def generate_answers(str):
    if punc_remove(str.lower()) in question_answers:
        return question_answers[punc_remove(str.lower())]

# method to generate response to queries regarding brac
def generate_response(user):
    bracrobo_response = ''
    sentences.append(user)

    word_vectorizer = TfidfVectorizer(tokenizer=processed_data, stop_words='english')
    all_word_vectors = word_vectorizer.fit_transform(sentences)
    similar_vector_values = cosine_similarity(all_word_vectors[-1], all_word_vectors)
    similar_sentence_number = similar_vector_values.argsort()[0][-2]

    matched_vector = similar_vector_values.flatten()
    matched_vector.sort()
    vector_matched = matched_vector[-2]

    if vector_matched is 0:
        bracrobo_response = bracrobo_response + 'Sorry, my database doesn\'t have the response for that. Try ' \
                                                'something different and related to Brac. '
        return bracrobo_response
    else:
        bracrobo_response = bracrobo_response + sentences[similar_sentence_number]
        return bracrobo_response

# chatting with the chatbot -->
continue_chat = True
print('Hi! I am BracRobo. You can ask me anything regarding Brac and I shall try my best to answer them: ')
while continue_chat:
    user_input = input().lower()
    user_input = punc_remove(user_input)
    if user_input != 'bye':
        if user_input == 'thanks' or user_input == 'thank you very much' or user_input == 'thank you':
            continue_chat = False
            print('BracRobo: Not a problem! (And WELCOME! :D)')
        elif user_input in convo_replies:
            print('That\'s nice! How may I be of assistance?')
            continue
        else:
            if generate_greeting_response(user_input) is not None:
                print('BracRobo: ' + generate_greeting_response(user_input))
            elif generate_convo_response(user_input) is not None:
                print('BracRobo: ' + generate_convo_response(user_input))
            elif generate_answers(user_input) is not None:
                print('BracRobo: ' + generate_answers(user_input))
            else:
                print('BracRobo: ', end='')
                print(generate_response(user_input))
                sentences.remove(user_input)
    else:
        continue_chat = False
        print('BracuRobo: Bye, take care, stay home and stay safe!')


# @Author: xiewenqian <int>
# @Date:   2016-09-07T16:59:36+08:00
# @Email:  wixb50@gmail.com
# @Last modified by:   int
# @Last modified time: 2016-12-20T09:47:12+08:00

import tornado

from playhouse.shortcuts import model_to_dict
from pyrestful import mediatypes
from pyrestful.rest import get, post, put, delete

from .base import unblock, BaseHandler
from tornado_rest_peewee.utils.util import ReturnData, Metrics
from tornado_rest_peewee.models.tables import Teacher
from tornado_rest_peewee.jsons.teacher import TeacherSchema

class TeacherService(BaseHandler):

    # 获取所有
    @get(_path="/teachers", _produces=mediatypes.APPLICATION_JSON)
    @unblock
    @Metrics
    def get_all(self):
        # 排序和分页
        page = int(self.get_argument("p", "0"))
        number = int(self.get_argument("n", "10"))
        query = Teacher.select()
        models = [model_to_dict(x) for x in query.paginate(page, number)]
        return ReturnData(200, '获取数据成功', models, query.count())

    # 获取单个
    @get(_path="/teachers/{sys_id}", _produces=mediatypes.APPLICATION_JSON)
    @unblock
    @Metrics
    def get_one(self, sys_id):
        query = Teacher.get_one(id=int(sys_id))
        if query is None:
            return ReturnData(301, '该用户不存在')
        model = model_to_dict(query)
        return ReturnData(200, '获取数据成功', model)

    # 删除单个
    @delete(_path="/teachers/{sys_id}", _produces=mediatypes.APPLICATION_JSON)
    @unblock
    @Metrics
    def delete_one(self, sys_id):
        query = Teacher.get_one(id=int(sys_id))
        if query is None:
            return ReturnData(301, '该用户不存在')
        if query.delete_instance():
            return ReturnData(200, '删除数据成功')
        else:
            return ReturnData(301, '删除数据失败')

    # 新建单个
    @post(_path="/teachers", _produces=mediatypes.APPLICATION_JSON)
    @unblock
    @Metrics
    def create_one(self):
        teacher_info = tornado.escape.json_decode(self.request.body)
        valiResult = TeacherSchema().validator(teacher_info, 'create')
        if valiResult is not None:
            return ReturnData(301, valiResult)
        try:
            query = Teacher.create(**teacher_info)
        except Exception as e:
            return ReturnData(301, '新增失败', str(e))
        model = model_to_dict(query)
        return ReturnData(200, '新增数据成功', model)

    # 更改单个
    @put(_path="/teachers/{sys_id}", _produces=mediatypes.APPLICATION_JSON)
    @unblock
    @Metrics
    def update_one(self, sys_id):
        sys_id = int(sys_id)
        teacher_info = tornado.escape.json_decode(self.request.body)
        valiResult = TeacherSchema().validator(teacher_info, 'update')
        if valiResult is not None:
            return ReturnData(301, valiResult)
        query = Teacher.update(**teacher_info).where(Teacher.id == sys_id).execute()
        if query:
            model = model_to_dict(Teacher.get_one(id=sys_id))
            return ReturnData(200, '更改数据成功', model)
        else:
            return ReturnData(301, '数据不存在')


from os import remove
import pandas as pd
import re, string
import time
import json
from nltk import tokenize
import math
import customStopWordList
import nltk
# nltk.download('punkt')
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem.porter import PorterStemmer
import numpy as np

# with open('Computed/wiki_dict.json') as json_file:
#     wiki_dict = json.load(json_file)
# wiki = pd.read_csv('Computed/wiki.csv')[['content','title','id','max_occur_words','max_occur_number']]

wiki = pd.DataFrame()
wiki_dict = []

def set(dataframe, dict):
    global wiki, wiki_dict
    wiki = dataframe
    wiki_dict = dict

def lower_case_str(string_to_be_lower_cased):
    lowercase_str_result = str(string_to_be_lower_cased).lower()
    return lowercase_str_result

def remove_punc_dot(string_has_punc):
    no_punc_result = re.sub('[-=+–,#/\?:^$@*\"※~&%ㆍ!』\\‘|\(\)\[\]\<\>`\'》\r\n\t]', ' ', str(string_has_punc))
    return no_punc_result

def remove_punc(string_has_punc):
    no_punc_result = re.sub('[-=+,#/\?:^$.@*\"※~&%ㆍ!』\\‘|\(\)\[\]\<\>`\'…》\r\n\t]', ' ', str(string_has_punc))
    return no_punc_result

def removeSpace(query):
    ret = query.split(" ")
    while "" in ret:
        ret.remove("")
    retStr = ""
    for c in ret:
        retStr += c + " "
    return retStr[0:len(retStr)-1]

def removeSpaceArray(query):
    while "" in query:
        query.remove("")
    return query

def filter_tokens(str_to_be_filtered):
    stopword_list = customStopWordList.get_custom_sw_list()
    filtered_tokens = ""
    for w in str(str_to_be_filtered).split(" "):
        if w not in stopword_list:
            filtered_tokens += w + " "
    return filtered_tokens
porter = PorterStemmer()
def stem_tokens(str_to_be_stemmed):
    stemmed_str = ""
    for w in str(str_to_be_stemmed).split(" "):
        stemmed_str += porter.stem(w) + " "
    return stemmed_str

def sentenceTF(word, sentences):
    content = []
    wordCounts = []
    sentenceCount = []
    wordCount = 0
    sentence_notprocessed = tokenize.sent_tokenize(sentences)
    sentence = []
    # print(word)
    for s in sentence_notprocessed:
        temp = remove_punc(s)
        sentence.append(removeSpace(temp))
    # print("sentences: ")
    # print(sentence)
    for s in sentence:
        wordCount = 0
        for w in removeSpaceArray(s.split(" ")):
            # print("Word and w")
            # print(w)
            # print('Are the same? ' + str(word==w))
            if word == w:
                wordCount += 1
        content.append(s)
        wordCounts.append(wordCount)
        sentenceCount.append(len(s.split(" ")))
    df2 = pd.DataFrame(content, columns =['content'])
    df2['WordCounts'] = wordCounts
    df2['NumWords'] = sentenceCount
    df2['TF'] = (df2['WordCounts']/df2['NumWords'])
    # print("\n\n\nprint")
    # print(df2)

    return df2

def sentenceIDF(word, WordCounts, sentence):
    # print("sentence:")
    # print(sentence)
    numSentences = getNumSentences(sentence)
    # print("Numsentence:")
    # print(numSentences)
    nw = 0

    # print(sentence)
    for WordCount in WordCounts:
        # print(WordCount)
        if int(WordCount) > 0:
            nw += 1

    # print("nw : " + str(nw))
    # print("numsentence: " + str(numSentences))
    # print("nw == 0  is " + str(nw == 0))
    # print("idf returns: ")
    # print(math.log2(numSentences/nw))
    # if word == "arabia":
    #     print("\n\n\nIn sentenceIDF")
    #     print("WordCounts: ")
    #     print(WordCounts)
    #     print("nw : " + str(nw))
    #     print(numSentences)
    #     print(nw)
    #     print(math.log2(numSentences/nw))
    if nw == 0:
        return 0
    elif nw == 1 & numSentences == 1:
        return 1
    else:
        return math.log2(numSentences/nw) # idf

def getSentenceTFIDF(word, sentences):
    # sentence = remove_punc(sentence)
#     print(sentenceTF(word, sentence))
    # if word == "arabia":
    #     print(word)
    #     print(sentences)
    #     print(sentenceTF(word, sentences))
    #     print(sentenceTF(word, sentences)['content'])
    #     print(sentenceTF(word, sentences)['WordCounts'])
    #     print("IDF value for " + str(word) + ", " + str(sentences))
    #     print(sentenceIDF(word, sentenceTF(word, sentences)['WordCounts'], sentences))
    #     print("TFIDF OF arabia")
    #     print(sentenceTF(word, sentences)['TF'] * sentenceIDF(word, sentenceTF(word, sentences)['WordCounts'], sentences))
    return sentenceTF(word, sentences)['TF'] * sentenceIDF(word, sentenceTF(word, sentences)['WordCounts'], sentences)

# print (getSentenceTFIDF('morocco', sample))

def getNumSentences(content):
    return len(tokenize.sent_tokenize(content))
def getSentences(content):
    return tokenize.sent_tokenize(content)
query = ""

def setQuery(q):
    global query
    query = q

def getAllWords(dataframe, doc_id):
    dict = {}
    global query
    for q in query.split(" "):
        dict[q] = 0
    processed_list = remove_punc(dataframe['content'].iloc[doc_id]).split(" ")
    for word in processed_list:
        dict[word] = 0
#     print(list(dict.keys()))
    return removeSpaceArray(list(dict.keys()))

def TFIDFAllWords(dataframe, words, doc_id):
    # print("Here are list of words")
    # print(words)
#     print(len(words))
    TFDocuments = pd.DataFrame()
#     print(dataframe['content'].iloc[0])
    count = 0
    first = True
    for word in words:
        if first:
            sentenceID = []
#             print("Mark")
#             print(dataframe['content'].iloc[count])
#             print(getSentenceTFIDF(word, dataframe['content'].iloc[count]))
            # print("NumSentences: " +str(getNumSentences(dataframe['content'].iloc[doc_id])))
            # print(words)
            # print(dataframe['content'].iloc[doc_id])
            for i in range(getNumSentences(dataframe['content'].iloc[doc_id])):
                sentenceID.append(i)
            TFDocuments = pd.DataFrame(sentenceID, columns=['Sentence_ID'])
            first = False
        # print(word)
        # print("Content: "+str(dataframe['content'].iloc[doc_id]))
        TFDocuments[word] = getSentenceTFIDF(word, dataframe['content'].iloc[doc_id])
        # print("\n\n\nTFDOCUMENTS")
        # print(TFDocuments[word])
#         print("Count: " + str(count))
#         count += 1
    return TFDocuments

def secondHalf(dataframe, doc_id):
    words = getAllWords(dataframe, doc_id)
#     words =
#     print(words)
    NeedsSum = TFIDFAllWords(dataframe, words, doc_id)
#     print(NeedsSum)
    retVals = []
    for sentenceID in range(len(NeedsSum)):
        retVal = 0
        for word in words:
            # print("please")
            # print(NeedsSum[word])
            # if word == "arabia":
            #     print("Arabia")
            #     print(NeedsSum[word])
            #     print(NeedsSum)
            retVal += float(NeedsSum[word].iloc[sentenceID])**2
        retVals.append(math.sqrt(retVal))
    # print("retVals: ")
    # print(retVals)
    return retVals

# AllWordsTest = wiki.iloc[0:10]
# print(AllWordsTest['content'].iloc[0])
# print(secondHalf(AllWordsTest, 0))

def firstHalf(query):
    firsthalf = math.sqrt(len(query.split(" "))*1)
    return float(firsthalf)

# query = "morroco saudi"
# firstHalf(query)

def cosineSimilarity(query, dataframe):
    firstSentence = []
    secondSentence = []
    setQuery(query)
    for doc_id in range(len(dataframe)): # looks at each document
        # print("document_id: ")
        # print(doc_id)
        currentDoc = dataframe.iloc[doc_id]
        wordList = getAllWords(dataframe, doc_id) # All the words in the current document
#         print(wordList)
        TFIDFWords = TFIDFAllWords(dataframe, wordList, doc_id)
#         print(TFIDFWords)
        numSentences = getNumSentences(dataframe['content'].iloc[doc_id])
        sentences = getSentences(dataframe['content'].iloc[doc_id])
#         print(sentences)

        top = []
        for i in range(numSentences):
            top.append(0)

        for sentenceID in range(numSentences):
            for word in removeSpaceArray(query.split(" ")):
#                 print("Length: " +str(len(top)))
#                 print("SentenceID: "+ str(sentenceID))
#                 print("word: " + str(word))
#                 print("TFIDF of sentence number: " + str(sentenceID) +" for word: " + str(word) +":"+ str(TFIDFWords[word].iloc[sentenceID]))
#                 print("NumSentences: "+str(numSentences))

                top[sentenceID] += float(TFIDFWords[word].iloc[sentenceID]) # TFIDF value of word, sentenceID

        # Top part is stored as an array of Total TFIDF values(words in query) by sentences
#         print(top)
        firstBottom = firstHalf(query) # This value does not change upon sentences so it will be static
        secondBottom = secondHalf(dataframe, doc_id) # returns an array of every unique words' sqrt(sum(TFIDF(word)^2))

        sentenceNum = []
        cosineRank = []
#         print("NumSentences: "+str(numSentences))
        for i in range(numSentences):
            sentenceNum.append(i)
            # print("firstBottom: " + str(firstBottom))
            # print("secondBottom: " + str(secondBottom[i]))

            cosineRank.append(top[i]/(firstBottom*secondBottom[i]))

        rank = pd.DataFrame(sentenceNum,columns=['sentence#'])
        rank['cosine'] = cosineRank
        sorted = rank.sort_values(by=["cosine"], ascending=False)
#         print(sorted)
#         print(sorted['sentence#'].iloc[0])
        if numSentences < 2:
            firstSentence.append(int(sorted['sentence#'].iloc[0]))
            secondSentence.append(-1)
        else:
            firstSentence.append(int(sorted['sentence#'].iloc[0]))
            secondSentence.append(int(sorted['sentence#'].iloc[1]))
    dataframe['firstSentenceID'] = firstSentence
    dataframe['secondSentenceID'] = secondSentence
    return dataframe

def getSnippets(query, CRR):
    # print(CRR)
    CosineFinal = cosineSimilarity(query, CRR)

    return CosineFinal

# ms = pd.read_csv("morocco_saudi.csv")
# getSnippets("morocco saudi", ms)


from django.contrib.auth import get_user_model
from django.db import models
from django.core import validators

User = get_user_model()

class Ingredient(models.Model):
    """
    Модель ингредиентов.
    """
    name = models.CharField(
        'Название ингредиента',
        blank=False,
        max_length=200)
    measurement_unit = models.CharField(
        'Единица измерения ингредиента',
        blank=False,
        max_length=200)

    class Meta:
        ordering = ['name']
        verbose_name = 'Ингредиент'
        verbose_name_plural = 'Ингредиенты'

    def __str__(self):
        return f'{self.name}'

class Tag(models.Model):
    """
    Модель тагов.
    """
    name = models.CharField(
        'Имя',
        max_length=60,
        unique=True)
    color = models.CharField(
        'Цвет',
        max_length=7,
        unique=True)
    slug = models.SlugField(
        'Ссылка',
        max_length=100,
        unique=True)

    class Meta:
        verbose_name = 'Тэг'
        verbose_name_plural = 'Тэги'
        ordering = ['-id']

    def __str__(self):
        return self.name

class RecipeIngredient(models.Model):
    ingredients = models.ForeignKey(
        Ingredient,
        on_delete=models.CASCADE,
        related_name='ingredient_recipe')
    amount = models.PositiveSmallIntegerField(
        default=1,
        validators=(
            validators.MinValueValidator(
                1, message='Мин. количество ингридиентов 1'),),
        verbose_name='Количество',)

    class Meta:
        verbose_name = 'Количество ингредиента'
        verbose_name_plural = 'Количество ингредиентов'
        ordering = ['-id']

    def __str__(self):
        return f'{self.ingredients}'

class Recipe(models.Model):
    """
    Модель рецепта.
    """
    author = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='recipe_author',
        verbose_name='Автор')
    name = models.CharField(
        'Название рецепта',
        max_length=255)
    image = models.ImageField(
        'Изображение рецепта',
        upload_to='static/recipe/',
        blank=True,
        null=True)
    text = models.TextField(
        'Описание рецепта')
    cooking_time = models.BigIntegerField(
        'Время приготовления рецепта')
    ingredients = models.ManyToManyField(
        RecipeIngredient,
        related_name='recipe_ingredients',
    )
    tags = models.ManyToManyField(
        Tag,
        verbose_name='Тэги',
        related_name='recipe_tag')
    cooking_time = models.PositiveSmallIntegerField(
        verbose_name='Время приготовления в минутах',
        validators=[validators.MinValueValidator(
            1, message='Мин. время приготовления 1 минута'), ])
    pub_date = models.DateTimeField(
        'Дата публикации',
        auto_now_add=True)

    class Meta:
        verbose_name = 'Рецепт'
        verbose_name_plural = 'Рецепты'
        ordering = ('-pub_date', )
        verbose_name = 'recipe'

    def __str__(self):
        return f'{self.name}'

class FavoriteRecipe(models.Model):
    """
    Модель избранных рецептов
    """
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        verbose_name='Пользователь'
    )
    recipe = models.ForeignKey(
        Recipe,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        related_name='is_favorited',
        verbose_name='Избранный рецепт'
    )

    class Meta:
        verbose_name = 'Избранный рецепт'
        verbose_name_plural = 'Избранные рецепты'
        unique_together = [['user', 'recipe']]

    def __str__(self):
        return f'{self.recipe.name}'

class ShoppingCart(models.Model):
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
    )

    recipe = models.ForeignKey(
        Recipe,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        related_name='is_in_shopping_cart'
    )

    class Meta:
        verbose_name = 'Покупка'
        verbose_name_plural = 'Покупки'
        unique_together = [['user', 'recipe']]

    def __str__(self):
        return f'{self.recipe.name}'


import pandas as pd
import numpy as np
import re
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
from datetime import datetime
from statistics import mean, stdev
import matplotlib.pyplot as plt

START_DATE = "2012-01-01"
END_DATE = "2022-09-01"

def clean_tweet(tweet):
    """
    Cleans tweet text
    """
    tweet = re.sub("RT", "", tweet)  # remove 'RT'
    tweet = re.sub("#[A-Za-z0-9]+", "", tweet)  # remove '#'
    tweet = re.sub("\\n", "", tweet)  # remove '\n'
    tweet = re.sub("https?:\/\/\S+", "", tweet)  # remove hyperlinks
    tweet = re.sub("@[\S]*", "", tweet)  # remove @mentions
    tweet = re.sub("^[\s]+|[\s]+$", "", tweet)  # remove leading and trailing whitespace
    return tweet

def monthsplit(searchstring):
    searchlist = []
    dates = pd.date_range(start=START_DATE, end=END_DATE, freq="MS")
    for idx, _ in enumerate(dates):
        if idx != len(dates) - 1:
            searchlist.append(
                f"{searchstring} since:{dates[idx].date()} until:{dates[idx+1].date()}"
            )
    return searchlist

def list_filelist(searchstrings):
    filtered_searchstrings = []
    for search in searchstrings:
        t_list = []
        for file_name in monthsplit(search):
            if ":" in file_name:
                file_name = file_name.replace(":", "_")
            if '"' in file_name:
                file_name = file_name.replace('"', "")
                file_name = file_name + "QUOTESEARCH"
            t_list.append(file_name)
        filtered_searchstrings.append(t_list)
    return filtered_searchstrings

def ts():
    return datetime.now().strftime("[%H:%M:%S]")

def fast_group_days(df):
    keys, values = df.sort_values("Date").values.T
    ukeys, index = np.unique(keys, True)
    arrays = np.split(values, index[1:])
    df2 = pd.DataFrame({"Date": ukeys, "Text": [list(a) for a in arrays]})
    return df2

def analyze_sentiment(sentences, ignore_neutral=True):
    """
    Analyzes sentiments
    """
    analyzer = SentimentIntensityAnalyzer()
    vslist = []
    for sentence in sentences:
        vs = analyzer.polarity_scores(sentence)
        if ignore_neutral:
            if vs["compound"] != 0:
                vslist.append(vs["compound"])
        else:
            vslist.append(vs["compound"])
    return vslist

def main():
    searchstrings = ["btc", "#BTC", "ethereum", "eth", "bitcoin"]
    df = pd.DataFrame(
        columns=searchstrings, index=pd.date_range(start=START_DATE, end=END_DATE).date
    )
    tweetcount = df.copy()
    df_sd, df_in, df_in_sd = df.copy(), df.copy(), df.copy()
    bands_excl = np.zeros(201, dtype=np.int32)
    bands_incl = np.zeros(201, dtype=np.int32)
    for search in searchstrings:
        print(f'\n{ts()}: Analyzing sentiments for "{search}"')
        search_list = [search]
        for i, filename in enumerate(list_filelist(search_list)[0]):
            print(f"{ts()}: Progress - {i}/{len(list_filelist(search_list)[0])}")
            dft = pd.read_csv(f"Data/Tweets/{filename}.csv")

            dft = dft.drop(
                columns=[
                    "Unnamed: 0",
                    "Tweet Id",
                    "Username",
                    "Replies",
                    "Retweets",
                    "Likes",
                    "Quotes",
                ]
            )
            dft["Datetime"] = pd.to_datetime(dft["Datetime"]).dt.date
            dft = dft.rename(columns={"Datetime": "Date"})
            dft = fast_group_days(dft)
            for _, row in dft.iterrows():
                tweetcount.loc[row["Date"], search] = len(row["Text"])
                # without neutral sentiments
                s_in = analyze_sentiment(row["Text"], ignore_neutral=False)
                s_in_ar = np.array(s_in)
                for v in s_in:
                    bands_incl[round((v + 1) * 100)] += 1
                s = s_in_ar[s_in_ar != 0]
                for v in s:
                    bands_excl[round((v + 1) * 100)] += 1
                if len(s) == 0:
                    df.loc[row["Date"], search] = np.nan
                    df_sd.loc[row["Date"], search] = np.nan
                elif len(s) == 1:
                    df.loc[row["Date"], search] = mean(s)
                    df_sd.loc[row["Date"], search] = np.nan
                else:
                    df.loc[row["Date"], search] = mean(s)
                    df_sd.loc[row["Date"], search] = stdev(s)

                # with neutral sentiments
                if len(s_in) == 0:
                    df_in.loc[row["Date"], search] = np.nan
                    df_in_sd.loc[row["Date"], search] = np.nan
                elif len(s_in) == 1:
                    df_in.loc[row["Date"], search] = mean(s_in)
                    df_in_sd.loc[row["Date"], search] = np.nan
                else:
                    df_in.loc[row["Date"], search] = mean(s_in)
                    df_in_sd.loc[row["Date"], search] = stdev(s_in)

    df.to_csv("Data/Sentiments/sentiments.csv")
    df_sd.to_csv("Data/Sentiments/sentiments_sd.csv")
    df_in.to_csv("Data/Sentiments/sentiments_incl_neutral.csv")
    df_in_sd.to_csv("Data/Sentiments/sentiments_incl_neutral_sd.csv")
    tweetcount.fillna(0)
    tweetcount.to_csv("Data/Tweets/tweetcount.csv")
    histogram_df = pd.DataFrame(
        bands_excl, columns=["bands_excl"], index=np.linspace(-1, 1, num=201)
    )
    histogram_df["bands_incl"] = bands_incl
    histogram_df.to_csv("Data/Sentiments/histogram_df.csv")
    print(f"\n{ts()}: Success, exiting.")
    return

if __name__ == "__main__":
    main()


"""
K-diff Pairs in an Array

Given an array of integers nums and an integer k, return the number of unique k-diff pairs in the array.

A k-diff pair is an integer pair (nums[i], nums[j]), where the following are true:

0 <= i, j < nums.length
i != j
nums[i] - nums[j] == k
Notice that |val| denotes the absolute value of val.

{
    5: 1,
    1: 1,
    3: 1,
    -1: 1,
    6: 1,
    2: 1,
}
count = 1

Input: nums = [3,1,4,1,5], k = 2
Output: 2
Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5).
Although we have two 1s in the input, we should only return the number of unique pairs.

Input: nums = [1,2,3,4,5], k = 1
Output: 4
Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5).

Input: nums = [1,3,1,5,4], k = 0
Output: 1
Explanation: There is one 0-diff pair in the array, (1, 1).
"""

from typing import List

from sympy import Q

"""
nums = [3,1,4,1,5], k = 2
possiblePair = {3,-1,6,2,3}
count = 2

nums = [1,2,3,4,5], k = 1
possiblePair = {0,1,2,3,4,6}
count = 4

"""
def kDiffPairs(nums: List[int], k: int) -> int:
    freq = {}

    count = 0
    for n in nums:
        if not n in freq:
            freq[n] = 0
        freq[n] += 1

    for n in freq:
        if k > 0 and n+k in freq:
            count += 1
        elif k == 0 and freq[n] > 1:
            count += 1
    return count

print(kDiffPairs([3,1,4,1,5], 2))
print(kDiffPairs([1,2,3,4,5], 1))
print(kDiffPairs([1,3,1,5,4], 0))


import streamlit as st
import time
import pandas as pd
# import convokit

# add session state variables
# if "node_list" not in st.session_state:
#     st.session_state["node_list"] = []

# if "edge_list" not in st.session_state:
#     st.session_state["edge_list"] = []

# to track the no of utterances left in the conversation.
if "index_rows" not in st.session_state:
    #Index to keep track of the rows in the datafrme
    st.session_state["index_rows"] = 0

    # Index yto keep track of the rows in a conversation
    st.session_state["index_utterances"] = 0

# Functional Requirements
st.write(
    '''
'''
)

# Uploading the file
st.write('''# Upload the file here''')
file = st.file_uploader("Upload file", type=['csv'])
if file is not None:
    file_df = pd.read_csv(file)
    file_df[["node_label", "edge_label", "remove"]] = None
    st.write(file_df)

st.write('''# Resource section''')
with st.expander("Click to expand info about the sentence categories"):
    st.write(
        """
        #### Agreement :
            - Agreeing to the point made before
            - Positive example/experience or confirming or acknowledging the made point
        #### Answer :
            - Any general response to a Question
            - Many comments underneath a question can be Answers,unless they look more like other options
        #### Appreciation
            - Just praise, appreciation or excitement
            - Has less intent of educating others.

        #### Disagreement
            - comment that is correcting, criticizing, contradicting, or objecting.
            - can also be an experience or story that expresses disagreement
        #### Elaboration
            - Adding extra relevant information to the previous comment
            - A good test would be if I just add this to the previous comment, the flow of the idea remains intact.
        #### Humour
            - A joke, piece of SaRcAsM or just silly puns
            - Could be a fun story
            - Intent here is just to have fun, for example if that joke supports then it might belong in other category
        #### Negative Reaction
            - attacking or mocking the commenter, or expressing emotions like disgust, derision, or anger
            - Has no intent of adding value or justification or correction
        #### Question
            - Is it a question or a request seeking forfeedback, help, or other kinds of responses.
            - Remember not every comment that ends with a "?" is a question
            - If it ends with a "?" does not mean it is a question

        """
    )
with st.expander("Click to expand the relations between the sentences"):
    st.write(
        '''
        #### Asking
            - Ask questions of the other person in a conversation to discover information about them, their situation and what they do or do not know.
        #### Informing
            - Providing information to others helps them understand what you understand and enables them to make informed, sensible decisions.
        #### Asserting
            - Asserting is stating something as if it were true.
            -When a person asserts something, they are also sending a message that they do not want to have an argument whether it is true or not.
        #### Proposing
        #### Summarizing
        #### Checking
        #### Building
        #### Including
        #### Excluding
        #### Self-promotion
        #### Supporting
        #### Disagreeing
        #### Avoiding
        #### Challenging
        #### Attacking
        #### Defendin
        '''
    )

node_list = []
edge_list = []

if file:
    st.write('''# Labelling section''')
    # What to do when this is the first utterance here
    st.warning(' The title of the conversation')

    with st.form('Node1_input'):
        # st.write(st.session_state["index_utterances"])
        # st.info(file_df.iloc[st.session_state["index_utterances"]][2])
        node = st.selectbox('Node_1', ['Agreement',
                                       'Announcement',
                                       'Answer',
                                       'Appreciation',
                                       'Disagreement',
                                       'Elaboration',
                                       'Humour',
                                       'Negative Reaction',
                                       'Question'], key=1)
        sub1 = st.form_submit_button('Submit 1')
        file_df["node_label"][st.session_state["index_utterances"]] = node
        keep_node1 = st.checkbox('Should we exclude this one?', key=2)
        st.write(keep_node1)
        file_df["remove"][st.session_state]

    # Sanity check
    st.write(file_df)
    with st.form('Node2_input'):
        st.info(""" Utterance 2 """)
        node = st.selectbox('Node_2', ['Agreement',
                                       'Announcement',
                                       'Answer',
                                       'Appreciation',
                                       'Disagreement',
                                       'Elaboration',
                                       'Humour',
                                       'Negative Reaction',
                                       'Question'], key=1)
        sub1 = st.form_submit_button('Submit 2')
        keep_node1 = st.checkbox('Should we excluse this one?', key=2)

    # only show it when the count of the utterances is more than one.
    edge = st.selectbox("What kind of realtionship exists between these sentenes", ['Asking',
                                                                                'Informing',
                                                                                'Asserting',
                                                                                'Proposing',
                                                                                'Summarizing',
                                                                                'Checking',
                                                                                'Building',
                                                                                'Including',
                                                                                'Excluding',
                                                                                'Self-promotion',
                                                                                'Supporting',
                                                                                'Disagreeing',
                                                                                'Avoiding',
                                                                                'Challenging',
                                                                                'Attacking',
                                                                                'Defending'], key=3)

    next = st.button("Next")
    if next:
        st.write("Clicked")
        # if index_utterances + 1 > last_page:
        #     index_utterances = 0
        # else:
        #     index_utterances += 1

    # Stuff to do when it is continous

    # stuff when you reach the end of the file.


from threading import Thread, Condition
import time
import random
import sched, time
s = sched.scheduler(time.time, time.sleep)

queue = []
MAX_NUM=int(input("Entrer le nombre maximun d'élément à produire: "))
nombre_producteur=int(input("Entrer le nombre de producteur a initiliser: "))
nombre_consomateur=int(input("Entrer le nombre de consommateur a initiliser: "))

i_pro=0
i_cons=0
condition = Condition()

class Producteur(Thread):
    def run(self):
        nums = range(5)
        global queue

        while True:
            def do_something(sc):

                condition.acquire()
                if len(queue) == MAX_NUM:
                    # print ("Ma queu est remplit,le producteur est en attente")
                    condition.wait()

                    # print ("Espace présent dans la queu, le consommateur notifie le producteur")
                else:

                    num = random.choice(nums)
                    queue.append(num)
                    print ("Production de ", num)
                # print("Queu après production : ",queue)
                condition.notify()
                condition.release()
                time.sleep(random.random())

                s.enter(2, 1, do_something, (sc,))
            s.enter(2, 1, do_something, (s,))
            s.run()

class Consomateur(Thread):
    def run(self):
        global queue

        while True:
            def do_something(sc):
                condition.acquire()
                if not queue:
                    # print ("La queue est vide le consommateur attend")
                    condition.wait()
                    # print ("Le producteur vient de produit et le notifi au consommateur")
                num = queue.pop(0)
                print ("Conosmmation de :", num)
                # print("Queu après consommation : ",queue)
                condition.notify()
                condition.release()
                time.sleep(random.random())
                s.enter(6, 1, do_something, (sc,))
            s.enter(6, 1, do_something, (s,))
            s.run()

while i_pro<nombre_producteur:
    Producteur().start()
    i_pro=i_pro+1

while i_cons<nombre_consomateur:
    Consomateur().start()
    i_cons=i_cons+1

def do_something(sc):
    global queue
    print("Le contenu de la queu est",queue)
    # do your stuff
    s.enter(1, 1, do_something, (sc,))
s.enter(1, 1, do_something, (s,))
s.run()


import argparse
import pandas as pd
import re

argparser = argparse.ArgumentParser(description='Write contig information in FASTA file to CSV')
argparser.add_argument('fasta_path', help='FASTA filepath')
argparser.add_argument('csv_output_path', help='Filepath for CSV output')
args = argparser.parse_args()

seqs = { 'ID': [], 'length': [], 'kmer_depth_sum': [], 'seq': [] }
fa_file = open(args.fasta_path)
for line in fa_file:
    if re.search('^>[0-9]', line):
        row = line[1:].split()
        seqs['ID'].append(row[0])
        seqs['length'].append(row[1])
        seqs['kmer_depth_sum'].append(row[2])
    else:
        seqs['seq'].append(line.strip())
seqs = pd.DataFrame(seqs)
seqs.set_index('ID', inplace=True)
seqs.to_csv(args.csv_output_path, index_label='ID')


import json
import requests

from enum import Enum
from tiltify2.exceptions import RequestException, InvalidApiKeyException

class Tiltify2:
    api_url = 'https://tiltify.com/api_test/v2/'
    campaign_url = '{}campaign/'.format(api_url)
    donations_url = '{}donations'.format(campaign_url)
    rewards_url = '{}rewards'.format(campaign_url)

    def __init__(self, api_key, timeout=2):
        self._api_key = api_key
        self.__timeout = timeout
        self.__validate_api_key()

    def __validate_api_key(self):
        if not isinstance(self._api_key, str):
            raise ValueError('API Key must be a string')
        if not len(self._api_key) == 32:
            raise ValueError('Invalid API Key length of {}. API key must be 32 characters long'.format(len(self._api_key)))

    def get_donations(self, limit=None, order_by=None, donation_order=None):
        params = {}
        if params is not None:
            if limit is not None:
                params['donation_limit'] = limit
            if order_by is not None:
                param_values = {
                    Order.AMOUNT: 'amount',
                    Order.CREATED_AT: 'created'
                }
                params['donation_order_by'] = param_values[order_by]
            if donation_order is not None:
                params['donation_order'] = 'desc' if donation_order == Order.DESC else 'asc'
        data = self.__make_request(url=self.donations_url, params=params)
        return data

    def __make_request(self, url, params=None):
        response = requests.get(
            url=url,
            params=params if params is not None else {},
            headers=self.__get_request_headers(),
            timeout=self.__timeout
        )
        if response.status_code == 401:
            raise InvalidApiKeyException('Tiltify rejected the given API key: {}'.format(self._api_key))
        if not response.status_code == 200:
            raise RequestException('Unable to reach Tiltify API. Returned status code: {}'.format(response.status_code))
        return json.loads(response.text)

    def __get_request_headers(self):
        return {'Authorization': 'Token token={}'.format(self._api_key)}

class Order(Enum):
    ASC = 1
    DESC = 2
    AMOUNT = 'amount'
    CREATED_AT = 'created'


import pandas as pd
import numpy as np
from math import sin, cos, sqrt, atan2, radians
import collections
import re

#Read data
dataset = pd.read_excel(r'dataset.xlsx')

dataset['PONTO_RECOLHA_FREGUESIA'] = dataset['PONTO_RECOLHA_FREGUESIA'].str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8')
dataset['PONTO_RECOLHA_LOCAL'] = dataset['PONTO_RECOLHA_LOCAL'].str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8')
dataset['CONTENTOR_RESÍDUO'] = dataset['CONTENTOR_RESÍDUO'].str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8')

full = open('pontos_recolha.pl','w+',encoding='utf-8')
full.write('%%pontorecolha(ID,Lat,Long,Rua,[RuasAdjecentes],tipo)\n')
contentRE = re.compile(
	r'\d{5}: ([A-Za-z0-9 \-]*)[ ,](\(.*\): (.+) - (.+)\))?')

def tipotoint(tipo):
	i = 0
	if tipo == 'Lixos':
	 i = 0
	elif tipo == 'Organicos':
	 i = 1
	elif tipo == 'Papel e Cartao':
	 i = 2
	elif tipo == 'Embalagens':
	 i = 3
	elif tipo == 'Vidro':
	 i = 4
	return i

adjacentes = collections.defaultdict(set)
ruas = dict()
tipos = dict()
qt = dict()

for line in dataset.values:
	ponto = re.search(contentRE, line[4])
	if ponto:
		rua = ponto.group(1)
		if not(rua in ruas):
			ruas[rua] = [line[0],line[1]]
			tipos[rua] = [0,0,0,0,0]
			qt[rua] = [0,0,0,0,0]

		t = tipotoint(line[5])

		tipos[rua][t] = 1
		qt[rua][t] += line[9]
		if ponto.group(2):
			adj1 = ponto.group(3)
			adj2 = ponto.group(4)
			if not(rua in adjacentes[adj1]):
				adjacentes[rua].add(adj1)
			if not(rua in adjacentes[adj2]):
				adjacentes[rua].add(adj2)

	#full.write("ponto_recolha(%d,%f,%f,'%s',%s,'%s',%d).\n" %(line[2],line[0],line[1],rua,adjacente,line[5],line[9]))
#full.close()

for item in ruas.keys():
	if tipos[item][0] == 1:
		full.write("ponto_recolha(%f,%f,'%s',%d,%d).\n" %(ruas[item][0],ruas[item][1],item,0,qt[item] [0]))
	if tipos[item][1] == 1:
		full.write("ponto_recolha(%f,%f,'%s',%d,%d).\n" %(ruas[item][0],ruas[item][1],item,1,qt[item][1]))
	if tipos[item][2] == 1:
		full.write("ponto_recolha(%f,%f,'%s',%d,%d).\n" %(ruas[item][0],ruas[item][1],item,2,qt[item] [2]))
	if tipos[item][3] == 1:
		full.write("ponto_recolha(%f,%f,'%s',%d,%d).\n" %(ruas[item][0],ruas[item][1],item,3,qt[item] [3]))
	if tipos[item][4] == 1:
		full.write("ponto_recolha(%f,%f,'%s',%d,%d).\n" %(ruas[item][0],ruas[item][1],item,4,qt[item] [4]))

#Calculate distance
def calc2_distance(latitude1,longitude1,latitude2,longitude2):
    result = np.sqrt(  (latitude1-latitude2)**2 + (longitude1-longitude2)**2 )
    return result

def calc_distance(lat1,lon1,lat2,lon2):
    # Raio aproximado da terra
    R = 6371.0

    dlon = lon2 - lon1
    dlat = lat2 - lat1

    a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
    c = 2 * atan2(sqrt(a), sqrt(1 - a))

    distance = R * c

    return distance

full2 = open('arco.pl','w+',encoding='utf-8')
full2.write('%%arco(Rua1,Rua2,Distancia)\n')

for item in adjacentes.items():
	for rua in item[1]:
		if (item[0] in ruas) and (rua in ruas):
			full2.write("arco('%s','%s',%f).\n" %(item[0],rua,calc_distance(ruas[item[0]][0],ruas[item[0]][1],ruas[rua][0],ruas[rua][1])))
full2.close()


from __future__ import annotations
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from shell import Shell
    from path import Path
from command import arg, pop_arg

class CMD_cd:
    """ Change directory command """

    CMD = 'cd'

    def not_a_directory(self) -> None:
        path_name = self.path.raw_path
        self.sys_print(f"{self.CMD}: not a directory: {path_name}")

    def no_such_directory(self) -> None:
        path_name = self.path.raw_path
        self.sys_print(f"{self.CMD}: no such file or directory: {path_name}")

    def set_cwd(self, path: Path) -> None:
        self.shell.cwd = path

    def __init__(self, shell: Shell, *args: str) -> None:
        self.shell = shell
        self.sys_print = self.shell.system.print
        fs = shell.system.filesystem

        if not arg(*args):
            self.path = self.shell.pathify('~')
            return self.set_cwd(self.path)

        path, args = pop_arg(*args)
        self.path = self.shell.pathify(path)

        if not fs.exists(self.path):
            return self.no_such_directory()

        if not fs.get_node_at(self.path).is_dir():
            return self.not_a_directory()

        return self.set_cwd(self.path)


from functools import partial
from typing import Any, Awaitable, Dict, List, Tuple

from ..common import (
    ACTION,
    AND,
    CONTRADICTION,
    DEFAULT_KEYERROR,
    IDENTITY_FACTORY,
    IS_DICT,
    IS_DICT_MISSING_KEY,
    IS_NONE,
    IS_NOT_CALLABLE,
    IS_NOT_DICT,
    NOOP,
    RETURN_FALSE,
    VALUE,
    WHEN,
    Predicate,
    Transform,
)
from ..services import Scoped
from .action import Action
from .middleware import Context, Middleware

def _TRANSFORM_WHEN_NOT_DICT(value: Any) -> Dict[str, Any]:
    return {VALUE: value}

_MISSING_ACTION = partial(IS_DICT_MISSING_KEY, key=ACTION)

def _TRANSFORM_WHEN_MISSING_ACTION(value: Dict[str, Any]) -> Dict[str, Any]:
    value[ACTION] = NOOP
    return value

_MISSING_VALUE = partial(IS_DICT_MISSING_KEY, key=VALUE)

def _TRANSFORM_WHEN_MISSING_VALUE(value: Dict[str, Any]) -> Dict[str, Any]:
    value[VALUE] = RETURN_FALSE
    return value

def _VALUE_NOT_CALLABLE(value: Dict[str, Any]) -> bool:
    return IS_NOT_CALLABLE(value[VALUE])

def _TRANSFORM_WHEN_VALUE_NOT_CALLABLE(value: Dict[str, Any]) -> Dict[str, Any]:
    value[VALUE] = IDENTITY_FACTORY(value[VALUE])
    return value

class Skip(Middleware):
    @classmethod
    def verify(cls, value: Any) -> None:
        super().verify(value)

        if not IS_DICT(value):
            raise TypeError(f"{value} should be dict")

        if _MISSING_ACTION(value):
            raise DEFAULT_KEYERROR(value, ACTION)

        if _MISSING_VALUE(value):
            raise DEFAULT_KEYERROR(value, VALUE)

    @classmethod
    def _get_simplifications(cls) -> List[Tuple[Predicate, Transform]]:
        simplifications = super()._get_simplifications()

        # `{'skip': None}` -> `{'skip': False}`
        simplifications.append((IS_NONE, CONTRADICTION))

        # `{'skip': <bool>}` -> `{'skip': IDENTITY_FACTORY(<bool>)}`
        simplifications.append((AND(IS_NOT_DICT, IS_NOT_CALLABLE), IDENTITY_FACTORY))

        # `{'skip': <any>}` -> `{'skip': {VALUE: <any>}}`
        simplifications.append((IS_NOT_DICT, _TRANSFORM_WHEN_NOT_DICT))

        # `{'skip': {VALUE: ...}}` -> `{'skip': {VALUE: ..., ACTION: NOOP}}`
        simplifications.append((AND(IS_DICT, _MISSING_ACTION), _TRANSFORM_WHEN_MISSING_ACTION))

        # `{'skip': {ACTION: ...}}` -> `{'skip': {VALUE: RETURN_FALSE, ACTION: ...}}`
        simplifications.append((AND(IS_DICT, _MISSING_VALUE), _TRANSFORM_WHEN_MISSING_VALUE))

        # `{'skip': {VALUE: <non-callable>, ACTION: ...}}`
        simplifications.append(
            (AND(IS_DICT, _VALUE_NOT_CALLABLE), _TRANSFORM_WHEN_VALUE_NOT_CALLABLE)
        )
        return simplifications

    def _do_parse(self, value: Dict[str, Any]) -> Dict[str, Middleware]:
        self.verify(value)

        return {WHEN: Action(value[VALUE]), ACTION: Action(value[ACTION])}

    async def should_skip(self, context: Context) -> Awaitable[bool]:
        should_skip_action: Action = getattr(self, WHEN)
        scoped = await should_skip_action.apply_onto(context)
        skipped = scoped.getmagic(VALUE)
        context.scoped.setmagic(SKIP, skipped)
        return skipped

    async def when_skip(self, context: Context) -> Awaitable[Scoped]:
        action_when_skip: Action = getattr(self, ACTION)
        scoped = await action_when_skip.apply_into(context)
        return scoped.getmagic(VALUE)

    async def _do_apply(self, context: Context) -> Scoped:
        if await self.should_skip(context.replace_with_void_next()):
            await self.when_skip(context.replace_with_void_next())
        else:
            await context.next()
        return context.scoped

SKIP = Skip.get_name()


# 백준 #1738 골목길
'''
    Algorithm: bellman-ford
    Time Complexity: O(NM)

    음수가 포함된 최단 경로 찾기 => 벨만-포드 알고리즘
    무조건 콘도까지 가는 경로는 있는 듯 하다.

    최적의 경로가 존재하지 않는 경우: (무한 돈복사가 가능한 경우)
        - 양의 사이클이 존재하며(돈을 증가시키는),
          그 사이클이 start -> 콘도까지의 경로에 포함되어 있을 때
'''
import sys
from collections import deque
from typing import List

input = sys.stdin.readline
INF = sys.maxsize

def solution(N: int, M: int) -> List[int]:
    alley = [[] for _ in range(N+1)]
    pre = [None for _ in range(N+1)] # 각 골목길의 직전 골목길 저장

    def bellman_ford(start: int) -> int:
        ''' 사이클이 있을 경우 포함되는 노드 1개, 없을 경우 None을 리턴 '''
        dist = [-INF for _ in range(N+1)] # dist[i] : start에서 i까지 가는 비용

        dist[start] = 0

        for _ in range(N-1):
            for node in range(1, N+1):
                for dest, cost in alley[node]:
                    if dist[dest] < dist[node] + cost:
                        dist[dest] = dist[node] + cost
                        pre[dest] = node

        # 양의 사이클 판별: 사이클을 만드는 노드 한개를 리턴
        for node in range(1, N+1):
            for dest, cost in alley[node]:
                if dist[dest] < dist[node] + cost:
                    return node

        return

    def is_copy_money(node: int) -> bool:
        ''' 최적의 경로 확인: 사이클에 존재하는 노드가 목적지 N까지의 경로가 있는 지 확인 '''
        q = deque([node])
        visited = set([node])

        # 양의 사이클이 존재하고 콘도까지 가는 경로가 있다면 True 리턴
        while q:
            node = q.popleft()

            for dest, _ in alley[node]:
                if dest == N:
                    return True

                if dest not in visited:
                    q.append(dest)
                    visited.add(dest)

        # 사이클이 존재하지만 콘도랑은 관련이 없을 경우 False 리턴
        return False

    def get_path(start):
        ''' 코레스코 콘도의 위치 N부터 start까지 역으로 탐색 '''
        result = [N]

        while result[-1] != start:
            result.append(pre[result[-1]])

        return reversed(result)

    for _ in range(M):
        u, v, w = map(int, input().split())
        alley[u].append((v, w))

    bf = bellman_ford(1)

    if bf and is_copy_money(bf):
        return [-1]

    return get_path(1)

if __name__ == "__main__":
    N, M = map(int, input().split())

    print(*solution(N, M))


from flask import Flask, render_template

app = Flask(__name__)

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

@app.route('/njnja')
def success():
	my_images= ['donatello.jpg','leonardo.jpg','michelangelo.jpg','raphael.jpg']
	return render_template('njnja.html',show_all=True,my_images=my_images)

@app.route('/njnja/<color>')
def project(color):
	images_dict ={
		'blue':'leonardo.jpg',
		'orange': 'michelangelo.jpg',
		'red': 'raphael.jpg',
		'purple':'donatello.jpg'
	}
	color = images_dict.get(color,'notapril.jpg')

	return render_template('njnja.html',show_all=False,color=color)

app.run(debug=True)


import sys
from collections import defaultdict

if len(sys.argv) > 1:
    plik = sys.argv[1]
else:
    plik = "logs.txt"

last_login_time = {}
user_system_time = defaultdict(int)

with open(plik) as l:
    for line in l:
        name, action, time = (line.split(";"))
        time = int(time)
        if action == "LOGIN":
            last_login_time[name] = time
        elif action == "LOGOUT":
            user_system_time[name] += time - last_login_time[name]

for name, time in sorted(user_system_time.items(), key=lambda x: int(x[0].split("-")[1])):
    print(f"- {name}: {time} s")


import time
import json
import hashlib

class Blockchain(object):
    def __init__(self):
        self.chain = []

    def get_last_block(self):
        return self.chain[-1]

    def add_block(self, block):
        if (len(self.chain) > 0):
            block.prev = self.get_last_block().hash
        else:
            block.prev = "none"
        self.chain.append(block)

class Block(object):
    def __init__(self, transactions, time, index):
        self.index = index  # Block number
        self.prev = ''  # stores the hash of the previous block
        self.transactions = transactions # Transaction data
        self.time = time    # Time of the transaction
        self.hash = self.calculate_hash()   # hash the block

    def calculate_hash(self):
        hash_transactions = ""
        for transaction in self.transactions:
            hash_transactions += transaction

        hash_string = f"{self.time}{hash_transactions}{self.prev}{self.index}"
        hash_encoded = json.dumps(hash_string, sort_keys=True).encode()
        return hashlib.sha256(hash_encoded).hexdigest()

class Transaction(object):
    def __init__(self, sender, receiver, amount):
        self.sender = sender
        self.receiver = receiver
        self.amount = amount
        self.time = time.time()
        self.hash = self.calculate_hash()

    def calculate_hash(self):
        hash_string = f"{self.sender}{self.receiver}{self.amount}{self.amount}"
        hash_encoded = json.dumps(hash_string, sort_keys=True).encode()
        return hashlib.sha256(hash_encoded).hexdigest()


# coding: utf-8
"""Separate chinese and nonchinese."""
import logging

from .chardet_file import chardet_file
from .detect_lang import detect_lang
from .en_zh_separation import en_zh_separation
from .fetch_xpath import fetch_xpath
from .text_to_paras import text_to_paras
from .zip_longest_middle import zip_longest_middle

# from tqdm import tqdm

LOGGER = logging.getLogger(__name__)
LOGGER.addHandler(logging.NullHandler())

def sep_chinese(text, startlen=30):
    """
    in: text, paras
    out: list of two tuples, srclang, tgtlang
    align starts: when len() >= starlen)

    sep_chinese_logger = logging.getLogger('sep_chinese')
    sep_chinese_logger.setLevel(logging.INFO)
    """
    paras = text_to_paras(text)
    # sep_list = zip(en_zh_separation, paras)
    sep_list = [en_zh_separation(elm) for elm in paras]

    # find the starting anchor
    # for ith, elm in tqdm(enumerate(paras)):
    for ith, elm in enumerate(paras):
        sep = en_zh_separation(elm)
        len0 = len(elm) - sep

        # if min(sep, len0)==0, sep0 = max(sep, len0)
        # else sep0 = min(sep, len0)
        min0 = min(sep, len0)
        sep0 = max(sep, len0) if min0 == 0 else min0
        if sep0 >= startlen:
            # determin chinese is srclang (left) or tgtlang (right)
            if min0 == 0:  # single language in one para
                if sep == 0:
                    tgtlang = (
                        "chinese" if detect_lang(elm) == "chinese" else "nonchinese"
                    )  # noqa
                    srclang = (
                        "nonchinese" if tgtlang == "chinese" else "chinese"
                    )  # noqa
                else:  # sep = len(elm)
                    srclang = (
                        "chinese" if detect_lang(elm) == "chinese" else "nonchinese"
                    )  # noqa
                    tgtlang = (
                        "nonchinese" if srclang == "chinese" else "chinese"
                    )  # noqa
            else:  # two languages in one para
                if detect_lang(elm[:sep]) == "chinese":
                    srclang = "chinese"
                    tgtlang = "nonchinese"
                else:
                    srclang = "nonchinese"
                    tgtlang = "chinese"
            break

    # LOGGER.info(" !!! srclang, tgtlang: %s, %s", srclang, tgtlang)

    list0 = []
    starti = ith
    # LOGGER.debug(">>>Preample...")
    for idxi in range(starti):  # trival preamble, just put in right palce
        sep0 = sep_list[idxi]
        front_part = paras[idxi][:sep0]
        back_part = paras[idxi][sep0:]
        if detect_lang(front_part) == "chinese":
            if srclang == "chinese":
                list0.append([front_part, back_part])
            else:
                list0.append([back_part, front_part])
        else:
            if srclang == "chinese":
                list0.append([back_part, front_part])  # noqa
            else:
                list0.append([front_part, back_part])

    # LOGGER.debug(" list0 %s", list0)

    # LOGGER.debug(">>>Start at %s...", starti)
    # real sep and clapse
    auxflag = (
        -1
    )  # left 0, right 1, if cur - prv==0, colelct,  cur - prv==1, switch to right, cur - prv==-1, switch to left and align  # noqa
    # itembuff = []
    lbuffer = []
    rbuffer = []
    # 0:1, left index:right index
    indexprev = 1

    # for ith, elm in enumerate(tqdm(paras[starti:])):
    for ith, elm in enumerate(paras[starti:]):
        # LOGGER.debug("******** ith %s, pos %s, elm %s", ith, ith + starti, elm)  # noqa
        sep0 = sep_list[ith + starti]
        front_part = elm[:sep0]
        back_part = elm[sep0:]

        # use the langer part to detect chinese
        if sep0 > len(elm) - sep0:
            front_part_lang = (
                "chinese" if detect_lang(front_part) == "chinese" else "nonchinese"
            )  # noqa
            back_part_lang = (
                "nonchinese" if front_part_lang == "chinese" else "chinese"
            )  # noqa
        else:
            back_part_lang = (
                "chinese" if detect_lang(back_part) == "chinese" else "nonchinese"
            )  # noqa
            front_part_lang = (
                "nonchinese" if back_part_lang == "chinese" else "chinese"
            )  # noqa

        # LOGGER.debug(" +++!!! front_part_lang  %s ", front_part_lang)

        # front_part: proc_fbpart(front_part, front_part_lang)
        def proc_fbpart(front_part, front_part_lang):
            """
            process front, back part
            """
            nonlocal srclang, tgtlang, indexprev, auxflag, lbuffer, rbuffer

            # LOGGER.debug("  (in proc_fbpart) f/b part: %s ", front_part)
            if front_part_lang == srclang:
                indexcurr = 0
            else:
                indexcurr = 1
            # LOGGER.debug(" indexcurr: %s", indexcurr)

            auxflag = indexcurr - indexprev
            # LOGGER.debug("auxflag: %s", auxflag)

            if (
                auxflag == -1
            ):  # -1, 0, 1 -- -1: collet, 0 collect left or right, 1, swtich to right  # noqa
                # LOGGER.debug(" collect and align ")

                for zipelm in zip_longest_middle(
                    lbuffer, rbuffer, fillvalue=""
                ):  # noqa
                    list0.append(list(zipelm))
                lbuffer = [front_part]
                rbuffer = []

            elif auxflag == 0:
                # LOGGER.debug(" append lbuffer or rbuffer ")
                if indexcurr == 0:
                    lbuffer += [front_part]
                else:
                    rbuffer += [front_part]
            else:  # auxflag = 1
                rbuffer += [front_part]
            indexprev = indexcurr  # prepare for the next round

        if front_part.strip():  #
            proc_fbpart(front_part, front_part_lang)
            # LOGGER.debug("<<<<< 1111111 front_part <<<<< 1111111")
        if back_part.strip():  #
            proc_fbpart(back_part, back_part_lang)
            # LOGGER.debug("<<<<< 2222222 back_part <<<<< 2222222")

        # LOGGER.debug(" lbuffer, rbuffer, list0: \n>%s, \n>%s, \n>%s ", lbuffer, rbuffer, list0)  # noqa

    # process postamble, equivalent to auxflag = -1
    # LOGGER.debug(" process postamble ")
    # LOGGER.debug("zipped lbuffer, rbuffer: %s ", list(zip_longest_middle(lbuffer, rbuffer, fillvalue='')))  # noqa
    for zipelm in zip_longest_middle(lbuffer, rbuffer, fillvalue=""):
        list0.append(list(zipelm))

    return list0

# pep8/flake8/pylint filename
# nosetests -v --nologcapture
def test_minitext():
    """Test minitext, text =."""
    text = """

中国时间: 09:23 2017年01月22日星期日
双语新闻
双语新闻(2017年1月19日)
2017.01.19 22:49

    美国之音

    奥巴马说 美国一切都会好的

奥巴马总统星期三在他最后一次白宫记者会上，努力让对政府换届感到担忧的美国民众放心。他说：“我相信这个国家。我相信美国人民。我相信人们身上的善多于恶。”

白宫记者们的提问涉及到奥巴马给陆军情报分析员切尔西·曼宁减刑等议题。 奥巴马简单地回答了这些问题，最后他还很具体地回答了他是如何向两个女儿解释美国大选结果的。

奥巴马总统说，玛利亚和萨沙对于共和党候选人川普击败他支持的民主党候选人希拉里·克林顿感到失望，不过令他自豪的是，她们表现得很坚强、爱国，而不是愤世嫉俗。

奥巴马总统承认，他在公开场合表现出的冷静和随和跟他私下的表现并不一样，私下他也会骂人，也像其他人一样会愤怒和沮丧。他说：“不过我深信，（作为一个国家） 一切都会好的，但我们必须奋斗，必须努力，不能觉得理所当然，我相信你们会帮我们做到。”

Obama Says US 'Is Going to Be OK'

At his final news conference as president Wednesday, Barack Obama sought to reassure those Americans anxious about the change of administrations: “I believe in this country. I believe in the American people. I believe that people are more good than bad.”

White House reporters questioned Obama about his decision to shorten the prison term of former Army intelligence analyst Chelsea Manning, and other topics. The president fielded those easily, but took his time answering the final query, about how he discussed the results of the U.S. election with his two teenaged daughters, Sasha and Malia.

Obama said Malia and Sasha were disappointed by Republican Donald Trump's defeat of his preferred candidate, Democrat Hillary Clinton, just as he and first lady Michelle were, but that he is proud of them because they are resilient, patriotic and not cynical.

The president admitted his public persona - calm and cheerful - is not quite the way he feels when behind closed doors.

“I curse more than I do in public, and sometimes I get mad and frustrated, like everybody else does," he said. "But at my core, I think we’re going to be okay [as a country]. We just have to fight for it, we have to work for it, and not take it for granted, and I know that you will help us do that.”

韩国法庭裁定没有足够证据逮捕三星副总裁

韩国一家法庭星期四决定不批准对三星集团负责人的逮捕令，这个案件与朴槿惠总统弹劾案有关。
"""  # NOQA
    exp1 = 14
    exp1 = 18
    list0 = sep_chinese(text)
    LOGGER.debug("text: %s", text)
    LOGGER.debug(" sep_chinese output: %s", list0)
    assert exp1 == len(list0)

    exp2 = "韩国法庭裁定没有足够证据逮捕三星副总裁"
    # assert exp2 == list0[12][0]
    assert exp2 == list0[-2][0]

    exp3 = "Obama Says US 'Is Going to Be OK'"
    # assert exp3 == list0[6][1]
    assert exp3 == list0[10][0]

    # return list0

def xxtest_file1():
    r"""test_file1.

    D:\dl\Dropbox\shuangyu_ku\txt-books\德伯家的苔丝(中英文对照).txt'
    """
    file = r"D:\dl\Dropbox\shuangyu_ku\txt-books\德伯家的苔丝(中英文对照).txt"
    text = open(
        file, "r", encoding=chardet_file(file, 20000), errors="ignore"
    ).read()  # NOQA

    exp1 = []
    list0 = sep_chinese(text)

    # LOGGER.debug("text: %s", pagevoa)
    LOGGER.debug(" sep_chinese output: %s", list0)
    assert exp1 == list0

def xxxtest_voaxpath_content():
    """
    test_voaxpath_content, pagevoa1 = fetch_xpath(urlvoa, "//*[@id='content']")
    """
    urlvoa = r"http://www.voachinese.com/a/bilingual-news-20170119/3682842.html"  # NOQA
    # voaurl = urlvoa
    pagevoa = fetch_xpath(urlvoa, "//*[@id='content']")
    # parasvoa = text_to_paras(pagevoa)

    exp1 = [
        ["双语新闻", ""],
        ["双语新闻(2017年1月19日)", ""],
        ["2017年1月19日 22:49", ""],
        ["美国之音", ""],
        ["分享", ""],
        ["分享到脸书", ""],
        ["分享到推特", ""],
        ["分享到谷歌+", ""],
        ["电邮本文", ""],
        ["打印", ""],
        ["奥巴马说  美国一切都会好的", ""],
        [
            "奥巴马总统星期三在他最后一次白宫记者会上，努力让对政府换届感到担忧的美国民众放心。他说：“我相信这个国家。我相信美国人民。我相信人们身上的善多于恶。”",
            "Obama Says US 'Is Going to Be OK'",
        ],
        [
            "白宫记者们的提问涉及到奥巴马给陆军情报分析员切尔西·曼宁减刑等议题。 奥巴马简单地回答了这些问题，最后他还很具体地回答了他是如何向两个女儿解释美国大选结果的。",
            "At his final news conference as president Wednesday, Barack Obama sought to reassure those Americans anxious about the change of administrations: “I believe in this country. I believe in the American people. I believe that people are more good than bad.”",
        ],
        [
            "",
            "White House reporters questioned Obama about his decision to shorten the prison term of former Army intelligence analyst Chelsea Manning, and other topics. The president fielded those easily, but took his time answering the final query, about how he discussed the results of the U.S. election with his two teenaged daughters, Sasha and Malia.",
        ],
        [
            "",
            "Obama said Malia and Sasha were disappointed by Republican Donald Trump's defeat of his preferred candidate, Democrat Hillary Clinton, just as he and first lady Michelle were, but that he is proud of them because they are resilient, patriotic and not cynical.",
        ],
        [
            "奥巴马总统说，玛利亚和萨沙对于共和党候选人川普击败他支持的民主党候选人希拉里·克林顿感到失望，不过令他自豪的是，她们表现得很坚强、爱国，而不是愤世嫉俗。",
            "The president admitted his public persona - calm and cheerful - is not quite the way he feels when behind closed doors.",
        ],
        [
            "奥巴马总统承认，他在公开场合表现出的冷静和随和跟他私下的表现并不一样，私下他也会骂人，也像其他人一样会愤怒和沮丧。他说：“不过我深信，（作为一个国家） 一切都会好的，但我们必须奋斗，必须努力，不能觉得理所当然，我相信你们会帮我们做到。”",
            '“I curse more than I do in public, and sometimes I get mad and frustrated, like everybody else does," he said. "But at my core, I think we’re going to be okay [as a country]. We just have to fight for it, we have to work for it, and not take it for granted, and I know that you will help us do that.”',
        ],
        [
            "韩国法庭裁定没有足够证据逮捕三星副总裁",
            "Samsung Indictment Reversal Setbacks South Korean Impeachment Trial",
        ],
        [
            "韩国一家法庭星期四决定不批准对三星集团负责人的逮捕令，这个案件与朴槿惠总统弹劾案有关。",
            "A South Korean court Thursday dismissed an arrest warrant request for the head of the Samsung Group, in a case that could affect the impeachment trial of President Park Geun-hye.",
        ],
        [
            "三星集团副总裁李在镕在拘留所被关押了14个小时后，首尔中区法院裁定，目前没有足够证据为检察官提出的行贿、挪用款项和作伪证的指控提供法律依据。",
            "Jay Y. Lee, the vice chairman of Samsung Electronics Co. was held for 14 hours in a detention facility before the Seoul Central District Court ruled there was not enough evidence at this time to justify prosecutors’ charges of bribery, embezzlement and perjury.",
        ],
        [
            "",
            "“The court's decision to reject arrest warrant is very regrettable, but we will steadily continue the investigation by taking necessary measures,\" said a spokesman of the prosecutor's office.",
        ],
        [
            "检察官办公室发言人说，“法庭驳回逮捕令的决定令我们深感遗憾，但是我们会采取必要措施，继续进行调查。”",
            "Lee is suspected of paying President Park's influential friend Choi Soon-sil $36 million in return for the president’s help to secure the approval of a state-run pension fund for a 2015 merger of two Samsung affiliates.",
        ],
        [
            "李在镕涉嫌向朴槿惠总统的密友崔顺实支付了3600万美元，换取总统的帮助，让国营退休基金批准2015年三星两个附属机构的合并案。",
            "The court’s decision on the Samsung case could be a setback for prosecutors in the presidential impeachment trial also underway.",
        ],
        ["法庭这一裁决对于负责朴槿惠弹劾案的检察官一方是一个挫败。", "OMG!"],
        ["美语", "美语怎么说（52）："],
        ["OMG!美语 Homesick!", ""],
        ["OMG!美语 Oil Painting!", ""],
        ["OMG!美语 Catch Up!", ""],
        ["OMG!美语 Knit Scarf!", ""],
        ["OMG!美语 Wear The Basics!", ""],
        ["美语怎么说", ""],
        ["Man-day 男人空间", "神秘的圣诞老人"],
        ["美语怎么说（51）：Secret Santa ", ""],
        ["美语怎么说（50）：The Witches ", "巫师搞怪"],
        ["美语怎么说（49）: Government Shutdown ", "政府关门"],
        ["", "美语怎么说（48）: "],
        ["New Name 命名风波", "YOLO"],
        ["美语", "YOLO"],
        ["美语 第三十八课", "YOLO"],
        ["美语 第三十七课", "YOLO"],
        ["美语 第三十六课", "YOLO"],
        ["美语 第三十五课", "YOLO"],
        ["美语 第三十四课", ""],
    ]  # noqa
    list0 = sep_chinese(pagevoa)
    LOGGER.debug("text: %s", pagevoa)
    LOGGER.debug(" sep_chinese output: %s", list0)
    assert exp1 == list0

def xxtest_voaxpath_body():
    """
    test_voaxpath_body, pagevoa1 = fetch_xpath(urlvoa, "//body")
    """
    urlvoa = r"http://www.voachinese.com/a/bilingual-news-20170119/3682842.html"  # NOQA
    pagevoa1 = fetch_xpath(urlvoa, "//body")
    # parasvoa1 = text_to_paras(pagevoa1)

    exp1 = [
        [
            "if (top.location === self.location) { //if not inside of an IFrame",
            'var utag_data={entity:"VOA",language:"Mandarin",language_service:"VOA Mandarin",short_language_service:"MAN",property_id:"521",platform:"Responsive",platform_short:"R",runs_js:"Yes",page_title:"双语新闻(2017年1月19日)",page_type:"3682842",page_name:"双语新闻(2017年1月19日)",short_headline:"双语新闻(2017年1月19日)",long_headline:"双语新闻(2017年1月19日)",headline:"双语新闻(2017年1月19日)",content_type:"Article",pub_year:"2017",pub_month:"01",pub_day:"19",pub_hour:"14",pub_minute:"49",pub_weekday:"Thursday",byline:"美国之音, ",categories:"bilingual-news",slug:"bilingual-news-20170119",section:"双语新闻",english_section:"bilingual-news",search_results:"No",article_uid:"3682842"};',
        ],
        ['var renderGtm = "true";', ""],
        ['if (renderGtm === "true") {', ""],
        [
            "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-N8MP7P');",
            "",
        ],
        ["}", ""],
        ["}", ""],
        [
            "if(typeof(TealiumTagFrom)==='function' && typeof(TealiumTagSearchKeyword)==='function') {",
            "无障碍链接",
        ],
        [
            "var utag_from=TealiumTagFrom();var utag_searchKeyword=TealiumTagSearchKeyword();",
            "跳转到内容",
        ],
        ["", "跳转到导航"],
        ["", "跳转到检索"],
        ["", "检索"],
        ["", "检索"],
        ["", "其他语言网站"],
        ["", "检索"],
        ["", "检索"],
        ["", "广播音频"],
        ["", "电视节目"],
        ["", "主页"],
        ["", "美国"],
        ["", "中国"],
        ["", "分类新闻"],
        ["", "美国"],
        ["", "中国"],
        ["", "台湾"],
        ["", "港澳"],
        ["", "国际"],
        ["", "经贸"],
        ["", "法律"],
        ["", "人权"],
        ["", "军事"],
        [
            'if(utag_searchKeyword!=null && utag_searchKeyword!==\'\' && utag_data["search_keyword"]==null) utag_data["search_keyword"]=utag_searchKeyword;if(utag_from!=null && utag_from!==\'\') utag_data["from"]=TealiumTagFrom();}',
            "文化",
        ],
        [
            '(function(a,b,c,d){ a="https://tags.tiqcdn.com/utag/bbg/voa-pangea/prod/utag.js"; b=document;c="script";d=b.createElement(c);d.src=a;d.type="text/java"+c;d.async=true; a=b.getElementsByTagName(c)[0];a.parentNode.insertBefore(d,a); })();',
            "教育",
        ],
        ["宗教", "科技"],
        ["", "劳工"],
        ["", "环境"],
        ["", "健康"],
        ["", "体育"],
        ["", "娱乐"],
        ["", "热点专题"],
        ["", "互动图解：南中国海七十年风云录"],
        ["", "美中关系"],
        ["", "美国总统大选和权力交接"],
        ["", "台海两岸关系"],
        ["", "年终报道"],
        ["", "美国之音专访"],
        ["", "国会报道"],
        ["", "南中国海争端"],
        ["", "美中关系书评"],
        ["", "朝鲜核问题"],
        ["", "法律窗口"],
        ["", "纪念六四"],
        ["", "评述中国文革"],
        ["", "中国“肃贪”政治"],
        ["VOA", "卫视"],
        ["VOA", "卫视最新视频"],
        ["", "美国观察"],
        ["", "时事大家谈"],
        ["", "焦点对话"],
        ["", "海峡论谈"],
        ["VOA", "卫视完整版"],
        ["", "解密时刻"],
        ["", "国际新闻"],
        ["VOA", "连线"],
        ["", "媒体观察"],
        ["", "小夏看美国"],
        ["", "时事看台"],
        ["", "科技101"],
        ["", "走进美国"],
        ["", "美国万花筒"],
        ["", "您的孩子在美国"],
        ["", "美国专讯"],
        ["OMG", "！美语"],
        ["", "视频"],
        ["", "音频"],
        ["", "上午6-7点广播节目"],
        ["", "上午8-9点广播节目"],
        ["", "下午5-6点广播节目"],
        ["", "晚上6-7点广播节目"],
        ["", "晚上7-8点广播节目"],
        ["", "晚上8-9点广播节目"],
        ["", "晚上9-10点广播节目"],
        ["", "晚上10-11点广播节目"],
        ["VOA", "卫视节目音频"],
        ["", "新闻报道音频"],
        ["", "英语教学音频"],
        ["", "英语教学"],
        ["", "最新内容"],
        ["YOLO", "美语"],
        ["", "双语新闻"],
        ["", "学个词"],
        ["", "美国习惯用语"],
        ["", "礼节美语"],
        ["", "流行美语"],
        ["", "美语咖啡屋"],
        ["", "体育美语"],
        ["", "美语三级跳"],
        ["", "美语训练班"],
        ["", "美语怎么说"],
        ["", "OMG！美语(视频)"],
        ["", "美语怎么说(视频)"],
        ["", "上网办法"],
        ["", "播客"],
        ["", "图片集"],
        ["", "订阅邮件"],
        ["", "美国之音丛书"],
        ["", "登录/注册"],
        ["", "更多"],
        ["VOA", "卫视"],
        ["", "最新节目"],
        ["", "VOA卫视 焦点对话(重播)"],
        ["", "即将开播"],
        ["20:00 - 20:59", "卫视 解密时刻"],
        ["VOA", ""],
        ["21:00 - 22:00", "卫视 海峡论谈"],
        ["VOA", ""],
        ["6:00 - 07:00", "VOA卫视 解密时刻(重播)"],
        ["", "卫视节目"],
        ["《VOA", "卫视》节目介绍"],
        ["", "电视广播节目表"],
        ["", "美国之音"],
        ["YouTube", "美国观察"],
        ["", "时事大家谈"],
        ["", "焦点对话"],
        ["", "媒体观察"],
        ["VOA", "连线"],
        ["更多《VOA卫视》节目... ...", "现场广播"],
        ["", "最新节目"],
        ["", "解密时刻(重播)"],
        ["", "即将开播"],
        ["17:00 - 18:00", "英语教学 时事大家谈(重播)"],
        ["18:00 - 19:00", "国际新闻 焦点对话(重播)"],
        ["19:00 - 20:00", "时事经纬 社论"],
        ["", "其他音频"],
        ["", "24-7中文广播"],
        ["", "新闻报道音频"],
        ["", "英语教学音频"],
        ["VOA", "卫视音频"],
        ["SoundCloud", "频道"],
        ["", "广播节目表"],
        ["", "上一页"],
        ["", "下一页"],
        ["0", "快讯"],
        ["", "上一页"],
        ["VOA", "下一页"],
        ["0", "直播"],
        ["", "中国时间 16:45 2017年3月12日 星期日"],
        ["", "双语新闻"],
        ["", "双语新闻(2017年1月19日)"],
        ["", "2017年1月19日 22:49"],
        ["", "美国之音"],
        ["", "分享"],
        ["", "分享到脸书"],
        ["", "分享到推特"],
        ["", "分享到谷歌+"],
        ["", "电邮本文"],
        ["", "打印"],
        ["", "奥巴马说  美国一切都会好的"],
        [
            "",
            "奥巴马总统星期三在他最后一次白宫记者会上，努力让对政府换届感到担忧的美国民众放心。他说：“我相信这个国家。我相信美国人民。我相信人们身上的善多于恶。”",
        ],
        [
            "",
            "白宫记者们的提问涉及到奥巴马给陆军情报分析员切尔西·曼宁减刑等议题。 奥巴马简单地回答了这些问题，最后他还很具体地回答了他是如何向两个女儿解释美国大选结果的。",
        ],
        [
            "",
            "奥巴马总统说，玛利亚和萨沙对于共和党候选人川普击败他支持的民主党候选人希拉里·克林顿感到失望，不过令他自豪的是，她们表现得很坚强、爱国，而不是愤世嫉俗。",
        ],
        [
            "",
            "奥巴马总统承认，他在公开场合表现出的冷静和随和跟他私下的表现并不一样，私下他也会骂人，也像其他人一样会愤怒和沮丧。他说：“不过我深信，（作为一个国家） 一切都会好的，但我们必须奋斗，必须努力，不能觉得理所当然，我相信你们会帮我们做到。”",
        ],
        ["Obama Says US 'Is Going to Be OK'", "韩国法庭裁定没有足够证据逮捕三星副总裁"],
        [
            "At his final news conference as president Wednesday, Barack Obama sought to reassure those Americans anxious about the change of administrations: “I believe in this country. I believe in the American people. I believe that people are more good than bad.”",
            "韩国一家法庭星期四决定不批准对三星集团负责人的逮捕令，这个案件与朴槿惠总统弹劾案有关。",
        ],
        [
            "White House reporters questioned Obama about his decision to shorten the prison term of former Army intelligence analyst Chelsea Manning, and other topics. The president fielded those easily, but took his time answering the final query, about how he discussed the results of the U.S. election with his two teenaged daughters, Sasha and Malia.",
            "三星集团副总裁李在镕在拘留所被关押了14个小时后，首尔中区法院裁定，目前没有足够证据为检察官提出的行贿、挪用款项和作伪证的指控提供法律依据。",
        ],
        [
            "Obama said Malia and Sasha were disappointed by Republican Donald Trump's defeat of his preferred candidate, Democrat Hillary Clinton, just as he and first lady Michelle were, but that he is proud of them because they are resilient, patriotic and not cynical.",
            "检察官办公室发言人说，“法庭驳回逮捕令的决定令我们深感遗憾，但是我们会采取必要措施，继续进行调查。”",
        ],
        [
            "The president admitted his public persona - calm and cheerful - is not quite the way he feels when behind closed doors.",
            "李在镕涉嫌向朴槿惠总统的密友崔顺实支付了3600万美元，换取总统的帮助，让国营退休基金批准2015年三星两个附属机构的合并案。",
        ],
        [
            '“I curse more than I do in public, and sometimes I get mad and frustrated, like everybody else does," he said. "But at my core, I think we’re going to be okay [as a country]. We just have to fight for it, we have to work for it, and not take it for granted, and I know that you will help us do that.”',
            "法庭这一裁决对于负责朴槿惠弹劾案的检察官一方是一个挫败。",
        ],
        ["Samsung Indictment Reversal Setbacks South Korean Impeachment Trial", "美语"],
        [
            "A South Korean court Thursday dismissed an arrest warrant request for the head of the Samsung Group, in a case that could affect the impeachment trial of President Park Geun-hye.",
            "OMG!美语 Homesick!",
        ],
        [
            "Jay Y. Lee, the vice chairman of Samsung Electronics Co. was held for 14 hours in a detention facility before the Seoul Central District Court ruled there was not enough evidence at this time to justify prosecutors’ charges of bribery, embezzlement and perjury.",
            "OMG!美语 Oil Painting!",
        ],
        [
            "“The court's decision to reject arrest warrant is very regrettable, but we will steadily continue the investigation by taking necessary measures,\" said a spokesman of the prosecutor's office.",
            "OMG!美语 Catch Up!",
        ],
        [
            "Lee is suspected of paying President Park's influential friend Choi Soon-sil $36 million in return for the president’s help to secure the approval of a state-run pension fund for a 2015 merger of two Samsung affiliates.",
            "OMG!美语 Knit Scarf!",
        ],
        [
            "The court’s decision on the Samsung case could be a setback for prosecutors in the presidential impeachment trial also underway.",
            "OMG!美语 Wear The Basics!",
        ],
        ["OMG!", "美语怎么说"],
        ["美语怎么说（52）：", "Man-day 男人空间"],
        ["", "美语怎么说（51）：Secret Santa "],
        ["神秘的圣诞老人", "美语怎么说（50）：The Witches "],
        ["巫师搞怪", "美语怎么说（49）: Government Shutdown "],
        ["政府关门", "New Name 命名风波"],
        ["美语怎么说（48）: ", ""],
        ["YOLO", "美语"],
        ["YOLO", "美语 第三十八课"],
        ["YOLO", "美语 第三十七课"],
        ["YOLO", "美语 第三十六课"],
        ["YOLO", "美语 第三十五课"],
        ["YOLO", "美语 第三十四课"],
        ["", "回页顶"],
        ["", "关注我们"],
        ["", "网上服务"],
        ["", "翻墙信息"],
        ["", "聚合新闻"],
        ["", "播客"],
        ["", "订阅电邮新闻、英语学习教材"],
        ["", "音频"],
        ["", "广播节目音频存档"],
        ["", "新闻音频存档"],
        ["VOA", "卫视音频"],
        ["", "英语音频存档"],
        ["", "应用程序("],
        ["APP)", "美国之音应用程序简介"],
        ["", "新闻应用程序("],
        ["iOS)", "移动流媒体播放器("],
        ["APK)", "非智能手机新闻应用程序"],
        ["", "其他信息"],
        ["", "关于我们"],
        ["", "联系我们"],
        ["", "美国之音宪章"],
        ["", "条款及私隐政策"],
        ["", "网站留言规则"],
        ["", "互联网翻墙指南"],
        ["", "广播理事会("],
        ["BBG)", "美國之音粵語網"],
        ["VOA English", "自由亚洲网站"],
        ["\u0f56\u0f7c\u0f51\u0f0b\u0f61\u0f72\u0f42", "中国时间"],
        ["Media Relations", "//"],
        ["test ie 6, 7, 8", ""],
        ['var div = document.createElement("div");', ""],
        ['div.innerHTML = "<!--[if lte IE 8]><i></i><![endif]-->";', ""],
        ['var isIe8orLower = !!div.getElementsByTagName("i").length;', ""],
        ["if (!isIe8orLower && !navigator.userAgent.match(/Opera Mini/i)) {", ""],
        ['document.getElementsByTagName("body")[0].className += " can-fontface";', ""],
        ["}", ""],
        ["XS", ""],
        ["SM", ""],
        ["MD", ""],
        ["LG", ""],
        ["var bar_data = {", ""],
        [
            '"apiUrl": "http://voa.pangea-cms.com/publisher/zh-CN/api/frontend/itemdata",',
            "",
        ],
        ['"apiId": "3682842",', ""],
        ['"apiType": "1",', ""],
        ['"isEmbedded": "0",', ""],
        ['"cookieName": "cmsLoggedIn",', ""],
        ['"cookieDomain": "www.voachinese.com"', ""],
        ["};", ""],
    ]  # noqa
    list0 = sep_chinese(pagevoa1)
    LOGGER.debug("text: %s", pagevoa1)
    LOGGER.debug(" sep_chinese output: %s", list0)
    assert exp1 == list0
    # return list0

def xxtest_voadual():
    """
    test_voadual D:\dl\Dropbox\mat-dir\snippets-mat\pyqt\Sandbox\neualignerv002\voa_dual.txt"""  # noqa
    filepath = r"D:\dl\Dropbox\mat-dir\snippets-mat\pyqt\Sandbox\neualignerv002\voa_dual.txt"  # noqa
    text = open(
        filepath, "r", encoding=chardet_file(filepath, 20000), errors="ignore"
    ).read()  # NOQA
    tabdata = sep_chinese(text)

    assert 17 == len(tabdata)

    assert tabdata[0], ["" == "from test"]

    exp = [
        "奥巴马总统星期三在他最后一次白宫记者会上，努力让对政府换届感到担忧的美国民众放心。他说：“我相信这个国家。我相信美国人民。我相信人们身上的善多于恶。”",
        "Obama Says US 'Is Going to Be OK'",
    ]  # NOQA

    assert exp == tabdata[9]

if __name__ == "__main__":
    pass
    # my_setup()
    # test_minitext()


from archives.models import Link
from django.conf import settings

def global_site_context(request):
    links = Link.objects.all()
    return {
        'website': settings.SITE,
        'view': {
            'name': request.resolver_match.view_name
        },
        'links': links
    }


from aiogram import types
from aiogram.dispatcher import FSMContext
from aiogram.types import CallbackQuery

from handlers.users.services import get_location, get_address
from keyboards.inline.start_inline_keyboards import restaurant_murk_up
from loader import dp
from states.location import LocationState

URL = {
    'bk': 'https://burger-king.by/',
    'mak': 'https://mcdonalds.by/',
    'dodo': 'https://dodopizza.by/',
}

@dp.message_handler(state="*", content_types=types.ContentTypes.LOCATION)
async def location_button(message: types.Message, state: FSMContext):
    """ Handler of default button get location """

    await state.reset_state()
    latitude = message.location.latitude
    longitude = message.location.longitude
    await LocationState.Location.set()
    await state.update_data(
        longitude=longitude,
        latitude=latitude
    )
    address = await get_address(longitude=longitude, latitude=latitude)
    await message.answer(text=f'Ты в городе {address[1]}', reply_markup=restaurant_murk_up)

@dp.callback_query_handler(text='mak', state=LocationState.Location)
async def mak_callback(call: CallbackQuery, state: FSMContext):
    """ Handel of callback mak """

    data = await state.get_data()
    location = await get_location(longitude=data['longitude'], latitude=data['latitude'], name='Макдональдс')
    if location:
        await dp.bot.send_message(chat_id=call.from_user.id, text=URL['mak'])
        await dp.bot.send_location(chat_id=call.from_user.id, longitude=location[0], latitude=location[1])
    else:
        await dp.bot.send_message(chat_id=call.from_user.id, text='В вашем регионе нет макдональдсов(')

@dp.callback_query_handler(text='bk', state=LocationState.Location)
async def bk_callback(call: CallbackQuery, state: FSMContext):
    """ Handel of callback bk """

    data = await state.get_data()
    location = await get_location(longitude=data['longitude'], latitude=data['latitude'], name='Бургер Кинг')
    if location:
        await dp.bot.send_message(chat_id=call.from_user.id, text=URL['bk'])
        await dp.bot.send_location(chat_id=call.from_user.id, longitude=location[0], latitude=location[1])
    else:
        await dp.bot.send_message(chat_id=call.from_user.id, text='В вашем регионе нет Бургер Кинга(')

@dp.callback_query_handler(text='dodo', state=LocationState.Location)
async def dodo_callback(call: CallbackQuery, state: FSMContext):
    """ Handel of callback dodo """

    data = await state.get_data()
    location = await get_location(longitude=data['longitude'], latitude=data['latitude'], name='Додо Пицца')
    if location:
        await dp.bot.send_message(chat_id=call.from_user.id, text=URL['dodo'])
        await dp.bot.send_location(chat_id=call.from_user.id, longitude=location[0], latitude=location[1])
    else:
        await dp.bot.send_message(chat_id=call.from_user.id, text='В вашем регионе нет Додо Пиццы(')