from sympy import symbols, preorder_traversal, Float
import re
import sys
import subprocess
import math

def separate(somelist):
    imaginary = []
    real = []
    for expression in somelist:
        if 'i' in expression:
            if len(expression) > 2:
                imaginary.append(expression[:-2])
            elif len(expression) == 2:
                imaginary.append(str(-1))
            else:
                imaginary.append(str(1))
        else:
            real.append(expression)
    return real, imaginary

def transform(pretrans):
    newstring = ""
    for i in pretrans:
        if i == 'a':
            newstring += "(a*i)"
        elif i == 'b':
            newstring += "(b*i)"
        else:
            newstring += i
    return newstring

def angletransform(pretrans, oor):
    angle = 2 * math.pi / oor  # factor of rotation
    tangle = angle
    expressionlist = []
    for j in range(oor - 1):
        sinepart = str(math.sin(tangle))
        cospart = str(math.cos(tangle))
        newstring = ""
        for i in pretrans:
            if i == 'a':
                newstring += "(a*(" + cospart + "+i*" + sinepart + "))"
            elif i == 'b':
                newstring += "(b*(" + cospart + "+i*" + sinepart + "))"
            else:
                newstring += i
        expressionlist.append(newstring)
        print(newstring)
        tangle += angle
    return expressionlist

# a^4 = a(cos0+isin0)^4
# factor of rotation = 4
# angle = 2pi/4 = pi/2
# pi/2, pi, 3pi/2, 2pi

# what gets preserved during these sitautions and why?

def rewrite_imaginary(someList):
    for expression in someList:
        if 'i' in expression and expression[-1] != 'i':
            imagine = expression.split("i**")
            thenumber = int(imagine[1])
            if (thenumber - 3) % 4 == 0:
                if expression[0] == '-':
                    someList[someList.index(expression)] = imagine[0][1:] + "i"
                else:
                    addminus = '-'
                    addminus += imagine[0] + "i"
                    someList[someList.index(expression)] = addminus
            elif (thenumber - 1) % 4 == 0:
                someList[someList.index(expression)] = imagine[0] + "i"
            elif thenumber % 4 == 0:
                someList[someList.index(expression)] = imagine[0][0:-1]
            elif thenumber % 2 == 0:
                if expression[0] == '-':
                    someList[someList.index(expression)] = imagine[0][1:-1]
                else:
                    addminus = '-'
                    addminus += imagine[0][0:-1]
                    someList[someList.index(expression)] = addminus

def import_libraries(filename):
    f = open(filename, "w")
    f.write("import numpy as np\n")
    f.write("import matplotlib.pyplot as plt\n")
    f.write("import sys\n")
    f.close()

def Write_graph(somelist, filename, title):
    if len(somelist) <= 0:
        print("\nno " + title + " part\n")
        return
    title_ext = ""
    f = open(filename, "a")
    f.write("a = np.linspace(-10, 10, 100)\n")
    f.write("b = np.linspace(-10, 10, 100)\n")
    f.write("a, b = np.meshgrid(a, b)\n")
    f.write("z = ")
    sumstring = ""
    for i in somelist:
        sumstring += i
        sumstring += "+"
    sumstring = sumstring[:-1:]
    test = sympy.expand(sumstring)
    newstring = str(test)
    ex2 = test
    for a in preorder_traversal(ex2):
        if isinstance(a, Float):
            ex2 = ex2.subs(
                a, round(a, 7))

    ex2 = str(ex2)

    if ex2.strip() == "0":
        print("\nno " + title + " part\n")
        f.close()
        return
    newlist = ex2.split('+')
    if len(newlist) > 1:
        for i in range(len(newlist) - 1):
            f.write("(" + newlist[i] + ")")
            f.write('+')
            title_ext += (newlist[i] + "+")
        f.write("(" + newlist[-1] + ")\n")
        title_ext += newlist[-1]
    else:
        a = newlist[0]
        if a.isdigit():
            f.write(a + "+ (a-a)\n")
        else:
            f.write(newlist[0] + "\n")
        title_ext += newlist[0]
    f.write("fig = plt.figure(figsize=[12, 8])\n")
    f.write("fig.suptitle(" + "'" + title + ": " + title_ext + "'" + ")\n")
    f.write("ax = plt.axes(projection='3d')\n")
    f.write("ax.plot_surface(a, b, z)\n")
    f.close()

def instructions():
    print("\n -g to enter main function of program, no argument afterwards")
    print("Anything being multiplied must be separated by * EX: ab must be a*b")
    print("Can use a,b for polynomials, and imaginary numbers can be represented by i")
    print("You can select aspects of graph once graph is parsed")
    print("-h to print this message again\n")

def showplot(filename):
    f = open(filename, "a")
    f.write("plt.show()\n")
    subprocess.Popen(["python", filename])

def split(somestring):
    somestring = somestring.lower()
    try:
        ex = sympy.expand(somestring)
    except Exception as e:
        print("\ninvalid input, use -h command for clearer instructions")
        exit(1)

    ex = str(ex)
    # print(ex)
    ostring = ""
    for i in range(len(ex)):
        if ex[i] == '-' and i != 0:
            if ex[i - 1] != 'e':
                ostring += '+-'
            else:
                ostring += '-'
        else:
            ostring += ex[i]

    ostring = re.sub(r"\s+", "", ostring, flags=re.UNICODE)
    returnlist = ostring.split('+')
    return returnlist

def printmenu():
    print("\n[1] for original real part:")
    print("[2] for original imaginary part:")
    print("[3] for transformed real part:")
    print("[4] for transformed imaginary part:")
    print("[5] roots of unity rotation")
    print("[6] print menu")
    print("[q] to quit\n")

def rootsofunity(fraction):
    a_splitlist = angletransform(gfg_exp, int(fraction))
    x = input("enter state of rotation between 1 - " + str(int(fraction)) + ": ")
    while x != 'q':
        if x.isdigit() and (0 < int(x) <= int(fraction)):
            if int(x) == int(fraction):
                print("input is equivalent to original graph")
            else:
                anglegraph = split(a_splitlist[int(x) - 1])
                rewrite_imaginary(anglegraph)
                print(anglegraph)
                r_angle, i_angle = separate(anglegraph)
                import_libraries("myfile.py")
                Write_graph(r_angle, "myfile.py", "Real Rotated by a factor of " + x + "/" + fraction)
                showplot("myfile.py")

                import_libraries("other.py")
                Write_graph(i_angle, "other.py", "Imaginary Rotated by a factor of " + x + "/" + fraction)
                showplot("other.py")
        x = input("enter state of rotation between 1 - " + str(int(fraction)) + " (q to exit to menu): ")

def menuoptions():
    printmenu()
    condition = input("enter input: ")

    while condition != "q":
        if condition == "1":
            import_libraries("myfile.py")
            Write_graph(realist, "myfile.py", "og-real")
            showplot("myfile.py")
        elif condition == "2":
            import_libraries("myfile.py")
            Write_graph(imaginarylist, "myfile.py", "og-imaginary")
            showplot("myfile.py")
        elif condition == "3":
            import_libraries("myfile.py")
            Write_graph(t_realist, "myfile.py", "transformed-real")
            showplot("myfile.py")
        elif condition == "4":
            import_libraries("myfile.py")
            Write_graph(t_imaginarylist, "myfile.py", "transformed-imaginary")
            showplot("myfile.py")
        elif condition == "5":
            fraction = input("Select fraction of rotation: ")
            rootsofunity(fraction)
            printmenu()
        elif condition == "6":
            printmenu()
        elif condition == "q":
            exit(1)
        else:
            print("invalid input\n")
        condition = input("\nenter input: ")

x, y, z = symbols('a b i')

if len(sys.argv) >= 2:
    if sys.argv[1] == "-h":
        instructions()
        exit(1)
else:
    gfg_exp = input("Enter a expression: ")

splitlist = split(gfg_exp)

t_splitlist = split(transform(gfg_exp))
rewrite_imaginary(splitlist)
rewrite_imaginary(t_splitlist)
realist, imaginarylist = separate(splitlist)
t_realist, t_imaginarylist = separate(t_splitlist)

print("og-realpart: " + str(realist))
print("og-imaginarypart: " + str(imaginarylist))
print("transformed-realpart " + str(t_realist))
print("transformed-imaginarypart " + str(t_imaginarylist))

menuoptions()


from keras.models import Sequential
from keras.layers import Dense
from keras.models import model_from_json
from keras import optimizers
import numpy as np
import os
import pandas as pd
import sys, getopt
from optparse import OptionParser
from pathlib import Path

def train_model(train,truth):
    # Load dataset
    dataset_train = pd.read_csv(train)
    dataset_trainresults = pd.read_csv(truth)

    # Split into input (X) and output (Y) variables
    X_train = dataset_train.iloc[:, 1:21].values
    y_train = dataset_trainresults

    # Create slope model
    model_slope = Sequential()
    model_slope.add(Dense(12, input_dim=20, init='uniform', activation='linear'))
    model_slope.add(Dense(6, init='uniform', activation='linear'))
    model_slope.add(Dense(1, init='uniform', activation='linear'))
    # Compile slope model
    model_slope.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
    # Fit the slope model
    model_slope.fit(X_train, y_train['slope'], epochs=5, batch_size=10,  verbose=2)

    # Create intercept model
    model_intercept = Sequential()
    model_intercept.add(Dense(12, input_dim=20, init='uniform', activation='linear'))
    model_intercept.add(Dense(6, init='uniform', activation='linear'))
    model_intercept.add(Dense(1, init='uniform', activation='linear'))
    # Compile intercept model
    model_intercept.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
    # Fit the intercept model
    model_intercept.fit(X_train, y_train['intercept'], epochs=5, batch_size=10,  verbose=2)

    ## Just for test the predictions
    # Calculate predictions of slope
    #predictions = model_slope.predict(X_train)
    # round predictions
    #rounded_slope = [x[0] for x in predictions]
    #print(rounded)
    #np.savetxt("slope_predict_train.txt",rounded_slope)

    # calculate predictions of intercept
    #predictions2 = model_intercept.predict(X_train)
    # round predictions
    #rounded_intercept = [x[0] for x in predictions2]
    #print(rounded2)
    #np.savetxt("intercept_predict_train.txt",rounded_intercept)

    # serialize slope model to JSON
    model_slope_json = model_slope.to_json()
    with open("model_slope.json", "w") as json_file:
        json_file.write(model_slope_json)
    # serialize slope weights to HDF5
    model_slope.save_weights("model_slope.h5")

    # serialize intercept model to JSON
    model_intercept_json = model_intercept.to_json()
    with open("model_intercept.json", "w") as json_file:
        json_file.write(model_intercept_json)
    # serialize intercept weights to HDF5
    model_intercept.save_weights("model_intercept.h5")
    print("Saved model to disk")

