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

from selenium import webdriver
from os import environ
from pathlib import Path

def __get_current_path():
    return str(Path(__file__).parent.absolute())

def __get_firefox(headless: str) -> webdriver:
    """This function establishes firefox browser."""
    firefox_options = None
    if headless:
        firefox_options = webdriver.firefox.options.Options()
        firefox_options.add_argument('--headless')
        firefox_options.add_argument('--disable-gpu')
        firefox_options.add_argument('--debug')
    geckodriver = __get_current_path() +\
        "/drivers/geckodriver_linux64/geckodriver"
    environ["webdriver.gecko.driver"] = geckodriver
    return webdriver.Firefox(executable_path=geckodriver,
                             firefox_options=firefox_options)

def __get_chrome(headless: str) -> webdriver:
    """This function establishes chrome browser."""
    chrome_options = None
    if headless:
        chrome_options = webdriver.chrome.options.Options()
        chrome_options.add_argument('--headless')
        # open Browser in maximized mode
        chrome_options.add_argument('start-maximized')
        # disable info bars
        # chrome_options.add_argument('disable-infobars')
        # disable extensions
        chrome_options.add_argument('--disable-extensions')
        chrome_options.add_argument('--disable-gpu')  # For windows os only
        chrome_options.add_argument('--no-sandbox')  # bypass OS security model
        # overcome limited resource problems
        chrome_options.add_argument('--disable-dev-shm-usage')
    chromedriver = __get_current_path() +\
        "/drivers/chromedriver_linux64/chromedriver"
    environ["webdriver.chrome.driver"] = chromedriver
    return webdriver.Chrome(executable_path=chromedriver,
                            chrome_options=chrome_options)

def get_browser(name: str, headless: bool):
    """This function is used for quick selection of browser."""
    switcher = {
        "firefox": __get_firefox,
        "chrome": __get_chrome
    }
    func = switcher.get(name)
    return func(headless)


import random
import open3d as o3d

from grassdata_new import Part, Mesh, PartLabel, GRASSNewDataset
from aggregator import Aggregator

import copy
import numpy as np

from utils import reindex_faces

