"""File that defines the scraper to parse books' rating from 'lirtes.ru'"""

from bs4 import BeautifulSoup

import requests
import os
import csv

class Scraper:
    def get_files(self):
        """Get files from corpus"""
        # Changing directory to corpus location
        if "/rating-scraper" in os.path.abspath(os.curdir):
            os.chdir("..")
        list_of_files = os.listdir("corpus txt")
        return list_of_files

    def get_mark(self, book_name):
        """Get marks of a book from 'litres'"""
        search_url = "https://www.litres.ru/pages/rmd_search_arts/?q=" + book_name
        search_response = requests.get(search_url)
        soup = BeautifulSoup(search_response.text, "lxml")
        # Checking if the book has been found
        if soup.find("div", class_="ab-container b_interested__book") is not None:
            return "Not found"
        # Playing safe with the parser
        try:
            book_link = soup.find("a", class_="art-item__name__href").get("href")
        except AttributeError:
            return "Not found"
        book_url = "https://www.litres.ru" + book_link
        book_response = requests.get(book_url)
        soup = BeautifulSoup(book_response.text, "lxml")
        marks = soup.find_all("div", class_="rating-number bottomline-rating")
        all_votes = soup.find_all("div", class_="votes-count bottomline-rating-count")
        # Comparing names of a book
        if (
            book_name
            in soup.find("div", class_="biblio_book_name biblio-book__title-block").text
        ):
            pass
        else:
            return "COULD BE AN ERROR"
        # Checking for livelib marks
        if len(marks) > 1:
            litres_mark, livelib_mark = marks[0].text, marks[1].text
            litres_votes, livelib_votes = all_votes[0].text, all_votes[1].text
        else:
            litres_mark, livelib_mark = marks[0].text, "None"
            litres_votes, livelib_votes = all_votes[0].text, "None"
        return (
            litres_mark + "-" + litres_votes + "-" + livelib_mark + "-" + livelib_votes
        )

    def scrape_marks(self):
        """Write parsed data to csv-file"""
        with open("marks.csv", "a", newline="") as mark_file:
            writer = csv.writer(mark_file, quotechar='"')
            for book_name in self.get_files():
                # Tracing the book to be parsed
                print(book_name)
                # Example: |War and Peace - Leo Tolstoy.txt| -> War and Peace, Leo Tolstoy, txt
                if not len(book_name.split("-")) > 1:
                    writer.writerow("not found")
                    continue
                title_and_author = [
                    book_name.split("-")[0],
                    book_name.split("-")[1].split(".")[0],
                ]
                writer.writerow(
                    title_and_author + self.get_mark(book_name.split(".")[0]).split("-")
                )

    def filter_marks():
        """Cut unknown books"""
        # Changing directory to scraper location
        if not "/rating-scraper" in os.path.abspath(os.curdir):
            os.chdir(os.path.abspath("rating-scraper"))
        with open("evaluated_texts.csv", "a", newline="") as eval_file:
            with open("marks.csv", "a+", newline="") as mark_file:
                reader = csv.reader(mark_file, quotechar='"')
                writer = csv.writer(eval_file, quotechar='"')
                for row in reader:
                    if not "Not found" in row:
                        print(",".join(row))
                        writer.writerow(row)

    def check_marked(self) -> list:
        """Checks for possible parser errors"""
        if not "/rating-scraper" in os.path.abspath(os.curdir):
            os.chdir(os.path.abspath("src/rating-scraper"))
        with open("evaluated_texts.csv", "a+", newline="") as eval_file:
            reader = csv.reader(eval_file, quotechar='"')
            suspicion_lst = []
            for row in reader:
                if self.get_mark(row[0]) != "COULD BE AN ERROR":
                    continue
                else:
                    row = [str(i) for i in row]
                    suspicion_lst.append(" ".join(row))

        return suspicion_lst

    def find_path(self) -> str:
        """Gets the path to the file"""
        if not "/rating-scraper" in os.path.abspath(os.curdir):
            os.chdir(os.path.abspath("src/rating-scraper"))
        with open("evaluated_texts.csv", "r", newline="") as file:
            reader = csv.reader(file, quotechar='"')
            counter = 0
            list_of_files = []
            csv_path = []
            for row in reader:
                for current_file in sorted(self.get_files()):
                    if row[0] in current_file:
                        if current_file in list_of_files:
                            continue
                        counter += 1
                        list_of_files.append(current_file)
                        row.append(os.path.abspath(current_file))
                        csv_path.append(row)
                        break

        return csv_path

sc = Scraper()
# print(sc.get_mark("Война и мир"))


import matplotlib.pyplot as plt
import time
import random
mylist = []
numbers = []
sec = []

def mergeSort(arr):
    if len(arr) > 1:
        mid = len(arr)//2  # Finding the mid of the array
        L = arr[:mid]  # Dividing the array elements
        R = arr[mid:]  # into 2 halves

        mergeSort(L)  # Sorting the first half
        mergeSort(R)  # Sorting the second half

        i = j = k = 0

        # Copy data to temp arrays L[] and R[]
        while i < len(L) and j < len(R):
            if L[i] < R[j]:
                arr[k] = L[i]
                i += 1
            else:
                arr[k] = R[j]
                j += 1
            k += 1

        # Checking if any element was left
        while i < len(L):
            arr[k] = L[i]
            i += 1
            k += 1

        while j < len(R):
            arr[k] = R[j]
            j += 1
            k += 1
    return arr

for num in range(10, 100, 10):
    for i in range(0, num):
        x = random.randint(1, 100)
        mylist.append(x)
    start = time.perf_counter()
    mergeSort(mylist)
    end = time.perf_counter()
    numbers.append(num)
    sec.append(end-start)
# print(numbers)
# print(sec)
plt.xlabel("size of inputs")
plt.ylabel("time taken")
plt.title("graph for merge sort")
plt.plot(numbers, sec)
plt.show()


from ctypes import cast
import json
import dash_bootstrap_components as dbc
from dash import Dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
from monitor import check_site, card_result
from decouple import config

app = Dash('Monitoramento dos sites', external_stylesheets=[dbc.themes.BOOTSTRAP])

jumbotron = html.Div(
    dbc.Container(
        [
            html.H1("Dash de monitoramento", className="display-3"),
            html.P(
                "Use o json do projeto para registrar cada site a ser monitorado!",
                className="lead",
            ),
            html.Hr(className="my-2"),
            dbc.Badge("Disponivel", color="success", className="me-1"),
            dbc.Badge("Lento", color="warning", className="me-1"),
            dbc.Badge("Erro/Timeout", color="danger", className="me-1"),
            html.Hr(className="my-2"),
            dbc.Button('Verificar Sites', id='refresh'),
            dcc.Interval(
                id='interval-component',
                interval=60*1000, # in milliseconds
                n_intervals=0
            )
        ],
        fluid=True,
        className="py-3",
    ),
    className="p-3 mb-3 bg-light rounded-3",
)

@app.callback(
    Output('sites', 'children'),
    Input('refresh', 'n_clicks'),
    Input('interval-component', 'n_intervals')
)
def update_output(n_clicks, n_intervals):

    site = {}
    with open('sites.json', 'r') as file:
        sites = json.loads(file.read())

    results = []
    for site in sites['sites']:
        card = card_result(check_site(site))
        results.append(card)

    return results

app.layout = dbc.Container(
    [
        jumbotron,
        dbc.Row(id='sites')
    ]
)

app.run_server(debug=config('DEBUG', default=False, cast=bool))


name='abracadabra'
none_dup=[]
arrange=[]

#Removing duplicates
for i in range(len(name)):
    if name[i] not in none_dup:
        none_dup.append(name[i])

#Adding lookalikes
for i in range(len(none_dup)):
    for j in range(len(name)):
        if none_dup[i]==name[j]:
            arrange.append(name[j])

#Sorting answers in alphabetical order
arrange.sort()
print(''.join(arrange))


"""Support for Bbox binary sensors."""
from __future__ import annotations

import logging