def test_model(test):
    # Load json and create slope model
    json_file_slope = open('model_slope.json', 'r')
    loaded_model_json_slope = json_file_slope.read()
    json_file_slope.close()
    loaded_model_slope = model_from_json(loaded_model_json_slope)
    # Load slope weights into new model
    loaded_model_slope.load_weights("model_slope.h5")
    print("Loaded model slope from disk")

    # Load json and create intercept model
    json_file_intercept = open('model_intercept.json', 'r')
    loaded_model_json_intercept = json_file_intercept.read()
    json_file_intercept.close()
    loaded_model_intercept = model_from_json(loaded_model_json_intercept)
    # Load intercept weights into new model
    loaded_model_intercept.load_weights("model_intercept.h5")
    print("Loaded model intercept from disk")

    # Load dataset of test
    dataset_test = pd.read_csv(test)
    X_test = dataset_test.iloc[:, 1:21].values

    # Evaluate loaded model on test data
    loaded_model_slope.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
    slopes = loaded_model_slope.predict(X_test)
    # Saving the slope predict in file
    np.savetxt("slope_predict_test.txt",slopes)
    print("Slope of prediction save at: slope_predict_test.txt")

    # Evaluate loaded model on test data
    loaded_model_intercept.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
    intercept = loaded_model_intercept.predict(X_test)
    # Saving the intercept predict in file
    np.savetxt("intercept_predict_test.txt",intercept)
    print("Intercept of prediction save at: intercept_predict_test.txt")

def main(argv):

    traintruth = ''
    train = ''
    test = ''

    #Getting args (-t,-r,-n) and testing if is correctly
    try:
        opts, args = getopt.getopt(argv,"h:t:r:n:",["train","traintruth","test"])
    except getopt.GetoptError:
        print('deepersystem.py -t <train.csv> -r <traintruth.csv> || -n <test.csv>')
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print('deepersystem.py -t <train.csv> -r <traintruth.csv> || -n <test.csv>')
            sys.exit()
        elif opt in ("-t", "--train"):
            train = arg
        elif opt in ("-r", "--traintruth"):
            traintruth = arg
        elif opt in ("-n", "--test"):
            test = arg

    # If all args is null, so exit
    if (test == "" and traintruth=="" and train==""):
        print('deepersystem.py -t <train.csv> -r <traintruth.csv> || -n <test.csv>')
        sys.exit(2)

    # If all args is present, so exit too
    if (test != "" and traintruth!="" and train!=""):
        print('deepersystem.py -t <train.csv> -r <traintruth.csv> || -n <test.csv>')
        print('just -t and -r OR -n')
        sys.exit(2)

    # Verify if train arg and traintruth arg is correctly. If exist model, so dont enter to train, just to test
    if (train != "" and traintruth!=""):
        if Path("model_slope.json").is_file() and Path("model_slope.h5").is_file() and Path("model_intercept.json").is_file() and Path("model_intercept.h5").is_file():
            print("Model already created, please use the test arg or delete the model_slope and model_intercept in both formats .h5 and .json")
        else:
            train_model(train,traintruth)
    elif (test != ""):
        if Path("model_slope.json").is_file() and Path("model_slope.h5").is_file() and Path("model_intercept.json").is_file() and Path("model_intercept.h5").is_file():
            test_model(test)
        else:
            print("Please, use the train to create a Model.")

if __name__ == "__main__":
    main(sys.argv[1:])


'''
List Multiplication Program

'''

# List Multiplication

def listMultiplication(multiList):
    listMulti = 1

    for num in multiList:
        listMulti = listMulti * num
    return listMulti

multiList = []

listNumber = int(input("Enter the Total List Items = "))
for i in range(1, listNumber + 1):
    listValue = int(input("Enter the %d List Item = " %i))
    multiList.append(listValue)

print("List Items = ", multiList)

listMultip = listMultiplication(multiList)

print("The Multiplication of all the List Items = ", listMultip)

Python Code/40.A.List Algorithms/12.List Multiplication Program.py


from connect import cursor as c
import utils

db = utils.read("DB: ")
table = utils.read("Table: ")

try:
    sql = """INSERT INTO {}.dbo.{}
    VALUES(100001,'John Rambo',100,'HD')""".format(db,table)
    c.execute(sql)
    print(f'A new record has been created!!!')
except ConnectionError:
    print("Cannot connect to SQL Server")


from TsAgent import TsAgent
import numpy as np
if __name__ == '__main__':
    agent = TsAgent(3)

    while True:
        print('counts: ', agent.counts)
        print('wins: ', agent.wins)
        print('probas: ', agent.get_arm())
        print('input: ')
        selected = int(input().strip())
        reward = 1 if np.random.random() > 0.5 else 0
        agent.sample(selected, reward)


def goodVsEvil(good, evil):
    worths = [1, 2, 3, 3, 4, 10, 1, 2, 2, 2, 3, 5, 10]
    g_e = [int(j) for i in [good, evil] for j in i.split() if j.isdigit()]
    result = [g_e[i]*worths[i] for i in list(range(13))]

    if sum(result[:6]) > sum(result[6:]):
        return "Battle Result: Good triumphs over Evil"
    elif sum(result[:6]) < sum(result[6:]):
        return "Battle Result: Evil eradicates all trace of Good"
    else:
        return "Battle Result: No victor on this battle field"


import math

def sieve_of_eratosthenes(n):
    l = [True for i in range(n+1)]
    for i in range(2, round(math.sqrt(n))+1):
        if l[i]:
            for j in range(i**2, n+1, i):
                l[j] = False

    result = []
    for i in range(2, n+1):
        if l[i]:
            result.append(i)

    return result

def solution():
    primes = sieve_of_eratosthenes(120000)
    return primes[10000]

if __name__ == "__main__":
    print(solution())


import logging
from platform import system

from serial import *
from utils.logger import create_logger

logger = create_logger(name=__name__, level=logging.DEBUG)

# COMMON_BAUD_RATES = (
#     50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200,
#     38400, 57600, 115200
# )

COMMON_BAUD_RATES = Serial.BAUDRATES
logger.debug(f"Ccommon baud rates available: {COMMON_BAUD_RATES}")

HIGH_SPEED_BAUD_RATES = (
    230400, 460800, 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
    2500000, 3000000, 3500000, 4000000
)
logger.debug(f"High speed baud rates: {HIGH_SPEED_BAUD_RATES}")

ALL_BAUD_RATES = COMMON_BAUD_RATES + HIGH_SPEED_BAUD_RATES

DEFAULT_BAUD_RATE = 9600
logger.debug(f"Default baud rate: {DEFAULT_BAUD_RATE}")

# BYTE_SIZES = {
#     "&5 bits": FIVEBITS,
#     "&6 bits": SIXBITS,
#     "&7 bits": SEVENBITS,
#     "&8 bits": EIGHTBITS
# }
BYTE_SIZES = dict(zip(
    (f"&{s} bits" for s in Serial.BYTESIZES),
    Serial.BYTESIZES
))
logger.debug(f"Byte sizes available: {BYTE_SIZES}")

DEFAULT_BYTE_SIZE = EIGHTBITS
logger.debug(f"Default byte size: {DEFAULT_BYTE_SIZE}")

# PARITIES = {
#     "&No parity": PARITY_NONE,
#     "&Even parity": PARITY_EVEN,
#     "&Odd parity": PARITY_ODD,
#     "&Mark parity": PARITY_MARK,
#     "&Space parity": PARITY_SPACE
# }
PARITIES = dict(filter(
    lambda p: p[1] in Serial.PARITIES,
    {
        "&No parity": PARITY_NONE,
        "&Even parity": PARITY_EVEN,
        "&Odd parity": PARITY_ODD,
        "&Mark parity": PARITY_MARK,
        "&Space parity": PARITY_SPACE
    }.items()
))
logger.debug(f"Parities available: {PARITIES}")

DEFAULT_PARITY = PARITY_NONE
logger.debug(f"Default parity: {DEFAULT_PARITY}")

STOP_BITS = dict(filter(
    lambda b: b[1] in Serial.STOPBITS,
    {
        "&1 stop bit": STOPBITS_ONE,
        "1.&5 stop bits": STOPBITS_ONE_POINT_FIVE,
        "&2 stop bits": STOPBITS_TWO
    }.items()
))
logger.debug(f"Stop bits available: {STOP_BITS}")

DEFAULT_STOP_BIT = STOPBITS_ONE
logger.debug(f"Default stop bit: {DEFAULT_STOP_BIT}")

NO_FLOW_CONTROL = 0
XON_XOFF_SOFT_FLOW_CONTROL = 1
RTS_CTS_HARD_FLOW_CONTROL = 2
DSR_DTR_HARD_FLOW_CONTROL = 3

FLOW_CONTROLS = {
    "&No flow control": NO_FLOW_CONTROL,
    "&XON/XOFF (software) flow control": XON_XOFF_SOFT_FLOW_CONTROL,
    "&RTS/CTS (hardware) flow control": RTS_CTS_HARD_FLOW_CONTROL,
    "&DSR/DTR (hardware) flow control": DSR_DTR_HARD_FLOW_CONTROL
}
logger.debug(f"Flow control methods available: {FLOW_CONTROLS}")

DEFAULT_FLOW_CONTROL = NO_FLOW_CONTROL
logger.debug(f"Default flow control: {DEFAULT_FLOW_CONTROL}")

NEWLINE_LF = 0
NEWLINE_CR = 1
NEWLINE_CRLF = 2

LINE_ENDINGS = {
    "&Line feed (\\n)": NEWLINE_LF,
    "&Carriage return (\\r)": NEWLINE_CR,
    "Carriage return &and line feed (\\r\\n)": NEWLINE_CRLF
}
logger.debug(f"Line endings available: {LINE_ENDINGS}")

DEFAULT_LINE_ENDING = NEWLINE_LF
# Possible values of platform.system():
#   - Linux
#   - Darwin
#   - Java
#   - Windows
if system() == "Windows":
    DEFAULT_LINE_ENDING = NEWLINE_CRLF