class RandomizedExtractor(object):
	def __init__(self, dataset):
		self.aggregator = Aggregator()
		self.dataset = dataset
		self.target_index, target = self.__choose_random_sample(dataset)
		self.target = copy.deepcopy(target)
		#self.target.set_mesh_and_parts_colour([1, 0, 0])
		self.set_colour_coded_sources(dataset) ############# ADD TO RESET TARGET?? ##############

	def __choose_random_sample(self, dataset):
		data_size = len(dataset)

		sample_idx = random.randint(0, data_size-1)
		sample = dataset[sample_idx]

		return sample_idx, sample

	def reset_target(self, dataset):
		idx = self.target_index
		while idx == self.target_index:
			self.target_index, target = self.__choose_random_sample(dataset)

		self.target = copy.deepcopy(target)
		#self.set_colour_coded_sources(self.dataset)

	def get_target_labels_with_bounding_box(self):
		assert(self.target is not None)

		bboxes_dict = {}
		for part in self.target.parts:
			if part.label not in bboxes_dict:
				bboxes_dict[part.label] = self.aggregator.get_super_bounding_box(self.target, part.label)

		return bboxes_dict

	def get_target_labels_with_parts(self):
		assert(self.target is not None)

		bboxes_dict = {}
		for part in self.target.parts:
			if part.label not in bboxes_dict:
				bboxes_dict[part.label] = self.aggregator.get_all_parts_by_label(self.target, part.label)

		return bboxes_dict

	def get_target_parts_by_label(self, label):
		return self.aggregator.get_all_parts_by_label(self.target, label)

	def make_target_parts_invisible_by_label(self, label):
		assert(self.target is not None)

		for part in self.target.parts:
			if part.label == label:
				part.render = False

	def add_parts_to_target(self, parts):
		assert(self.target is not None)

		self.target.parts.extend(parts)

	def replace_target_parts_by_label(self, label, parts):
		assert(self.target is not None)

		target_parts = []
		for part in self.target.parts:
			if part.label != label:
				target_parts.append(part)

		target_parts.extend(parts)
		self.target.parts = target_parts

	def find_source_part(self, dataset, label, iter_limit=10):
		bbox = None
		idx = self.target_index

		iter_count = 0
		while bbox is None or idx == self.target_index:
			idx, source_mesh = self.__choose_random_sample(dataset)
			parts, bbox = self.aggregator.get_parts_with_bounding_box(source_mesh, label)

			iter_count += 1
			if iter_count == iter_limit:
				break

		return parts, bbox

	def __reindex_faces(part_faces, new_offset=0):
		part_faces_np = np.asarray(part_faces, dtype=np.int32)
		part_faces_np = part_faces_np - np.amin(part_faces_np) + new_offset

		return part_faces_np

	def get_triangle_part_meshes(self, parts):
		triangle_meshes = []

		for part in parts:
			tri_mesh = o3d.geometry.TriangleMesh()
			tri_mesh.vertices = o3d.utility.Vector3dVector(np.asarray(part.vertices, dtype=np.float64))
			tri_mesh.triangles = o3d.utility.Vector3iVector(np.asarray(part.faces, dtype=np.int32))

			triangle_meshes.append(tri_mesh)

		return triangle_meshes

	def smooth_part_meshes(self, parts):
		triangle_meshes = self.get_triangle_part_meshes(parts)

		for part, mesh in zip(parts, triangle_meshes):
			mesh.filter_smooth_laplacian(number_of_iterations=3)

			part.vertices = np.asarray(mesh.vertices, dtype=np.float64).tolist()
			part.faces = np.asarray(mesh.triangles, dtype=np.int32).tolist()

		return parts

	def set_colour_coded_sources(self, dataset):
		data_size = len(dataset)
		cols = [[1,0,0],[0.2, 0.2, 0.6],[0.2, 0.7, 0.3],[1, 0.7, 0.2],[0.5, 0.1, 0.5],
          [1, 0.4, 0.4],[0.8, 0.5, 0.1],[1, 0, 0.5],[0.5, 0.6, 0.2],[0.3, 0.6, 0.9]]
		# List of colours
		# 1: Dark Blue, 2: Green, 3: Yellow, 4: Purple
		i=0

		for idx in range (data_size):
			if idx == self.target_index: # For target
				self.target.set_mesh_and_parts_colour(cols[i])
				#print("Setting colour for target with colour red at idx ", idx)
				#continue
			mesh = dataset[idx]
			print("Setting colour for ", idx, " with colour number ", i)
			mesh.set_mesh_and_parts_colour(cols[i])
			i = i + 1

	def get_source_meshes(self):
		data_size = len(self.dataset)
		meshes = []
		i=0

		for idx in range (data_size):
			if idx == self.target_index:
				continue
			meshes.append(self.dataset[idx])
		return meshes


import unittest
from p2p import P2PApp

class TestP2PApp(unittest.TestCase):
    def setUp(self):
        self.app = P2PApp()
        self.user_a = self.app.add_user("User A")
        self.user_b = self.app.add_user("User B")

    def test_deposit(self):
        self.app.deposit("User A", 10)
        self.assertEqual(self.app.check_balance("User A"), 10)
        self.app.deposit("User B", 20)
        self.assertEqual(self.app.check_balance("User B"), 20)

    def test_send_money(self):
        self.app.deposit("User A", 10)
        self.app.deposit("User B", 20)
        self.app.send_money(self.user_b, "User A", 15)
        self.assertEqual(self.app.check_balance("User A"), 25)
        self.assertEqual(self.app.check_balance("User B"), 5)

    def test_transfer_out(self):
        self.app.deposit("User A", 25)
        self.app.transfer_out("User A", 25)
        self.assertEqual(self.app.check_balance("User A"), 0)

if __name__ == "__main__":
    unittest.main()


import collections
import time
import math
import re

def get_sentence_lists_from_files(books):
    sentences = []
    for i in range(0, len(books)):
        sentences += getSentenceLists(books[i])
    return sentences

def getSentenceLists(book):
    sentences = []
    with open(book, "r", buffering = 16777216, encoding = 'utf-8') as file:
        text = file.read().lower().strip("\n")
        Sentences = re.compile("[?.!]+").split(text)
        for i in range(0, len(Sentences)):
            sentences += [re.compile("[\W0-9]+").split(Sentences[i])]
            sentences[i] = [x for x in sentences[i] if len(x) > 0]
    return [sentences]

