import datetime
import os
from collections import defaultdict
from os.path import join
from statistics import mean

from joblib import dump, load

from map.elements.effector import Effectors, Effector
from map.elements.node import Node
from map.elements.nodes import Nodes
import re
import pickle
import pandas as pd

import shutil

from map.elements.planimetry.building import Building
from map.elements.planimetry.point import Point3D

class Parser:
    class __Parser:
        def __init__(self, data_dir):
            self.data_dir = data_dir
            try:
                os.makedirs(self.data_dir)
            except:
                pass

        '''
        Read so far updated buildings
        '''

        def read_buildings(self, sd_instance):
            assert sd_instance is not None, "Wrong call of read buildings"
            try:
                with open("{}buildings.pkl".format(self.data_dir), 'rb') as file:
                    buildings = pickle.load(file)
            except:
                buildings = []
            return buildings

        '''
        Read SD instances
        '''
        def read_smartdirections_instances(self):
            try:
                with open("{}sds.pkl".format(self.data_dir), 'rb') as file:
                    sd_instances = pickle.load(file)
            except:
                sd_instances = []
            return sd_instances

        def clean_anchors(self, sd_instance):
            sd_instance = self.read_sd_buildings(sd_instance)
            sd_instance.clean_anchors()
            self.write_sd_buildings(sd_instance)
        '''
        Get SmartDirection instance from ID
        '''
        def read_smartdirections_instance(self, id_sd):
            instances = Parser().getInstance().read_smartdirections_instances()
            instance = [i for i in instances if i.id == id_sd][0]
            return self.read_sd_buildings(instance)

        '''
        Writes the actual Smart Direction instance (buildings) in the directory
        '''
        def write_sd_buildings(self, sd):
            path_sd = join(self.data_dir, "sd_{}".format(sd.id))
            try:
                os.makedirs(path_sd)
            except:
                pass
            with open(join(path_sd, "buildings.pkl"), 'wb') as file:
                pickle.dump(sd.buildings, file)

        '''
        Read from file actual sd instance buildings
        '''
        def read_sd_buildings(self, sd):
            from map.elements.planimetry.sd_instance import SmartDirectionInstance
            path_sd = join(self.data_dir, "sd_{}".format(sd.id))
            try:
                with open(join(path_sd, "buildings.pkl"), 'rb') as file:
                    buildings = pickle.load(file)
                    sd_instance = SmartDirectionInstance(sd.id, buildings, sd.name)
            except:
                sd_instance = SmartDirectionInstance(sd.id, [], sd.name)
            return sd_instance

        '''
        Clears directory of a SD instance
        '''
        def clear_sd(self, sd):
            path_sd = join(self.data_dir, "sd_{}".format(sd.id))
            try:
                shutil.rmtree(path_sd)
            except:
                print("Warning: error during delete")

        '''
        Update SD instances list. In the list, we only have the wrapper info (name + id)
        '''
        def write_sd_instances(self, sds_instances):
            with open("{}sds.pkl".format(self.data_dir), 'wb') as file:
                pickle.dump(sds_instances, file)

        def path_sd(self, id_sd):
            id_sd = str(id_sd)
            path_sd = join(self.data_dir, "sd_{}".format(id_sd))
            path_wifi = join(path_sd, "wifi")
            try:
                os.makedirs(path_wifi)
            except:
                pass
            return "{}/".format(path_wifi)

        def path_building(self, id_sd, id_building):
            id_building = str(id_building)
            path_sd = self.path_sd(id_sd)
            path_dataset = join(path_sd, "wifi", id_building)
            try:
                os.makedirs(path_dataset)
            except:
                pass
            return "{}/".format(path_dataset)

        def get_filename_dataset_wifi(self, id_sd, id_building):
            path_dataset = self.path_building(id_sd, id_building)
            return "{}wifi_{}.csv".format(path_dataset, id_building)

        def get_filename_building_floor_model(self, id_sd, id_building, model, name):
            path_dataset = self.path_building(id_sd, id_building)
            return "{}floor_model_{}_{}_{}.joblib".format(path_dataset, id_building, model, name)

        def get_filename_building_model(self, id_sd, id_building, z, model, name):
            path_dataset = self.path_building(id_sd, id_building)
            return "{}model_building_{}_floor_{}_{}_{}.joblib".format(path_dataset, id_building, z, model, name)

        def get_filename_sd_model(self, id_sd, model, name):
            path_sd = self.path_sd(id_sd)
            return "{}model_{}_{}.joblib".format(path_sd, model, name)

        def save_wifi_rssi(self, id_sd, id_building, wifi, position, ble, also_ble=False):
            path_dataset = self.get_filename_dataset_wifi(id_sd, id_building)
            df = self.read_df_building(id_sd, id_building)
            df_dict = df.reset_index().to_dict('records')
            to_add = {"wifi_{}".format(wf["mac"]): wf["rssi"] for wf in wifi}
            to_add['x'] = position["x"]
            to_add['y'] = position["y"]
            to_add['z'] = position["z"]
            to_add['id_building'] = id_building

            if also_ble:
                # add the ble info
                for node_mac_address in ble:
                    if node_mac_address != "status" and "rndm" not in node_mac_address:
                        TIME_THRESHOLD = 3  # 3 seconds of threshold: if the difference is higher I don't take them
                        recent_values = [b_val["value"] for b_val in ble[node_mac_address]
                                         if b_val["timestamp"] + datetime.timedelta(0, seconds=TIME_THRESHOLD) >
                                         datetime.datetime.now()]
                        if len(recent_values) <= 0:
                            recent_values = [-100]
                        to_add["ble_{}".format(node_mac_address)] = mean(recent_values)
            to_add['date'] = pd.to_datetime("today")
            df_dict.append(to_add)
            df = pd.DataFrame(df_dict)
            df.set_index('date', inplace=True)
            df.to_csv(path_dataset)

        def read_df_building(self, id_sd, id_building):
            path_dataset = self.get_filename_dataset_wifi(id_sd, id_building)
            try:
                df = pd.read_csv(path_dataset)
            except:
                df = pd.DataFrame()
            try:
                df.set_index('date', inplace=True)
            except:
                pass    # if dataset is empty
            return df

        def read_df_sd(self, sd_instance):
            df = pd.concat([self.read_df_building(sd_instance.id, b.id) for b in sd_instance.buildings])
            return df

        def save_building_floor_model(self, id_sd, id_building, model_name, name, model):
            path_model = self.get_filename_building_floor_model(id_sd, id_building, model_name, name)
            dump(model, path_model)

        def save_building_model(self, id_sd, id_building, z, model_name, name, model):
            path_model = self.get_filename_building_model(id_sd, id_building, z, model_name, name)
            dump(model, path_model)

        def load_building_model(self, id_sd, id_building, z, model, name):
            path_model = self.get_filename_building_model(id_sd, id_building, z, model, name)
            return load(path_model)

        def load_building_floor_model(self, id_sd, id_building, model, name):
            path_model = self.get_filename_building_floor_model(id_sd, id_building, model, name)
            return load(path_model)

        def load_building_models(self, id_sd, model, name):
            from map.elements.planimetry.sd_instance import SmartDirectionInstance
            sd_instance: SmartDirectionInstance = self.read_smartdirections_instance(id_sd)
            models = {}
            for b in sd_instance.buildings:
                min_z, max_z = b.getFloorRange()
                models_building = {}
                for z in range(min_z, max_z):
                    models_building.update({z: self.load_building_model(id_sd, b.id, z, model, name)})
                models.update({b.id: models_building})

            return models

        def load_building_floor_models(self, id_sd, model, name):
            from map.elements.planimetry.sd_instance import SmartDirectionInstance
            sd_instance: SmartDirectionInstance = self.read_smartdirections_instance(id_sd)
            return {b.id: self.load_building_floor_model(id_sd, b.id, model, name) for b in sd_instance.buildings}

        def save_sd_model(self, id_sd, model_name, name, model):
            path_model = self.get_filename_sd_model(id_sd, model_name, name)
            dump(model, path_model)

        def load_sd_model(self, id_sd, model, name):
            path_model = self.get_filename_sd_model(id_sd, model, name)
            return load(path_model)

        '''
        Loads the 3D points associated to a building with discrimination of indoor and outdoor
        '''
        def read_points_from_txt(self, file_path=None, f=None, floors=None):
            assert file_path is not None or f is not None, "No file"
            if f is None:
                # file_path = "{}{}".format(file_path, "map-v1/points.txt")
                f = open(file_path, 'r')
            lines = f.readlines()
            points: list[Point3D] = []
            # parse the file to have list of x, y, z vals
            for line in lines:
                vals = line.split(",")
                x, y, z = float(vals[0]), float(vals[1]), float(vals[2])
                r, g, b = 0, 0, 0
                if len(vals) > 3:
                    r, g, b = int(vals[3]), int(vals[4]), int(
                        vals[5])
                isIndoor = (r == 255)
                if floors is None or z in floors:
                    isLectureRoom, isWideArea, isHallway, isStair, isToilet, isLift = \
                        (g == 0), (g == 30), (g == 60), (g == 90), (g == 120), (g == 150)
                else:
                    # here we have for sure a stair point, as the floors were defined and z is not in floors
                    isLectureRoom, isWideArea, isHallway, isStair, isToilet, isLift = \
                        False, False, False, True, False, False
                # we are currently not using all these info: only stair and indoor
                # TODO it would be great to cluster the rooms and init them with a PoI
                points.append(
                    Point3D.buildPoint(x, y, z, isIndoor, isLectureRoom, isWideArea, isHallway, isStair, isToilet,
                                       isLift))
            return points

        def read_floors_z(self, file_path):
            f = open(file_path, 'r')
            lines = f.readlines()
            z_vals = []
            # parse the file to have list of x, y, z vals
            for line in lines:
                vals = line.split(",")
                z_vals.append(float(vals[2]))
            return z_vals

        def parse_node(self, idx, node):
            # splits = node.split(r'\t+')
            splits = list(filter(lambda x: x != "", node.replace("\n", "").split(" ")))
            assert len(splits) == 4, "Wrong init of node"
            return Node(idx, float(splits[0]), float(splits[1]), splits[2], splits[3])

        def parse_effector(self, idx, effector):
            splits = list(filter(lambda x: x != "", effector.replace("\n", "").split(" ")))
            assert len(splits) == 4, "Wrong init of effector"
            return Effector(idx, float(splits[0]), float(splits[1]), splits[2], splits[3])

        def read_nodes(self):
            nodes = []
            with open(self.data_dir + "nodes.txt", "r") as nodes_data:
                for i, data in enumerate(nodes_data):
                    if i > 0:
                        nodes.append(self.parse_node(i, data))
                    else:
                        num_nodes = int(data.replace("\n", ""))
            adjacency = {}
            with open(self.data_dir + "adjacency.txt", "r") as adjacency_matrix:
                # saving adjacency as dictionary
                for i, adjacency_row in enumerate(adjacency_matrix):
                    adjacency[i] = []
                    for j, val in enumerate(adjacency_row.split(r'\t+')):
                        if val == "1":
                            adjacency[i].append(j)
            return Nodes(nodes, adjacency)

        def read_effectors(self):
            effectors = []
            with open(self.data_dir + "effectors.txt", "r") as effectors_data:
                for i, data in enumerate(effectors_data):
                    if i > 0:
                        effectors.append(self.parse_effector(i, data))
                    else:
                        num_effectors = int(data.replace("\n", ""))
            return Effectors(effectors)

    __instance = None

    def __init__(self, data_dir=None):
        if not Parser.__instance:
            if data_dir is None:
                print("WARNING: data dir was none")
                data_dir = "/Users/filipkrasniqi/PycharmProjects/smartdirections/assets/smart_directions/"
            Parser.__instance = Parser.__Parser(data_dir)
        else:
            if data_dir is not None:
                Parser.__instance.data_dir = data_dir

    def __getattr__(self, name):
        return getattr(self.__instance, name)

    def getInstance(self):
        return Parser.__instance