logger.debug(f"Default line ending: {DEFAULT_LINE_ENDING}")


from __future__ import print_function
from surprise import BaselineOnly
from surprise.dataset import DatasetAutoFolds
from surprise.dataset import Dataset
from surprise import evaluate
from surprise import Reader
from surprise import SVD
from surprise import NMF
from surprise import KNNWithMeans
from surprise import GridSearch
from surprise import accuracy
from operator import itemgetter
import numpy as np
import data_preprocessing as dp
import pprint
import threading
import os
try:
    import cPickle as p
except:
    import Pickle as p

# reader = Reader(line_format='user item rating timestamp', sep=',')

# data = Dataset.load_from_file('../data_collab.csv', reader=reader)
DATA_DIR='../data/'

class Surprise_recommender:
    def __init__(self,reader):
        '''
        Constructor

        ------
        Args:
        reader: A reader object for the dataset object in surprise
        '''
        self.reader=reader
        return

    def create_test_set(self,test_data):
        '''
        Function to create test_set
        This function drops timestamp from the data

        ------
        Args:
        test_data: input test data

        ------
        Returns:
        ts: test data after removing time stamp feature
        Basically a list with the following format: user, item, rating
        '''
        ts=[[td[0],td[1],td[2]] for td in test_data]
        return ts

    def create_train_set(self,train_data):
        '''
        Function to create training set

        ------
        Args:
        train_data: Training set in the form of list

        ------
        Returns:
        Trainset object from surprise
        Basically a list with the following format: user, item, rating, timestamp
        '''
        ds=Dataset(self.reader)
        return ds.construct_trainset(train_data)

    def train_test_model(self,validation_set,train_set,test_set,algorithm,task):
        '''
        Function to train models using different algorithms. Dumps GridSearch results
        for further analysis.

        ------
        Args:
        train_set: The training data formatted according to the needs of surprise
        algorithm: The algorithm for training the model
        test_set: Testing data to check RMSE and MAE after GridSearch
        validation_set: Dataset for hyperparameter optimization
        task: Make predictions for rating, sentiment scores or for combined rating

        ------
        Returns:None
        '''

        if algorithm == 'SVD':

            param_grid = {'n_epochs':np.arange(1,101,10).tolist(),'n_factors':[10,50,100]}
            grid_search = GridSearch(SVD, param_grid, measures=['RMSE', 'MAE'])

            grid_search.evaluate(validation_set)

            p.dump(grid_search.cv_results,open('../stats/svd_results_'+task+'.p','wb'))
            best_model_RMSE = grid_search.best_params['RMSE']
            validation_rmse = grid_search.best_score['RMSE']
            best_model_mae = grid_search.best_params['MAE']
            validation_mae = grid_search.best_score['MAE']
            #print(validation_rmse)
            #print(validation_mae)
            print(type(grid_search.cv_results))
            print(grid_search.cv_results)

            #Test based on best training RMSE
            n_epochs = best_model_RMSE['n_epochs']
            n_factors = best_model_RMSE['n_factors']
            self.algo = SVD(n_epochs = n_epochs, n_factors = n_factors)
            self.algo.train(train_set)
            predictions = self.algo.test(test_set)
            test_rmse = accuracy.rmse(predictions,verbose = True)
            test_mae = accuracy.mae(predictions,verbose = True)
            print("RMSE of predictions",test_rmse)
            print("MAE of predictions",test_mae)

        if algorithm == 'NMF':

            param_grid = {'n_epochs':np.arange(0,100,10).tolist(),'n_factors':[10,100]}
            grid_search = GridSearch(NMF, param_grid, measures=['RMSE', 'MAE'])

            grid_search.evaluate(validation_set)

            p.dump(grid_search,open('../stats/nmf_results_'+task+'.p','wb'))
            best_model_RMSE = grid_search.best_params['RMSE']
            validation_rmse = grid_search.best_score['RMSE']
            best_model_mae = grid_search.best_params['MAE']
            validation_mae = grid_search.best_score['MAE']
            print(validation_rmse)
            print(validation_mae)

            #Test based on best training RMSE
            n_epochs = best_model_RMSE['n_epochs']
            n_factors = best_model_RMSE['n_factors']
            self.algo = NMF(n_epochs = n_epochs, n_factors = n_factors)
            self.algo.train(train_set)
            predictions = self.algo.test(test_set)
            test_rmse = accuracy.rmse(predictions,verbose = True)
            test_mae = accuracy.mae(predictions,verbose = True)
            print("RMSE of predictions",test_rmse)
            print("MAE of predictions",test_mae)

        if algorithm == 'KNNWithMeans':
            param_grid = {'k':np.arange(1,20).tolist(),'sim_options':[{'name':'cosine','user_based':True},
                {'name':'msd','user_based':True},{'name':'pearson','user_based':True}]}
            grid_search = GridSearch(KNNWithMeans,param_grid,measures=['RMSE','MAE'])
            grid_search.evaluate(validation_set)

            p.dump(grid_search,open('../stats/knn_means_results'+task+'.p','wb'))

            best_model_RMSE = grid_search.best_params['RMSE']
            validation_rmse = grid_search.best_score['RMSE']
            best_model_mae = grid_search.best_score['MAE']
            validation_mae = grid_search.best_score['MAE']

            #Test based on best training RMSE
            k = best_model_RMSE['k']
            sim_options = best_model_RMSE['sim_options']
            self.algo = KNNWithMeans(k = k, sim_options = sim_options)
            self.algo.train(train_set)
            predictions = self.algo.test(test_set)
            test_rmse = accuracy.rmse(predictions,verbose = True)
            test_mae = accuracy.mae(predictions,verbose = True)
            print("RMSE of predictions",test_rmse)
            print("MAE of predictions",test_mae)

    def generate_top_n_recommendation(self,test_set,train_set):
        '''
        Function to generate top N recommendations

        ----
        Args:
        user_id: The id of the user
        test_set: The testing set as a list
        train_set: The training set as a list
        '''
        user_list=set([x[0] for x in train_set])
        print ("Number of users = ",len(user_list))

        precision_list=[]
        recall_list=[]
        f_score_list=[]
        j=0
        for user in user_list:
            # print("===============================================================")
            # print("=====================+++++++++++++++++++++++===================")
            # print("===============================================================")
            j+=1
            if j%1000==0:
                print("Touchdown, j = ",j)
            item_train=set([x[1] for x in train_set if x[0]==user])
            item_test=set([x[1] for x in test_set if x[0]==user])
            item_train_all=set([x[1] for x in train_set])
            item_test_all=set([x[1] for x in test_set])
            item_all=item_train_all.union(item_test_all)
            # print("User = ",user)
            # print("===============================================================")
            # print("TRain items = ",item_train)
            # print("===============================================================")
            # print("Test items = ",item_test)
            # print("ITem all = ",item_all)
            # print("Number of  test items= ",len(item_test))
            negative_items=[x for x in item_all if x not in item_train and x not in item_test]
            # print("Number of negative items = ",len(negative_items))

            # Get 1000 random negative items
            negative_indices=np.random.randint(0,len(negative_items),size=1000)
            negative_subset=[negative_items[x] for x in negative_indices]
            # Get 5 positive items from testing set:
            positive_subset=list(item_test)
            np.random.shuffle(positive_subset)
            # print("Positive subset items = ",positive_subset)
            # print(negative_subset)
            subset=positive_subset+negative_subset
            pred_list=[]
            for item in subset:
                pred=self.algo.predict(user,item,r_ui=1,verbose=False)
                pred_list.append(pred)
            predictions = sorted(pred_list, key=lambda x: x.est,reverse=True)
            # print(" =============================================================")
            precision=self.calculate_precision(predictions,positive_subset,10)
            # print("Precision = ",precision)
            recall=self.calculate_recall(predictions,positive_subset,10)
            # print("Recall = ",recall)
            # f_score=self.calculate_f_measure(precision,recall)
            # print("F score = ",f_score)
            precision_list.append(precision)
            recall_list.append(recall)
            # f_score_list.append(f_score)

        precision=np.mean(precision_list)
        recall=np.mean(recall_list)
        print ("Mean precision = ",precision)
        print("Mean recall = ",recall)
        print("fscore=",self.calculate_f_measure(precision,recall))
        return

    def calculate_precision(self,predictions,positive_items,N):
        '''
        Function to calculate precision
        '''
        count=0
        for i in np.arange(N):
            p=predictions[i]
            if p.iid in positive_items:
                count+=1
        precision=float(count)/N
        return precision

    def calculate_recall(self,predictions,positive_items,N):
        '''
        Function to calculate recall
        '''
        count=0
        pred=predictions[:N] #Get TOP N Predictions
        for p in positive_items:
            for i in pred:
                if i.iid==p:
                    count+=1
                    break

        recall=float(count)/len(positive_items)
        return recall

    def  calculate_f_measure(self,precision,recall):
        '''
        Function to calculate recall
        '''
        try:
            f=2.0*precision*recall/(precision+recall)
        except:
            f=0
        return f

class DatasetForCV(DatasetAutoFolds):

    def __init__(self,raw_ratings,ratings_file = None,reader = None):
        #self g.ratings_file = ratings_file
        self.reader = reader
        self.n_folds = 5
        self.shuffle = False
        self.raw_ratings = raw_ratings
        self.ratings_file=ratings_file