from homeassistant.components.binary_sensor import (
    BinarySensorDeviceClass,
    BinarySensorEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import DOMAIN
from .entity import BboxEntity
from .helpers import BboxBinarySensorDescription, finditem

_LOGGER = logging.getLogger(__name__)

SENSOR_TYPES: tuple[BboxBinarySensorDescription, ...] = (
    BboxBinarySensorDescription(
        key="info.device.status",
        name="Link status",
        device_class=BinarySensorDeviceClass.CONNECTIVITY,
        value_fn=lambda x: x == 1,
    ),
)

async def async_setup_entry(
    hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
    """Set up sensor."""
    coordinator = hass.data[DOMAIN][entry.entry_id]

    entities = [
        BboxBinarySensor(coordinator, description) for description in SENSOR_TYPES
    ]

    async_add_entities(entities)

class BboxBinarySensor(BboxEntity, BinarySensorEntity):
    """Representation of a sensor."""

    @property
    def is_on(self):
        """Return sensor state."""
        _LOGGER.debug("%s %s", self.name, self.entity_description.key)
        data = finditem(self.coordinator.data, self.entity_description.key)
        if self.entity_description.value_fn is not None:
            return self.entity_description.value_fn(data)
        return data


# Pedir un número entre 0 y 9.999 y decir cuantas cifras tiene. Cuando el número exceda los límites emita un mensaje y finalice el programa

def contCifras():
    num = int(input("Ingrese un numero mayor que 0 y menor que 9999: "))

    if num < 0 or num > 9999:
        print("El número excede los límites.")
    else:
        cifras = len(str(num))
        print("El número tiene", cifras, "cifras.")

contCifras()


# -*- coding: utf-8 -*-
"""
Created on Thu Apr 23 18:58:08 2020

@author: ZLT
"""

import pca
import matplotlib
import matplotlib.pyplot as plt
from numpy import *

dataMat = pca.loadDataSet('testSet.txt')
print(dataMat)
lowDMat, reconMat = pca.pca(dataMat,1) #变一维
#lowDMat, reconMat = pca.pca(dataMat,2) #变二维

print(shape(lowDMat))
print(shape(reconMat))

fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(dataMat[:,0].flatten().A[0], dataMat[:,1].flatten().A[0],marker='^',s=90)
ax.scatter(reconMat[:,0].flatten().A[0], reconMat[:,1].flatten().A[0],marker='o',s=50,c='red')

plt.show()

dataMat = pca.loadDataSet('testSet3.txt')
print(dataMat)

from mpl_toolkits.mplot3d import Axes3D
fig=plt.figure()
ax1 = Axes3D(fig)
ax1.scatter3D(dataMat[:,0].flatten().A[0], dataMat[:,1].flatten().A[0],dataMat[:,2].flatten().A[0], cmap='Blues')  #绘制散点图
plt.show()

lowDMat2, reconMat2 = pca.pca(dataMat,2) #变二维
lowDMat, reconMat = pca.pca(lowDMat2,1) #变一维
print(shape(lowDMat))
print(shape(lowDMat2))
print(shape(reconMat))
print(shape(reconMat2))

fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(lowDMat2[:,0].flatten().A[0],lowDMat2[:,1].flatten().A[0],marker='^',s=90)
ax.scatter(reconMat[:,0].flatten().A[0], reconMat[:,1].flatten().A[0],marker='o',s=50,c='red')

plt.show()

print(reconMat)


'''
ProcessPoolExecutor is similar to the ThreadPoolExecutor.
'''

import time
from random import randint
from concurrent.futures import ProcessPoolExecutor

def processing(id, cnt):
    num = 0
    print(f"Processing Task {id}...")
    # Similate CPU Bound task
    while num <= cnt:
        num += 1
    print(f"Task {id} is Completed")

if __name__ == "__main__":

    sTime = time.perf_counter()

    with ProcessPoolExecutor(max_workers=2) as pool:
        print("assigning work")
        # we can use the `submit` function to assign the work to the pool of Processes.
        pool.submit(processing, 1, randint(50000000, 1000000000))
        pool.submit(processing, 2, randint(50000000, 1000000000))
        pool.submit(processing, 3, randint(50000000, 1000000000))

        # we can even use the `map` function
        # pool.map(processing, tasks)

    eTime = time.perf_counter()

    print(f"Took {eTime-sTime} seconds to finish")

'''
Output:
> python .\11.ProcessPools.py
assigning work
Processing Task 1...
Processing Task 2...
Task 1 is Completed
Processing Task 3...
Task 2 is Completed
Task 3 is Completed
Took 39.191284499829635 seconds to finish
>

Note: It only started two processes as we kept the `max_workers=2`
'''


class DFA:

    # Creates a new DFA with the alphabet alpha
    def __init__(self, alpha):
        self.current_state = None
        self.start_state = None
        self.alphabet = alpha
        self.accept_states = []
        # Connection list keeps track of connections between states
        # con_list[i] contains a list of tuples of (new_state, character) values for state i
        self.con_list = []

    def print_info(self):
        print("Total number of states: " + str(len(self.con_list)))
        print("Current state: " + str(self.current_state))
        print("Start state: " + str(self.start_state))
        print("Alphabet:")
        print(self.alphabet)
        print("Accept States:")
        print(self.accept_states)

    def get_num_states(self):
        return len(self.con_list)

    def is_valid_state(self, state):
        if state >= 0 and state < self.get_num_states():
            return True
        else:
            return False

    # Adds a new state to the connection matrix, by default is not an accept state
    def add_state(self, accept = False):
        # If first state, make start state by default
        if self.get_num_states() == 0:
            self.set_start_state(0)

        # Add a new entry to the bottom of the connection list
        self.con_list.append([])

        # Append accept status to list of accept states
        self.accept_states.append(accept)

    # Checks if the character given is in the alphabet of the DFA
    def is_valid_character(self, char):
        if char in self.alphabet:
            return True
        else:
            return False

    # Creates a new connection between old_state and new_state when character is entered
    def add_connection(self, old_state, new_state, character):
        if self.is_valid_state(old_state):
            if self.is_valid_state(new_state):
                if self.is_valid_character(character):
                    self.con_list[old_state].append((new_state, character))
                else:
                    print("Character is invalid: " + character)
            else:
                print("New state is invalid: " + str(new_state))
        else:
            print("Original state is invalid: " + str(old_state))

    # Checks if a DFA has the correct number of connections to be usable
    def is_valid_DFA(self):
        # Each state must have a connection for each character in the alphabet
        for state in self.con_list:
            # Creates an empty set to hold characters of transitions for this state
            state_set = set()
            for conn in state:
                # Add the character from each transition
                state_set.add(conn[1])

            # Checks if number of connections = length of alphabet
            if len(state_set) != len(self.alphabet):
                print("DFA invalid, incorrect number of connections")
                return False

            # Checks if state_list is same as the alphabet set
            if state_set != set(self.alphabet):
                print("DFA invalid, not a connection for every alphabet character")
                return False

        # Check if DFA has start state set
        if self.start_state == None:
            print("DFA invalid, cannot find start state")
            return False

        # If all checks passed, return true
        return True

    # By default, start state is 0 but this will change it
    def set_start_state(self, state):
        self.start_state = state

    # Returns the next state given the current state and the next character input
    def find_next_state(self, char):
        current_transitions = self.con_list[self.current_state]
        i = 0
        for t in current_transitions:
            if t[1] == char:
                return i
            else:
                i += 1

        print("Could not find next state")
        return None

    # Transitions from current state to a new state depending on char
    def transition(self, char):
        next_state = self.find_next_state(char)
        self.current_state = self.con_list[self.current_state][next_state][0]

    # Checks if string only contains characters from alphabet
    def is_valid_string(self, string):
        for char in string:
            if char not in self.alphabet:
                print("Character " + char + " not in alphabet")
                return False
        return True

    # Runs the DFA with string as the input
    # Returns "accept" if string is accepted, "reject" otherwise
    # Verbose mode outputs info on each transition
    def run(self, string, verbose = False):
        if self.is_valid_DFA():
            if self.is_valid_string(string):
                self.current_state = self.start_state
                for char in string:
                    # Tracking previous state for verbos mode
                    last_state = self.current_state
                    self.transition(char)
                    # Output verbose mode info
                    if verbose:
                        print("Old state: " + str(last_state) + ", new state: " + str(self.current_state) + ", character: " + str(char))

                # Check if final state is accept state
                if self.accept_states[self.current_state]:
                    result = "accept"
                else:
                    result = "reject"
            else:
                result = "Error in string"
        else:
            result = "Error in DFA"

        # Set current state back to None as the DFA finishes
        self.current_state = None
        return "Input string: " + string + " Result: " + result

if __name__ == "__main__":
    alphabet = ("a", "b")
    test = DFA(alphabet)
    test.add_state()
    test.add_state()
    test.add_state()
    test.add_state(True)
    test.add_state()

    test.add_connection(0, 1, "a")
    test.add_connection(0, 4, "b")
    test.add_connection(1, 4, "a")
    test.add_connection(1, 2, "b")
    test.add_connection(2, 3, "a")
    test.add_connection(2, 4, "b")
    test.add_connection(3, 3, "a")
    test.add_connection(3, 3, "b")
    test.add_connection(4, 4, "a")
    test.add_connection(4, 4, "b")

    print(test.run("ababbb"))
    test.print_info()


# https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array

from typing import List
import unittest
from dataclasses import dataclass

class Solution:
    def findDisappearedNumbers(self, nums: List[int]) -> List[int]:

        seen = set(nums)
        result = []
        n = len(nums)

        for i in range(1, n + 1):
            if i not in seen:
                result.append(i)

        return result

@dataclass
class TestCase:
    nums: List[int]
    expectation: List[int]

class TestSolution(unittest.TestCase):
    def test_solution(self):
        solution = Solution()

        tests = [
            TestCase([4, 3, 2, 7, 8, 2, 3, 1], [5, 6]),
            TestCase([1, 1], [2])
        ]

        for t in tests:
            with self.subTest(t):
                self.assertEqual(solution.findDisappearedNumbers(t.nums), t.expectation)


sum = 0
arr = list(map(int, input().split()))

for i in range(1, 1 << len(arr)): # 부분 갯수 수만큼 만들어주기위해 2**n 번 합니다. 어차피 0 은 아님요 ( 그래서 1부터임)
    sum = 0 # 각 부분집합 합을 0이라고 초기화하기
    for j in range(len(arr)): # i를 이진법으로 하고 1의 위치를 알아보기 위해 for를 돌립니다.
        if i & (1<<j) : # 마 니 j 번째에 1 있나?
            sum += arr[j] #잇으면 합해라

    if sum == 10: #그 i번째 부분집합의 합이 10인가?
        for j in range(len(arr)): #그면 뽑기위해 다시 부분집합 다 만드세여
            if i & (1 << j): # 마 니 j번째에 1 잇나?
                print(arr[j], end= " ") #있으면 나와라

        print() # 한 부분집합이 끝나면 엔터 드감


# coding=utf-8

# 双指针头尾同时开始遍历

class Solution(object):
    def isPalindrome(self, s):
        """
        :type s: str
        :rtype: bool
        """
        st = 0
        ed = len(s) - 1
        while st < ed:
            while st <= ed and not s[st].isalpha() and not s[st].isdigit(): st += 1    # st <= ed必须写在前面
            while st <= ed and not s[ed].isalpha() and not s[ed].isdigit(): ed -= 1
            if st >= ed: break
            if s[st].lower() != s[ed].lower(): return False   # 所有string值都可以用于lower函数，不光是字母
            st += 1
            ed -= 1

        return True


#!/usr/bin/python3
# -*- coding: UTF-8 -*-
#-----------------------------------------------------------------------------------------------------------------------

import sys, interrupt_names_teensy_3_6

#-----------------------------------------------------------------------------------------------------------------------

def ENDC () :
  return '\033[0m'

#-----------------------------------------------------------------------------------------------------------------------

def RED () :
  return '\033[91m'

#-----------------------------------------------------------------------------------------------------------------------

def BOLD () :
  return '\033[1m'

#-----------------------------------------------------------------------------------------------------------------------

def BOLD_RED () :
  return BOLD () + RED ()

#-----------------------------------------------------------------------------------------------------------------------

def asSeparator () :
  return "@" + ("-" * 119) + "\n"

#-----------------------------------------------------------------------------------------------------------------------

def cppSeparator () :
  return "//" + ("-" * 118) + "\n"

#-----------------------------------------------------------------------------------------------------------------------

def generateSVChandler ():
  sFile = asSeparator ()
  sFile += "@                 S V C    H A N D L E R    ( D O U B L E    S T A C K    M O D E )\n"
  sFile += asSeparator ()
  sFile += "@\n"
  sFile += "@          PSP+32 -> |                            |\n"
  sFile += "@                    |----------------------------| \\\n"
  sFile += "@          PSP+28 -> | xPSR                       |  |\n"
  sFile += "@                    |----------------------------|  |\n"
  sFile += "@          PSP+24 -> | PC (after SVC instruction) |  |\n"
  sFile += "@                    |----------------------------|  |\n"
  sFile += "@          PSP+20 -> | LR                         |  |\n"
  sFile += "@                    |----------------------------|  |\n"
  sFile += "@          PSP+16 -> | R12                        |  |  Saved by interrupt response\n"
  sFile += "@                    |----------------------------|  |\n"
  sFile += "@          PSP+12 -> | R3                         |  |\n"
  sFile += "@                    |----------------------------|  |\n"
  sFile += "@          PSP+8  -> | R2                         |  |\n"
  sFile += "@                    |----------------------------|  |\n"
  sFile += "@          PSP+4  -> | R1                         |  |\n"
  sFile += "@                    |----------------------------|  |\n"
  sFile += "@     /--- PSP ----> | R0                         |  |\n"
  sFile += "@     |              |----------------------------| /\n"
  sFile += "@     |              |                            |\n"
  sFile += "@     |\n"
  sFile += "@     |                          ---------------------*\n"
  sFile += "@     |                                          | LR return code      | +36 [ 9]\n"
  sFile += "@     |                          ---------------------*\n"
  sFile += "@     \----------------------------------------- | R13 (PSP)           | +32 [ 8]\n"
  sFile += "@                                ---------------------*\n"
  sFile += "@                                                | R11                 | +28 [ 7]\n"
  sFile += "@                                ---------------------*\n"
  sFile += "@                                                | R10                 | +24 [ 6]\n"
  sFile += "@                                ---------------------*\n"
  sFile += "@                                                | R9                  | +20 [ 5]\n"
  sFile += "@                                ---------------------*\n"
  sFile += "@                                                | R8                  | +16 [ 4]\n"
  sFile += "@                                ---------------------*\n"
  sFile += "@                                                | R7                  | +12 [ 3]\n"
  sFile += "@                                ---------------------*\n"
  sFile += "@                                                | R6                  | + 8 [ 2]\n"
  sFile += "@                                ---------------------*\n"
  sFile += "@                                                | R5                  | + 4 [ 1]\n"
  sFile += "@  *------------------------------------*        *---------------------*\n"
  sFile += "@  | var.running.task.control.block.ptr +------> | R4                  | + 0 [ 0]\n"
  sFile += "@  *------------------------------------*        *---------------------*\n"
  sFile += "@\n"
  sFile += asSeparator () + "\n"
  sFile += "	.section	.bss.var.background.task.context, \"aw\", %nobits\n"
  sFile += "  .align	  2\n\n"
  sFile += "var.background.task.context:\n"
  sFile += "  .space  4\n\n"
  sFile += asSeparator () + "\n"
  sFile += "	.section	.text.interrupt.SVC, \"ax\", %progbits\n\n"
  sFile += "  .global interrupt.SVC\n"
  sFile += "  .type interrupt.SVC, %function\n\n"
  sFile += "interrupt.SVC:\n"
  sFile += "@----------------------------------------- Save preserved registers\n"
  sFile += "  push  {r4, lr}\n"
  sFile += "@----------------------------------------- R4 <- thread SP\n"
  sFile += "  mrs   r4, psp\n"
  sFile += "@----------------------------------------- Restore R0, R1, R2 and R3 from saved stack\n"
  sFile += "  ldmia r4!, {r0, r1, r2, r3}       @ R4 incremented by 16\n"
  sFile += "@----------------------------------------- R4 <- Address of SVC instruction\n"
  sFile += "  ldr   r4, [r4, #8]                @ 8 : 2 stacked registers before saved PC\n"
  sFile += "@----------------------------------------- R12 <- bits 0-7 of SVC instruction\n"
  sFile += "  ldrb  r12, [r4, #-2]              @ R12 is service call index\n"
  sFile += "@----------------------------------------- R4 <- address of dispatcher table\n"
  sFile += "  ldr   r4, =svc.dispatcher.table\n"
  sFile += "@----------------------------------------- R12 <- address of routine to call\n"
  sFile += "  ldr   r12, [r4, r12, lsl #2]      @ R12 = R4 + (R12 << 2)\n"
  sFile += "@----------------------------------------- R4 <- calling task context\n"
  sFile += "  ldr   r4, =var.running.task.control.block.ptr\n"
  sFile += "  ldr   r4, [r4]\n"
  sFile += "@----------------------------------------- Call service routine\n"
  sFile += "  blx   r12                         @ R4:calling task context address\n"
  sFile += "@--- Continues in sequence to handle.context.switch\n\n"
  sFile += asSeparator ()
  sFile += "@\n"
  sFile += "@                 H A N D L E    C O N T E X T    S W I T C H    ( D O U B L E    S T A C K    M O D E )\n"
  sFile += "@\n"
  sFile += "@  On entry:\n"
  sFile += "@    - R4 contains the runnning task save context address,\n"
  sFile += "@    - R4 and LR of running task have been pushed on handler stack.\n"
  sFile += "@\n"
  sFile += asSeparator () + "\n"
  sFile += "handle.context.switch:\n"
  sFile += "@----------------------------------------- Select task to run\n"
  sFile += "  bl    kernel.select.task.to.run\n"
  sFile += "@----------------------------------------- R0 <- calling task context, R1 <- new task context\n"
  sFile += "  ldr   r1, =var.running.task.control.block.ptr\n"
  sFile += "  mov   r0, r4\n"
  sFile += "  ldr   r1, [r1]\n"
  sFile += "@----------------------------------------- Restore preserved registers\n"
  sFile += "  pop   {r4, lr}\n"
  sFile += "@----------------------------------------- Running task did change ?\n"
  sFile += "  cmp   r0, r1  @ R0:calling task context, R1:new task context\n"
  sFile += "  bne   running.state.did.change\n"
  sFile += "  bx    lr  @ No change\n"
  sFile += "@----------------------------------------- Save context of preempted task\n"
  sFile += "running.state.did.change:\n"
  sFile += "  mrs   r12, psp\n"
  sFile += "  cbz   r0, save.background.task.context\n"
  sFile += "@--- Save registers r4 to r11, PSP (stored in R12), LR\n"
  sFile += "  stmia r0, {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}\n"
  sFile += "  b     perform.restore.context\n"
  sFile += "save.background.task.context:\n"
  sFile += "  ldr   r2, =var.background.task.context\n"
  sFile += "  str   r12, [r2]\n"
  sFile += "@----------------------------------------- Restore context of activated task\n"
  sFile += "perform.restore.context:\n"
  sFile += "  cbz   r1, restore.background.task.context\n"
  sFile += "  ldmia r1, {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}\n"
  sFile += "  msr   psp, r12\n"
  sFile += "  bx    lr\n"
  sFile += "@----------------------------------------- Restore background task context\n"
  sFile += "restore.background.task.context:\n"
  sFile += "  ldr   r2, =var.background.task.context\n"
  sFile += "  ldr   r2, [r2]\n"
  sFile += "  msr   psp, r2\n"
  sFile += "  bx    lr\n\n"
  return sFile

#-----------------------------------------------------------------------------------------------------------------------

def generateBreakpointHandler () :
  sFile = asSeparator ()
  sFile += "@\n"
  sFile += "@                 B K P T    H A N D L E R    ( D O U B L E    S T A C K    M O D E )\n"
  sFile += "@\n"
  sFile += asSeparator ()
  sFile += "@\n"
  sFile += "@                    |                            |\n"
  sFile += "@          PSP+32 -> |----------------------------| \\\n"
  sFile += "@                    | xPSR                       |  |\n"
  sFile += "@          PSP+28 -> |----------------------------|  |\n"
  sFile += "@                    | PC (BKPT instruction)      |  |\n"
  sFile += "@          PSP+24 -> |----------------------------|  |\n"
  sFile += "@                    | LR                         |  |\n"
  sFile += "@          PSP+20 -> |----------------------------|  |\n"
  sFile += "@                    | R12                        |  |  Saved by interrupt response\n"
  sFile += "@          PSP+16 -> |----------------------------|  |\n"
  sFile += "@                    | R3                         |  |\n"
  sFile += "@          PSP+12 -> |----------------------------|  |\n"
  sFile += "@                    | R2                         |  |\n"
  sFile += "@          PSP+8  -> |----------------------------|  |\n"
  sFile += "@                    | R1                         |  |\n"
  sFile += "@          PSP+4  -> |----------------------------|  |\n"
  sFile += "@                    | R0                         |  |\n"
  sFile += "@          PSP    -> |----------------------------| /\n"
  sFile += "@\n"
  sFile += asSeparator () + "\n"
  sFile += "  .section  .text.interrupt.DebugMonitor, \"ax\", %progbits\n\n"
  sFile += "  .global interrupt.DebugMonitor\n"
  sFile += "  .type interrupt.DebugMonitor, %function\n\n"
  sFile += "interrupt.DebugMonitor:\n"
  sFile += "@--------------------- Save preserved registers\n"
  sFile += "  push  {r5, lr}\n"
  sFile += "@--------------------- R5 <- thread SP\n"
  sFile += "  mrs   r5, psp\n"
  sFile += "  ldmia r5, {r0, r1, r2, r3}\n"
  sFile += "@--------------------- LR <- Address of BKPT instruction\n"
  sFile += "  ldr   lr, [r5, #24]     @ 24 : 6 stacked registers before saved PC\n"
  sFile += "@--------------------- Set return address to instruction following BKPT\n"
  sFile += "@  adds  lr, #2\n"
  sFile += "@  str   lr, [r5, #24]\n"
  sFile += "@--------------------- R12 <- address of dispatcher\n"
  sFile += "  ldr   r12, =section.dispatcher.table\n"
  sFile += "@--------------------- LR <- bits 0-7 of BKPT instruction\n"
  sFile += "  ldrb  lr, [lr, #-2]            @ LR is service call index\n"
  sFile += "@--------------------- r12 <- address of routine to call\n"
  sFile += "  ldr   r12, [r12, lr, lsl #2]   @ R12 = [R12 + LR * 4]\n"
  sFile += "@--------------------- Call service routine\n"
  sFile += "  blx   r12\n"
  sFile += "@--------------------- Set return code (from R0 to R3) in stacked registers\n"
  sFile += "  stmia r5!, {r0, r1, r2, r3}\n"
  sFile += "@--------------------- Restore preserved registers, return from interrupt\n"
  sFile += "  pop   {r5, pc}\n\n"
  return sFile

#-----------------------------------------------------------------------------------------------------------------------

def generateBreakpointSection (sectionName, idx):
  sFile  = asSeparator () + "\n"
  sFile += "  .section .text." + section + ", \"ax\", %progbits\n"
  sFile += "  .global " + section +"\n"
  sFile += "  .align 1\n"
  sFile += "  .type " + section +", %function\n\n"
  sFile += section +":\n"
  sFile += "  .fnstart\n"
  sFile += "  mrs  r12, IPSR @ r12 <- 0x??????00 in thread mode, 0x??????nn, nn ≠ 0 in handler mode\n"
  sFile += "  ands r12, #255\n"
  sFile += "  bne  section." + section + " @ in handler mode, call implementation routine directly\n"
  sFile += "  bkpt #" + str (idx) + "\n"
  sFile += "  bx   lr\n\n"
  sFile += ".Lfunc_end_" + section +":\n"
  sFile += "  .size " + section +", .Lfunc_end_" + section +" - " + section +"\n"
  sFile += "  .cantunwind\n"
  sFile += "  .fnend\n\n"
  return sFile

#-----------------------------------------------------------------------------------------------------------------------

def generateSoftwareInterruptandler () :
  sFile = asSeparator ()
  sFile += "@\n"
  sFile += "@     SECTIONS: Software Interrupt Handler (two stack mode)\n"
  sFile += "@\n"
  sFile += asSeparator ()
  sFile += "@\n"
  sFile += "@                    |                            |\n"
  sFile += "@          PSP+32 -> |----------------------------| \\\n"
  sFile += "@                    | xPSR                       |  |\n"
  sFile += "@          PSP+28 -> |----------------------------|  |\n"
  sFile += "@                    | PC                         |  |\n"
  sFile += "@          PSP+24 -> |----------------------------|  |\n"
  sFile += "@                    | LR                         |  |\n"
  sFile += "@          PSP+20 -> |----------------------------|  |\n"
  sFile += "@                    | R12                        |  |  Saved by interrupt response\n"
  sFile += "@          PSP+16 -> |----------------------------|  |\n"
  sFile += "@                    | R3                         |  |\n"
  sFile += "@          PSP+12 -> |----------------------------|  |\n"
  sFile += "@                    | R2                         |  |\n"
  sFile += "@          PSP+8  -> |----------------------------|  |\n"
  sFile += "@                    | R1                         |  |\n"
  sFile += "@          PSP+4  -> |----------------------------|  |\n"
  sFile += "@                    | R0                         |  |\n"
  sFile += "@          PSP    -> |----------------------------| /\n"
  sFile += "@\n"
  sFile += asSeparator () + "\n"
  sFile += "  .section  .text.interrupt.SWINT, \"ax\", %progbits\n\n"
  sFile += "  .global interrupt.SWINT\n"
  sFile += "  .type interrupt.SWINT, %function\n\n"
  sFile += "interrupt.SWINT:\n"
  sFile += "@--------------------- Save preserved registers\n"
  sFile += "  push  {r5, lr}\n"
  sFile += "@--------------------- R5 <- thread SP\n"
  sFile += "  mrs   r5, psp\n"
  sFile += "@--------------------- Restore R0, R1, R2 and R3 from saved stack\n"
  sFile += "  ldmia r5, {r0, r1, r2, r3}\n"
  sFile += "@--------------------- R12 <- Address section routine\n"
  sFile += "  ldr   r12, [r5, #16]     @ 16 : 4 stacked registers before saved R12\n"
  sFile += "@--------------------- Call section routine\n"
  sFile += "  blx   r12\n"
  sFile += "@--------------------- Set return code (from R0 to R3) in stacked registers\n"
  sFile += "  stmia r5!, {r0, r1, r2, r3}    @ R5 is thread SP\n"
  sFile += "@--------------------- Set R12 stacked register to 0\n"
  sFile += "  mov   r0, #0\n"
  sFile += "  str   r0, [r5]\n"
  sFile += "@--------------------- Restore preserved registers, return from interrupt\n"
  sFile += "  pop   {r5, pc}\n\n"
  sFile += asSeparator () + "\n"
  sFile += "  .section  .text.direct.call.or.call.software.interrupt, \"ax\", %progbits\n\n"
  sFile += "  .type direct.call.or.call.software.interrupt, %function\n\n"
  sFile += "direct.call.or.call.software.interrupt: @ R12 contains the address of section implementation function\n"
  sFile += "@--------------------- Save preserved registers\n"
  sFile += "  push {r6, r7}\n"
  sFile += "  mrs  r6, IPSR          @ IPSR[8...0] ≠ 0 in handler mode, = 0 in thread mode\n"
  sFile += "  mov  r7, #511\n"
  sFile += "  tst  r6, r7\n"
  sFile += "  bne  direct.call\n"
  sFile += "@--------------------- Software interrupt\n"
  sFile += "  ldr  r6, = 0xE000EF00  @ Address of STIR control register\n"
  sFile += "  movs r7, # (80 - 16)   @ Software Interrupt has number #80\n"
  sFile += "  str  r7, [r6]          @ Generate Software Interrupt\n"
  sFile += "@--------------------- Wait for the exception is carried out\n"
  sFile += "wait.software.interrupt.done: @ R12 is reset by interrupt handler\n"
  sFile += "  cmp  r12, #0\n"
  sFile += "  bne  wait.software.interrupt.done\n"
  sFile += "@--------------------- Restore preserved registers\n"
  sFile += "  pop  {r6, r7}\n"
  sFile += "  bx   lr\n"
  sFile += "@--------------------- Direct call\n"
  sFile += "direct.call:\n"
  sFile += "  pop  {r6, r7}\n"
  sFile += "  bx   r12              @ in handler mode, call implementation routine directly\n\n"
  return sFile

#-----------------------------------------------------------------------------------------------------------------------

def generateSoftwareInterruptSection (sectionName, idx):
  sFile  = asSeparator () + "\n"
  sFile += "  .section .text." + sectionName + ", \"ax\", %progbits\n"
  sFile += "  .global " + sectionName +"\n"
  sFile += "  .align 1\n"
  sFile += "  .type " + sectionName +", %function\n\n"
  sFile += sectionName +":\n"
  sFile += "  .fnstart\n"
  sFile += "  ldr  r12, =section." + sectionName + "\n"
  sFile += "  b    direct.call.or.call.software.interrupt\n\n"
  sFile += ".Lfunc_end_" + sectionName +":\n"
  sFile += "  .size " + sectionName +", .Lfunc_end_" + sectionName +" - " + sectionName +"\n"
  sFile += "  .cantunwind\n"
  sFile += "  .fnend\n\n"
  return sFile

#-----------------------------------------------------------------------------------------------------------------------

def generateCppForBreakpointSection ():
  s = "#include \"all-headers.h\"\n\n"
  s += cppSeparator () + "\n"
  s += "static void enableDebugMonitorInterruption (BOOT_MODE) {\n"
  s += "//--- Enable DebugMonitor interrupt\n"
  s += "  #define DEMCR (* ((volatile uint32_t *) 0xE000EDFC))\n"
  s += "  DEMCR |= (1 << 16) ; // Set MON_EN\n"
  s += "}\n\n"
  s += cppSeparator () + "\n"
  s += "MACRO_BOOT_ROUTINE (enableDebugMonitorInterruption) ;\n\n"
  s += cppSeparator ()
  return s

#-----------------------------------------------------------------------------------------------------------------------

def generateCppForSoftwareInterruptSection ():
  s = "#include \"all-headers.h\"\n\n"
  s += cppSeparator () + "\n"
  s += "static void enableSoftwareInterrupt (BOOT_MODE) {\n"
  s += "//--- Enable software interrupt\n"
  s += "  NVIC_ENABLE_IRQ (ISRSlot::SWINT) ;\n"
  s += "//--- Make STIR register accessible in unprivileged mode\n"
  s += "  #define CCR (* ((volatile uint32_t *) 0xE000ED14))\n"
  s += "  CCR |= (1 << 1) ;\n"
  s += "}\n\n"
  s += cppSeparator () + "\n"
  s += "MACRO_BOOT_ROUTINE (enableSoftwareInterrupt) ;\n\n"
  s += cppSeparator ()
  return s

#-----------------------------------------------------------------------------------------------------------------------

def generateDisableInterruptSection (sectionName):
  sFile  = asSeparator ()
  sFile += "@   SECTION - " + sectionName + "\n"
  sFile += asSeparator () + "\n"
  sFile += "  .section .text." + sectionName + ", \"ax\", %progbits\n"
  sFile += "  .global " + sectionName +"\n"
  sFile += "  .align 1\n"
  sFile += "  .type " + sectionName +", %function\n\n"
  sFile += sectionName +":\n"
  sFile += "  .fnstart\n"
  sFile += "@--- Save preserved registers\n"
  sFile += "  push  {r6, lr}\n"
  sFile += "@--- Save interrupt enabled state\n"
  sFile += "  mrs   r6, PRIMASK\n"
  sFile += "@--- Disable interrupt\n"
  sFile += "  cpsid i\n"
  sFile += "@--- Call section, interrupts disabled\n"
  sFile += "  bl    section." + sectionName + "\n"
  sFile += "@--- Restore interrupt state\n"
  sFile += "  msr   PRIMASK, r6\n"
  sFile += "@--- Restore preserved registers and return\n"
  sFile += "  pop   {r6, pc}\n\n"
  sFile += ".Lfunc_end_" + sectionName +":\n"
  sFile += "  .size " + sectionName +", .Lfunc_end_" + sectionName +" - " + sectionName +"\n"
  sFile += "  .cantunwind\n"
  sFile += "  .fnend\n\n"
  return sFile

#-----------------------------------------------------------------------------------------------------------------------
#    ENTRY POINT
#-----------------------------------------------------------------------------------------------------------------------

#------------------------------ Interrupt dictionary
interruptDictionary = interrupt_names_teensy_3_6.interruptNames ()
# print ("Dest " + destinationFile)
#------------------------------ Assembly destination file
destinationCppFile = sys.argv [1]
# print ("Dest " + destinationAssemblerFile)
#------------------------------ Assembly destination file
destinationAssemblerFile = sys.argv [2]
# print ("Dest " + destinationAssemblerFile)
#------------------------------ Service scheme
serviceScheme = sys.argv [3]
#------------------------------ Section scheme
sectionScheme = sys.argv [4]
#------------------------------ Header files
headerFiles = []
for i in range (5, len (sys.argv)):
  headerFiles.append (sys.argv [i])
#print headerFiles
#------------------------------ Destination file string
cppFile = ""
sFile  = "  .syntax unified\n"
sFile += "  .cpu cortex-m4\n"
sFile += "  .thumb\n\n"
#------------------------------ Explore header files
interruptServiceList = []
interruptSectionList = []
boolServiceSet = set ()
serviceList = []
sectionList = []
for header in headerFiles:
  with open (header) as f:
    for line in f:
      splitStr = line.strip ().split ("//$interrupt-section ")
      if len (splitStr) == 2 :
        interruptName = splitStr [1].strip ()
        if interruptName in interruptDictionary :
          interruptSectionList.append (interruptName)
          del interruptDictionary [interruptName]
        else:
          print (BOLD_RED () + "Error, interrupt '" + interruptName + "' does not exist, or is already assigned." + ENDC ())
          sys.exit (1)
      splitStr = line.strip ().split ("//$interrupt-service ")
      if len (splitStr) == 2 :
        interruptName = splitStr [1].strip ()
        if interruptName in interruptDictionary :
          interruptServiceList.append (interruptName)
          del interruptDictionary [interruptName]
        else:
          print (BOLD_RED () + "Error, interrupt '" + interruptName + "' does not exist, or is already assigned." + ENDC ())
          sys.exit (1)
      splitStr = line.strip ().split ("//$service ")
      if len (splitStr) == 2 :
        serviceName = splitStr [1].strip ()
        serviceList.append (serviceName)
      splitStr = line.strip ().split ("//$bool-service ")
      if len (splitStr) == 2 :
        serviceName = splitStr [1].strip ()
        serviceList.append (serviceName)
        boolServiceSet.add (serviceName)
      splitStr = line.strip ().split ("//$section ")
      if len (splitStr) == 2 :
        sectionName = splitStr [1].strip ()
        sectionList.append (sectionName)
#------------------------------ Has service ?
if (len (serviceList) > 0) and (serviceScheme == "") :
  print (BOLD_RED ()
         + "As the project defines service(s), the makefile.json file should have a \"SERVICE-SCHEME\" "
         + "entry (asoociated value: \"svc\")"
         +  ENDC ())
  sys.exit (1)
#------------------------------ Has sections ?
if (len (sectionList) > 0) and (sectionScheme == "") :
  print (BOLD_RED ()
         + "As the project defines section(s), the makefile.json file should have a \"SECTION-SCHEME\" "
         + "entry (possible associated value: \"disableInterrupt\", \"bkpt\", \"swint\")"
         +  ENDC ())
  sys.exit (1)
#------------------------------ Services
if serviceScheme == "svc" :
  sFile += generateSVChandler ()
  del interruptDictionary ["SVC"]
  sFile += asSeparator ()
  sFile += "@   SERVICES\n"
  idx = 1
  for service in serviceList :
    sFile += asSeparator () + "\n"
    sFile += "  .section .text." + service + ", \"ax\", %progbits\n"
    sFile += "  .global " + service +"\n"
    sFile += "  .align 1\n"
    sFile += "  .type " + service +", %function\n\n"
    sFile += service +":\n"
    sFile += "  .fnstart\n"
    sFile += "  svc #" + str (idx) + "\n"
    if service in boolServiceSet :
      sFile += "  b   get.user.result\n\n"
    else:
      sFile += "  bx  lr\n\n"
    sFile += ".Lfunc_end_" + service +":\n"
    sFile += "  .size " + service +", .Lfunc_end_" + service +" - " + service +"\n"
    sFile += "  .cantunwind\n"
    sFile += "  .fnend\n\n"
    idx += 1
  sFile += asSeparator ()
  sFile += "@    SERVICE DISPATCHER TABLE\n"
  sFile += asSeparator () + "\n"
  sFile += "  .align   2\n"
  sFile += "  .global  svc.dispatcher.table\n\n"
  sFile += "svc.dispatcher.table:\n"
  sFile += "  .word start.phase2 @ 0\n"
  idx = 1
  for service in serviceList :
    sFile += "  .word service." + service + " @ " + str (idx) + "\n"
    idx += 1
  sFile += "\n"
#------------------------------ Generate section handler
if sectionScheme == "bkpt" :
  cppFile += generateCppForBreakpointSection ()
  sFile += generateBreakpointHandler ()
  del interruptDictionary ["DebugMonitor"]
  sFile += asSeparator ()
  sFile += "@   SECTIONS\n"
  idx = 0
  for section in sectionList :
    sFile += generateBreakpointSection (section, idx)
    idx += 1
  sFile += asSeparator ()
  sFile += "@    SECTION DISPATCHER TABLE\n"
  sFile += asSeparator () + "\n"
  sFile += "  .global section.dispatcher.table\n\n"
  sFile += "section.dispatcher.table:\n"
  idx = 0
  for section in sectionList :
    sFile += "  .word section." + section + " @ " + str (idx) + "\n"
    idx += 1
  sFile += "\n"
elif sectionScheme == "swint" :
  cppFile += generateCppForSoftwareInterruptSection ()
  sFile += generateSoftwareInterruptandler ()
  del interruptDictionary ["SWINT"]
  sFile += asSeparator ()
  sFile += "@   SECTIONS\n"
  idx = 0
  for section in sectionList :
    sFile += generateSoftwareInterruptSection (section, idx)
    idx += 1
elif sectionScheme == "disableInterrupt" :
  for section in sectionList :
    sFile += generateDisableInterruptSection (section)
elif len (sectionList) > 0 :
  print (BOLD_RED ()
         + "In the makefile.json file, the \"SECTION-SCHEME\" key has an invalid \"" + sectionScheme + "\" value; "
         + "(possible value: \"disableInterrupt\", \"swint\")"
         +  ENDC ())
  sys.exit (1)
#------------------------------ Interrupts as service
for interruptServiceName in interruptServiceList :
  sFile += asSeparator ()
  sFile += "@   INTERRUPT - SERVICE: " + interruptServiceName + "\n"
  sFile += asSeparator () + "\n"
  sFile += "  .section .text.interrupt." + interruptServiceName + ", \"ax\", %progbits\n\n"
  sFile += "  .align  1\n"
  sFile += "  .global interrupt." + interruptServiceName + "\n"
  sFile += "  .type interrupt." + interruptServiceName + ", %function\n\n"
  sFile += "interrupt." + interruptServiceName + ":\n"
  sFile += "@----------------------------------------- Save preserved registers\n"
  sFile += "  push  {r4, lr}\n"
  sFile += "@----------------------------------------- Activity led On\n"
  sFile += "  ldr   r0, =0x400FF084  @ Address of GPIOC_PSOR control register\n"
  sFile += "  movs  r1, # (1 << 5)   @ Port D13 is PORTC:5\n"
  sFile += "  str   r1, [r0]         @ turn on\n"
  sFile += "@----------------------------------------- R4 <- running task context\n"
  sFile += "  ldr   r4, =var.running.task.control.block.ptr\n"
  sFile += "  ldr   r4, [r4]\n"
  sFile += "@----------------------------------------- Call Interrupt handler\n"
  sFile += "  bl    interrupt.service." + interruptServiceName + "\n"
  sFile += "@----------------------------------------- Perform the context switch, if needed\n"
  sFile += "  b     handle.context.switch\n\n"
#------------------------------ Interrupts as section
for interruptSectionName in interruptSectionList :
  sFile += asSeparator ()
  sFile += "@   INTERRUPT - SECTION: " + interruptSectionName + "\n"
  sFile += asSeparator () + "\n"
  sFile += "  .section .text.interrupt." + interruptSectionName + ", \"ax\", %progbits\n\n"
  sFile += "  .align  1\n"
  sFile += "  .global interrupt." + interruptSectionName + "\n"
  sFile += "  .type interrupt." + interruptSectionName + ", %function\n\n"
  sFile += "interrupt." + interruptSectionName + ":\n"
  sFile += "@----------------------------------------- Activity led On\n"
  sFile += "  ldr   r0, =0x400FF084  @ Address of GPIOC_PSOR control register\n"
  sFile += "  movs  r1, # (1 << 5)   @ Port D13 is PORTC:5\n"
  sFile += "  str   r1, [r0]         @ turn on\n"
  sFile += "@----------------------------------------- Goto interrupt function\n"
  sFile += "  b     interrupt.section." + interruptSectionName + "\n\n"
#------------------------------ Unused interrupts
for unusedInterruptName in interruptDictionary.keys () :
  sFile += asSeparator ()
  sFile += "@   INTERRUPT - UNUSED: " + unusedInterruptName + "\n"
  sFile += asSeparator () + "\n"
  sFile += "  .section .text.interrupt." + unusedInterruptName + ", \"ax\", %progbits\n\n"
  sFile += "  .align  1\n"
  sFile += "  .type interrupt." + unusedInterruptName + ", %function\n"
  sFile += "  .global interrupt." + unusedInterruptName + "\n\n"
  sFile += "interrupt." + unusedInterruptName + ":\n"
  sFile += "  movs r0, #" + str (interruptDictionary [unusedInterruptName]) + "\n"
  sFile += "  b    unused.interrupt\n\n"
#------------------------------ Write destination file
sFile += asSeparator ()
f = open (destinationAssemblerFile, "wt")
f.write (sFile)
f.close()
f = open (destinationCppFile, "wt")
f.write (cppFile)
f.close()

#-----------------------------------------------------------------------------------------------------------------------


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

"""
判断运行环境
通过检测环境变量
"""

# 基本包

try:
    #策略中必须导入kuanke.user_space_api包
    from kuanke.user_space_api import *
except:
    pass

import numpy as np
import pandas as pd
import math
import os

# 聚源数据、交易日
from jqdata import jy

# 日期时间
import time
from datetime import timedelta,date,datetime

IN_BACKTEST=not(os.environ.get("JUPYTERHUB_API_TOKEN") or os.environ.get("JPY_API_TOKEN"))

#检测文件
def exists_file_in_research(file_name):
    """
    研究中检测文件，使用os.path.exists函数
    file_name：文件名、含路径，str
    """
    return os.path.exists(file_name)

#检测文件
def exists_file_in_backtest(file_name):
    """
    策略中检测文件，使用read_file函数
    file_name：文件名、含路径，str
    """
    try:
        # 尝试读取文件，成功则文件存在
        read_file(file_name)
        return True
    except:
        # 出现错误，则文件不存在
        return False

exists_file=exists_file_in_backtest if IN_BACKTEST else exists_file_in_research

def get_volatility(df,years=None,days=30):
    """
    波动率
    df：数据表，df
    years：以年为单位的时段，int
    days：以年为单位的时段，int
    返回：波动率，float
    """
    # 按照年取数据
    if not years is None:
        start_date=df.index[-1].date()-timedelta(365*years)
        df=df[df.index>=str(start_date)]

    # 按照天数取数据
    if not days is None:
        start_date=df.index[-1].date()-timedelta(days+1)
        df=df[df.index>=str(start_date)]

    # 无数据返回Nan
    if len(df)==0:
        return float(np.NaN)

    #前一日收盘价
    df['pre']=df.iloc[:,0].shift(1)
    # 清除无效数据
    df=df.dropna()
    # 日收益率(当日收盘价/前一日收盘价，然后取对数)
    df['day_volatility']=np.log(df['pre']/df.iloc[:,0])
    # 波动率（年化收益率的方差*sqrt(250)）
    volatility=df['day_volatility'].std()*math.sqrt(250.0)*100

    # 返回值
    return round(volatility,2)

def get_annualized(df,years=5):
    """
    年化回报率
    df：数据表，df
    years：以年为单位的时段，int
    返回：回报率，float
    """
    # 按照年取数据
    if not years is None:
        start_date=df.index[-1].date()-timedelta(365*years)
        df=df[df.index>=str(start_date)]
    try:
        # 总收益率
        annualized=(df.iloc[:,0][-1]-df.iloc[:,0][0])/df.iloc[:,0][0]
        # 年化收益率
        annualized=(pow(1+annualized,250/(years*250.0))-1)*100
    except:
        annualized=float(np.NaN)
    # 返回报率
    return round(annualized,2)

def get_divid(code,end_date):
    """
    指定日期股息率,jy版本
    code：股票代码,list or str
    end_date：截至日期
    返回：股息率、市值
    """
    # 判断代码是str还是list
    if not type(code) is list:
        code=[code]

    #聚宽代码转换为jy内部代码
    InnerCodes=Code.stk_to_jy(code)
    #获取所有成份股派息总额
    #数据表
    df=pd.DataFrame()
    #因jy每次最多返回3000条数据，所以要多次查询
    #偏移值
    offset=0
    while True:
        #查询语句
        q=query(
            #内部代码
            jy.LC_Dividend.InnerCode,
            #派息日期
            jy.LC_Dividend.ToAccountDate,
            #派息总额
            jy.LC_Dividend.TotalCashDiviComRMB,
        ).filter(
            # 已分红
            jy.LC_Dividend.IfDividend==1,
            # 获取指定日期前所有分红
            jy.LC_Dividend.ToAccountDate<=end_date,
            jy.LC_Dividend.InnerCode.in_(InnerCodes)
        #偏移
        ).offset(offset)
        #查询
        temp_df=jy.run_query(q)
        if len(temp_df)==0:
            break
        #追加数据
        df=df.append(temp_df)
        #偏移值每次递增3000
        offset+=3000

    if len(df)==0:
        div=float('NaN')
    else:
        # 生成排序字段
        df['sort']=df['InnerCode'].astype('str')+df['ToAccountDate'].astype('str').str[0:10]
        df=df.sort('sort')
        # 只保留最后一次派息数据
        df=df.drop_duplicates('InnerCode',take_last=True) #keep='last'
        # 返回合计的派息数
        div=df['TotalCashDiviComRMB'].sum()

    #获取指数总市值
    q=query(
        #市值
        valuation.market_cap
    ).filter(
        valuation.code.in_(code)
    )
    #获取各成份股市值(亿元)
    df=get_fundamentals(q,end_date)
    #返回合计的成份股总市值（亿元）
    cap=df['market_cap'].sum()

    try:
        #返回股息率
        return div/cap/100000000*100.0,cap
    except:
        return float('NaN'),float('NaN')

#对源数据按照周、月、年筛选
#period：D、W、M分别为日线、周线、月线
def data_to_period(df,period='W'):
    df['date']=df.index
    df=df.resample(period,how='last')
    df.index=df['date']
    del df['date']
    df=df.dropna()
    df.index.name=None
    return df

#四分位去除负值、极值
def data_del_IQR(p,k=0.5):
    #去除负值
    x=np.array(p[p>0])
    #排序
    x=np.sort(x)
    #取中值
    m=np.median(x)
    #按照m分为两个数据表
    #取小于m的数据表中值
    q1=np.median(x[x<=m])
    #取大于m的数据表中值
    q3=np.median(x[x>m])
    #计算上下临界值
    d=q1-k*(q3-q1)
    u=q3+k*(q3-q1)
    #取大于d小于u且大于0的数据，并去除空值
    return p[(p>d)&(p<u)&(p>0)].dropna()

#四分位填充极值
def data_fill_IQR(p,k=0.734):
    x=np.array(p)
    x=np.sort(x)
    m=np.median(x)
    q1=np.median(x[x<=m])
    q3=np.median(x[x>m])
    d=q1-k*(q3-q1)
    u=q3+k*(q3-q1)
    p[p<=d]=d
    p[p>=u]=u
    return p

# 日期转换成时间戳
def date_to_timestamp(date):
    return int(time.mktime(time.strptime(date,'%Y-%m-%d')))

# 时间戳转换成日期
def timestamp_to_date(timestamp):
    return time.strftime('%Y-%m-%d',time.localtime(timestamp))

class Code(object):

    @classmethod
    def __secu_to_jq(cls,code):
        if code.endswith('SH'):
            return code.replace('SH','XSHG')
        if code.endswith('SZ'):
            return code.replace('SZ','XSHE')

    @classmethod
    def __jq_to_secu(cls,code):
        if code.endswith('XSHG'):
            return code.replace('XSHG','SH')
        if code.endswith('XSHE'):
            return code.replace('XSHE','SZ')

    @classmethod
    def secu_to_jq(cls,code):
        if type(code) is str:
            return cls.__secu_to_jq(code)
        elif type(code) is list:
            return [cls.__secu_to_jq(item) for item in code]

    @classmethod
    def jq_to_secu(cls,code):
        if type(code) is str:
            return cls.__jq_to_secu(code)
        elif type(code) is list:
            return [cls.__jq_to_secu(item) for item in code]

    @classmethod
    def __secu_to_jy(cls,codes,category=1):
        df=pd.DataFrame()
        #因jy每次最多返回3000条数据，所以要多次查询
        #偏移值
        offset=0
        while True:
            q=query(
                #内部代码
                jy.SecuMain.InnerCode,
            ).filter(
                #去除聚宽代码后缀
                jy.SecuMain.SecuCode.in_(codes),
                #限定查询股票
                jy.SecuMain.SecuCategory==category
                #偏移
            ).offset(offset)
            #查询
            temp_df=jy.run_query(q)
            #无数据时退出
            if len(temp_df)==0:
                break
            #追加数据
            df=df.append(temp_df)
            #偏移值每次递增3000
            offset+=3000
        #返回代码list
        return df.InnerCode.tolist()

    @classmethod
    def idx_to_jy(cls,code):
        if type(code) is str:
            return cls.__secu_to_jy([code[0:6]],category=4)[0]
        elif type(code) is list:
            return cls.__secu_to_jy([item[0:6] for item in code],category=4)

    @classmethod
    def stk_to_jy(cls,code):
        if type(code) is str:
            return cls.__secu_to_jy([code[0:6]],category=1)[0]
        elif type(code) is list:
            return cls.__secu_to_jy([item[0:6] for item in code],category=1)


import math
import numpy as np
import h5py
import matplotlib.pyplot as plt
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
from tensorflow.python.framework import ops
from Week23.tf_utils import load_dataset, random_mini_batches, convert_to_one_hot, predict

y_hat = tf.constant(36, name='y_hat')            # Define y_hat constant. Set to 36.
y = tf.constant(39, name='y')                    # Define y. Set to 39
loss = tf.Variable((y - y_hat)**2, name='loss')  # Create a variable for the loss
init = tf.global_variables_initializer()         # When init is run later (session.run(init)),
                                               # the loss variable will be initialized and ready to be computed
with tf.Session() as session:                    # Create a session and print the output
    session.run(init)                            # Initializes the variables
    print(session.run(loss))                     # Prints the loss

a = tf.constant(2)
b = tf.constant(10)
c = tf.multiply(a,b)
sess = tf.Session()
print(sess.run(c))
x = tf.placeholder(tf.int64, name = 'x')
print(sess.run(2 * x, feed_dict = {x: 3}))
sess.close()

# GRADED FUNCTION: linear_function

def linear_function():
    """
    Implements a linear function:
            Initializes W to be a random tensor of shape (4,3)
            Initializes X to be a random tensor of shape (3,1)
            Initializes b to be a random tensor of shape (4,1)
    Returns:
    result -- runs the session for Y = WX + b
    """
    np.random.seed(1)
    ### START CODE HERE ### (4 lines of code)
    X = tf.constant(np.random.randn(3,1), name = "X")
    W = tf.constant(np.random.randn(4,3), name = "W")
    b = tf.constant(np.random.randn(4,1), name  = "b")
    Y = tf.add(tf.matmul(W, X), b)
    ### END CODE HERE ###
    # Create the session using tf.Session() and run it with sess.run(...) on the variable you want to calculate
    ### START CODE HERE ###
    sess = tf.Session()
    result = sess.run(Y)
    ### END CODE HERE ###
    # close the session
    sess.close()
    return result

print( "result = " + str(linear_function()))

# GRADED FUNCTION: sigmoid

def sigmoid(z):
    """
    Computes the sigmoid of z
    Arguments:
    z -- input value, scalar or vector
    Returns:
    results -- the sigmoid of z
    """
    ### START CODE HERE ### ( approx. 4 lines of code)
    # Create a placeholder for x. Name it 'x'.
    x = tf.placeholder(tf.float32, name = "x")
    # compute sigmoid(x)
    sigmoid = tf.sigmoid(x)
    # Create a session, and run it. Please use the method 2 explained above.
    # You should use a feed_dict to pass z's value to x.
    with tf.Session() as sess:
        # Run session and call the output "result"
        result = sess.run(sigmoid, feed_dict = {x:z})
    ### END CODE HERE ###
    return result
print ("sigmoid(0) = " + str(sigmoid(0)))
print ("sigmoid(12) = " + str(sigmoid(12)))

# GRADED FUNCTION: cost

def cost(logits, labels):
    """
    Computes the cost using the sigmoid cross entropy
    Arguments:
    logits -- vector containing z, output of the last linear unit (before the final sigmoid activation)
    labels -- vector of labels y (1 or 0)
    Note: What we've been calling "z" and "y" in this class are respectively called "logits" and "labels"
    in the TensorFlow documentation. So logits will feed into z, and labels into y.

    Returns:
    cost -- runs the session of the cost (formula (2))
    """
    ### START CODE HERE ###
    # Create the placeholders for "logits" (z) and "labels" (y) (approx. 2 lines)
    z = tf.placeholder(tf.float32, name = "z")
    y = tf.placeholder(tf.float32, name = "y")
    # Use the loss function (approx. 1 line)
    cost = tf.nn.sigmoid_cross_entropy_with_logits(logits = z, labels = y)
    # Create a session (approx. 1 line). See method 1 above.
    sess = tf.Session()
    # Run the session (approx. 1 line).
    cost = sess.run(cost, feed_dict = {z:logits, y:labels})
    # Close the session (approx. 1 line). See method 1 above.
    sess.close()
    ### END CODE HERE ###
    return cost

logits = sigmoid(np.array([0.2,0.4,0.7,0.9]))
cost = cost(logits, np.array([0,0,1,1]))
print ("cost = " + str(cost))

# GRADED FUNCTION: one_hot_matrix

def one_hot_matrix(labels, C):
    """
    Creates a matrix where the i-th row corresponds to the ith class number and the jth column
    corresponds to the jth training example. So if example j had a label i. Then entry (i,j)
    will be 1.
    Arguments:
    labels -- vector containing the labels
    C -- number of classes, the depth of the one hot dimension
    Returns:
    one_hot -- one hot matrix
    """
    ### START CODE HERE ###
    # Create a tf.constant equal to C (depth), name it 'C'. (approx. 1 line)
    C = tf.constant(value = C, name = "C")
    # Use tf.one_hot, be careful with the axis (approx. 1 line)
    one_hot_matrix = tf.one_hot(labels, C, axis = 0)
    # Create the session (approx. 1 line)
    sess = tf.Session()
    # Run the session (approx. 1 line)
    one_hot = sess.run(one_hot_matrix)
    # Close the session (approx. 1 line). See method 1 above.
    sess.close()
    ### END CODE HERE ###
    return one_hot
labels = np.array([1,2,3,0,2,1])
one_hot = one_hot_matrix(labels, C = 4)
print ("one_hot = " + str(one_hot))

# GRADED FUNCTION: ones
def ones(shape):
    """
    Creates an array of ones of dimension shape
    Arguments:
    shape -- shape of the array you want to create
    Returns:
    ones -- array containing only ones
    """
    ### START CODE HERE ###
    # Create "ones" tensor using tf.ones(...). (approx. 1 line)
    ones = tf.ones(shape)
    # Create the session (approx. 1 line)
    sess = tf.Session()
    # Run the session to compute 'ones' (approx. 1 line)
    ones = sess.run(ones)
    # Close the session (approx. 1 line). See method 1 above.
    sess.close()
    ### END CODE HERE ###
    return ones

print ("ones = " + str(ones([3])))


from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd

webdriver = webdriver.Chrome()
webdriver.get('https://www.roamright.com/country/list/')

content = webdriver.page_source
beautifulSoup = BeautifulSoup(content, features='html.parser')

places = []
descriptions = []

for div in beautifulSoup.findAll('div', attrs={'class': 'media-body'}):
    place = div.find('a')
    places.append(place.text)
    description_including_empties = div.find_all('p')
    for description in description_including_empties:
        if (description.text != ''):
            descriptions.append(description.text)

dataframe = pd.DataFrame({'Place':places, 'Description':descriptions})
dataframe.to_csv('places_descriptions.csv', index=False, encoding='utf-8')

webdriver.close()


'''
Symmetric Tree
Easy

Given the root of a binary tree, check whether it is a mirror of itself (i.e., symmetric around its center).

Example 1:

Input: root = [1,2,2,3,4,4,3]
Output: true

Example 2:

Input: root = [1,2,2,null,3,null,3]
Output: false
'''

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:
        if root == None:
            return True

        return self.is_symmetric(root.left, root.right)

    def is_symmetric(self, left, right):
        if left == None or right == None:
            return left == right

        if left.val != right.val:
            return False

        return self.is_symmetric(left.left, right.right) and self.is_symmetric(left.right, right.left)


#!/usr/bin/env python3
import logging
import os
from time import monotonic

import torch
from dotenv import load_dotenv
from langchain import HuggingFacePipeline, HuggingFaceHub, LLMChain, PromptTemplate
from langchain.callbacks.base import BaseCallbackHandler
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
from langchain.llms import LlamaCpp, GPT4All, OpenAI
from langchain.schema import Document
from torch import cuda as torch_cuda
from transformers import LlamaForCausalLM
from transformers import LlamaTokenizer
from transformers import pipeline

from scripts import app_logs
from scripts.app_environment import model_type, openai_api_key, model_n_ctx, model_temperature, model_top_p, model_n_batch, model_use_mlock, model_verbose, \
    huggingface_hub_key, args, db_get_only_relevant_docs, gpt4all_backend, model_path_or_id, gpu_is_enabled, cpu_model_n_threads, gpu_model_n_threads, model_n_answer_words
from scripts.app_qa_builder import print_document_chunk, print_hyperlink, process_database_question, process_query
from scripts.app_user_prompt import prompt

# Ensure TOKENIZERS_PARALLELISM is set before importing any HuggingFace module.
os.environ["TOKENIZERS_PARALLELISM"] = "true"
# load environment variables

try:
    load_dotenv()
except Exception as e:
    logging.error("Error loading .env file, create one from example.env:", str(e))

def get_gpu_memory() -> int:
    """
    Returns the amount of free memory in MB for each GPU.
    """
    return int(torch_cuda.mem_get_info()[0] / (1024 ** 2))

# noinspection PyPep8Naming
def calculate_layer_count() -> None | int | float:
    """
    How many layers of a neural network model you can fit into the GPU memory,
    rather than determining the number of threads.
    The layer size is specified as a constant (120.6 MB), and the available GPU memory is divided by this to determine the maximum number of layers that can be fit onto the GPU.
    Some additional memory (the size of 6 layers) is reserved for other uses.
    The maximum layer count is capped at 32.
    """
    if not gpu_is_enabled:
        return None
    LAYER_SIZE_MB = 120.6  # This is the size of a single layer on VRAM, and is an approximation.
    # The current set value is for 7B models. For other models, this value should be changed.
    LAYERS_TO_REDUCE = 6  # About 700 MB is needed for the LLM to run, so we reduce the layer count by 6 to be safe.
    if (get_gpu_memory() // LAYER_SIZE_MB) - LAYERS_TO_REDUCE > 32:
        return 32
    else:
        return get_gpu_memory() // LAYER_SIZE_MB - LAYERS_TO_REDUCE

def get_llm_instance(*callback_handler: BaseCallbackHandler):
    logging.debug(f"Initializing model...")

    callbacks = [] if args.mute_stream else callback_handler

    if model_type == "gpt4all":
        if gpu_is_enabled:
            logging.warn("GPU is enabled, but GPT4All does not support GPU acceleration. Please use LlamaCpp instead.")
            exit(1)
        return GPT4All(
            model=model_path_or_id,
            n_ctx=model_n_ctx,
            backend=gpt4all_backend,
            callbacks=callbacks,
            use_mlock=model_use_mlock,
            n_threads=gpu_model_n_threads if gpu_is_enabled else cpu_model_n_threads,
            n_predict=1000,
            n_batch=model_n_batch,
            top_p=model_top_p,
            temp=model_temperature,
            streaming=False,
            verbose=False
        )
    elif model_type == "llamacpp":
        return LlamaCpp(
            model_path=model_path_or_id,
            temperature=model_temperature,
            n_ctx=model_n_ctx,
            top_p=model_top_p,
            n_batch=model_n_batch,
            use_mlock=model_use_mlock,
            n_threads=gpu_model_n_threads if gpu_is_enabled else cpu_model_n_threads,
            verbose=model_verbose,
            n_gpu_layers=calculate_layer_count() if gpu_is_enabled else None,
            callbacks=callbacks,
        )
    elif model_type == "huggingface-local":
        return HuggingFacePipeline(pipeline=pipeline(
            "text-generation",
            model=LlamaForCausalLM.from_pretrained(
                model_path_or_id,
                load_in_8bit=gpu_is_enabled if gpu_is_enabled else False,
                device_map={
                    '': 'cuda' if gpu_is_enabled else 'cpu',
                    'transformer': 'cuda' if gpu_is_enabled else 'cpu',
                    'lm_head': 'cuda' if gpu_is_enabled else 'cpu',
                },  # if GPU: device_map='auto',
                torch_dtype=torch.float16 if gpu_is_enabled else torch.float32,
                low_cpu_mem_usage=True
            ),
            tokenizer=LlamaTokenizer.from_pretrained(model_path_or_id),
            max_length=2048,
            temperature=model_temperature,
            top_p=model_top_p,
            repetition_penalty=1.15
        ))
    elif model_type == "huggingface-hub":
        return LLMChain(
            prompt=PromptTemplate(template="""<|prompter|>{question}<|endoftext|><|assistant|>""", input_variables=["question"]),
            llm=HuggingFaceHub(
                repo_id=model_path_or_id,
                huggingfacehub_api_token=huggingface_hub_key
            ),
        )
    #     return HuggingFaceHub(
    #         repo_id=model_path_or_id,
    #         task="summarization",
    #         huggingfacehub_api_token=huggingface_hub_key,
    #         model_kwargs={"temperature": model_temperature, "max_length": 1000})
    elif model_type == "openai":
        assert openai_api_key is not None, "Set ENV OPENAI_API_KEY, Get one here: https://platform.openai.com/account/api-keys"
        return OpenAI(openai_api_key=openai_api_key, callbacks=callbacks)
    else:
        logging.error(f"Model {model_type} not supported!")
        raise Exception(f"Model type {model_type} is not supported. Please choose one of the following: LlamaCpp, GPT4All")

def main():
    llm = get_llm_instance(StreamingStdOutCallbackHandler())
    if llm is None:
        logging.error("Could not initialize LLM instance.")
        return

    selected_directory_list = prompt()

    # Initialize a chat history list
    chat_history = []

    while True:
        query = input("\nEnter question (q for quit): ")
        if query.strip() == "":
            continue
        if query == "q":
            break

        qa_list = []
        for dir_name in selected_directory_list:
            # Check if the directory name contains a slash, indicating a sub-collection
            if "/" in dir_name:
                # If so, split the string to separate the database name and the collection name
                database_name, collection_name = dir_name.split("/")
            else:
                # If not, the database name and the collection name are the same
                database_name, collection_name = dir_name, dir_name

            qa_list.append(process_database_question(database_name=database_name, llm=llm, collection_name=collection_name))

        # Doesn't work very well for some reason won't send proper collection name to process_database_question?
        # def worker(j):
        #     return process_database_question(selected_directory_list[j], llm, selected_directory_list[j])
        #
        # with ThreadPoolExecutor() as executor:
        #     qa_list = list(executor.map(worker, range(len(selected_directory_list))))

        for i in range(len(qa_list)):
            start_time = monotonic()
            qa = qa_list[i]

            print(f"\n\033[94mSeeking for answer from: [{selected_directory_list[i]}]. May take some minutes...\033[0m")
            answer, docs = process_query(qa, query, model_n_answer_words, chat_history, db_get_only_relevant_docs, translate_answer=True)
            print(f"\033[94mTook {round(((monotonic() - start_time) / 60), 2)} min to process the answer!\n\033[0m")

            if isinstance(docs, Document):
                doc = docs
                print_hyperlink(doc)
                print_document_chunk(doc)
            else:
                for doc in docs:
                    print_hyperlink(doc)
                    print_document_chunk(doc)

if __name__ == "__main__":
    app_logs.initialize_logging()

    main()


from pymongo import MongoClient
from bson.objectid import ObjectId

class AnimalShelter(object):
    """ CRUD Operations for Animal Collection in MongoDB """

    # Declare one's self into existence
    def __init__(self, username, password):
        self.client = MongoClient('mongodb://%s:%s@localhost:48219/?authMechanism=DEFAULT&authSource=admin'%(username, password))
        self.database = self.client['AAC']

    # Insert data into the animals collection
    def create(self, data):

        # Double-check the user actually provided data to be created
        if data is None:
            raise Exception("PLEASE NOTE: Data must be provided in order to be saved.")

        # Instantiate a variable for the created data to utilize as an "existence check"
        saved = self.database.animals.insert_one(data)

        # Subsequently, check if the created data is null within the animals collection
        # Return False or True depending on the result
        return False if saved is None else True

    # Search for data within the animals collection
    def read(self, query):

        # Double-check the user actually provided a query to be filtered with
        if query is None:
            raise Exception("PLEASE NOTE: Cannot search for something that is not requested.")

        # Return the data that results from the query search
        return self.database.animals.find_one(query)

    # Pull all data within the animals collection
    def readAll(self, data):

        # Return a cursor that acts like a stopping point of all data before it
        cursor = self.database.animals.find(data, {"_id":False})
        return cursor

    # Update data that is already present in the animals collection
    def update(self, query, data):

        # Double-check the user actually provided data to be updated
        if data is None:
            raise Exception("PLEASE NOTE: In order to update, new information must be provided.")

        # Double-check the user wishes to update information that can be updated instead of created
        if query is None:
            raise Exception("PLEASE NOTE: In order to update, present information must be provided.\nOtherwise, create data instead.")

        # Updating is involved.  TRY to see if it is successful
        try:
            updated = self.database.animals.find_one_and_update(query, {"$set":data}, {"upsert":True, "new":True})

            # Check if the update was successful or not based on if the newly updated document was returned...
            if updated is not None:

                # ... if so, return the data as a JSON
                print("PLEASE NOTE: Successful update.")
                return updated
            else:

                # ... and if not, let the user know
                raise Exception("ERROR: Could not update the query.")

        except Exception as exc:
            print("ERROR: Something went wrong in the updating process:", exc)

    # Delete data from the animals collection
    def delete(self, data):

        # Double-check the user actually provided data to be deleted
        if data is None:
            raise Exception("PLEASE NOTE: To delete one's self, one's self must present one's self to be deleted.")

        # Deleting is involved; TRY it to see if it is successful
        try:
            preDeleted = self.database.animals.find_one(data)
            deleted = self.database.animals.find_one_and_delete(data, {"new":False})

            # Check if the deletion registers...
            if deleted is not None:

                # ... if so, let the user know and return the deleted data as affirmation...
                print("PLEASE NOTE: Deletion successful.")
                return preDeleted
            else:

                # ... otherwise, let the user know deletion did not occur
                raise Exception("PLEASE NOTE: Nothing could be deleted with the given parameters.")

        # If the deletion attempt was unsuccessful for any reason, showcase the error to the user
        except Exception as exc:
            print("ERROR: Something went wrong in the deletion process:", exc)


import os
import sys
import numpy as np

datasets_path = 'external_maf/datasets/data/lhc'
dataset_name = sys.argv[1]

signal_file_name = os.path.join(datasets_path, "sig_{}.npy".format(dataset_name))
background_file_name = os.path.join(datasets_path, "bg_{}.npy".format(dataset_name))

sig = np.nan_to_num(np.load(signal_file_name))
sig = np.append(sig, np.ones((sig.shape[0], 1)), axis=1)
bg = np.nan_to_num(np.load(background_file_name))
bg = np.append(bg, np.zeros((bg.shape[0], 1)), axis=1)

data = np.append(sig, bg, axis=0)

np.save(os.path.join(datasets_path, "lhc_{}.npy".format(dataset_name)), data)


# -*- coding: utf-8 -*-
import os
import pdb
import numpy as np
from joblib import Parallel, delayed
from tqdm import tqdm
import sys
import argparse
from nltk.tokenize import TweetTokenizer
import preprocessor as pre
import pandas as pd

cwd=os.getcwd()

def parse_args():
    parser = argparse.ArgumentParser(description='build data graph to npz file')
    parser.add_argument('-format', type=str, default='txt_emb')
    parser.add_argument('-obj', type=str, default='')
    parser.add_argument('-early', type=str, default='')
    parser.add_argument('-class_num', type=int, default=2)
    args = parser.parse_args()
    return args

def clean_data(line):
    ## Remove @, reduce length, handle strip
    tokenizer = TweetTokenizer(strip_handles=False, reduce_len=True)
    line = ' '.join(tokenizer.tokenize(line))

    ## Remove url, emoji, mention, prserved words, only preserve smiley
    #pre.set_options(pre.OPT.URL, pre.OPT.EMOJI, pre.OPT.MENTION, pre.OPT.RESERVED)
    #pre.set_options(pre.OPT.URL, pre.OPT.RESERVED, pre.OPT.MENTION)
    pre.set_options(pre.OPT.URL, pre.OPT.RESERVED)
    line = pre.tokenize(line)

    ## Remove non-sacii
    line = ''.join([i if ord(i) else '' for i in line]) # remove non-sacii
    return line

class Node_tweet(object):
    def __init__(self, idx=None):
        self.children = []
        self.idx = idx
        self.word = []
        self.index = []
        self.parent = None

def str2matrix(Str):  # str = index:wordfreq index:wordfreq
    wordFreq, wordIndex = [], []
    for pair in Str.split(' '):
        freq=float(pair.split(':')[1])
        index=int(pair.split(':')[0])
        if index<=5000:
            wordFreq.append(freq)
            wordIndex.append(index)
    return wordFreq, wordIndex

def constructMat(tree):
    index2node = {}
    for i in tree:
        node = Node_tweet(idx=i)
        index2node[i] = node
    for j in tree:
        indexC = j
        indexP = tree[j]['parent']
        nodeC = index2node[indexC]
        wordFreq, wordIndex = str2matrix(tree[j]['vec'])
        nodeC.index = wordIndex
        nodeC.word = wordFreq
        ## not root node ##
        if not indexP == 'None':
            nodeP = index2node[int(indexP)]
            nodeC.parent = nodeP
            nodeP.children.append(nodeC)
        ## root node ##
        else:
            rootindex=indexC-1
            root_index=nodeC.index
            root_word=nodeC.word
    rootfeat = np.zeros([1, 5000])
    if len(root_index)>0:
        rootfeat[0, np.array(root_index)] = np.array(root_word)
    matrix=np.zeros([len(index2node),len(index2node)])
    row=[]
    col=[]
    x_word=[]
    x_index=[]
    for index_i in range(len(index2node)):
        for index_j in range(len(index2node)):
            if index2node[index_i+1].children != None and index2node[index_j+1] in index2node[index_i+1].children:
                matrix[index_i][index_j]=1
                row.append(index_i)
                col.append(index_j)
        x_word.append(index2node[index_i+1].word)
        x_index.append(index2node[index_i+1].index)
    edgematrix=[row,col]
    return x_word, x_index, edgematrix,rootfeat,rootindex

def constructMat_txt(tree):
    index2node = {}
    for i in tree:
        node = Node_tweet(idx=i)
        index2node[i] = node
    for j in tree:
        indexC = j
        indexP = tree[j]['parent']
        nodeC = index2node[indexC]
        text = tree[j]['vec'] # raw text
        nodeC.text = text
        ## not root node ##
        if not indexP == 'None':
            #nodeP = index2node[indexP]
            nodeP = index2node[int(indexP)]
            nodeC.parent = nodeP
            nodeP.children.append(nodeC)
        ## root node ##
        else:
            rootindex=indexC-1
            root_text = text
    matrix=np.zeros([len(index2node),len(index2node)])
    row=[]
    col=[]
    x_text=[]
    for index_i in range(len(index2node)):
        for index_j in range(len(index2node)):
            if index2node[index_i+1].children != None and index2node[index_j+1] in index2node[index_i+1].children:
                matrix[index_i][index_j]=1
                row.append(index_i)
                col.append(index_j)
        x_text.append(clean_data(index2node[index_i+1].text))
    if row == [] and col == []:
        matrix[0][0] = 1
        row.append(0)
        col.append(0)
    edgematrix=[row,col]
    return x_text, edgematrix, root_text, rootindex

def getfeature(x_word,x_index):
    x = np.zeros([len(x_index), 5000])
    for i in range(len(x_index)):
        if len(x_index[i])>0:
            x[i, np.array(x_index[i])] = np.array(x_word[i])
    return x

def buildgraph(obj, format_, class_num, portion='', texts=None, labels=None):
    """
    labels: lines with label and event id
    """
    if texts is None:
        if format_ == 'idx_cnt':
            treePath = os.path.join(cwd, '../dataset/' + obj + '/data.TD_RvNN.vol_5000.{}txt'.format(portion))
            print("loading text from ", treePath)
        elif format_ == 'txt_emb':
            treePath = os.path.join(cwd, '../dataset/' + obj + '/data.text.{}txt'.format(portion))
            print("loading text from", treePath)
        texts = open(treePath)

        treeDic = {}
        f_tree = open(treePath, 'r')
        for line in f_tree:
            # maxL: max # of clildren nodes for a node; max_degree: max # of the tree depth
            line = line.rstrip()

            eid, indexP, indexC, max_degree, maxL = line.split("\t")[:5]
            Vec = line.split("\t")[-1]
            indexC = int(indexC)
            max_degree = int(max_degree)
            maxL = int(maxL)

            if not treeDic.__contains__(eid):
                # If the event id hasn't been contained
                treeDic[eid] = {}
            treeDic[eid][indexC] = {'parent': indexP, 'max_degree': max_degree, 'maxL': maxL, 'vec': Vec}
        f_tree.close()
    else:
        treeDic = {}
        for _, line in texts.iterrows():

            eid, indexP, indexC, max_degree, maxL = line[:5]
            Vec = line[len(line)-1]
            eid = str(eid)
            indexC = int(indexC)
            max_degree = int(max_degree)
            maxL = int(maxL)

            if not treeDic.__contains__(eid):
                # If the event id hasn't been contained
                treeDic[eid] = {}
            treeDic[eid][indexC] = {'parent': indexP, 'max_degree': max_degree, 'maxL': maxL, 'vec': Vec}

    print('tree number:', len(treeDic))

    # Prepare class name by class number
    if class_num == 2:
        labelset_0, labelset_1 = ['non-rumours', 'non-rumor', 'true'], ['rumours', 'rumor', 'false']
        labelset_2, labelset_3 = [], []
    elif class_num == 4:
        labelset_0, labelset_1, labelset_2, labelset_3 = ['true'], ['false'], ['unverified'], ['non-rumor']
    elif class_num == 3:
        labelset_0, labelset_1, labelset_2, labelset_3 = ['true'], ['false'], ['unverified'], []

    # Load the label file
    if labels is None:
        labels = pd.read_csv(os.path.join(cwd, "../dataset/" + obj + "/data.label.txt"), delimiter="\t", header=None)

    print("loading tree label")
    event, y = [], []
    l0 = l1 = l2 = l3 = 0
    labelDic = {}

    for _, line in labels.iterrows():
        label, eid = line[0], str(line[1])
        label=label.lower()
        event.append(eid)
        if label in labelset_0:
            labelDic[eid]=0
            l0 += 1
        if label in labelset_1:
            labelDic[eid]=1
            l1 += 1
        if label in labelset_2:
            labelDic[eid]=2
            l2 += 1
        if label in labelset_3:
            labelDic[eid]=3
            l3 += 1
    print(len(labelDic))
    print(l1, l2)

    if format_ =='idx_cnt':
        os.makedirs(os.path.join(cwd, '../dataset/'+obj+'graph'), exist_ok=True)
    elif format_ =='txt_emb':
        print(os.path.join(cwd, '../dataset/'+obj+ 'textgraph'))
        os.makedirs(os.path.join(cwd, '../dataset/'+obj+ 'textgraph'), exist_ok=True)

    def loadEid(event, id, y, format_):
        if event is None:
            return None
        if len(event) < 1:
            return None
        if len(event)>= 1:
            if format_ == 'idx_cnt':
                x_word, x_index, tree, rootfeat, rootindex = constructMat(event)
                x_x = getfeature(x_word, x_index) # x_word: the occur times of words, x_index: the index of words
                rootfeat, tree, x_x, rootindex, y = np.array(rootfeat), np.array(tree), np.array(x_x), np.array(
                rootindex), np.array(y)
                np.savez( os.path.join(cwd, '../dataset/'+obj+'graph/'+id+'.npz'), x=x_x,root=rootfeat,edgeindex=tree,rootindex=rootindex,y=y)
            elif format_ == 'txt_emb':
                x_text, tree, root_text, rootindex = constructMat_txt(event)
                tree, rootindex, y = np.array(tree), np.array(rootindex), np.array(y)
                np.savez( os.path.join(cwd, '../dataset/'+obj+'textgraph/'+id+'.npz'), x=x_text,root=root_text,edgeindex=tree,rootindex=rootindex,y=y)
            return None

    print("loading dataset", )
    Parallel(n_jobs=1, backend='threading')(delayed(loadEid)(treeDic[eid] if eid in treeDic else None,eid,labelDic[eid], format_) for eid in tqdm(event))
    return treeDic

if __name__ == '__main__':
    args = parse_args()
    obj = args.obj
    if args.format=='idx_cnt':
        path = os.path.join(cwd, '../dataset/'+obj+'graph/')
        print('Building the graph data by index:cnt at ', path)
    elif args.format=='txt_emb':
        path = os.path.join(cwd, '../dataset/'+obj+'text'+'graph/')
        print('Building the graph data by raw text at ', path)

    portion = '{}.'.format(args.portion)
    os.makedirs(path, exist_ok=True)
    buildgraph(args.obj, args.format, args.class_num, portion)


# -*- coding: utf-8 -*-
from openerp import models, fields, api
import time

class JasperReportCDReceivablePaymentHistory(models.TransientModel):
    _name = 'jasper.report.cd.receivable.payment.history'
    _inherit = 'report.account.common'

    groupby = fields.Selection(
        [('groupby_borrower_partner', 'Customer CD'),
         ('groupby_partner', 'Customer (bank)')],
        string='Group By',
        default='groupby_borrower_partner',
        required=True,
    )
    borrower_partner_ids = fields.Many2many(
        'res.partner',
        'payment_history_borrower_partner_rel',
        'history_id', 'partner_id',
        string='Customer CD',
        domain=[('customer', '=', True)],
    )
    partner_ids = fields.Many2many(
        'res.partner',
        'payment_history_partner_rel',
        'history_id', 'partner_id',
        string='Customer (bank)',
        domain=[('customer', '=', True)],
    )

    @api.onchange('groupby')
    def _onchange_groupby(self):
        self.borrower_partner_ids = False
        self.partner_ids = False

    @api.multi
    def _get_report_name(self):
        self.ensure_one()
        report_name = "cd_receivable_payment_history_group_by_customer"
        if self.groupby == "groupby_partner":
            report_name = "cd_receivable_payment_history_group_by_bank"
        return report_name

    @api.multi
    def _get_domain(self):
        self.ensure_one()
        dom = [('loan_agreement_id.state', 'in', ('bank_paid', 'done')),
               ('loan_agreement_id.sale_id.state', 'in', ('progress', 'done'))]
        if self.borrower_partner_ids:
            dom += [('loan_agreement_id.borrower_partner_id', 'in',
                     self.borrower_partner_ids.ids)]
        if self.partner_ids:
            dom += [('loan_agreement_id.partner_id', 'in',
                     self.partner_ids.ids)]
        return dom

    @api.multi
    def _get_datas(self):
        self.ensure_one()
        data = {'parameters': {}}
        dom = self._get_domain()
        data['ids'] = \
            self.env['pabi.common.loan.agreement.report.view'].search(dom).ids
        data['parameters']['user'] = self.env.user.display_name
        data['parameters']['date_run'] = time.strftime('%d/%m/%Y')
        return data

    @api.multi
    def run_report(self):
        self.ensure_one()
        return {
            'type': 'ir.actions.report.xml',
            'report_name': self._get_report_name(),
            'datas': self._get_datas(),
        }


from MaKaC.webinterface.rh.conferenceDisplay import RHConferenceBaseDisplay
from MaKaC.webinterface.pages import authors
from MaKaC.webinterface import urlHandlers

class RHAuthorDisplayBase( RHConferenceBaseDisplay ):

    def _checkParams( self, params ):
        RHConferenceBaseDisplay._checkParams( self, params )
        self._authorId = params.get( "authorId", "" ).strip()

class RHAuthorDisplay( RHAuthorDisplayBase ):
    _uh = urlHandlers.UHContribAuthorDisplay

    def _process( self ):
        p = authors.WPAuthorDisplay( self, self._conf, self._authorId )
        return p.display()


import cv2
import numpy as np
import math

def longestVerticalLine(key,arr):
    ls = []
    for line in arr:
        ls.append(line[1])
        ls.append(line[3])
    ls = sorted(ls)
    return key,ls[0],key,ls[len(ls)-1]
def longestHoriLine(key,arr):
    ls = []
    for line in arr:
        ls.append(line[0])
        ls.append(line[2])
    ls = sorted(ls)
    return ls[0],key,ls[len(ls)-1],key

def imagetoLines(img,w,h):
# img = cv2.imread('loll.jpeg')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray,50,200,apertureSize = 3)
    lines = cv2.HoughLinesP(
        edges,
        rho=6,
        theta=np.pi / 180,
        threshold=120,
        lines=np.array([]),
        minLineLength=50,
        maxLineGap=40
    )
    hori_line = []
    vertical_line = []
    for line in lines:
        for x1,y1,x2,y2 in line:
            if x1 != x2:
                slope = (y2 - y1) / (x2 - x1) # <-- Calculating the slope.
                if abs(slope) < 0.5:
                    hori_line.append([x1, y1, x2, y2])
                else:
                    vertical_line.append([x1, y1, x2, y2])

    hori_line = sorted(hori_line,key=lambda x: x[1])
    usy = hori_line[0][1]
    udict = {}
    udict[usy] = [hori_line[0]]
    for line in hori_line:
        if abs(usy - line[1]) < 100:
            arr = udict[usy]
            arr.append(line)
            udict[usy] = arr
        else:
            usy =  line[1]
            udict[usy] = [line]

    vertical_line = sorted(vertical_line,key=lambda x: x[0])
    usy1 = vertical_line[0][0]
    udict1 = {}
    udict1[usy1] = [vertical_line[0]]
    for line in vertical_line:
        if abs(usy1 - line[0]) < 100:
                arr = udict1[usy1]
                arr.append(line)
                udict1[usy1] = arr
        else:
            usy1 =  line[0]
            udict1[usy1] = [line]
    longest_hori_lines = []
    longest_vert_lines = []
    for key in udict1.keys():
        x1,y1,x2,y2 = longestVerticalLine(key,udict1[key])
        if y1 < y2:
            position_x = -(w/2) + x1
            position_y = -(h/3.6) + y1
        else:
            position_x = -(w/2) + x2
            position_y = -(h/3.6) + y2
        line  = abs(y2 - y1)
        longest_vert_lines.append([position_x,position_y,line])
    for key in udict.keys():
        x1,y1,x2,y2 =  longestHoriLine(key,udict[key])
        if x1 < x2:
            position_x = -(w/2) + x1
            position_y = -(h/2) + y1
        else:
            position_x = -(w/2) + x2
            position_y = -(h/2) + y2
        position_x = -(w/4) + x1
        position_y = -(h/2) + y1
        line  = abs(x2 - x1)
        longest_hori_lines.append([position_x,position_y,line])
    return longest_hori_lines,longest_vert_lines


#!/usr/bin/python3
"""Node And SinglyLinkedList Class"""

class Node:
    """A Node class that define the next node and the data"""

    def __init__(self, data, next_node=None):
        """Initializes the data and the next value"""
        self.data = data
        self.next_node = next_node

    @property
    def data(self):
        """Get the data"""
        return self.__data

    @data.setter
    def data(self, value):
        """Set the data."""
        if type(value) != int:
            raise TypeError('data must be an integer')
        self.__data = value

    @property
    def next_node(self):
        """Get the next node value"""
        return self.__next_node

    @next_node.setter
    def next_node(self, value):
        """Set the next node of the list and set the error"""
        if type(value) != Node and value is not None:
            raise TypeError('next_node must be a Node object')
        self.__next_node = value

class SinglyLinkedList:
    """A SinglyLinkedList class that define a linket list"""

    def __init__(self):
        """Initialize the head of the list"""
        self.head = None

    def __repr__(self):
        """Initialize the string and the current position"""
        string = ''
        current = self.head
        while current:
            string += str(current.data) + '\n'
            current = current.next_node
        return string[:-1]

    def sorted_insert(self, value):
        """Add a new node sorted in the correct position"""
        new_node = Node(value)
        current = self.head
        if current is None:
            self.head = new_node
            return
        if current.data > value:
            new_node.next_node = self.head
            self.head = new_node
            return
        while current.next_node is not None:
            if current.next_node.data > value:
                break
            current = current.next_node
        new_node.next_node = current.next_node
        current.next_node = new_node
        return