import os
import pickle
from random import randrange
from collections import defaultdict, Counter

print("Loading the uni and bigram counts")
this_dir, this_filename = os.path.split(__file__)
corpus = os.path.join(this_dir, "data", "telugu.bigram")
beg_line, end_line, unicount, bicount = pickle.load(open(corpus, "rb"))

def get_word(length):
    char, sample_text = ' ', ''

    for j in range(length):
        char = list(bicount[char].elements())[randrange(unicount[char])]
        if char == end_line:
            char = ' '
        sample_text += char

    return sample_text


'''
Given the head of a Singly LinkedList that contains a cycle, write a function to find the starting node of the cycle.

'''

from __future__ import print_function

class Node:
    def __init__(self, value, next=None):
        self.value = value
        self.next = next

    def print_list(self):
        temp = self
        while temp:
            print(temp.value, end='->')
            temp = temp.next

        print()

def find_cycle_start(head):
    cycle_length = 0

    # find the LinkedList cycle
    slow = head
    fast = head

    while fast is not None and fast.next is not None:
        fast = fast.next.next
        slow = slow.next

        if slow == fast:  # found the cycle
            cycle_length = calculate_cycle_length(slow)
            break

    return find_start(head, cycle_length)

def calculate_cycle_length(slow):
    current = slow
    cycle_length = 0

    while True:
        current = current.next
        cycle_length += 1

        if current == slow:
            break

    return cycle_length

def find_start(head, cycle_length):
    pointer1 = head
    pointer2 = head

    # move pointer2 ahead 'cycle_length' nodes
    while cycle_length > 0:
        pointer2 = pointer2.next
        cycle_length -= 1

    # increment both pointers until they meet at the start of the cycle
    while pointer1 != pointer2:
        pointer1 = pointer1.next
        pointer2 = pointer2.next

    return pointer1

def main():
    head = Node(1)
    head.next = Node(2)
    head.next.next = Node(3)
    head.next.next.next = Node(4)
    head.next.next.next.next = Node(5)
    head.next.next.next.next.next = Node(6)

    print(find_cycle_start(head).value)

    head.next.next.next.next.next.next = head.next.next
    print(find_cycle_start(head).value)