def main():

    #Load the data
    data=dp.read_data_list('data_collab.csv',contains_header=False)
    data_sentiment = dp.read_data_list('data_collab_sentiment.csv',contains_header = False)
    data_combined = dp.read_data_list('data_collab_combined.csv',contains_header = False)

    for d in data:
        d[2] = float(d[2])

    for d in data_sentiment:
        d[2] = float(d[2])

    for d in data_combined:
        d[2] = float(d[2])

    #a = dict()
    print("Size of data = ",len(data))
    reader = Reader(line_format='user item rating timestamp', sep=',')
    sp=Surprise_recommender(reader)

    #Create splits
    if not('train_test_splits.p' in os.listdir(DATA_DIR)):
        train,test,train_indices,test_indices=dp.create_train_test_split(data,0.8)
        train_sentiment,test_sentiment=dp.create_train_test_split(data_sentiment,0.8,train_indices,test_indices)
        train_combined,test_combined= dp.create_train_test_split(data_combined,0.8,train_indices,test_indices)
        print("Creating pickle dump")
        with open(DATA_DIR+'train_test_splits.p','wb') as f:
            p.dump([train_indices, test_indices, train,test,train_sentiment,test_sentiment,train_combined,test_combined],f)
    else:
        print("Load pickle dump")
        with open(DATA_DIR+'train_test_splits.p','rb') as f:
            train_indices, test_indices, train,test,train_sentiment,test_sentiment,train_combined,test_combined=p.load(f)
    #Create validation sets
    validation = DatasetForCV(train,None,reader)
    validation_sentiment  = DatasetForCV(train_sentiment,None, reader)
    validation_combined = DatasetForCV(train_combined,None,reader)

    # #Create train and test sets
    print("Training length = ",len(train))
    train_list=train
    train=sp.create_train_set(train)
    print("Test length = ",len(test))
    test_list=test
    test=sp.create_test_set(test)
    # print(train)
    # print(test)
    train_sent_list=train_sentiment
    train_sentiment = sp.create_train_set(train_sentiment)
    test_sent_list=test_sentiment
    test_sentiment = sp.create_test_set(test_sentiment)
    train_combined_list=train_combined
    train_combined = sp.create_train_set(train_combined)
    test_combined_list=test_combined
    test_combined = sp.create_test_set(test_combined)

    #Testing and trainig models based on RMSE

    #Run and measure RMSE, MAE for different algorithms
    print('--------------Normal Ratings---------------------')
    sp.train_test_model(validation,train,test,'SVD','rating')
    sp.generate_top_n_recommendation(test_list,train_list)

    print('--------------Combined Scores---------------------')
    sp.train_test_model(validation_combined,train_combined,test_combined,'SVD','combined')
    sp.generate_top_n_recommendation(test_combined_list,train_combined_list)

    #time_exp_svd = sp.train_test_model(validation,train_combined,test_combined,'SVD','experiment')

    print('--------------Normal Ratings---------------------')
    sp.train_test_model(validation,train,test,'NMF','rating')
    sp.generate_top_n_recommendation(test_list,train_list)

    print('--------------Combined Scores---------------------')
    sp.train_test_model(validation_combined,train_combined,test_combined,'NMF','combined')
    sp.generate_top_n_recommendation(test_combined_list,train_combined_list)

    #time_exp_nmf = sp.train_test_model(validation,train_combined,test_combined,'NMF','experiment')

    print('--------------Normal Ratings---------------------')
    sp.train_test_model(validation,train,test,'KNNWithMeans','rating')
    sp.generate_top_n_recommendation(test_list,train_list)

    #time_exp_knn = sp.train_test_model(validation,train_combined,test_combined,'KNNWithMeans','experiment')

    print('--------------Combined Scores---------------------')
    sp.train_test_model(validation_combined,train_combined,test_combined,'KNNWithMeans','combined')
    sp.generate_top_n_recommendation(test_combined_list,train_combined_list)

if __name__=='__main__':
    main()


import csv
import threading
import time

import cv2
import numpy as np
import os
import queue
import random

class CSI_Camera:

    def __init__(self, sensor_id=None):
        self.video_capture = None
        self.frame = None
        self.grabbed = False
        self.read_thread = None
        self.read_lock = threading.Lock()
        self.running = False
        self.sensorID = sensor_id
        self.isOpened = False
        self.sensorIsReady = False
        self.postprocess = None
        self.logObj = None
        self.writerObj = None

    def open(self, gstreamer_pipeline_string):
        try:
            self.video_capture = cv2.VideoCapture(
                gstreamer_pipeline_string, cv2.CAP_GSTREAMER
            )
            # Grab the first frame to start the video capturing
            self.grabbed, self.frame = self.video_capture.read()
            self.sensorIsReady = self.grabbed

        except:
            self.video_capture = None
            print("Unable to open camera")
            print("Pipeline: " + gstreamer_pipeline_string)

    def start(self):
        if self.running:
            print('Video capturing is already running')
            return None
        # create a thread to read the camera image
        if self.video_capture != None:
            self.running = True
            self.read_thread = threading.Thread(target=self.updateCamera)
            self.read_thread.start()
            self.isOpened = self.video_capture.isOpened()
        return self

    def stop(self):
        self.running = False
        # Kill the thread
        self.read_thread.join()
        self.read_thread = None
        if self.video_capture != None:
            self.video_capture.release()
            self.video_capture = None
        print(f'[OK]{self.sensorID} is closed')

    def updateCamera(self):
        while self.running:
            try:
                grabbed, frame = self.video_capture.read()
                with self.read_lock:
                    self.grabbed = grabbed
                    self.frame = frame
            except RuntimeError:
                print("Could not read image from camera")

    def read(self):
        with self.read_lock:
            time_stamp = time.time()
            frame = self.frame
            grabbed = self.grabbed
            self.frame = None
            self.grabbed = 0
        return grabbed, frame, time_stamp

    def release(self):
        if self.video_capture != None:
            self.video_capture.release()
            self.video_capture = None
        if self.read_thread != None:
            self.read_thread.join()

    def log(self, tempObj):
        filename = f"frame_{self.sensorID}_{tempObj.index}"
        if tempObj.data_is_ok:
            self.logger.writerow([
                tempObj.index,
                tempObj.time,
                filename
            ])
        else:
            self.logger.writerow([
                tempObj.index,
                tempObj.time,
                "",
            ])

    def logP(self, log_buffer):
        log_file = open(f'{os.getpid()}.csv', 'w', newline='')
        file_header = ["index", "time", "imageName"]
        logger = csv.writer(log_file)
        logger.writerow(file_header)
        while self.logObj.running.value or not log_buffer.empty():
            try:
                tempObj = log_buffer.get(0)
                filename = f"{tempObj.source}/{tempObj.source}_{tempObj.index}.jpg"
                logger.writerow([
                    tempObj.index,
                    tempObj.time,
                    filename if tempObj.data_is_ok else None
                ])
            except RuntimeError:
                print('[ERROR] Could not save an frame')
            except queue.Empty:
                pass
        else:
            log_file.close()
            os.rename(f'{os.getpid()}.csv', f'{tempObj.source}.csv')
            print(f"[OK] Process id: {self.logObj.name} has joined")

    def video_writer(self, data_buffer, cap_size):
        pWriter = cv2.VideoWriter(f'{os.getpid()}.mp4',
                        0x7634706d,
                        30,
                        cap_size,
                        )
        with open(f'{os.getpid()}.txt', 'w') as f:
            while self.writerObj.running.value or not data_buffer.empty():
                try:
                    if random.random() < .9:
                        tempObj = data_buffer.get(0)
                        if tempObj.data_is_ok:
                            pWriter.write(tempObj.data)
                            f.write(f'{tempObj.source}_{tempObj.index}\n')
                except RuntimeError:
                    print('[ERROR] Could not save an frame')
                except queue.Empty:
                    time.sleep(.01)
            else:
                pWriter.release()
                print(f"[OK] Process id: {os.getpid()} has joined")

    def image_writer(self, data_buffer):
        while self.writerObj.running.value or not data_buffer.empty():
            try:
                if random.random() < .9:
                    tempObj = data_buffer.get(0)
                    if tempObj.data_is_ok:
                        filename = f"{tempObj.source}/{tempObj.source}_{tempObj.index}.jpg"
                        cv2.imwrite(filename, tempObj.data)
            except RuntimeError:
                print('[ERROR] Could not save an frame')
            except queue.Empty:
                time.sleep(.01)
        else:
            print(f"[OK] process id: {os.getpid()} has joined")

"""
gstreamer_pipeline returns a GStreamer pipeline for capturing from the CSI camera
Flip the image by setting the flip_method (most common values: 0 and 2)
display_width and display_height determine the size of each camera pane in the window on the screen
Default 1920x1080
"""

def gstreamer_pipeline(
        sensor_id=0,
        capture_width=1920,
        capture_height=1080,
        display_width=1920,
        display_height=1080,
        framerate=30,
        flip_method=0,
):
    return (
            "nvarguscamerasrc sensor-id=%d ! "
            "video/x-raw(memory:NVMM), width=(int)%d, height=(int)%d, framerate=(fraction)%d/1 ! "
            "nvvidconv flip-method=%d ! "
            "video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
            "videoconvert ! "
            "video/x-raw, format=(string)BGR ! appsink"
            % (
                sensor_id,
                capture_width,
                capture_height,
                framerate,
                flip_method,
                display_width,
                display_height,
            )
    )

def run_cameras():
    window_title = "Dual CSI Cameras"
    left_camera = CSI_Camera()
    left_camera.open(
        gstreamer_pipeline(
            sensor_id=0,
            capture_width=1920,
            capture_height=1080,
            flip_method=0,
            display_width=960,
            display_height=540,
        )
    )
    left_camera.start()

    right_camera = CSI_Camera()
    right_camera.open(
        gstreamer_pipeline(
            sensor_id=1,
            capture_width=1920,
            capture_height=1080,
            flip_method=0,
            display_width=960,
            display_height=540,
        )
    )
    right_camera.start()

    if left_camera.video_capture.isOpened() and right_camera.video_capture.isOpened():

        cv2.namedWindow(window_title, cv2.WINDOW_AUTOSIZE)

        try:
            while True:
                _, left_image = left_camera.read()
                _, right_image = right_camera.read()
                # Use numpy to place images next to each other
                camera_images = np.hstack((left_image, right_image))
                # Check to see if the user closed the window
                # Under GTK+ (Jetson Default), WND_PROP_VISIBLE does not work correctly. Under Qt it does
                # GTK - Substitute WND_PROP_AUTOSIZE to detect if window has been closed by user
                if cv2.getWindowProperty(window_title, cv2.WND_PROP_AUTOSIZE) >= 0:
                    cv2.imshow(window_title, camera_images)
                else:
                    break

                # This also acts as
                keyCode = cv2.waitKey(30) & 0xFF
                # Stop the program on the ESC key
                if keyCode == 27:
                    break
        finally:

            left_camera.stop()
            left_camera.release()
            right_camera.stop()
            right_camera.release()
        cv2.destroyAllWindows()
    else:
        print("Error: Unable to open both cameras")
        left_camera.stop()
        left_camera.release()
        right_camera.stop()
        right_camera.release()

# if __name__ == "__main__":
#     run_cameras()


#Main class for the game

#Important modules
import sys
import pygame
from settings import *
from ship import *
from bullet import *
from alien import *
from time import sleep
from game_stats import GameStats
from button import *
from scoreboard import *