def build_semantic_descriptors(sentences):
    descriptors = collections.defaultdict(int)
    for book in range(0, len(sentences)):
        sentencesOfBook = sentences[book]
        for sentence in range(0, len(sentencesOfBook)):
            Sentence = sentencesOfBook[sentence]
            for word in range(0, len(Sentence)):
                string = Sentence[word]
                if string not in descriptors:
                    descriptors[string] = collections.defaultdict(int)
                for previous_word in range(0, word):
                    previous_string = Sentence[previous_word]
                    descriptors[string][previous_string] += 1
                    descriptors[previous_string][string] += 1
    return descriptors

answers = ""
def run_similarity_test(filename, semantic_descriptors):
    global answers
    questionCount = 0
    guessedRight = 0
    with open(filename, "r", encoding = "utf-8") as file:
        for line in file:
            split = line.strip("\n").split(" ")
            question = split[0]
            answer = split[1]
            questionCount += 1
            if most_similar_word(question, split, semantic_descriptors) == answer:
                answers += "\tAnswer is " + answer + " and AI guessed correctly\n\n"
                guessedRight += 1
            else:
                answers += "\tAnswer is " + answer + " and AI guessed incorrectly\n\n"
    answers += "Number of questions: " + str(questionCount) + "\n"
    answers += "Number of correct guesses: " + str(guessedRight) + "\n"
    answers += "AI was correct " + str((guessedRight / questionCount) * 100) + "% of the times!\n"
    print(answers)
    file = open("logs.txt", "w")
    file.write(answers)
    file.close()

def most_similar_word(word, choices, descriptors):
    global answers
    answers += word + ":\n"
    indexOfSynonym = 0
    biggestSimilarity = 0.0
    for i in range(2, len(choices)):
        similarity = 0.0
        if word in descriptors and choices[i] in descriptors:
            similarity = cosine_similarity(descriptors[word], descriptors[choices[i]])
        if similarity > biggestSimilarity:
            biggestSimilarity = similarity
            indexOfSynonym = i
        answers += "\t(" + chr(97 + i - 2) + ") " + choices[i]
        answers += ", " + str(similarity * 100) + "% to be synonym\n"
    return choices[indexOfSynonym]

def norm(vec):
    sum_of_squares = 0.0
    for x in vec:
        sum_of_squares += vec[x] * vec[x]
    return math.sqrt(sum_of_squares)

def cosine_similarity(vec1, vec2):
    dot_product = 0.0
    for x in vec1:
        if x in vec2:
            dot_product += vec1[x] * vec2[x]
    return dot_product / (norm(vec1) * norm(vec2))

# Main program
start_time = time.time()
books = ["b1.txt", "b2.txt", "b3.txt"]
sentences = get_sentence_lists_from_files(books)
semantic_descriptors = build_semantic_descriptors(sentences)
run_similarity_test("toefel.txt", semantic_descriptors)
print("%s seconds" % (time.time() - start_time))


import numpy as np

with open('../PuzzleData/day4_puzzle_input.txt') as my_file:
    data = my_file.read()

    draw, boards = data.split('\n', 1)
    draw = [int(i) for i in draw.split(',')]
    boards = boards.strip().split('\n\n')

    boards = [
        np.array([[int(j) for j in i.split(' ') if j != ''] for i in board.strip().split('\n')])
        for board in boards
    ]

def check_win(board):
    for y in range(board.shape[0]):
        if np.all(board[y,:] < 0): return True

    for x in range(board.shape[1]):
        if np.all(board[:,x] < 0): return True

    return False

def score(board, call):
    return np.sum(board[board > 0]) * call

winner = []
for call in draw:
    for i in range(len(boards)-1,-1,-1):
        board = boards[i]
        board[board == call] *= -1
        if check_win(board):
            winner.append((board, call))
            boards.pop(i)

print(f"Winning Score is: {score(*winner[0])}")
print(f"Losing Score is: {score(*winner[len(winner) - 2])}")


import discord
from discord.ext import commands

command_list = ["!KRANTHOS ", "!kranthos ", "!Kranthos "]

bot = commands.Bot(command_prefix=commands.when_mentioned_or(*command_list), case_insensitive=True)

@bot.event
async def on_ready():
    print('Kranthos Bot is running!')

@bot.command()
async def crazy(ctx):
    await ctx.send("Whoooaaa")

bot.run("e.i sddsf7jgsf6d5g-dhdg2hf4g4hf5gh-Yw#") #REPLACE THE TOKEN TO RUN THE BOT