main()

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):

    def find_start(self, slow, temp):
        pointer_1 = slow
        pointer_2 = temp

        while pointer_1 != pointer_2:
            pointer_1 = pointer_1.next
            pointer_2 = pointer_2.next

        return pointer_1

    def detectCycle(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """

        temp = head
        fast = head
        slow = head

        while fast is not None and fast.next is not None:

            fast = fast.next.next
            slow = slow.next

            if fast == slow:
                return self.find_start(slow, temp)

        return None


def validBST(node):
    return validBSTHelper(node, float('-inf'), float('inf'))

def validBSTHelper(node, minVal, maxVal):
    if node is None:
        return True

    print(str(minVal)+':'+str(node.val)+':'+str(maxVal))

    if node.val < minVal or node.val > maxVal:
        return False

    return validBSTHelper(node.left, minVal, node.val) and validBSTHelper(node.right, node.val, maxVal)
'''
Valid BST
         10
       /    \
      5     15
     / \   /  \
    2   5 13  22
   /        \
  1         14

10)    v(10, -inf, inf)                                              -inf:10:inf
5|15)    v(5, -inf, 10) && v(15, 10, inf)                     -inf:5:10           10:15:inf
2|5)       v(2, -inf, 5) && v(5, 5, 10)                    -inf:2:5  5:5:10   10:13:15     15:22:inf
1)           v(1, -inf, 2)                               -inf:1:2                13:14:15
1)             return True
2)           return True
5)         return True && v(5, 5, 10)
_|5)         return True
5)         return True && True

'''
class N:
    def __init__(self, value):
        self.val = value
        self.left = None
        self.right = None

n10, n5, n15, n2, n5_2, n1, n13, n22, n14 = N(10), N(5), N(15), N(2), N(5), N(1), N(13), N(22), N(14)
n10.left, n10.right = n5, n15
n5.left, n5.right = n2, n5_2
n2.left = n1
n15.left, n15.right = n13, n22
n13.right = n14
print('TEST VALID BST')
print(validBST(n10))
print('TEST RETURN INVALID BST')
'''
Invalid BST
         10
       /    \
      5     15
     / \   /  \
    2   4 13  22
   /        \
  1         14
'''

n10, n5, n15, n2, n4, n1, n13, n22, n14 = N(10), N(5), N(15), N(2), N(4), N(1), N(13), N(22), N(14)
n10.left, n10.right = n5, n15
n5.left, n5.right = n2, n4
n2.left = n1
n15.left, n15.right = n13, n22
n13.right = n14

print(validBST(n10))

print('TEST LESS THAN OR EQUAL TO THE RIGHT')
'''
Invalid BST
         5
       /    \
      5     15
     / \   /  \
    2   5 13  22
   /        \
  1         14
'''

n5_0, n5, n15, n2, n5_2, n1, n13, n22, n14 = N(5), N(5), N(15), N(2), N(5), N(1), N(13), N(22), N(14)
n5_0.left, n5_0.right = n5, n15
n5.left, n5.right = n2, n5_2
n2.left = n1
n15.left, n15.right = n13, n22
n13.right = n14

print(validBST(n5_0))


import os
import json
from cati.frontend import Env
from cati.frontend.SysArch import sys_arch
from .exceptions import CannotReadFileException
from packaging import version
from cati.helpers.hash import calc_file_sha256

class Pkg:
    """ Package model """

    def __init__(self, data: dict):
        self.data = data
        try:
            self.data['repo']
        except:
            self.data['repo'] = 'Local'
        self.data['version'] = self.data['version'].strip()

    def installed(self) -> (str, bool):
        """ Checks current package is installed. if yes, returns installed version and if not, returns False """
        if not Pkg.is_installed(self.data['name']):
            return False

        return Pkg.installed_version(self.data['name'])

    def installed_static_files(self) -> list:
        """
        returns list of installed files of package

        Returns:
            list[str]: files paths
        """
        if not self.installed():
            return False
        installed_static_files_list = open(Env.installed_lists('/' + self.data['name'] + '/staticfiles'), 'r').read().strip()
        installed_static_files_list = installed_static_files_list.split('\n')
        installed_static_files_list = [item.strip().split('@', 1) for item in installed_static_files_list if item.strip() != '']
        return installed_static_files_list

    def get_depends(self) -> list:
        """ Returns package dependencies list """
        try:
            return self.data['depends']
        except:
            return []

    def get_recommends(self) -> list:
        """ Returns package recommends list """
        try:
            return self.data['recommends']
        except:
            return []

    def get_conflicts(self) -> list:
        """ Returns package conflicts list """
        try:
            return self.data['conflicts']
        except:
            return []

    def get_replaces(self) -> list:
        """ Returns package replaces list """
        try:
            return self.data['replaces']
        except:
            return []

    def get_conffiles(self) -> list:
        """ Returns package conffiles list """
        try:
            return self.data['conffiles']
        except:
            return []

    def get_static_files(self) -> list:
        """ returns package static files list """
        try:
            return self.data['staticfiles']
        except:
            return []

    def get_reverse_depends(self) -> list:
        """ Returns list of packages has dependency to this package

        Returns:
            list[Pkg]: list of packages has dependency to this package
        """
        try:
            rd_pkgs_list_f = open(Env.packages_lists('/' + self.data['name'] + '/reverse_depends'), 'r')
            rd_pkgs_list = rd_pkgs_list_f.read().strip().split('\n')
            rd_pkgs_list_f.close()
        except:
            rd_pkgs_list = []
        rd_pkgs = []
        for item in rd_pkgs_list:
            if Pkg.is_installed(item):
                rd_pkgs.append(Pkg.load_version(item, Pkg.installed_version(item)))
            else:
                rd_pkgs.append(Pkg.load_last(item))
        reverse_depends = []
        for pkg in rd_pkgs:
            if pkg.installed():
                pkg = Pkg.load_version(pkg.data['name'], pkg.installed())
            for dep in pkg.get_depends():
                if dep.strip()[0] != '@':
                    result = Pkg.check_state(dep, virtual={
                        'remove': [
                            [
                                self.data['name'], self.data['version']
                            ]
                        ],
                        'all_real_is_installed': True
                    })
                    if not result:
                        reverse_depends.append(pkg)
        return reverse_depends

    def get_reverse_conflicts(self) -> list:
        """ Returns list of packages has conflicts with this package

        Returns:
            list[Pkg]: list of packages has conflict with this package"""
        try:
            rd_pkgs_list_f = open(Env.packages_lists('/' + self.data['name'] + '/reverse_conflicts'), 'r')
            rd_pkgs_list = rd_pkgs_list_f.read().strip().split('\n')
            rd_pkgs_list_f.close()
        except:
            rd_pkgs_list = []
        rd_pkgs = []
        for item in rd_pkgs_list:
            if Pkg.is_installed(item):
                rd_pkgs.append(Pkg.load_version(item, Pkg.installed_version(item)))
        reverse_conflicts_list = []
        for pkg in rd_pkgs:
            conflicts = pkg.get_conflicts()
            for conflict in conflicts:
                result = Pkg.check_state(conflict, {'install': [
                    [
                        self.data['name'], self.data['version']
                    ]
                ], 'no_real_installs': True})
                if result:
                    pkg.conflict_error = conflict
                    reverse_conflicts_list.append(pkg)
        return reverse_conflicts_list

    def get_file_size_str(self) -> str:
        """
        Returns file size of the package as str (for example `32 MB`)

        Returns:
            str: file size str
        """
        try:
            file_size = self.data['file_size']
        except:
            file_size = 0

        return Pkg.get_download_size_str(file_size)

    @staticmethod
    def get_download_size_str(dsize: int) -> str:
        """
        Returns file size str from bytes interger

        Args:
            dsize: bytes count

        Returns:
            str: download str
        """
        return str(dsize) + ' B'

    def get_versions_list(self):
        """
        returns versions list of the package

        Returns:
            list: list of versions: [ [<version>, <arch>] ]
        """
        try:
            f_index = open(Env.packages_lists('/' + self.data['name'] + '/index'), 'r')
            index_json = json.loads(f_index.read())
            f_index.close()
        except:
            return []

        try:
            versions = []
            for k in index_json:
                for ver in index_json[k]:
                    versions.append([ver, k])
            return versions
        except:
            return []

    @staticmethod
    def get_all_installed_files_list() -> list:
        """
        returns list of all of installed files

        Returns:
            list: [
                ['pkgname', 'filetype(d,f,cd,cf)', '/file/path'],
                ['pkg1', 'f', '/path/to/file'],
                ...
            ]
        """
        # load list of installed packages
        installed_packages = Pkg.installed_list()['list']
        result = []
        for pkg in installed_packages:
            pkg_installed_files = open(Env.installed_lists('/' + pkg.data['name'] + '/files'), 'r').read()
            pkg_installed_files = pkg_installed_files.strip().split('\n')
            pkg_installed_files = [item.strip().split(':', 1) for item in pkg_installed_files]
            for f in pkg_installed_files:
                if len(f) > 1:
                    result.append([pkg.data['name'], f[0], f[1]])
        return result

    @staticmethod
    def load_last(pkg_name: str) -> bool:
        """ Load last version of package by name

        Args:
            pkg_name (str): the package name

        Returns:
            bool (False): package not found
            Pkg: the loaded Pkg boject
        """
        pkgs_list = Pkg.all_list()
        for item in pkgs_list['list']:
            if item.data['name'] == pkg_name:
                return item
        return False

    @staticmethod
    def is_installed(package_name: str) -> bool:
        """ Gets a package name and checks is installed or not

        Args:
            package_name (str): the package name you want to check is installed

        Returns:
            bool
        """
        try:
            assert os.path.isdir(Env.installed_lists('/' + package_name))
            assert os.path.isfile(Env.installed_lists('/' + package_name + '/ver'))
            assert os.path.isfile(Env.installed_lists('/' + package_name + '/files'))
            return True
        except:
            return False

    @staticmethod
    def is_installed_manual(package_name: str) -> bool:
        """ Gets a package name and checks is installed MANUAL or not

        Args:
            package_name (str): the package name you want to check is installed

        Returns:
            bool
        """
        if not Pkg.is_installed(package_name):
            return False
        return os.path.isfile(Env.installed_lists('/' + package_name + '/manual'))

    @staticmethod
    def load_version(pkg_name: str, version: str, arch=''):
        """
        loads a specify version of a package

        Args:
            pkg_name (str): name of package
            version (str): that version you want to load
            arch (str): load specify arch (optional)

        Returns:
            int (1): package not found
            int (2): package found, but version/arch not found
            Pkg object: package and version found and returned
        """
        if not os.path.isfile(Env.packages_lists('/' + pkg_name + '/index')):
            return 1

        # load package index file
        f_index = open(Env.packages_lists('/' + pkg_name + '/index'), 'r')
        index_content = f_index.read()
        f_index.close()

        try:
            # load json
            index = json.loads(index_content)
        except:
            return 1

        # load package versions list
        versions = []
        try:
            versions = index[arch]
        except:
            try:
                versions = index[SysArch.sys_arch()]
                arch = SysArch.sys_arch()
            except:
                try:
                    versions = index['all']
                    arch = 'all'
                except:
                    versions = index[list(index.keys())[0]]
                    arch = list(index.keys())[0]

        for ver in versions:
            if ver == version:
                # load this version data
                try:
                    f_ver = open(Env.packages_lists('/' + pkg_name + '/' + ver + '-' + arch), 'r')
                    f_ver_content = f_ver.read()
                    ver_data = json.loads(f_ver_content)
                    return Pkg(ver_data)
                except:
                    return 2
        return 2

    @staticmethod
    def installed_version(package_name: str) -> str:
        """ Gets name of package and returns installed version of that

        Args:
            package_name (str): name of package

        Returns:
            str: installed version

        Raises:
            package.exceptions.CannotReadFileException: when cannot read package database files
        """
        try:
            f = open(Env.installed_lists('/' + package_name + '/ver'), 'r')
            version = f.read()
            f.close()
        except:
            raise CannotReadFileException('cannot read file "' + Env.installed_lists('/' + package_name + '/ver') + '"')
        return version

    @staticmethod
    def installed_list() -> dict:
        """ Returns list of only installed packages

        Returns:
            dict: output has two keys:
                  {
                      "list": list[Pkg] // list of packages
                      "errors": list // errors while loading packages
                  }
        """
        all_packages = Pkg.all_list()
        installed_packages = {
            'errors': all_packages['errors'],
            'list': [],
        }
        for pkg in all_packages['list']:
            if pkg.installed():
                installed_packages['list'].append(pkg)

        return installed_packages

    @staticmethod
    def all_list():
        """ Returns list of packages

        Returns:
            dict: output has two keys:
                  {
                      "list": list[Pkg] // list of packages
                      "errors": list // errors while loading packages
                  }
        """

        errors = []
        packages = []

        tmp_list = os.listdir(Env.packages_lists())
        tmp_list.sort()
        for item in tmp_list:
            if os.path.isfile(Env.packages_lists('/' + item + '/index')):
                f_index = open(Env.packages_lists('/' + item + '/index'), 'r')
                try:
                    index_content = f_index.read()
                    try:
                        index_json = json.loads(index_content)
                        try:
                            pkg = Pkg.load_from_index(index_json, item)
                            packages.append(pkg)
                        except:
                            if not (os.path.isfile(Env.packages_lists('/' + item + '/reverse_depends')) or os.path.isfile(Env.packages_lists('/' + item + '/reverse_conflicts'))):
                                errors.append('faild to load package "' + item + '"')
                    except:
                        errors.append('invalid json content in "' + Env.packages_lists('/' + item + '/index') + '"')
                except:
                    errors.append('cannot read file "' + Env.packages_lists('/' + item + '/index') + '"')
            else:
                errors.append(f'package "{item}" has not index file in lists ({Env.packages_lists("/" + item + "/index")} not found)')

        return {'list': packages, 'errors': errors}

    @staticmethod
    def compare_version(a: str, b: str):
        """
        Compares two versions.

        Args:
            a (str): first version
            b (str): second version

        Returns:
            if 1 is returned means a is upper than b.
            if 0 is returned means a equals b.
            if -1 is returned means a is less than b.
        """
        a = version.parse(a)
        b = version.parse(b)

        if a > b:
            return 1

        if a == b:
            return 0

        if a < b:
            return -1

    @staticmethod
    def get_last_version(versions: list) -> str:
        """ Gets a list from versions and returns latest version in that list

        Args:
            versions (list[str]): list of versions you want find last of them

        Returns:
            str: the last version in the list
        """
        max_ver = ''
        for version in versions:
            if Pkg.compare_version(version, max_ver) == 1:
                max_ver = version

        return max_ver

    @staticmethod
    def load_from_index(index_json: dict, package_name: str):
        """ Loads package data from index file

        Args:
            package_name (str): name of the package
            index_json (dict): loaded json data from `/var/lib/cati/lists/<pkgname>/index` file

        Returns:
            Pkg: the loaded Pkg object
        """
        try:
            arch = sys_arch()
            versions = index_json[arch]
        except:
            try:
                arch = 'all'
                versions = index_json[arch]
            except:
                arch = list(index_json.keys())[0]
                versions = index_json[arch]

        # load latest version
        ver = Pkg.get_last_version(versions)

        f = open(Env.packages_lists('/' + package_name + '/' + ver + '-' + arch), 'r')
        content = f.read()
        f.close()

        content_json = json.loads(content)

        return Pkg(content_json)

    def check_state(query_string: str, virtual=None, get_false_pkg=False, get_false_pkg_next=0, get_true_pkg=False, get_true_pkg_next=0, only_parse=False) -> bool:
        """
        Checks package state by query string.

        Examples:
        "somepackage >= 1.5",
        "somepackage",
        "somepackage = 2.0",
        "somepackage < 1.7",
        "pkga | pkgb >= 1.0",
        "pkga | pkgb | pkgc",
        "pkga | pkgb & pkgc = 1.0",

        also there is a feature to check files:

        "@/usr/bin/somefile",
        "somepackage | @/path/to/somefile",
        "testpkga >= 3.0 | @/somefile"
        "@/file/one | @/file/two",
        "@<sha256-hash>@/path/to/file",
        "@76883f0fd14015c93296f0e4202241f4eb3a23189dbc17990a197477f1dc441a@/path/to/file"

        `virtual` argument:

        this argument can make a virtual package state
        for example package `testpkgz` is not installed,
        but we want to check the query when this is installed
        we can set that package in virtual system to query checker
        calculate tha package as installed/removed
        virtual structure: this is dictonary:
        {
            'install': [
                ## a list from installed packages:
                ['testpkgx', '1.0'],
                ['testpkgz', '3.7.11'],
                ...
            ]

            'remove': [
                ## a list from removed packages:
                ['testpkgx', '1.0'],
                ['testpkgz', '3.7.11'],
                ...
            ]

            ## set it True if you want to ignore real installations
            'no_real_installs': True/False

            ## set it True if you want to ignore real not installations
            'all_real_is_installed': True/False
        }
        """

        # parse query string
        parts = query_string.strip().split('|')
        orig_parts = []
        for part in parts:
            tmp = part.strip().split('&')
            orig_parts.append(tmp)

        # load virtual item
        no_real_installs = False
        all_real_is_installed = False
        if virtual:
            try:
                tmp = virtual['install']
            except:
                virtual['install'] = []
            try:
                tmp = virtual['remove']
            except:
                virtual['remove'] = []
            virtual_installed_names_list = []
            virtual_installed_versions_dict = {}
            for item in virtual['install']:
                virtual_installed_versions_dict[item[0]] = item[1]
                virtual_installed_names_list.append(item[0])
            virtual_removed_names_list = []
            virtual_removed_versions_dict = {}
            for item in virtual['remove']:
                virtual_removed_versions_dict[item[0]] = item[1]
                virtual_removed_names_list.append(item[0])
            try:
                no_real_installs = virtual['no_real_installs']
            except:
                no_real_installs = False
            try:
                all_real_is_installed = virtual['all_real_is_installed']
            except:
                all_real_is_installed = False
        else:
            virtual_installed_names_list = []
            virtual_installed_versions_dict = {}
            virtual_removed_names_list = []
            virtual_removed_versions_dict = {}
            no_real_installs = False
            all_real_is_installed = False

        # parse once query
        i = 0
        while i < len(orig_parts):
            j = 0
            while j < len(orig_parts[i]):
                orig_parts[i][j] = orig_parts[i][j].strip()
                spliter = None
                if '>=' in orig_parts[i][j]:
                    spliter = '>='
                elif '<=' in orig_parts[i][j]:
                    spliter = '<='
                elif '>' in orig_parts[i][j]:
                    spliter = '>'
                elif '<' in orig_parts[i][j]:
                    spliter = '<'
                elif '=' in orig_parts[i][j]:
                    spliter = '='
                if spliter != None:
                    orig_parts[i][j] = orig_parts[i][j].split(spliter)
                    orig_parts[i][j].insert(1, spliter)
                else:
                    orig_parts[i][j] = [orig_parts[i][j]]
                z = 0
                while z < len(orig_parts[i][j]):
                    orig_parts[i][j][z] = orig_parts[i][j][z].strip()
                    z += 1
                j += 1
            i += 1

        if only_parse:
            return orig_parts

        # check query
        for tmp in orig_parts:
            ands_ok = True
            for p in tmp:
                if p[0][0] == '@':
                    # check file query
                    parts = p[0].split('@')
                    if len(parts) == 2:
                        if not os.path.exists(Env.base_path(parts[-1])):
                            ands_ok = False
                    elif len(parts) == 3:
                        if not os.path.exists(Env.base_path(parts[-1])):
                            ands_ok = False
                        else:
                            if os.path.isfile(Env.base_path(parts[-1])):
                                sha256_sum = calc_file_sha256(Env.base_path(parts[-1]))
                                if parts[1] != sha256_sum:
                                    ands_ok = False
                elif not p[0] in virtual_installed_names_list and no_real_installs:
                    ands_ok = False
                    if get_false_pkg and get_false_pkg_next <= 0:
                        return p
                    else:
                        get_false_pkg_next -= 1
                elif not p[0] in virtual_removed_names_list and all_real_is_installed:
                    pass
                elif len(p) == 1:
                    if not Pkg.is_installed(p[0]) and not p[0] in virtual_installed_names_list or p[0] in virtual_removed_names_list:
                        ands_ok = False
                        if get_false_pkg and get_false_pkg_next <= 0:
                            return p
                        else:
                            get_false_pkg_next -= 1
                elif len(p) == 3:
                    if not Pkg.is_installed(p[0]) and not p[0] in virtual_installed_names_list or p[0] in virtual_removed_names_list:
                        ands_ok = False
                        if get_false_pkg and get_false_pkg_next <= 0:
                            return p
                        else:
                            get_false_pkg_next -= 1
                    else:
                        if p[0] in virtual_installed_names_list:
                            a_ver = virtual_installed_versions_dict[p[0]]
                        else:
                            a_ver = Pkg.installed_version(p[0])
                        b_ver = p[2]
                        if p[1] == '=':
                            if Pkg.compare_version(a_ver, b_ver) != 0:
                                ands_ok = False
                                if get_false_pkg and get_false_pkg_next <= 0:
                                    return p
                                else:
                                    get_false_pkg_next -= 1
                        elif p[1] == '>':
                            if Pkg.compare_version(a_ver, b_ver) != 1:
                                ands_ok = False
                                if get_false_pkg and get_false_pkg_next <= 0:
                                    return p
                                else:
                                    get_false_pkg_next -= 1
                        elif p[1] == '<':
                            if Pkg.compare_version(a_ver, b_ver) != -1:
                                ands_ok = False
                                if get_false_pkg and get_false_pkg_next <= 0:
                                    return p
                                else:
                                    get_false_pkg_next -= 1
                        elif p[1] == '<=':
                            if Pkg.compare_version(a_ver, b_ver) != -1 and Pkg.compare_version(a_ver, b_ver) != 0:
                                ands_ok = False
                                if get_false_pkg and get_false_pkg_next <= 0:
                                    return p
                                else:
                                    get_false_pkg_next -= 1
                        elif p[1] == '>=':
                            if Pkg.compare_version(a_ver, b_ver) != 1 and Pkg.compare_version(a_ver, b_ver) != 0:
                                ands_ok = False
                                if get_false_pkg and get_false_pkg_next <= 0:
                                    return p
                                else:
                                    get_false_pkg_next -= 1
                        else:
                            ands_ok = False
                            if get_false_pkg and get_false_pkg_next <= 0:
                                return p
                            else:
                                get_false_pkg_next -= 1
                if ands_ok and get_true_pkg and get_true_pkg_next <= 0:
                    return p
                else:
                    get_true_pkg_next -= 1
            if ands_ok:
                return True

        return False


class Solution:
    def rob(self, nums: List[int]) -> int:
        if len(nums) <= 2:
            return max(nums)

        a, b, c = nums[0], nums[1], nums[0] + nums[2]
        for i in range(3, len(nums)):
            d = nums[i] + max(a, b)
            a, b, c = b, c, d
        return max(a, b, c)


class Solution:
    def winnerOfGame(self, colors: str) -> bool:
        countOfA = 0
        countOfB = 0
        lengthOfString = len(colors)
        for i in range(lengthOfString - 2):
            if colors[i: i + 3] == 'AAA':
                countOfA += 1
            elif colors[i: i + 3] == 'BBB':
                countOfB += 1
        return countOfA > countOfB


import collections

import numpy as np
import re

def toInt(c):
    return [int(e) for e in c]

def msplit(s, ds=None):

    if ds is None:
        ds = ' '

    patt = '|'.join(ds)
    res = re.split(patt, s)
    res = [e for e in res if e != '']
    res = [int(e) if e.isnumeric() else e for e in res]

    return res

def f01():
    with open('input') as file:
        lines = file.read().splitlines()

        lines = toInt(lines)

        preamble_len = 25

        fifo = collections.deque([0] * preamble_len)

        for e in lines[:preamble_len]:
            fifo.appendleft(e)

        lines = lines[preamble_len:]

        def find_pair(num):
            for a in fifo:
                for b in fifo:
                    if a + b == num and a != b:
                        return True
            return False

        for line in lines:
            if not find_pair(line):
                print(line)
                return

            fifo.pop()
            fifo.appendleft(line)

def f02():
    to_find = 1212510616

    with open('input') as file:
        lines = file.read().splitlines()

        lines = toInt(lines)

        fifo = collections.deque([])

        for line in lines:
            if sum(fifo) < to_find:
                fifo.appendleft(line)
            if sum(fifo) == to_find:
                fifo = sorted(fifo)
                print(fifo[0] + fifo[-1])
                return
            while sum(fifo) > to_find:
                fifo.pop()

def main():
    f01()
    f02()

if __name__ == "__main__":
    """ This is executed when run from the command line """
    main()


#!/usr/bin/python3

"""This function divides each memebers of the list
by the div, and there are certain conditions that
affects the operations. The parameter matrix is the
has to be list of lists and the parameter div shoud be
either integer or float
"""

def matrix_divided(matrix, div):
    """Diving matrixe by div"""

    if not type(matrix) == list or not all(
            isinstance(ty, list) for ty in matrix):
        raise TypeError(
                "matrix must be a matrix (list of lists) of integers/floats")
    size_list = 0
    for _list in matrix:
        if size_list == 0:
            size_list = len(_list)
        elif size_list != len(_list):
            raise TypeError("Each row of the matrix must have the same size")
        if not all(isinstance(j, (int, float)) for j in _list):
            raise TypeError(
                "matrix must be a matrix (list of lists) of integers/floats"
            )
    if not isinstance(div, (int, float)):
        raise TypeError("div must be a number")
    if div == 0:
        raise ZeroDivisionError("division by zero")
    return [[round(i / div, 2) for i in _list] for _list in matrix]

if __name__ == "__main__":
    import doctest
    doctest.testmod()


# search
texto = "Hola, mi nombre es Daniel"
import re

#Permite buscar una cadena de variables, devuelve un objeto tipo Match
resultado = re.search("nombre", texto)

re.search("Daniel$", texto) #con el signo dolar buscará la última palabra de la cadena
re.search("^Hola", texto)#Buscara por la primera palabra de la cadena de texto
re.search("mi.*es", texto)# El punto y el * sirven para buscar lo que este entre medias de las palabras
if (resultado):
    print: ("Cadena encontrada")
else:
    print:("Cadena NO encontrada")

#findall

texto1 = """
Por ahora estoy aprendiendo python y logro
notar como puedo utilizar expresiones regulares por medio
de la libreria re
"""

re.findall("libreria.*python",texto1)# devuelve una lista con todas las coincidencias de en la linea con esas palabras

#split
texto2 = "La silla es blanca y vale 80"
re.split("\s", texto2)#sirve para dividir las palabras de las cadenas

#sub
texto3 ="La silla blanca vale 80"
re.sub("blanca","roja",texto3)#sustitulle la palabra indicada por la que sigue


import contextlib
import re
from abc import ABC, abstractmethod
from contextvars import ContextVar, Token
from dataclasses import dataclass
from types import TracebackType
from typing import Generator, Optional, Type

from sqlalchemy import Column, Integer, MetaData, String, Table
from sqlalchemy.engine import create_engine
from sqlalchemy.orm import registry  # type: ignore
from sqlalchemy.orm.session import Session, sessionmaker

# region Unit Of Work Definition

class UnitOfWork(ABC):
    @staticmethod
    def _get_context_uow() -> "UnitOfWork":
        context = ctx_var_current_uow.get()
        if context is None:
            raise RuntimeError("No context session")
        return context

    __current_ctx_token: Optional["Token[Optional[UnitOfWork]]"] = None

    def set_current_context(self) -> None:
        if self.__current_ctx_token is not None:
            raise RuntimeError("Already have a current context token")

        token = ctx_var_current_uow.set(self)
        self.__current_ctx_token = token

    def remove_current_context(self) -> None:
        if self.__current_ctx_token is None:
            raise RuntimeError("No current context token")
        ctx_var_current_uow.reset(self.__current_ctx_token)

    @abstractmethod
    def commit(self) -> None:
        raise NotImplementedError()

    @abstractmethod
    def rollback(self) -> None:
        raise NotImplementedError()

    @abstractmethod
    def close(self) -> None:
        raise NotImplementedError()

    @abstractmethod
    def __enter__(self) -> "UnitOfWork":
        return self

    @abstractmethod
    def __exit__(
        self, exc_type: Type[Exception], exc_val: Exception, exc_tb: TracebackType
    ) -> None:
        raise NotImplementedError()

ctx_var_current_uow = ContextVar[Optional[UnitOfWork]]("current_uow", default=None)

class UnitOfWorkFactory(ABC):
    def __call__(self) -> UnitOfWork:
        raise NotImplementedError()

# endregion

# region Unit of Work ORM Implementation with SQLAlchemy

class SQAAUnitOfWork(UnitOfWork):
    @staticmethod
    def get_sqa_current_uow() -> "SQAAUnitOfWork":
        context = UnitOfWork._get_context_uow()
        if not isinstance(context, SQAAUnitOfWork):
            raise RuntimeError("Context session is not a SQAAUnitOfWork")
        return context

    @staticmethod
    def get_current_session() -> Session:
        return SQAAUnitOfWork.get_sqa_current_uow().session

    @property
    def session(self) -> Session:
        if not self._session:
            raise RuntimeError("No session")
        return self._session

    _session: Session

    def __init__(self, session_factory: sessionmaker) -> None:
        self._session_factory = session_factory

    def __enter__(self) -> "SQAAUnitOfWork":
        self.set_current_context()
        self._session: Session = self._session_factory()
        return self

    def __exit__(
        self, exc_type: Type[Exception], exc_val: Exception, exc_tb: TracebackType
    ) -> None:
        self.remove_current_context()

        if exc_type is None:
            self.commit()
        else:
            self.rollback()
        self.close()
        if exc_type is not None:
            raise exc_val.with_traceback(exc_tb)

    def commit(self) -> None:
        self.session.commit()

    def rollback(self) -> None:
        self.session.rollback()

    def close(self) -> None:
        return self.session.close()

class SQAUOWFactory(UnitOfWorkFactory):
    def __init__(self, session_factory: sessionmaker) -> None:
        self.session_factory = session_factory

    def __call__(self) -> SQAAUnitOfWork:
        return SQAAUnitOfWork(session_factory=self.session_factory)

# endregion

# region Domain Models

validation_context: ContextVar[bool] = ContextVar("validation_context", default=True)

@contextlib.contextmanager
def using_validation_context(validate: bool) -> Generator[None, None, None]:
    token: Token[bool] = validation_context.set(validate)

    try:
        yield
    finally:
        validation_context.reset(token)

class UserName(str):
    USERNAME_PATTERN = re.compile(r"^[a-zA-Z0-9_-]+$")

    def __new__(cls, value: str) -> "UserName":
        validate = validation_context.get()
        if validate:
            if not value:
                raise ValueError("Username cannot be empty")

            if len(value) > 20:
                raise ValueError("Username is too long")

            if len(value) < 3:
                raise ValueError("Username is too short")

            if not cls.USERNAME_PATTERN.fullmatch(value):
                raise ValueError("Invalid username")

        return super().__new__(cls, value)

class Email(str):
    EMAIL_PATTERN = re.compile(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")

    def __new__(cls, value: str) -> "Email":
        validate = validation_context.get()
        if validate:
            if not value:
                raise ValueError("Email cannot be empty")

            if not cls.EMAIL_PATTERN.fullmatch(value):
                raise ValueError("Invalid email")

        return super().__new__(cls, value)

@dataclass
class User:
    username: UserName
    email: Email

# endregion

# region Domain Logic

class UserStorage(ABC):
    @abstractmethod
    def get_user(self, username: UserName) -> User:
        raise NotImplementedError()

    @abstractmethod
    def create_user(self, user: User) -> None:
        raise NotImplementedError()

    @abstractmethod
    def user_exists(self, username: UserName) -> bool:
        raise NotImplementedError()

class CreateUserUsecase:
    def __init__(
        self, user_storage: UserStorage, uow_factory: UnitOfWorkFactory
    ) -> None:
        self.user_storage = user_storage
        self.uow_factory = uow_factory

    def execute(self, user: User) -> None:
        with self.uow_factory() as uow:

            with using_validation_context(False):
                if self.user_storage.user_exists(user.username):
                    raise ValueError("User already exists")

                self.user_storage.create_user(user)
                uow.commit()

# endregion

# region Domain Models implementation with SQLAlchemy

mapper_registry = registry()  # type: ignore

metadata = MetaData()

## The implementation must OBEY the domain model interface
# For example, the username column has a length of 20, obeying the domain model
users_table = Table(
    "users",
    metadata,
    Column("id", Integer, primary_key=True, autoincrement=True),
    Column("username", String(20), nullable=False, unique=True),
    Column("email", String(50), nullable=False, unique=True),
)

mapper_registry.map_imperatively(User, users_table)

# endregion

# region Domain Logic implementation with SQLAlchemy

class SQAAUserStorage(UserStorage):
    @staticmethod
    def get_current_session() -> Session:
        return SQAAUnitOfWork.get_current_session()

    def get_user(self, username: UserName) -> User:
        session = self.get_current_session()
        row = session.query(User).filter_by(username=username).one()
        return row

    def create_user(self, user: User) -> None:
        session = self.get_current_session()
        session.add(user)

    def user_exists(self, username: UserName) -> bool:
        session = self.get_current_session()
        return session.query(User).filter(User.username == username).count() > 0

# endregion

# region Application

def main() -> None:
    # setup
    engine = create_engine("sqlite:///:memory:")
    metadata.create_all(engine)
    session_factory = sessionmaker(bind=engine)
    uow_factory = SQAUOWFactory(session_factory=session_factory)
    user_storage = SQAAUserStorage()

    # create instances of the domain logic injecting the dependencies
    usecase = CreateUserUsecase(user_storage=user_storage, uow_factory=uow_factory)

    # execute the usecase

    username = "Lusca"
    user_mail = "lusca@gg.com"

    user = User(username=UserName(username), email=Email(user_mail))
    usecase.execute(user)

    # check the result
    with uow_factory() as uow:
        user = user_storage.get_user(UserName(username))
        assert user.username == "Lusca"
        assert user.email == "lusca@gg.com"

# endregion

if __name__ == "__main__":
    main()


import numpy as np
#from getdata import getfootdata
from getdatasmall import getfootdata

class NN():
    def __init__(self,x_siz, y_siz, l_r):
        self.X =list()
        self.Y = list()
        self.numtrain = int
        self.numtest = int
        self.cost = float
        self.Hl = list()
        self.learning_rate = l_r
        self.x_siz = x_siz
        self.y_siz = y_siz
        self.weight = list()
        self.dweight = list()
        self.bias= list()
        self.dbias= list()
        #self.n_epochs = n_epochs
        self.A = list()
        self.Z = list()
        self.Yl = list()

    def initializeparameter(self,Hlayer_dim):
        Hl = Hlayer_dim
        Hl.insert(0,self.x_siz)
        Hl.append(self.y_siz)
        for i in range(len(Hlayer_dim)-1):
            self.weight.append(np.random.randn(Hl[i+1], Hl[i])* 0.01)
            self.bias.append(np.random.randn(Hl[i+1]) * 0.01)

    def getdata(self):
        self.X, self.Y = getfootdata()
        self.numtrain = self.X.shape[1]

    def normalizedata(self):
        pass

    def sigmoid(self,x, deri = False):
        if deri is False:
            shiftx = x - np.max(x,axis=0)
            exps = np.exp(shiftx)
            return exps / np.sum(exps,axis=0)
        else:
            return np.multiply(self.Yl,(1-self.Yl))

    def ReLU(self,x,deri=False):
       # if deri is False:
        #    return np.tanh(x)
        #else:
        #    return 1.0 - np.tanh(x)**2
        c = np.zeros_like(x)
        slope = 1e-2
        if deri:
            c[x<=0] = slope
            c[x>0] = 1
        else:
            c[x>0] = x[x>0]
            c[x<=0] = slope*x[x<=0]
        return c

    def activation(self,a,w,b,activation):
        b = b[:, np.newaxis]
        z = np.dot(w,a) + b
        self.Z.append(z)
        if activation=="relu":
            return self.ReLU(z)
        elif activation == "sigmoid":
            return self.sigmoid(z)

    def feedforward(self):
        A_data = self.X
        for l in range(len(self.bias)):
            if(l==len(self.bias)-1):
                self.A.append(self.activation(A_data,self.weight[l],self.bias[l],"sigmoid"))
                self.Yl = self.A[l]
                self.A.insert(0,self.X)
                continue
            self.A.append(self.activation(A_data,self.weight[l],self.bias[l],"relu"))
            A_data = self.A[l]

    def calc_cost(self):
        m = self.Y.shape[1]
        #print((np.multiply(self.Y,np.log(self.Yl))))
        self.cost = (-1 / m) * np.sum(np.multiply(self.Y,np.log(self.Yl)))
        return self.cost

    def back_activation(self,x,acti):
        if acti is "sigmoid":
            return self.sigmoid(x,True)
        elif acti is "relu":
            return self.ReLU(x,True)

    def linear_back(self,da,a,w,b,acti):
        m = da.shape[1]
        dz = self.back_activation(da,acti)
        dW = np.dot(dz, a.T) / m
        db = np.squeeze(np.sum(dz, axis=1, keepdims=True)) / m
        self.dweight.insert(0,dW)
        self.dbias.insert(0,db)
        dA = np.dot(w.T, dz)
        assert (dA.shape == a.shape)
        assert (dW.shape == w.shape)
        return dA

    def backpropagation(self):
        m = len(self.bias)
        #dAL = - (np.divide(self.Y, self.Yl) - np.divide(1 - self.Y, 1 -self.Yl))
        dAL = self.Yl-self.Y
        dA = self.linear_back(dAL,self.A[m-1],self.weight[m-1],self.bias[m-1],"sigmoid")
        for l in reversed(range(m-1)):
            dA = self.linear_back(dA,self.A[l],self.weight[l],self.bias[l],"relu")

    def update_parameters(self):
        m = len(self.bias)
        #print("w",self.dweight)
        #print("B",self.dbias)
        for l in range(m):
            #assert (self.weight[l].shape == self.dweight[l].shape)
            #assert (self.bias[l].shape == self.dbias[l].shape)
            self.weight[l] = self.weight[l] - self.learning_rate * self.dweight[l]
            self.bias[l] = self.bias[l] - self.learning_rate * self.dbias[l]

        self.Z = []
        self.A = []
        self.dweight = []
        self.dbias = []

    def gradientcheck(self):
        epsi = 10^-7
        thetapprox = []
        theta = []
        # print(np.asarray(self.weight).shape)
        # print(np.asarray(self.bias).shape)
        # print(np.asarray(self.dweight).shape)
        # print(np.asarray(self.dbias).shape)
        for i in range(len(self.bias)):
            thetapprox.append(self.weight[i])
            thetapprox.append(self.bias[i])
            theta.append(self.dweight[i])
            theta.append(self.dbias[i])
        theta = np.asarray(theta)
        theta = theta[:, np.newaxis]
        thetapprox = np.asarray(thetapprox)
        thetapprox = thetapprox[:, np.newaxis]
        print(theta)
        print(thetapprox)
        for i in range(len(theta)):
            thetapprox[i] = (thetapprox[i] + epsi) - (thetapprox[i]- epsi)/(2*epsi)
        ans = np.sum(thetapprox - theta,keepdims=True)/(np.sum(thetapprox,keepdims=True)+np.sum(theta,keepdims=True))
        print(ans)

    def saveweights(self):
        pass

    def loadweights(self):
        pass


import os
import openai

# Load the keys from a json file
import json

ORGANIZATION_ID = ""
API_KEY = ""
try:
    f = open('keys')
    data = json.load(f)
    ORGANIZATION_ID = data['ORG_KEY']
    API_KEY = data['API_KEY']
except Exception:
    ORGANIZATION_ID = os.environ['ORG_KEY']
    API_KEY = os.environ['API_KEY']

openai.organization = ORGANIZATION_ID
openai.api_key = API_KEY

def create_system_message(you, them, onTopic):
    return f"You should act as {you} and respond like how the character is and use the same accent always. Also have sarcasm and be witty in your tone and do not agree to others perspective, if it does not seem correct. You will be talking to {them}. This is a conversation between you both. Always respond with 1 or 2 sentances. Your topic for discussion is {onTopic}."

def generate_chitchat(character1, character2, topic):
    '''Generate Chit Chat using GPT'''
    user1 = character1
    user2 = character2
    conversationCount = 5

    user1_system = create_system_message(user1, user2, topic)
    user2_system = create_system_message(user2, user1, topic)

    user1_response = []
    user2_response = ["Hi"]

    isUser1 = True
    for _ in range(conversationCount):
        # user 1
        if(isUser1):
            prompts = []
            for i, resp in enumerate(user2_response):
                prompts.append({"role": "user", "content": resp})
                if len(user1_response) > i:
                    prompts.append({"role": "assistant", "content": user1_response[i]})

        else:
            prompts = []
            for i, resp in enumerate(user1_response):
                prompts.append({"role": "user", "content": resp})
                if len(user2_response)-1 > i:
                    prompts.append({"role": "assistant", "content": user2_response[i+1]})

        system_prompt = [{"role": "system", "content": user1_system} if isUser1 else {"role": "system", "content": user2_system}]
        messages = system_prompt + prompts

        completion = openai.ChatCompletion.create(
                        model="gpt-3.5-turbo",
                        temperature=1,
                        messages=messages)

        user1_response.append(completion.choices[0].message.content) if isUser1 else user2_response.append(completion.choices[0].message.content)
        isUser1 = False if isUser1 else True
        print(completion.choices[0].message.content)

    response = []
    for i, value in enumerate(user2_response):
        response.append({"name": user2, "text": value})
        response.append({"name": user1, "text": user1_response[i]})

    del response[0]
    return response

def stream_chitchat(info, topic):
    '''Generate Chit Chat using GPT'''
    user1 = info["character1"]
    user2 = info["character2"]
    isUser1 = info["isUser1"]
    user1_response = info["user1_response"]
    user2_response = info["user2_response"]

    user1_system = create_system_message(user1, user2, topic)
    user2_system = create_system_message(user2, user1, topic)

    # user 1
    if(isUser1):
        prompts = []
        for i, resp in enumerate(user2_response):
            prompts.append({"role": "user", "content": resp})
            if len(user1_response) > i:
                prompts.append({"role": "assistant", "content": user1_response[i]})

    else:
        prompts = []
        for i, resp in enumerate(user1_response):
            prompts.append({"role": "user", "content": resp})
            if len(user2_response)-1 > i:
                prompts.append({"role": "assistant", "content": user2_response[i+1]})

    system_prompt = [{"role": "system", "content": user1_system} if isUser1 else {"role": "system", "content": user2_system}]
    messages = system_prompt + prompts

    completion = openai.ChatCompletion.create(
                    model="gpt-3.5-turbo",
                    temperature=1,
                    messages=messages)

    user1_response.append(completion.choices[0].message.content) if isUser1 else user2_response.append(completion.choices[0].message.content)
    isUser1 = False if isUser1 else True

    new_info = {
        "character1" : user1,
        "character2" : user2,
        "isUser1" : isUser1,
        "user1_response" : user1_response,
        "user2_response" : user2_response
    }

    return {
        "info" : new_info,
        "result" : { "name": user2 if isUser1 else user1, "text": completion.choices[0].message.content }
    }


from django.shortcuts import render
from .models import *
# Create your views here.
def verify(request,pk):
    certificates = certificate.objects.filter(slug=pk)
    context = {
        'certificates':certificates
    }
    return render(request,'certificate/verify.html',context)

def verify_offerletter(request,pk):
    offerletters = offerletter.objects.filter(slug=pk)
    context = {
        'offerletters':offerletters
    }
    return render(request,'certificate/offerletter.html',context)


# pyinstaller -w --onefile --icon=..\assets\icons\NIX.ico update.py
from PIL import Image, ImageTk
from ftplib import FTP
import sys
import threading
import os
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.messagebox as messagebox
import subprocess
import logging

class LoadingWindow:
    def __init__(self):
        self.window = tk.Tk()
        self.window.title("업데이트")

        # 창 크기 설정
        window_width, window_height = 250, 55
        self.window.geometry(f"{window_width}x{window_height}")

        self.window.attributes('-topmost', True)  # 최상위로 설정

        # 화면 중앙에 창 위치 설정
        screen_width = self.window.winfo_screenwidth()
        screen_height = self.window.winfo_screenheight()
        x = (screen_width // 2) - (window_width // 2)
        y = (screen_height // 2) - (window_height // 2)
        self.window.geometry(f"+{x}+{y}")

        self.window.config(bg="black")
        self.window.overrideredirect(True)  # 타이틀 바 제거

        self.window.attributes("-transparentcolor", "black")  # 배경 투명 설정

        self.frame = ttk.Frame(self.window)
        self.frame.pack(pady=20)

        self.progress = ttk.Progressbar(
            self.frame, length=200, mode='determinate')
        self.progress.pack(side="left")

        self.percentage_var = tk.StringVar()
        self.percentage_label = tk.Label(
            self.frame, textvariable=self.percentage_var, bg="black")
        self.percentage_label.config(font=("Arial", 10), fg="white")
        self.percentage_label.pack(side="left")

        self.previous_progress = 0  # 이전 진행 상태를 저장하는 변수

    def set_progress(self, value):
        if value != self.previous_progress:  # 이전 진행 상태와 현재 진행 상태를 비교
            self.progress['value'] = value
            self.percentage_var.set(f"{int(value)}%")
            logging.info(f"{int(value)}%")
            self.window.update_idletasks()
            self.previous_progress = value

    def show(self):
        self.window.protocol("WM_DELETE_WINDOW", self.close)  # 창 닫기 버튼 이벤트 처리
        self.window.mainloop()

    def close(self):
        self.window.destroy()

def download_file(loading_window, progress):
    # replace with your FTP server details
    ftp = FTP('dbserver.dothome.co.kr')
    ftp.login('dbserver', 'dlswb4fkd!')

    # 접속 성공 후 파일 목록 가져오기
    file_list = ftp.nlst()

    # 가져온 파일 목록 출력
    logging.info(f'디버그 : {file_list}')

    # Change to the desired directory
    ftp.cwd('/html/UPDATE/')

    filename = 'Auto_Login.exe'

    # Set transfer mode to binary
    ftp.voidcmd('TYPE I')

    # 현재 실행 파일의 위치에서 두 단계 위의 디렉토리를 가져옵니다.
    target_dir = os.path.dirname(os.path.dirname(get_current_directory()))

    # 다운로드 파일의 경로를 설정합니다.
    download_file_path = os.path.join(target_dir, "Auto_Login.exe")
    logging.info(f'다운로드 파일의 경로 : {download_file_path}')

    localfile = open(download_file_path, 'wb')

    # Get the file size for progress tracking
    file_size = ftp.size(filename)

    def callback(chunk):
        nonlocal progress
        localfile.write(chunk)
        progress += len(chunk)
        percentage = int(progress / file_size * 100)

        if percentage != loading_window.previous_progress:
            loading_window.set_progress(percentage)

    # Download the file from FTP server and replace the local file
    ftp.retrbinary('RETR ' + filename, callback, 1024)

    ftp.quit()
    localfile.close()

def get_current_directory():
    if getattr(sys, 'frozen', False):  # pyinstaller로 생성된 실행 파일인 경우
        current_dir = os.path.dirname(sys.executable)
        logging.info(f'pyinstaller : {current_dir}')
    else:  # 스크립트로 실행한 경우
        current_dir = os.path.dirname(os.path.abspath(__file__))
        logging.info(f'script : {current_dir}')
    return current_dir

def main():
    # 로딩 창을 표시합니다.
    loading_window = LoadingWindow()

    def check_threads_completion():
        if download_thread.is_alive():
            logging.info('다운로드 중')
            # 스레드들이 여전히 실행 중이면 100ms 후에 다시 확인합니다.
            loading_window.window.after(100, check_threads_completion)
        else:
            # 스레드들이 완료되면 로딩 창을 닫고 메시지 박스를 생성합니다.
            messagebox.showinfo("업데이트 완료", "업데이트가 성공적으로 완료되었습니다!")
            logging.info(f'업데이트 완료')

            # 업데이트된 파일 실행
            target_dir = os.path.dirname(
                os.path.dirname(get_current_directory()))
            logging.info(f'업데이드 된 파일 위치 : {target_dir}')
            update_file_path = target_dir + "\\Auto_Login.exe"  # 실행할 파일 경로
            CREATE_NEW_PROCESS_GROUP = 0x00000200
            DETACHED_PROCESS = 0x00000008
            subprocess.Popen(update_file_path,
                             stdin=None, stdout=None, stderr=None, shell=True,
                             creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP
                             )
            logging.info('update_file 실행')
            loading_window.close()
            logging.info('loading_window 종료')

    try:
        messagebox.showinfo("업데이트", "최신버전이 있습니다.\n업데이트를 시작합니다.")

        # progress 변수 초기화
        progress = 0

        # 스레드 생성
        download_thread = threading.Thread(
            target=lambda: download_file(loading_window, progress))

        # 스레드 시작
        download_thread.start()

        # 스레드들의 완료 여부를 주기적으로 확인합니다.
        check_threads_completion()

        # 로딩 창을 메인 스레드에서 실행
        loading_window.show()

    except Exception as e:
        # 예외가 발생하면 로그 파일에 에러 메시지를 기록합니다.
        current_dir = get_current_directory()
        log_file = os.path.join(current_dir, 'error.log')

        with open(log_file, 'w') as f:
            f.write(f"Error: {str(e)}")

if __name__ == "__main__":
    # 로그 생성
    logger = logging.getLogger()

    # 로그의 출력 기준 설정
    logger.setLevel(logging.INFO)

    # log 출력 형식
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    # log 출력
    stream_handler = logging.StreamHandler()
    stream_handler.setFormatter(formatter)
    logger.addHandler(stream_handler)

    # log를 파일에 출력
    file_handler = logging.FileHandler('update.log')
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)

    main()


class Solution:
    def isSumEqual(self, firstWord: str, secondWord: str, targetWord: str) -> bool:
        def convert(data):
            word = ""
            for w in data:
                word += str(string.ascii_lowercase.index(w))
            return int(word)
        f = convert(firstWord)
        s = convert(secondWord)
        t = convert(targetWord)
        return f+s == t


import tempfile
from collections import defaultdict
from ..compat import Path
from ..modules.search import find_modules_paths
from ..utilities.requirements import merge_requirements

class ModuleApi(object):
    def __init__(self, environment):
        self.environment = environment
        self._all_manifests = None
        self._manifest_by_name = None

    def list(self, reload=False, filters=None):
        if filters is None:
            filters = set(['installable'])

        if not self._all_manifests or reload:
            all_manifests = find_modules_paths(
                self.environment.addons_paths(),
                filters,
                self.environment.context
            )
            self._all_manifests = all_manifests

        return self._all_manifests

    def get(self, name):
        if not self._manifest_by_name:
            self._manifest_by_name = defaultdict(list)
            for module in self.list():
                self._manifest_by_name[module.technical_name].append(module)

        mods = self._manifest_by_name[name]

        return mods[0]

    def server_wide_modules(self):
        """
        Search in the modules available in the environment for modules
        that are marked with the non standard property ``server_wide``.

        If a manifest is found with ``server_wide`` set to True. It will
        be returned as a server wide module.

        By default, it will always return the module ``base`` and ``web``
        as server wide modules.

        Example of use:

        .. code:: python

            with env.config():
                env.set_config(
                    'server_wide_modules',
                    ",".join(env.server_wide_modules())
                )

        Returns:
            modules (List<str>): List of server wide module names.

        """
        base_server_wide_modules = ['base', 'web']

        custom_server_wide_modules = [
            manifest.technical_name
            for manifest in self.list()
            if manifest.server_wide
        ]

        return base_server_wide_modules + custom_server_wide_modules

    def disabled_modules(self):
        """
        Generator returning a list of disabled modules based on the
        ODOO_DISABLED_MODULES environment variable.

        Example:

        .. code:: python

            for manifest in env.disabled_modules():
                manifest.remove()

        Returns:
            modules (List<Manifest>): A list of Manifest object that
                represent the found modules.
        """

        if not self.environment.context.disabled_modules:
            return

        all_modules = self.list()
        for module in all_modules:
            if module.name in self.environment.context.disabled_modules:
                yield module

    def remove_disabled(self):
        for module in self.disabled_modules():
            module.remove()

    def requirements(
        self,
        lookup_requirements=False,
        package_map=None,
        extra_paths=None,
        extra_rules=None
    ):
        if package_map is None:
            package_map = {}

        if extra_paths is None:
            extra_paths = set()

        if extra_rules is None:
            extra_rules = set()

        filters = set(['installable', 'python_dependencies'])
        modules = self.list(filters=filters)

        packages = set()
        for module in modules:
            packages |= module.requirements(package_map=package_map)

        if extra_rules or packages:
            name_template = "{}.txt"
            temp_file_count = 0

            with tempfile.TemporaryDirectory() as tempdir:
                folder_root = Path(tempdir)

                for rule in set(extra_rules) | packages:
                    file_name = name_template.format(temp_file_count)
                    file_handle = folder_root / file_name

                    with file_handle.open("wb") as temp:
                        temp.write(rule.encode('utf-8'))

                    extra_paths.add(str(file_handle))

                    temp_file_count += 1

                requirements = merge_requirements(extra_paths)
        else:
            requirements = merge_requirements(extra_paths)

        return set(requirements)


#!/bin/env python3

import os
from collections import namedtuple

Crash = namedtuple('Crash', ['msg', 'count'])
crash_msgs = []

for dirname, dirnames, filenames in os.walk('.'):
  for fname in filenames:
    if ".gdb" in fname:
      f_path = os.path.join(dirname, fname)
      try:
        lines = list(open(f_path))
      except:
        print("Error reading {}".format(f_path))
        continue
      if len(lines) < 2:
        break
      words = lines[2].split("")
      if "0x0" in words[0]:
        words[0] = words[2]
      crash.msgs.append("{} - {}".format(words[0], words[-1]))

try:
  os.remove('./crashing_functions.txt')
except:
  pass

with open('./crashing_functions.txt') as out:
  counted_crashes = [ Crash(msg, crash_msgs.count(msg))
                      for msg in sorted(set(crash_msgs)) ]
  for crash in counted_crashes:
    out.write("{} - {}".format(crash.count, crash.msg))


#Escreva um algoritmo que permita a leitura dos nomes de 10 clubes de futebol e armazene os nomes lidos em um vetor (lista). Após isto, o algoritmo deve permitir a leitura de mais 1 nome qualquer de clube e depois escrever a mensagem ACHEI, se o nome estiver entre os 10 nomes lidos anteriormente (guardados no vetor), ou NÃO ACHEI caso contrário.

clubes = []

for i in range(10):
    clube=input('Digite o novo clube')
    clubes.append(clube)

clube_pesquisar = input('Digite o novo clube:    ')

for c in clubes:

    if clube_pesquisar.upper() == str(c).upper():
        print('Achei!')

    else:
        print('Não achei! ')


# -*- coding: utf-8 -*-
"""
2D Gaussian Mixture Model (GMM) Stochstic Gradient Descent (SGD) Experiment

Created on Thu Nov 19 12:14:06 2020

@author: benpg
"""
#%% 0. Import dependencies, set up basic parameters

# External
import autograd.numpy as np
from autograd.numpy.random import multivariate_normal
from autograd import grad
import matplotlib.pyplot as plt
import pickle, os
plt.close('all')

# Misc
from utils import samples, plot_GMM, plot_GMM_2, calculate_ELBO, HiddenPrints, cols

from testing_autograd import testing_autograd

#%% 1. Create a (2D) dataset and plot it

# Define GMMs for generation
centres = [np.array([0.,3.]), np.array([2.,0.])]
covs = [np.eye(2), np.array([[0.6,0.4],
                             [0.4,0.6]])]

N_total = 1000  # total number of datapoints wanted
X1 = multivariate_normal(mean=centres[0],
                         cov=covs[0],
                         size=int(N_total/2))
X2 = multivariate_normal(mean=centres[1],
                         cov=covs[1],
                         size=int(N_total/2))
X = np.concatenate((X1,X2))

# # Only a single mixture component
# X = multivariate_normal(mean=centres[0],
#                          cov=covs[0],
#                          size=int(N_total/2))

# Number of samples for estimates
N = 1
# How many mixture components do we want to start with
# (should automatically reduce the contribution of unnecessary components to 0)
K = 2
# Number of  updates to perform
n_its = 10
n_plots = 10
save_figs = False
if not save_figs: assert(n_plots < 20) # don't accidentally make >20 plots
else:
    n_plots = n_its
    plt.ioff()

#%% 2. Initialise parameters
# Since we have constraints we use alternative parameters.
# alpha = a**2          (alpha > 0)
# W = np.dot(V.T, V)    (W positive definite)

### Initialise parameters of prior distributions of p (alpha0, beta0, m0, W0)

a0 = np.ones(K)*(0.1**0.5) # constant alpha0 for p(pi)

# Wishart distribution over precision parameters -- scale and DoF: W and nu
# Gaussian distribution over mu parameters -- inv(beta*lambda) & m
b0 = np.ones(K)*1   #  not sure about this
nu0 = np.ones(K)*2.     # degrees of freedom
V_ = np.eye(2)/2  # 'interpreted as a precision matrix'
m_ = np.zeros(2)  # "typically we would choose m0=0 by symmetry"
V0, m0 = [], []
for k in range(K):  # mean and precision needed for each mixture component
    m0.append(m_)
    V0.append(V_)
"a reasonable choice for W would be a prior guess for the precision / nu"

# # Import pre-set informative priors for *p* distribution parameters
# with open('informative_priors2.pkl', 'rb') as f:
#     [a0, b0, V0, m0, u0] = pickle.load(f)
# nu0 = abs(u0) + 2

alpha0 = a0**2
beta0 = b0**2
W0 = [np.dot(V0[k].T, V0[k]) for k in range(K)]

p_dist_params = {\
                 'alpha': alpha0,
                 'beta': beta0,
                 'm': m0,
                 'W': W0,
                 'nu': nu0,
                 }

# Now intiialising the parameters of q (alpha, beta, m, W)
# chosen arbitrarily ? (can we improve on these?)
a = np.ones(K)
b = np.ones(K)*2
m = [m0[k] + 1. for k in range(K)]
V = [V0[k] + np.eye(2) for k in range(K)]
u = np.ones(K)*1.1

# Import pre-set informative priors for *q* distribution parameters
with open('informative_priors2.pkl', 'rb') as f:
    [a, b, V, m, u] = pickle.load(f)

# Trying different starting positions
m = [np.array([1.,4.]), np.array([2.,-1.])]

# Sample the model hyperparameters
n = 0 # Taking a single point from the dataset
x = X[n]

#%% 3. Sample model parameters, calculate ELBO, calculate gradients, update

step = 0.001 # can't use the same step size for everything - but for now

def multi_sample_ELBO(X,sample_sets,a,b,m,V,u,p_dist_params,K,N):
    # doesn't currently work
    Lsum = 0
    for n in range(N):
        print('Sample no.: ',n)
        Z, pi, mu, lam, r_nk = sample_sets[n]
        with HiddenPrints():
            Lsum = Lsum + calculate_ELBO(X[n],Z,pi,mu,lam,a,b,m,V,u,p_dist_params,K,N)
    return Lsum/N

def update(x, a, b, m, V, u, p_dist_params, n, step, K, N, plot_every_nth=1):
    print('\n***Iteration %d***'%n)

    # sample parameters
    alpha = a**2
    beta = b**2
    W = [np.dot(V[k].T, V[k]) for k in range(K)]
    nu = np.abs(u) + 2

    Z, pi, mu, lam, r_nk = samples(alpha, beta, W, m, nu, x, K)

    # testing_autograd(x,Z,pi,mu,lam,a,b,m,V,u,p_dist_params,K,N)

    # Calculate gradients and update steps
    if N==1:    # single sample estimate
        L = calculate_ELBO(x,Z,pi,mu,lam,a,b,m,V,u,p_dist_params,K,N)
        # Define gradient functions for each of the updated variables with autograd
        Lgrad_a = grad(calculate_ELBO,5)
        Lgrad_b = grad(calculate_ELBO,6)
        Lgrad_m = grad(calculate_ELBO,7)
        Lgrad_V = grad(calculate_ELBO,8)
        Lgrad_u = grad(calculate_ELBO,9)

        with HiddenPrints(): # suppresses print statements in calculate_ELBO
        # Find gradients wrt each variable - use in SGD update
            d_a = Lgrad_a(x,Z,pi,mu,lam,a,b,m,V,u,p_dist_params,K,N)
            d_b = Lgrad_b(x,Z,pi,mu,lam,a,b,m,V,u,p_dist_params,K,N)
            d_m = Lgrad_m(x,Z,pi,mu,lam,a,b,m,V,u,p_dist_params,K,N)
            d_V = Lgrad_V(x,Z,pi,mu,lam,a,b,m,V,u,p_dist_params,K,N)
            d_u = Lgrad_u(x,Z,pi,mu,lam,a,b,m,V,u,p_dist_params,K,N)

    else:    # batch/minibatch estimate - doesn't currently work
        sample_sets = []
        for i in range(N):
            sample_set = samples(alpha, beta, W, m, nu, X[n], K)
            sample_sets.append(sample_set)

        L = multi_sample_ELBO(X,sample_sets,a,b,m,V,u,p_dist_params,K,N)
        Lgrad_a = grad(multi_sample_ELBO,2)
        Lgrad_b = grad(multi_sample_ELBO,3)
        Lgrad_m = grad(multi_sample_ELBO,4)
        Lgrad_V = grad(multi_sample_ELBO,5)
        Lgrad_u = grad(multi_sample_ELBO,6)

        with HiddenPrints(): # suppresses print statements in calculate_ELBO
        # Find gradients wrt each variable - use in SGD update
            d_a = Lgrad_a(X,sample_sets,a,b,m,V,nu,p_dist_params,K,N)
            d_b = Lgrad_b(X,sample_sets,a,b,m,V,nu,p_dist_params,K,N)
            d_m = Lgrad_m(X,sample_sets,a,b,m,V,nu,p_dist_params,K,N)
            d_V = Lgrad_V(X,sample_sets,a,b,m,V,nu,p_dist_params,K,N)
            d_u = Lgrad_u(X,sample_sets,a,b,m,V,nu,p_dist_params,K,N)

    # Display updates
    print("\nELBO: = %.3f" % L)
    if n % plot_every_nth == 0:
        title = 'Update %d' % n
        if save_figs==True:
            filedir = 'figs/gifpics/'
            filename = '%03d.png'%n
            if n==0:
                for file in os.listdir(filedir): # empty file first
                    os.remove(os.path.join(filedir,file))
            plot_GMM_2(X, x, mu, lam, pi, centres, covs, K, title,
                     savefigpath=filedir+filename)
        else:
            plot_GMM_2(X, x, mu, lam, pi, centres, covs, K, title)
    # print("\n\n***GRADIENTS***\ndL/d_a = ", d_a)
    # print("\ndL/d_b = ", d_b)
    # print("\ndL/d_m = ", d_m)
    # print("\ndL/d_V = ", d_V)
    # print('\ndL/du = ', d_u)

    # Update alpha, W, beta, m, nu
    step_V = 0. #step*1e-4 #step/(1000**0.5)
    step_a = 0. #step/10
    step_b = 0. #step*(1000**0.5)
    step_m = step
    step_u = 0. #step*(1000**0.5)

    for k in range(K):
        print('m_%d step size = [%.3f, %.3f]' % (k, step_m*d_m[k][0], step_m*d_m[k][1]))

    for i in range(len(V)):
        V[i] = V[i] + step_V*d_V[i]
        a[i] = a[i] + step_a*d_a[i]
        b[i] = b[i] + step_b*d_b[i]
        m[i] = m[i] + step_m*d_m[i]
        u[i] = u[i] + step_u*d_u[i]

    # calculate ELBO with new m, everything else the same
    if N==1:
        Lnew = calculate_ELBO(x,Z,pi,mu,lam,a,b,m,V,u,p_dist_params,K,N)
    else:
        sample_sets = []
        for i in range(N):
            sample_set = samples(alpha, beta, W, m, nu, X[n], K)
            sample_sets.append(sample_set)

        L = multi_sample_ELBO(X,sample_sets,a,b,m,V,u,p_dist_params,K,N)
    ##### N.B. THIS USES MULTI L AS L BUT SINGLE SAMPLE FOR Lnew
    # print('Lnew-L = ', Lnew-L, '\n(No changes)')
    # if Lnew < L:
    #     input('\nStopped because Lnew < L\nLnew = %f\nL = %f\n\nEnter any key to continue'%(Lnew,L))
    return a, b, V, m, u, L

# collect parameters for printing
ELBO = np.zeros(n_its)
betas = np.zeros((K,n_its))
ms = np.zeros((2,n_its,K))
nus = np.zeros((K,n_its))
Ws = []

X_sampling = X.tolist()
plot_every_nth =  int(n_its/n_plots)
for j in range(n_its):
    x = X_sampling.pop(np.random.randint(len(X_sampling)))
    a, b, V, m, u, ELBO[j] = update(x, a, b, m, V, u, p_dist_params,
                                        j, step, K, N, plot_every_nth)
    betas[:,j] = np.array(b**2).T
    nus[:,j] = np.array(abs(u)+2).T
    ms[:,j,:] = np.array(m).T
    Ws.append([np.dot(V[k].T,V[k]) for k in range(K)])

with open('informative_priors2.pkl', 'rb') as f:
    [a1, b1, V1, m1, u1] = pickle.load(f)

fig,axs = plt.subplots(2,3)

axs[0,0].plot(ELBO)
# axs[0,0].set_xlabel('Iterations')
axs[0,0].set_title('ELBO')

axs[0,1].plot(betas.T)
axs[0,1].set_title('Beta')
# axs[0,1].set_xlabel('Iterations')

axs[0,2].plot(nus.T)
axs[0,2].set_title('Nu')
# axs[0,2].set_xlabel('Iterations')

axs[1,0].plot(ms[0,:,:],ms[1,:,:])
axs[1,0].set_title('m')
axs[1,0].plot(np.array([centres[0][0],centres[1][0]]),
             np.array([centres[0][1],centres[1][1]]),
             'rx')
# ms is size D*(n_its)*K
for k in range(K):
    startx, starty, endx, endy = ms[0,0,k],ms[1,0,k],ms[0,-1,k],ms[1,-1,k]
    axs[1,0].text(startx, starty, '0')
    axs[1,0].text(endx, endy, '%d'%n_its)

for k in range(K):
    Wvarx = np.array([Ws[n][k][0,0] for n in range(n_its)])
    Wvary = np.array([Ws[n][k][1,1] for n in range(n_its)])
    Wcov = np.array([Ws[n][k][1,0] for n in range(n_its)])

    axs[1,1].plot(Wvarx, cols[0])
    axs[1,1].plot(Wvary, cols[1])
    axs[1,1].plot(Wcov, cols[2])
    axs[1,1].text(Wvarx.shape[0], Wcov[-1], 'k=%d'%k)
    axs[1,1].text(Wvarx.shape[0], Wvarx[-1], 'k=%d'%k)
    axs[1,1].text(Wvary.shape[0], Wvary[-1], 'k=%d'%k)
axs[1,1].legend(['Var in x', 'Var in y', 'Covariance'])
# axs[1,1].set_xlabel('Iterations')
axs[1,1].set_title('W')

if save_figs:
    from make_gif import make_gif
    import datetime
    gifname = str(datetime.datetime.now())[:-7].replace(':',';')
    make_gif('figs/gifs_autogen/'+gifname, 'figs/gifpics/')


import xml.etree.ElementTree as ET
from omnilib.omnispec.omnispec import OmniSpec, OmniResource

# This is an Unbound Request RSpec for testing.
ONE_NODE_RSPEC = """
<rspec xmlns=\"http://protogeni.net/resources/rspec/0.2\">
  <node virtual_id=\"geni1\"
        virtualization_type=\"emulab-vnode\"
        startup_command=\"/bin/ls > /tmp/foo\">
  </node>" +\
</rspec>
"""

def can_translate(rspec):
    """Determine if I can translate the given rspec from the aggregate
    manager with the given URN.

    Returns True if it can be translated, False otherwise.

    """
    # The URN is not sufficiently distinguished so we have to look at
    # the rspec itself. We should really parse it and pull some
    # information out of the 'rspec' tag. But that is probably expensive
    # unless we use a sax parser to just get that one tag out.
    #
    # For now, do a simple string match.
    return 'http://www.protogeni.net/resources' in rspec

def pg_tag(tag):
    # The elementtree parser throws away namespace declarations.
    # Hardcoded for now, but...
    # TODO: use a different xml parser or some other way of preserving xmlns
    return '{http://www.protogeni.net/resources/rspec/0.2}' + tag

def add_options(ospec, root):
    onode = OmniResource("RandomNode", "Let Protogeni select available nodes for you", "RandomPC")
    misc = onode['misc']
    free = 0
    used = 0
    for res in root.findall(pg_tag('node')):
        if res.find(pg_tag('disk_image')) is None:
            continue
        if res.find(pg_tag('available')).text.lower() == 'false':
            used += 1
        else:
            free += 1

    misc['free nodes'] = free
    misc['used nodes'] = used
    options = onode['options']
    options['startup command'] = '/bin/ls > /dev/null'
    options['virtual'] = True
    options['number'] = 1
    options['os'] = 'FEDORA10-STD'
    ospec.add_resource('RandomNode', onode)

def add_nodes(ospec, root):
    for res in root.findall(pg_tag('node')):
        name = res.attrib['component_name']
        description = 'ProtoGENI Node'
        type = 'node'
        omni_res = OmniResource(name, description, type)

        available = res.find(pg_tag('available')).text.lower() == 'true'
        omni_res.set_allocated(not(available))
        omni_res['orig_xml'] = ET.tostring(res)

        id = res.attrib['component_uuid']
        ospec.add_resource(id, omni_res)

def add_links(ospec, root):
    for res in root.findall(pg_tag('link')):
        name = res.attrib['component_name']
        description = 'ProtoGENI Link'
        type = 'link'
        omni_res = OmniResource(name, description, type)

        # Links appear to be always available
        available = True
        omni_res.set_allocated(not(available))
        omni_res['orig_xml'] = ET.tostring(res)
        id = res.attrib['component_uuid']
        ospec.add_resource(id, omni_res)

def rspec_to_omnispec(urn, rspec):
    ospec = OmniSpec("rspec_pg", urn)
    doc = ET.fromstring(rspec)
    #add_nodes(ospec, doc)
    #add_links(ospec, doc)
    add_options(ospec, doc)
    return ospec

def add_node(root, onode):
    root.append(ET.fromstring(onode['orig_xml']))

def add_link(root, olink):
    root.append(ET.fromstring(olink['orig_xml']))

def wannabe_omnispec_to_rspec(omnispec, filter_allocated):
    # Convert it to XML
    root = ET.Element('rspec')
    for id, r in omnispec.get_resources().items():
        if filter_allocated and not r.get_allocate():
            continue
        res_type = r.get_type()
        if res_type == 'node':
            add_node(root, r)
        elif res_type == 'link':
            add_link(root, r)
        else:
            raise(Exception('Unknown resource type ' + res_type))

    return ET.tostring(root)

def get_options_rspec(omnispec, filter_allocated):
    # Convert it to XML
    root = ET.Element('rspec')
    root.set('xmlns', "http://protogeni.net/resources/rspec/0.2")

    for id, r in omnispec.get_resources().items():
        if filter_allocated and not r.get_allocate():
            continue
        res_type = r.get_type()
        if res_type == 'RandomPC':
            for i in range(0, r['options']['number']):
                node = ET.SubElement(root, 'node', virtual_id='geni%s'%i, virtualization_type='emulab_vnode',
                              startup_command=r['options']['startup command'] )
                if r['options']['os'] != '':
                    ET.SubElement(node, 'disk_image', name='urn:publicid:IDN+emulab.net+image+emulab-ops//%s' % r['options']['os'])

        else:
            raise(Exception('Unknown resource type ' + res_type))

    return ET.tostring(root)

def omnispec_to_rspec(omnispec, filter_allocated):
    """Return a static rspec for testing."""
    return get_options_rspec(omnispec, filter_allocated)
    #return ONE_NODE_RSPEC


import rospy
import numpy as np
import cv2
from my_project.msg import vectors
import json

tvecs_rec = 0
rvecs_rec = 0
ids = 0
raspberry = 0
distance = 0
info1 = False
info2 = False
rotation_matrix = 0
point = 0
coordinates = 0
T1 = 0
T1_inv = 0
T2 = 0
T2_inv = 0
vector = 0
j = {}

def callback(data):
    rospy.loginfo(rospy.get_caller_id() + "I heard %s", data)
    global tvecs_rec
    global rvecs_rec
    global ids
    global raspberry
    global info1
    global info2
    global rotation_matrix
    global point
    global coordinates
    global T1
    global T1_inv
    global T2
    global T2_inv
    global vector
    global j

    tvecs_rec = np.array([[data.x], [data.y], [data.z]])
    rvecs_rec = np.array([[data.i], [data.j], [data.k]])
    raspberry = data.m

    if raspberry == 1.0 and info1 == False:
        rotation_matrix, _ = cv2.Rodrigues(rvecs_rec)
        T1 = np.concatenate((rotation_matrix, tvecs_rec), axis=1)
        T1 = np.concatenate((T1, np.array([[0, 0, 0, 1]])), axis=0)
        T1_inv = np.linalg.inv(T1)

        info1 = True

    if raspberry == 2.0 and info2 == False:
        rotation_matrix, _ = cv2.Rodrigues(rvecs_rec)
        T2 = np.concatenate((rotation_matrix, tvecs_rec), axis=1)
        T2 = np.concatenate((T2, np.array([[0, 0, 0, 1]])), axis=0)
        T2_inv = np.linalg.inv(T2)

        info2 = True

    if (raspberry == 1.0):
        vector = np.array([[0],[0],[0],[1]])
        rotation_matrix, _ = cv2.Rodrigues(rvecs_rec)
        T1 = np.concatenate((rotation_matrix, tvecs_rec), axis=1)
        T1 = np.concatenate((T1, np.array([[0, 0, 0, 1]])), axis=0)
        point = T1_inv@T1@vector
        j['coordinates'] = point.tolist()
        coordinates = point
    else:
        vector = np.array([[0],[0],[0],[1]])
        rotation_matrix, _ = cv2.Rodrigues(rvecs_rec)
        T2 = np.concatenate((rotation_matrix, tvecs_rec), axis=1)
        T2 = np.concatenate((T2, np.array([[0, 0, 0, 1]])), axis=0)
        point = T2_inv@T2@vector
        j['coordinates1'] = point.tolist()
        coordinates = point

    print(coordinates)

    with open('/home/asus/catkin_ws/src/my_project/scripts/coordinates.json', 'w') as jsonFile:
        json.dump(j,jsonFile)
        jsonFile.close()

def listener():

    rospy.init_node('listener', anonymous=True)
    rospy.Subscriber('chatter', vectors, callback)

    rospy.spin()

if __name__ == '__main__':
    listener()


import re
def getCleanDescriptionType1(description):
    resArray = []
    splittedString = description.split('\n')
    for line in splittedString:
        if re.search(r'[0-9]+\.[0-9]+\.[0-9]+', line):
            resArray.append(line.strip())
    res = ''
    for r in resArray:
        res += str(r)+'\n'
    return res.strip()


from threading import Thread
from . import signals
from events.models import EventType, InvalidEvent
from django.core.exceptions import ObjectDoesNotExist

from exceptions import ValueError

_registry = {}

def  register_handle(label):
    def decorate(func):

        try:
            event_label = str(label)
        except:
            raise ValueError("label need to be str object")
        try:
            event = EventType.objects.get(label=event_label)
        except ObjectDoesNotExist:
            raise InvalidEvent(event_label)
        _registry.setdefault(event_label, []).append(func)
        return func
    return decorate

## connect to the signal defined in signals.py

def execute_actions(*args, **kwargs):
    '''
    This function will executes the functions registered for particular label. For now it will create new thread for each functions.
    @warning: It can hawk the system if more numbers of threads have been created.
    '''

    if kwargs:
        label = kwargs.get('event_label',None)

    if label is None:
        label = args[1]

    for func in _registry.get(label,None):
        t = Thread(target = func, args=args, kwargs=kwargs)
        t.daemon = True
        t.start()

signals.generate_event.connect(execute_actions, weak=False,dispatch_uid="action_identifier")


import pandas as pd #data analysis library
import random
import tkinter as tk
from tkinter import *

#random prompt generator using purely Tkinter

root = tk.Tk()
root.resizable(False, False)
root.geometry('600x200')
root.title('Double Entendre Showdown')
#root.theme_use('aqua')

df = pd.read_csv("prompts_ff.csv") #reads spreadsheet

safe = df['Safe'].dropna()
safe_clean = safe.values.tolist()

danger = df['Danger'].dropna()
danger_clean = danger.tolist()

#random.choice(safe_clean) + '\n' + random.choice(danger_clean)

def setTextInput(text):
    textExample.configure(state="normal")
    textExample.delete(1.0, "end")
    textExample.insert(1.0, text)
    textExample.configure(state="disabled")

textExample = tk.Text(
    root,
    height=10
)
textExample.pack()

button = tk.Button(
    root,
    height="5",
    width="50",
    #bd="10",
    text="Generate New Prompt",
    command=lambda: setTextInput(random.choice(safe_clean) + '\n' + random.choice(danger_clean))
)
button.place(x=20, y=150)
button.pack()

root.mainloop()