class AlienInvasion:
	"""Class to manage the game"""

	def __init__(self):

		pygame.init()
		self.settings = Settings()

		#Defining the dimensions of the game window - Full Screen / pretty cool stuff ;)
		self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
		self.settings.screen_width = self.screen.get_rect().width
		self.settings.screen_height = self.screen.get_rect().height

		#Title of the window
		pygame.display.set_caption("Alien Invasion")

		#Creating an instance to score game statistics and a scoreboard
		self.stats = GameStats(self)
		self.sb = Scoreboard(self)

		#Entering the ship in the main game
		self.ship = Ship(self) #aqui é preciso por o self para o ship ter acesso aos recursos do jogo

		#Group to manage the bullets already fired
		self.bullets = pygame.sprite.Group()

		#Group to handle the alien ships
		self.aliens = pygame.sprite.Group()

		#Method for the alien fleet
		self._create_fleet()

		#Adding the button
		self.play_button = Button(self,"Click here to play or Press P")

		#Background color
		self.bg_color = (230,230,230)

	def run_game(self):
		#Main loop of the game

		while True:
			#This is the event manager.
			self._check_events()

			if self.stats.game_active:
				self.ship.update()
				self._update_bullets()
				self._update_aliens()

			self._update_screen()

	def _check_events(self):
		#Responding to Keyboard and mouse movements
		for event in pygame.event.get():

			#Events triggered by pressing on the keyboard
			if event.type == pygame.KEYDOWN:
				self._check_keydown_events(event)

			#Events triggered by releasing a key on the keyboard
			elif event.type == pygame.KEYUP:
				self._check_keyup_events(event)

			#Quit the game by pressing X on the top right corner
			elif event.type == pygame.QUIT:
				self._quit_game()
				sys.exit()

			elif event.type == pygame.MOUSEBUTTONDOWN:
				mouse_pos = pygame.mouse.get_pos()
				self._check_play_button(mouse_pos)

	def _check_play_button(self,mouse_pos):
		#Start a new game when the player clicks Play

		button_clicked = self.play_button.rect.collidepoint(mouse_pos)

		if button_clicked and not self.stats.game_active:
			self.settings.initialize_dynamic_settings()
			self._start_game()

			self.sb.prep_score()
			self.sb.prep_level()
			self.sb.prep_ships()

			#Reset the game statistics
			self.stats.reset_stats()

	def _check_keydown_events(self,event):
		#Refactor of the check_keydown events
		if event.key == pygame.K_RIGHT:
		#Move the ship to the right
			self.ship.moving_right = True

		#Move the ship to the left
		elif event.key == pygame.K_LEFT:
			self.ship.moving_left = True

		#Quit the game by pressing Q on the keyboard
		elif event.key == pygame.K_q:
			self._quit_game()
			sys.exit()

		#Fire a bullet when Spacebar is pressed
		elif event.key == pygame.K_SPACE:
			self._fire_bullet()

		elif event.key == pygame.K_p:
			self._start_game()

	def _quit_game(self):
		#Storing the High Score in a file
		f = open("high_score.txt","w+")
		f.write(str(self.stats.high_score))
		f.close()

	def _start_game(self):
		#Method for starting the game in 2 different ways

		#Resetting the game
		self.stats.reset_stats()

		#Activate the game after pressing Play
		self.stats.game_active = True

		#Get rid of any remaining aliens and bullets
		self.aliens.empty()
		self.bullets.empty()

		#Create a new fleet and center the ship
		self._create_fleet()
		self.ship.center_ship()

		#Hide the mouse cursor
		pygame.mouse.set_visible(False)

	def _check_keyup_events(self,event):
		if event.key == pygame.K_RIGHT:
			self.ship.moving_right = False

		elif event.key == pygame.K_LEFT:
			self.ship.moving_left = False

	def _fire_bullet(self):

		#Here we make sure that no more than the nr of allowed bullets are created and on the screen
		if len(self.bullets) < self.settings.bullets_allowed:
			#Create a new bullet and add it to the screen
			new_bullet = Bullet(self)
			#The add method here is similar to append, but specific for Pygames
			self.bullets.add(new_bullet)

	def _update_bullets(self):
		#Updating the position of the bullets and get rid of old bullets
		self.bullets.update()

		#Delete the bullets after they reached the top of the screen
		#We use the copy() method here because it is not possible to loop through dynamic lists
		for bullet in self.bullets.copy():
			if bullet.rect.bottom <= 0:
				self.bullets.remove(bullet)

		self._check_bullet_alien_collisions()

	def _check_bullet_alien_collisions(self):
		#Responding to bullet-alien collisions

		#Remove any bullets and aliens
		collisions = pygame.sprite.groupcollide(
			self.bullets,self.aliens,False,True)

		if collisions:

			#Msking sure that each allien hit counts for the score
			for aliens in collisions.values():
				self.stats.score += self.settings.alien_points * len(aliens)

			self.sb.prep_score()

			#Each time an alien is hit, check and compare the high score
			self.sb.check_high_score()

		#If the fleet is destroyed, activate this option to create a whole new one
		if not self.aliens:
			self.bullets.empty()
			self._create_fleet()
			self.settings.increase_speed()

			#Increase level
			self.stats.level += 1
			self.sb.prep_level()

	def _create_fleet(self):
		#Creating a new fleet of aliens

		#Crearing an alien to know the spacing between aliens
		alien = Alien(self)
		alien_width,alien_height = alien.rect.size

		#Available space between aliens and max number of them in one row
		available_space_x = self.settings.screen_width - (2*alien_width)
		number_of_aliens = available_space_x // (2* alien_width)

		#Determine the number of rows of aliens fitting the screen
		ship_height = self.ship.rect.height
		available_space_y = self.settings.screen_height - (3*alien_height)-ship_height
		number_rows = available_space_y // (2*alien_height)

		#Create the full fleet of aliens
		for row_number in range(number_rows):
			for alien_number in range(number_of_aliens):
				self._create_alien(alien_number,row_number)

	def _create_alien(self,alien_number,row_number):
		alien = Alien(self)
		alien_width, alien_height = alien.rect.size
		alien.x = alien_width + 2*alien_width*alien_number
		alien.rect.x = alien.x
		alien.rect.y = alien.rect.height+2*alien.rect.height*row_number
		self.aliens.add(alien)

	def _update_aliens(self):
		self._check_fleet_edges()
		self.aliens.update()

		#Check if the ship and fleet collided
		if pygame.sprite.spritecollideany(self.ship,self.aliens):
			self._ship_hit()

		#Look for aliens hitting the bottom of the screen
		self._check_aliens_bottom()

	def _check_aliens_bottom(self):
		#Check if any aliens have reached the bottom of the screen

		screen_rect = self.screen.get_rect()

		for alien in self.aliens.sprites():
			if alien.rect.bottom >= screen_rect.bottom:
				#The same thing as if the ship is hit
				self._ship_hit()
				break

	def _ship_hit(self):
		#Response when the shit collides with an allien

		self._quit_game()

		if self.stats.ships_left > 0:
			#Decrement ships left
			self.stats.ships_left -= 1

			#The gamer loses a life/ship so the prep_ship needs to be called
			#Update the scoreboard
			self.sb.prep_ships()

			#Get rid of any remaining aliens and bullets
			self.aliens.empty()
			self.bullets.empty()

			#Create a new fleet and center the ship
			self._create_fleet()
			self.ship.center_ship()

			#Pause
			sleep(0.5)

		else:
			self.stats.game_active = False
			pygame.mouse.set_visible(True)

	def _check_fleet_edges(self):
		#Response if any of the aliens reached an edge
		for alien in self.aliens.sprites():
			if alien.check_edges():
				self._change_fleet_direction()
				break

	def _change_fleet_direction(self):
		#Drop the fleet and change its direction
		for alien in self.aliens.sprites():
			alien.rect.y += self.settings.fleet_drop_speed

		self.settings.fleet_direction *= -1

	def _update_screen(self):
		#Redraw the screen after each event
		#Ter em atenção a ordem em que se coloca estes parametros!!!
		self.screen.fill(self.settings.bg_color)

		#Include the ship
		self.ship.blitme()

		#Returns a list of all sprites in the group bullets
		for bala in self.bullets.sprites():
			bala.draw_bullet()

		#Display the alien fleet
		self.aliens.draw(self.screen)

		#Draw the score information
		self.sb.show_score()

		#Draw the play button
		if not self.stats.game_active:
			self.play_button.draw_button()

		#Make the most recently drawn screen
		pygame.display.flip()

if __name__ == '__main__':
	#Make the game instance and run it
	ai = AlienInvasion()
	ai.run_game()


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

from pypfp.converters import *
import codecs

class Field(object):
    order = 0

    @staticmethod
    def get_order():
        Field.order += 1
        return Field.order

    def __init__(self, converter_class, width, start=None, name=None,
                db_field=None, validator=None, **converter_params):
        self.order = Field.get_order()
        self.name = name
        self.start = start
        self.width = width
        self.db_field = db_field
        self.validator = validator
        self.converter = converter_class(width, **converter_params)

    def to_string(self, obj):
        v = getattr(obj, self.name)
        return self.converter.to_string(v)

    def to_value(self, string, obj):
        v = self.converter.to_value(string)
        if self.validator:
            self.validator(v)
        setattr(obj, self.name, v)

def value_validator(valid_value):
    def f(value):
        if value != valid_value:
            raise ValueError('Invalid value: %s. Expected: %s'
                % (str(value), str(valid_value)))
    return f

class RecordOptions(object):

    def __init__(self, fill=u' ', selector_string=u'', stack_function=None):
        self.fields = []
        self.fill = fill
        self.selector_string = selector_string
        if stack_function is None:
            self.stack_function = lambda x: x + 1
        else:
            self.stack_function = stack_function

    def __str__(self):
        return '\n'.join(str(k) + ':' + str(v)
                        for k, v in self.__dict__.items())

class RecordMetaClass(type):

    meta_confs = ('fill', 'selector_string', 'stack_function')

    def __new__(cls, name, bases, attrs):
        cls.init_class(attrs, RecordMetaClass.get_default_value)
        return super(RecordMetaClass, cls).__new__(cls, name, bases, attrs)

    @staticmethod
    def get_default_value(field):
        if callable(field.converter.default):
            return field.converter.default()
        return field.converter.default

    @staticmethod
    def init_class(attrs, get_field_value):
        meta = attrs.get('Meta', None)
        meta_options = {}
        if meta:
            for k, v in meta.__dict__.items():
                if k in RecordMetaClass.meta_confs:
                    meta_options[k] = v
                    meta.__dict__.pop(k)
        _record_options = RecordOptions(**meta_options)
        stack_function = _record_options.stack_function

        records = [(k, v) for k, v in attrs.items() if isinstance(v, Field)]
        records.sort(key=lambda x: x[1].order)

        formats = []
        last_pos = -1
        for k, v in records:
            v.name = k
            if v.start is None:
                v.start = stack_function(last_pos)
            to_fill = v.start - last_pos - 1
            if to_fill > 0:
                formats.append(_record_options.fill * to_fill)
            formats.append(u'{:%d}' % v.width)
            last_pos = v.start + v.width - 1
            _record_options.fields.append(v)
        _record_options.string_format = u''.join(formats)

        attrs['_record_options'] = _record_options

        for field in _record_options.fields:
            attrs[field.name] = get_field_value(field)

class Record(object):
    __metaclass__ = RecordMetaClass

    @classmethod
    def to_string(cls, obj):
        return cls._record_options.string_format.format(*[x.to_string(obj)
                                        for x in cls._record_options.fields])

    @classmethod
    def to_value(cls, line):
        obj = cls()
        for field in cls._record_options.fields:
            s = line[field.start:field.start + field.width]
            field.to_value(s, obj)
        return obj

    def __unicode__(self):
        fields = ', '.join([u'{0}: {1}'.format(f.name, getattr(self, f.name))
                            for f in self.__class__._record_options.fields])
        return u'<{0} :: {1}>'.format(self.__class__.__name__, fields)

class FixedEngine(object):

    def __init__(self, records, selector=None, selector_slice=None,
                    end_with_new_line=False):
        self.records = records
        self.record_dict = {r.__name__: r for r in self.records}
        self.end_with_new_line = end_with_new_line
        if selector is not None:
            self.selector = selector
        elif selector_slice is not None:
            _x, _y = selector_slice
            d = {r._record_options.selector_string: r for r in records}
            self.selector = lambda s: d.get(s[_x:_y], None)
        elif len(records) == 1:
            r = records[0]
            self.selector = lambda s: r
        else:
            raise AssertionError('No selector provided')

    def save(self, path, objects, encoding='utf-8'):
        lines = []
        for obj in objects:
            record = self.find_record(obj)
            lines.append((record.to_string(obj)).encode(encoding))

        with open(path, 'w') as f:
            f.write('\n'.join(lines))
            if self.end_with_new_line:
                f.write('\n')

    def load(self, path, encoding='utf-8'):
        lines = codecs.open(path, 'r', encoding).readlines()
        res = []
        for line in lines:
            record = self.selector(line)
            if record:
                res.append(record.to_value(line))
        return res

    def find_record(self, obj):
        return self.record_dict[obj.__class__.__name__]


# iotest.py Test PR #3836 timing using GPIO pins.

import io, pyb
import uasyncio as asyncio
import micropython
micropython.alloc_emergency_exception_buf(100)

MP_STREAM_POLL = const(3)
MP_STREAM_POLL_RD = const(1)

y1 = pyb.Pin('Y1', pyb.Pin.OUT)

class MyIO(io.IOBase):
    def __init__(self):
        self.ready = False
        self.count = 0
        tim = pyb.Timer(4)
        tim.init(freq=1)  # 1Hz - 1 simulated input line per sec.
        tim.callback(self.setready)

    def ioctl(self, req, arg):
        if req == MP_STREAM_POLL and (arg & MP_STREAM_POLL_RD):
            state = pyb.disable_irq()
            r = self.ready
            self.ready = False
            pyb.enable_irq(state)
            return r
        return 0

    def readline(self):  # Y1 goes low when I/O is serviced
        y1.value(0)
        return '{}\n'.format(self.count)

    def setready(self, t):  # Y1 goes high when I/O becomes ready
        self.count += 1
        y1.value(1)
        self.ready = True

myio = MyIO()

async def foo(p):  # Toggle a pin when scheduled
    print('start foo', p)
    pin = pyb.Pin(p, pyb.Pin.OUT)
    while True:
        pin.value(1)
        await asyncio.sleep(0)
        pin.value(0)
        await asyncio.sleep(0)

async def receiver():
    last = None
    nmissed = 0
    sreader = asyncio.StreamReader(myio)
    while True:
        res = await sreader.readline()
        print('Recieved {} Missed {}'.format(res, nmissed))
        ires = int(res)
        if last is not None:
            if last != ires -1:
                print('Missed {}'.format(ires - 1))
                nmissed += 1
        last = ires

loop = asyncio.get_event_loop()
loop.create_task(receiver())
loop.create_task(foo('Y2'))
loop.create_task(foo('Y3'))
loop.run_forever()


import rasterio
import fiona
import rasterio.warp as warp
from rasterio.mask import mask
from rasterio.warp import Resampling
import os
from glob import glob
import numpy as np
from shapely.geometry import mapping, shape
from affine import Affine
from pyproj import Proj, transform
from s2cloudless import S2PixelCloudDetector
import subprocess

def resampling_method(method):
    if method == 'nearest':
        return Resampling.nearest
    elif method == 'bilinear':
        return Resampling.bilinear
    elif method == 'cubic':
        return Resampling.cubic
    elif method == 'cubic_spline':
        return Resampling.cubic_spline
    elif method == 'lanczos':
        return Resampling.lanczos
    elif method == 'average':
        return Resampling.average
    elif method == 'mode':
        return Resampling.mode
    elif method == 'max':
        return Resampling.max
    elif method == 'min':
        return Resampling.min
    elif method == 'med':
        return Resampling.med
    elif method == 'q1':
        return Resampling.q1
    elif method == 'q3':
        return Resampling.q3
    else:
        raise ValueError("Invalid method, does not exist, check rasterio.warp.Resampling for reference.")

def read_S2TOA(S2_SAFE_fp, pixel_res, temp=None, resample='average'):
    bands = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09','B10', 'B11', 'B12']
    res = np.array([60, 10, 10, 10, 20, 20, 20, 10, 20, 60,60, 20, 20])
    # list of rasters
    S2rasters = [glob(os.path.join(S2_SAFE_fp, 'GRANULE', 'L*', 'IMG_DATA', '*{}*'.format(band)))[0]
                 for band in bands]
    afftr = res / pixel_res
    S2_bands = []
    for i, band in enumerate(S2rasters):
        print("Band ", i + 1)
        with rasterio.open(band) as src:
            arr = src.read().astype('float32') / 10000
            kwargs = src.profile
            if res[i] == pixel_res:
                S2_bands.append(arr)
                if temp is not None:
                    temp_raster = os.path.join(temp, 'temp_raster.tif')
                    kwargs.update({'width': arr.shape[1],
                                   'height': arr.shape[2],
                                   "driver": 'GTiff',
                                   "dtype": arr.dtype,
                                   "nodata": src.profile['nodata']})
                    with rasterio.open(temp_raster, 'w', **kwargs) as dst:
                        dst.write(arr)
                continue
            else:
                aff = src.transform
                new_aff = Affine(aff.a / afftr[i], aff.b, aff.c,
                                 aff.d, aff.e / afftr[i], aff.f)

                kwargs.update({"transform": new_aff,
                               "driver": 'GTiff',
                               "dtype": arr.dtype,
                               "nodata": src.profile['nodata']})
                newarr = np.empty(shape=(arr.shape[0],
                                         int(round(arr.shape[1] * afftr[i])),
                                         int(round(arr.shape[2] * afftr[i]))), dtype='float32')
                warp.reproject(arr, newarr,
                               src_transform=aff,
                               dst_transform=new_aff,
                               src_crs=src.crs,
                               dst_crs=src.crs,
                               resampling=resampling_method(resample))
                S2_bands.append(newarr)

    S2_bands = np.concatenate(S2_bands, axis=0).transpose(1, 2, 0)
    if temp is not None:
        return S2_bands, temp_raster
    else:
        return S2_bands

def apply_acolite(S2_SAFE_fp,output, S2_target_res):

    """
    Create settings file for ACOLITE AC processor for multiple tiles and saves it in the
    working directory as "aculite_settings.txt". For any other settings, look at the aculite_config.txt
    in aculite_py_win/config folder

    :param inputfolder: folder with all the S2 level 1 products in SAFE format
    :param output: Output folder for
    :param s2_target_res: Resolotion for processed produce
    :param merge_tiles: if you do not wish to merge, make this False
    :return: settings
    """
    inputfiles = 'inputfile='+S2_SAFE_fp+'\n'
    outputfile = 'output=' + output + '\n'
    l2w = 'l2w_parameters=rhos_*\n'
    target_res = 's2_target_res=' + str(S2_target_res) + '\n'
    settings = inputfiles + outputfile + l2w + target_res

    with open("acolite_settings.txt", 'w') as dst:
        dst.write(settings)

    cwd = os.getcwd()
    acolitefp = r'acolite_py_win/dist/acolite'
    os.chdir(acolitefp)
    comm = r'acolite.exe --cli --settings="..\..\..\acolite_settings.txt"'
    subprocess.run(comm, shell=True)
    os.chdir(cwd)

def read_acolite(Acolite_fp):

    if os.path.basename(glob(os.path.join(Acolite_fp,'S2*'))[0])[:3]=='S2B':
        bands = ['442', '492', '559', '665', '704', '739', '780', '833', '864', '1610', '2186', ]
    else:
        bands = ['443', '492', '560', '665', '704', '740', '783', '833', '865', '1614', '2202']
    S2_BOA_bands = []
    """
    afftr = 10 / pixel_res
    for i, band in enumerate(bands):
        print("Band ", i+1, ':', bands[i])
        rhos_ = glob(os.path.join(Acolite_fp, '*rhos_' + band + '.tif'))[0]
        with rasterio.open(rhos_) as acsrc:
            arr = acsrc.read()
            aff = acsrc.transform
            new_aff = Affine(aff.a / afftr, aff.b, aff.c,
                             aff.d, aff.e / afftr, aff.f)
            kwargs = acsrc.profile
            kwargs.update({"transform": new_aff,
                           "driver": 'GTiff',
                           "dtype": arr.dtype,
                           "nodata": acsrc.profile['nodata']})
            newarr = np.empty(shape=(arr.shape[0],
                                     int(round(arr.shape[1] * afftr)),
                                     int(round(arr.shape[2] * afftr))), dtype='float32')
            warp.reproject(arr, newarr,
                           src_transform=aff,
                           dst_transform=new_aff,
                           src_crs=acsrc.crs,
                           dst_crs=acsrc.crs,
                           resampling=resampling_method(resample))
            S2_BOA_bands.append(newarr)
            print(newarr.shape)
            #S2_BOA_bands.append(arr)
    """
    for i, band in enumerate(bands):
        print("Band ", i + 1, ':', bands[i])
        rhos_ = glob(os.path.join(Acolite_fp, '*rhos_' + band + '.tif'))[0]
        with rasterio.open(rhos_) as acsrc:
            arr = acsrc.read()
            S2_BOA_bands.append(arr)

    S2_BOA_bands = np.concatenate(S2_BOA_bands, axis=0).transpose(1, 2, 0)

    return S2_BOA_bands

def createFootprint(pathname):
    """
    Function for creating footprint from geotiff raster file

    :param pathname: path to geotiff raster
    :return: geojson like object defining the footprint
    """
    # Read raster
    with rasterio.open(pathname) as r:
        T0 = r.transform  # upper-left pixel corner affine transform
        p1 = Proj(r.crs)
        A = r.read(1)  # pixel values

    # All rows and columns
    cols, rows = np.meshgrid(np.arange(A.shape[1]), np.arange(A.shape[0]))

    # Get affine transform for pixel centres
    T1 = T0 * Affine.translation(0.5, 0.5)
    # Function to convert pixel row/column index (from 0) to easting/northing at centre
    rc2en = lambda r, c: (c, r) * T1

    # All eastings and northings (there is probably a faster way to do this)
    eastings, northings = np.vectorize(rc2en, otypes=[np.float, np.float])(rows, cols)

    # Project all longitudes, latitudes
    p2 = Proj(proj='latlong', datum='WGS84')
    longs, lats = transform(p1, p2, eastings, northings)

    lonlat = np.zeros((longs.shape + (2,)))

    lonlat[..., 0] = longs
    lonlat[..., 1] = lats

    # Take only the edge pixels of the raster
    right = lonlat[:, 0, :][0::100]  # right
    down = lonlat[-1, :, :][0::100]  # down
    left = np.flip(lonlat[:, -1, :][0::100], axis=0)  # left
    up = np.flip(lonlat[0, :, :][0::100], axis=0)  # up
    up[-1] = right[0]
    footprint_arr = np.concatenate((right, down, left, up), axis=0).tolist()
    # Create geojson like file
    geom = {
        "type": "Polygon",
        "coordinates": [

        ]
    }
    # Append the footprint coordinates to the json
    geom["coordinates"].append(footprint_arr)

    return geom

def apply_landmask(rasterfp, detail=True, keep_land=False, mask_only=False):
    """
    Function for applying landmask, using a landmask shapefile in the included folder

    rasterfp - path to raster
    detail - Get detailed high resolution land mask if True (slow, high memory), else using a more rough, but much faster
    and efficient
    keep_land - Mask out land (False), or keep only the land pixels (True)
    mask_only - return just the mask (True), or remove the masked part from the raster (False)
    """
    # create Footprint for raster
    footprint = createFootprint(rasterfp)

    if detail:
        landpoly = r"include/land_polygons.shp"
    else:
        landpoly = r"include/GSHHS_i_L1.shp"

    with fiona.open(landpoly) as shapefile:
        # Use shapely for finding intersections between raster and land shapefile
        # by checking the shape intersects with the created footprint
        # Saves memory by not loading the whole shape, though it takes some time
        intersections = [mapping(shape(feature['geometry'])) for feature in shapefile
                         if shape(feature['geometry']).intersects(shape(footprint))]
        # Get shapefiles crs
        crsShape = shapefile.crs

    # Check if there are any intersections, if there are none, just return a message.
    if len(intersections) == 0:
        print("There are no lands within the raster. Returning None")
        return None

    # If there are, apply the mask:
    else:
        # Use rasterio.warp's transform_geom to transform the intersection shapes crs to the rasters crs
        # then mask out the pixels that's within the shapes using rasterio.mask's mask method
        with rasterio.open(rasterfp) as src:
            kwargs = src.profile
            intersect_trans = [warp.transform_geom(crsShape, src.crs, land) for land in intersections]
            landmasked_raster, transform = mask(src, intersect_trans, invert=~keep_land)

        if mask_only:
            mask_only_raster = np.zeros_like(landmasked_raster)
            mask_only_raster[0] = (landmasked_raster[0] == 0).astype('uint16')
            return mask_only_raster
        else:
            return landmasked_raster

def apply_cloudmask(S2DotSafefp=None, bands=None, threshold=0.4, dilation_size=3,
                    average_over=1, resolution_safe=100, save_mask=None, crs=None,
                    affine=None):
    """
    Function for applying cloud mask to either S2 product in safe format or a multiple rasters
    in numpy ndarray format. ndarray format is reccomended

    :param S2DotSafefp: path to S2 file
    :param bands: ndarray (N, H, W, B) N is the number of rasters, H is height, W is width, B are bands
    :param resolution_safe: Pixel resolution for cloud mask for .safe format in meters,
                            recommended to use higher than 60 as it's much more efficient.
    :param dilation_size: dilation for cloud pixels
    :param threshold: threshold for the cloud probability
    :param average_over: neighborhood of averaging
    :param save_mask:
    :param crs: If save_mask => crs for the saved mask
    :param affine: Affine transformation for the saved mask
    :return: cloud mask (N, H, W) cloud mask for each raster, if .safe format the output shape will be
            (1, H, W)

    """
    # If the input is in safe format
    if S2DotSafefp is not None:
        # resolutions for each band
        res = np.array([60, 10, 10, 20, 10, 20, 60, 60, 20, 20])
        # Valid bands
        bands_ = ['B01', 'B02', 'B04', 'B05', 'B08', 'B8A', 'B09', 'B10', 'B11', 'B12']
        # list of rasters
        S2rasters = [glob(os.path.join(S2DotSafefp, 'GRANULE', 'L*', 'IMG_DATA', '*{}*'.format(band)))[0]
                     for band in bands_]
        # Affine transformation list
        afftr = res / resolution_safe
        S2_cloud_bands = []

        # iterate through band rasters
        for i, raster in enumerate(S2rasters):
            with rasterio.open(raster) as src:
                # Divide by 10000 to get TOA values
                arr = src.read().astype('float32') / 10000
                aff = src.transform
                # Define new affine transform
                new_aff = Affine(aff.a / afftr[i], aff.b, aff.c,
                                 aff.d, aff.e / afftr[i], aff.f)
                # Empty array for destination
                newarr = np.empty(shape=(arr.shape[0],
                                         int(round(arr.shape[1] * afftr[i])),
                                         int(round(arr.shape[2] * afftr[i]))), dtype='float32')
                # Apply downsampling
                warp.reproject(arr, newarr,
                               src_transform=aff,
                               dst_transform=new_aff,
                               src_crs=src.crs,
                               dst_crs=src.crs)
                # Append to list
                S2_cloud_bands.append(newarr)
        # Concatenate the list and add a dim for compatibility with S2Cloudless function
        S2_cloud_bands = np.concatenate(S2_cloud_bands, axis=0)

        S2_cloud_bands = np.expand_dims(S2_cloud_bands, axis=0)
        # Apply cloudmask
        cloudmask = S2PixelCloudDetector(threshold=threshold,
                                         dilation_size=dilation_size,
                                         average_over=average_over,
                                         all_bands=False).get_cloud_masks(S2_cloud_bands)

        # save mask if path is specified
        if save_mask is not None:
            with rasterio.open(S2rasters[0]) as src:
                kwargs = src.profile
                kwargs['width'] = cloudmask.shape[1]
                kwargs['height'] = cloudmask.shape[2]
                kwargs['transform'] = new_aff
                kwargs['driver'] = 'Gtiff'
                kwargs['dtype'] = cloudmask.dtype
                kwargs['blockxsize'] = 128
                kwargs['blockysize'] = 128

                with rasterio.open(save_mask, 'w', **kwargs) as dst:
                    dst.write(cloudmask)
        # return the cloudmask as np ndarray
        return cloudmask
    # If valid bands are given
    elif bands is not None:

        cloudmask = S2PixelCloudDetector(threshold=threshold,
                                         dilation_size=dilation_size,
                                         average_over=average_over,
                                         all_bands=False).get_cloud_masks(bands)

        # save mask if path is specified
        if save_mask is not None and crs is not None:
            kwargs = {
                'driver': 'GTiff',
                'interleave': 'band',
                'tiled': True,
                'blockxsize': 128,
                'blockysize': 128,
                'nodata': 0,
                'dtype': cloudmask.dtype,
                'height': cloudmask.shape[1],
                'width': cloudmask.shape[2],
                'crs': crs,
                'transform': affine
            }

            with rasterio.open(save_mask, 'w', **kwargs) as dst:
                dst.write(cloudmask)
        elif save_mask is not None and crs is None:
            raise ValueError("To save the mask, crs needs to be provided")
        # return the cloudmask as np ndarray
        return cloudmask
    else:
        raise ValueError(
            "You need to provide a path to a Sentinel-2 .safe file, or a numpy ndarray consisting of the bands")

def Water_mask(S2_ndarray, threshold):

    pass

def apply_dos_all(S2_array):
    S2_dos = np.zeros_like(S2_array)
    for i in range(S2_dos.shape[-1]):
        S2_dos[..., i] = apply_dos(S2_array[..., i])

    return S2_dos

def apply_dos(S2_band):
    do = S2_band[S2_band!=0].min()
    S2_band[S2_band!=0] = S2_band[S2_band!=0]-do
    return S2_band

def estimate_albedo(S2_arr, BOA=False):
    weights = np.loadtxt('models/albedo_weights.txt')
    if BOA:
        weights_BOA = weights[[0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 12]]
        S2_tot_alb = np.zeros((S2_arr.shape[0],S2_arr.shape[1]))
        for i in range(S2_arr.shape[2]):
            S2_tot_alb += S2_arr[..., i] * weights_BOA[i]
    else:
        S2_tot_alb = np.zeros((S2_arr.shape[0],S2_arr.shape[1]))
        for i in range(S2_arr.shape[2]):
            S2_tot_alb += S2_arr[..., i] * weights[i]

    return S2_tot_alb


lines = list(map(lambda x: x.strip(), open("d7_input.txt")))
rules = dict() # key bags are contained by value bags

# populate the rules
for line in lines:
    key, values = line.split(" bags contain ")
    values = list(map(lambda x: " ".join(x.split(" ")[1:3]), values.split(", ")))
    for val in values:
        if val in rules:
            rules[val].append(key)
        else:
            rules[val] = [key]
rules["other bags."] = list()

this_layer = rules["shiny gold"]
seen_bags = set(this_layer) # bags that can eventually contain a shiny gold
next_layer = set()
color_ct = 0

while len(this_layer) != 0:
    color_ct += len(this_layer)
    for parent in this_layer:
        if parent not in rules: continue
        for child in rules[parent]:
            if child not in seen_bags:
                next_layer.add(child)
            seen_bags.add(child)
    this_layer = list(next_layer)
    next_layer.clear()

print(color_ct)


from Naive392 import Solution as naive

testcase = [
    ("b", "c", False),
    ("abc", "ahbgdc", True),
    ("axc", "ahbgdc", False),
    ("aaaaaa", "bbaaaa", False),
]

def test_naive():
    for s, t, ans in testcase:
        assert naive().isSubsequence(s, t) == ans


# Dado el número matemático PI, se solicita al usuario que ingrese el valor del radio de una
# circunferencia y calcule y muestre por pantalla el área y perímetro. (área = PI * radio2
# perímetro = 2 * PI * radio
import math

math.pi

radio = float(input("ingrese valor del radio: "))

area = (math.pi * radio**2)

permietro = (2 * math.pi * radio)

print("el area es: ", area)

print("perimetro es: ", permietro)


from sqlalchemy import select
from fin.adapters.db.db_schemas.db_model import Target
from fin.adapters.repository.target.error import TargetNotFoundError
from fin.adapters.repository.repository import Repository

class TargetRepository(Repository):

    def __init__(self, db_session) -> None:
        """Init."""
        self._db_session = db_session

    async def add(self, target: Target):
        """Add new Target"""
        async with self._db_session() as session:
            session.add(target)
            await session.commit()
            await session.refresh(target)
        return target

    async def is_obj_exist(self, trg_id: int):
        """Checking is target exist"""
        try:
            target = await self.get_object(trg_id)
            if target:
                return True
        except TargetNotFoundError:
            return False
        return False

    async def get_object(self, trg_id: int):
        """Get target info"""
        async with self._db_session() as session:
            targets = await session.execute(
                select(Target).filter(
                    Target.target_id == trg_id
                )
            )
            target = targets.fetchone()
            if not target:
                raise TargetNotFoundError(trg_id)
            else:
                return target[0]

    async def get_objects(self, unit_id: str, targets_cnt_id: list, offset=0, limit=100):
        """Get all targets"""
        async with self._db_session() as session:
            statement = select(
                Target,
            ).filter(
                Target.target_cnt_id.in_(targets_cnt_id),
            ).offset(offset).limit(limit)
            result = await session.execute(statement)
            return result.all()


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

import torch
from torch import nn, Tensor

from abc import ABC, abstractmethod

from ctp.kernels import BaseKernel
from ctp.reformulators.util import AttentiveLinear

from typing import List, Optional

import logging

logger = logging.getLogger(__name__)

class BaseReformulator(ABC, nn.Module):
    def __init__(self):
        super().__init__()

    @abstractmethod
    def forward(self, rel: Tensor) -> List[Tensor]:
        raise NotImplementedError

    @abstractmethod
    def forward(self, rel: Tensor) -> List[Tensor]:
        raise NotImplementedError

    def prior(self, rel: Tensor) -> Optional[Tensor]:
        # batch_size = rel.shape[0]
        # res = torch.ones(batch_size, dtype=rel.dtype)
        res = None
        return res

class StaticReformulator(BaseReformulator):
    def __init__(self,
                 nb_hops: int,
                 embedding_size: int,
                 init_name: Optional[str] = "uniform",
                 lower_bound: float = -1.0,
                 upper_bound: float = 1.0):
        super().__init__()

        self.nb_hops = nb_hops
        self.embedding_size = embedding_size
        self.init_name = init_name

        self.lower_bound = lower_bound
        self.upper_bound = upper_bound

        def make_memory() -> Tensor:
            return self._param(1, self.embedding_size)
        self.memory_lst = nn.ParameterList([make_memory() for _ in range(self.nb_hops)])

    def _param(self, dim_in: int, dim_out: int, std: float = 1.0) -> Tensor:
        w = torch.zeros(dim_in, dim_out)

        if self.init_name in {"uniform"}:
            nn.init.uniform_(w, self.lower_bound, self.upper_bound)
        elif self.init_name in {"normal"}:
            nn.init.normal_(w, std=std)

        return nn.Parameter(w, requires_grad=True)

    def forward(self, rel: Tensor) -> List[Tensor]:
        batch_size = rel.shape[0]
        res = [memory.repeat(batch_size, 1) for memory in self.memory_lst]
        return res

class NTPReformulator(StaticReformulator):
    def __init__(self,
                 kernel: BaseKernel,
                 **kwargs):
        super().__init__(**kwargs)
        self.kernel = kernel
        self.head = self._param(1, self.embedding_size)

    def forward(self, rel: Tensor) -> List[Tensor]:
        batch_size = rel.shape[0]
        res = [memory.repeat(batch_size, 1) for memory in self.memory_lst]
        return res

    def prior(self, rel: Tensor) -> Tensor:
        res = self.kernel(rel, self.head)
        return res.view(-1)

class GNTPReformulator(BaseReformulator):
    def __init__(self,
                 kernel: BaseKernel,
                 head: Tensor,
                 body: List[Tensor]):
        super().__init__()
        self.kernel = kernel
        self.head = head
        self.body = body

    def forward(self, rel: Tensor) -> List[Tensor]:
        for e in self.body:
            # print(rel.shape, e.shape)
            assert rel.shape[0] == e.shape[0]
        return self.body

    def prior(self, rel: Tensor) -> Tensor:
        assert rel.shape[0] == self.head.shape[0]
        res = self.kernel(rel, self.head)
        # print('XXX', rel.shape, self.head.shape, res.shape)
        return res.view(-1)

class LinearReformulator(BaseReformulator):
    def __init__(self,
                 nb_hops: int,
                 embedding_size: int,
                 init_name: Optional[str] = "uniform",
                 lower_bound: float = -1.0,
                 upper_bound: float = 1.0):
        super().__init__()

        self.nb_hops = nb_hops
        self.embedding_size = embedding_size
        self.init_name = init_name

        self.lower_bound = lower_bound
        self.upper_bound = upper_bound

        def make_hop(std: float = 1.0) -> nn.Module:
            res = nn.Linear(embedding_size, embedding_size)

            if self.init_name in {"uniform"}:
                nn.init.uniform_(res.weight, self.lower_bound, self.upper_bound)
            elif self.init_name in {"normal"}:
                nn.init.normal_(res.weight, std=std)

            return res

        self.hops_lst = nn.ModuleList([make_hop() for _ in range(nb_hops)])

    def forward(self, rel: Tensor) -> List[Tensor]:
        res = [hop(rel) for hop in self.hops_lst]
        return res

class AttentiveReformulator(BaseReformulator):
    def __init__(self,
                 nb_hops: int,
                 embeddings: nn.Embedding,
                 init_name: Optional[str] = "uniform",
                 lower_bound: float = -1.0,
                 upper_bound: float = 1.0):
        super().__init__()

        self.nb_hops = nb_hops
        self.embeddings = embeddings
        self.init_name = init_name

        self.lower_bound = lower_bound
        self.upper_bound = upper_bound

        def make_hop(std: float = 1.0) -> nn.Module:
            res = AttentiveLinear(embeddings)

            if self.init_name in {"uniform"}:
                nn.init.uniform_(res.projection.weight, self.lower_bound, self.upper_bound)
            elif self.init_name in {"normal"}:
                nn.init.normal_(res.projection.weight, std=std)

            return res
        self.hops_lst = nn.ModuleList([make_hop() for _ in range(nb_hops)])

    def forward(self, rel: Tensor) -> List[Tensor]:
        res = [hop(rel) for hop in self.hops_lst]
        return res

class MemoryReformulator(BaseReformulator):

    class Memory(nn.Module):
        def __init__(self,
                     nb_hops: int,
                     nb_rules: int,
                     embedding_size: int,
                     init_name: Optional[str] = "uniform",
                     lower_bound: float = -1.0,
                     upper_bound: float = 1.0):
            super().__init__()
            self.nb_hops = nb_hops
            self.nb_rules = nb_rules
            self.embedding_size = embedding_size
            self.init_name = init_name

            self.lower_bound = lower_bound
            self.upper_bound = upper_bound

            def _param(dim_in: int, dim_out: int, std: float = 1.0) -> Tensor:
                w = torch.zeros(dim_in, dim_out)

                if self.init_name in {"uniform"}:
                    nn.init.uniform_(w, self.lower_bound, self.upper_bound)
                elif self.init_name in {"normal"}:
                    nn.init.normal_(w, std=std)

                return nn.Parameter(w, requires_grad=True)

            def make_memory() -> Tensor:
                return _param(self.nb_rules, self.embedding_size)

            self.memory = nn.ParameterList([make_memory() for _ in range(self.nb_hops)])

    def __init__(self,
                 memory: Memory):
        # Note: this init_name governs the attention weights over the memory, I think it's fine to keep it as it is
        super().__init__()
        self.memory = memory
        self.projection = nn.Linear(self.memory.embedding_size, self.memory.nb_rules)

    def forward(self, rel: Tensor) -> List[Tensor]:
        attn_logits = self.projection(rel)
        attn = torch.softmax(attn_logits, dim=1)
        res = [attn @ cell for cell in self.memory.memory]
        return res

class SymbolicReformulator(BaseReformulator):
    def __init__(self,
                 embeddings: nn.Embedding,
                 indices: Tensor):
        super().__init__()
        self.embeddings = embeddings
        self.indices = indices

    def forward(self, rel: Tensor) -> List[Tensor]:
        batch_size = rel.shape[0]
        # [I, E]
        res = self.embeddings(self.indices)
        nb_indices, embedding_size = res.shape[0], res.shape[1]
        # [B, I, E]
        res = res.view(1, nb_indices, embedding_size).repeat(batch_size, 1, 1)

        # res = list(torch.split(res, split_size_or_sections=1, dim=1))
        res = [a.view(res.shape[0], res.shape[2]) for a in torch.split(res, split_size_or_sections=1, dim=1)]
        return res