from __future__ import print_function

import sqlite3
import numpy as np
from os.path import join
from pandas import read_csv
from perfect_match.data_access.batch_augmentation import BatchAugmentation

class DataAccess(BatchAugmentation):
    DB_FILE_NAME = "twins.db"

    TABLE_PAIRS = "pairs"

    GENDER_MALE = 0
    GENDER_FEMALE = 1

    def __init__(self, data_dir):
        self.data_dir = data_dir
        self.db = None
        self.connect()
        self.setup_schema()

    def get_split_indices(self):
        return None, None

    def connect(self):
        self.db = sqlite3.connect(join(self.data_dir, DataAccess.DB_FILE_NAME),
                                  check_same_thread=False,
                                  detect_types=sqlite3.PARSE_DECLTYPES)

        # Disable journaling.
        self.db.execute("PRAGMA journal_mode = OFF;")
        self.db.execute("PRAGMA page_size = 16384;")

    def setup_schema(self):
        self.setup_pairs()

        self.db.commit()

    def setup_pairs(self):
        columns = ""
        for idx, fields in enumerate(DataAccess.get_ordered_fields()):
            name = fields[1]
            if idx < 3:
                columns += name + "_0 INT,"
                columns += name + "_1 INT,"
            else:
                columns += name + " INT,"
        columns = columns[:-1]
        self.db.execute(("CREATE TABLE IF NOT EXISTS {table_name}"
                         "("
                         "id INT NOT NULL PRIMARY KEY, " + columns +
                         ");").format(table_name=DataAccess.TABLE_PAIRS))

    def insert_many(self, table_name, values):
        self.db.executemany("INSERT INTO {table_name} VALUES ({question_marks});"
                            .format(table_name=table_name,
                                    question_marks=",".join(["?"] * len(values[0]))),
                            values)

    def insert_clinical(self, values):
        self.insert_many(DataAccess.TABLE_PAIRS, values)

    def get_column(self, table_name, ids, column_name):
        tmp_name = "tmp_ids"
        self.create_temporary_table(tmp_name, ids)
        return_value = self.db.execute("SELECT {column_name} "
                                       "FROM {table_name} "
                                       "WHERE rowid IN (SELECT id FROM {tmp_table}) "
                                       "ORDER BY rowid;"
                                       .format(column_name=column_name,
                                               table_name=table_name,
                                               tmp_table=tmp_name)).fetchall()
        self.drop_temporary_table(tmp_name)
        return return_value

    def get_num_rows(self, table_name):
        # NOTE: This query assumes that there has never been any deletions in the time series table.
        return self.db.execute("SELECT MAX(_ROWID_) FROM {} LIMIT 1;".format(table_name)) \
            .fetchone()[0]

    def get_row(self, table_name, id, with_rowid=False):
        columns = "*"
        if with_rowid:
            columns = "rowid, " + columns

        query = "SELECT " \
                "{columns} " \
                "FROM {table_name} " \
                "WHERE rowid = ?;".format(table_name=table_name,
                                          columns=columns)
        return self.db.execute(query, (id,)).fetchone()

    def get_rows(self, train_ids):
        tmp_name = "tmp_pairs"
        self.create_temporary_table(tmp_name, map(lambda x: (x,), train_ids))

        pairs = self.db.execute("SELECT * "
                                "FROM {table_pairs} "
                                "WHERE rowid IN (SELECT id FROM {tmp_table});"
                                .format(table_pairs=DataAccess.TABLE_PAIRS,
                                        tmp_table=tmp_name)).fetchall()

        self.drop_temporary_table(tmp_name)

        input_data = np.array(pairs)
        ids, pair_data = input_data[:, 0], input_data[:, 7:]
        return input_data, ids, pair_data

    def get_row_by_id(self, table_name, id, with_rowid=False):
        columns = "*"
        if with_rowid:
            columns = "rowid, " + columns

        query = "SELECT " \
                "{columns} " \
                "FROM {table_name} " \
                "WHERE id = ?;".format(table_name=table_name,
                                       columns=columns)
        return self.db.execute(query, (id,)).fetchone()

    def get_rows_by_clinical_id(self, table_name, id):
        columns = "*"

        query = "SELECT " \
                "{columns} " \
                "FROM {table_name} " \
                "WHERE clinical_id = ?;".format(table_name=table_name,
                                                columns=columns)
        return self.db.execute(query, (id,)).fetchone()

    def get_labelled_patients(self):
        return np.arange(self.get_num_rows(DataAccess.TABLE_PAIRS)) + 1

    def create_temporary_table(self, table_name, values):
        self.db.execute("CREATE TEMP TABLE {table_name} (id INT);".format(table_name=table_name))
        if len(values) != 0:
            self.db.executemany("INSERT INTO {table_name} VALUES (?);".format(table_name=table_name), values)
        return table_name

    def drop_temporary_table(self, table_name):
        self.db.execute("drop table {tmp_table_name};".format(tmp_table_name=table_name))

    def get_pairs_dimension(self):
        pair = self.db.execute("SELECT * FROM {table_name} WHERE rowid = 1;"
                               .format(table_name=DataAccess.TABLE_PAIRS)).fetchone()
        return len(pair) - 7

    @staticmethod
    def get_ordered_fields(clean=False):
        if clean:
            factor_list = [8, 9]
            adequacy_missing = 4
        else:
            factor_list = 9
            adequacy_missing = None
        identity = lambda x: x
        minus_one = lambda x: x-1
        convert_gender = lambda x: DataAccess.GENDER_MALE if x == 1 else DataAccess.GENDER_FEMALE
        factor_fun = lambda x: 1 if x == 1 else 0
        divide_by = lambda val: lambda x: float(x) / float(val)

        return [
            ("DBIRWT", "birth_weight", None, identity, identity),
            ("CSEX", "child_sex", None, convert_gender, identity),
            ("AGED", "days_age_at_death", None, lambda x: 0 if np.isnan(x) else 1, identity),
            ("DTOTORD", "number_previous_births", 99, identity, divide_by(10)),
            ("DMAR", "marital_status", None, minus_one, identity),
            ("DMAGE", "mother_age", None, minus_one, divide_by(50)),
            ("DMEDUC", "mother_education", 99, minus_one, divide_by(17)),
            #("MRACE", "mother_race", None, minus_one),
            #("FRACE", "father_race", 99, minus_one),
            ("PLDEL", "place_of_delivery", 9, minus_one, identity),
            ("RESSTATB", "residence_state", None, minus_one, identity),
            # ("BRSTATE_REG", "residence_state_region", None),
            # ("DLIVORD", "number_previous_births_live", 99),
            ("GESTAT", "number_gestation_weeks", 99, identity, divide_by(47)),
            #("GESTAT10", "number_gestation_weeks_coded", 10),
            ("ADEQUACY", "adequacy_of_care", adequacy_missing, minus_one, identity),
            ("MPCB", "month_of_pregnancy_care_began", 99, minus_one, divide_by(9)),
            ("NPREVIST", "number_prenatal_visits", 99, identity, divide_by(49)),
            # ("DISLLB", "interval_since_last_live_birth", 999),
            ("ANEMIA", "anemia", factor_list, factor_fun, identity),
            ("CARDIAC", "cardiac", factor_list, factor_fun, identity),
            ("LUNG", "lung", factor_list, factor_fun, identity),
            ("DIABETES", "diabetes", factor_list, factor_fun, identity),
            ("HERPES", "herpes", factor_list, factor_fun, identity),
            ("HYDRA", "hydra", factor_list, factor_fun, identity),
            ("HEMO", "Hemoqlobinopathy", factor_list, factor_fun, identity),
            ("CHYPER", "hypertension_chronic", factor_list, factor_fun, identity),
            ("PHYPER", "hypertension_pregnancy", factor_list, factor_fun, identity),
            ("ECLAMP", "eclampsia", factor_list, factor_fun, identity),
            ("INCERVIX", "incompetent_cervix", factor_list, factor_fun, identity),
            ("PRE4000", "previous_infant_less_than_4000", factor_list, factor_fun, identity),
            ("PRETERM", "previous_preterm", factor_list, factor_fun, identity),
            ("RENAL", "renal", factor_list, factor_fun, identity),
            ("RH", "rh_sensitisation", factor_list, factor_fun, identity),
            ("UTERINE", "uterine_bleeding", factor_list, factor_fun, identity),
            ("OTHERMR", "other", factor_list, factor_fun, identity),
            # ("TOBACCO", "tobacco_use", 9),
            ("CIGAR", "num_cigarettes_per_day", 99, identity, divide_by(98)),  # < 98
            # ("ALCOHOL", "alcohol_use", 9),
            ("DRINK", "number_of_drinks", 99, identity, divide_by(98)),  # < 98
            ("WTGAIN", "num_pounds_gained", 99, identity, divide_by(98))  # < 98
        ]

    @staticmethod
    def get_pairs_data(filepath):
        pairs_data = read_csv(filepath)
        return pairs_data

    def get_labels(self, args, ids, benchmark):
        assignments = []
        for id in ids:
            pair = self.get_row(DataAccess.TABLE_PAIRS, id[0])
            assignment = benchmark.get_assignment(id, pair)[0]
            assignments.append(assignment)

        assignments = [t - 2 if t >= 2 else t for t in assignments]

        # get assignments from benchmark first - then select the correct "child_sex"
        sex_0 = np.squeeze(self.get_column(DataAccess.TABLE_PAIRS, ids, "child_sex_0"), axis=-1)
        sex_1 = np.squeeze(self.get_column(DataAccess.TABLE_PAIRS, ids, "child_sex_1"), axis=-1)
        dead_0 = np.squeeze(self.get_column(DataAccess.TABLE_PAIRS, ids, "days_age_at_death_0"), axis=-1)
        dead_1 = np.squeeze(self.get_column(DataAccess.TABLE_PAIRS, ids, "days_age_at_death_1"), axis=-1)
        sex = np.squeeze([np.stack([sex_0, sex_1]).T[idx, t] for idx, t in enumerate(assignments)])
        dead = np.squeeze([np.stack([dead_0, dead_1]).T[idx, t] for idx, t in enumerate(assignments)])

        num_labels = 2**2 - 1
        return sex * 2 ** 0 + dead * 2 ** 1, num_labels

    def get_entry_with_id(self, id, args):
        pair = self.get_row(DataAccess.TABLE_PAIRS, id)

        patient_id = pair[0]
        result = {"pair": pair}

        return patient_id, result

    def standardise_entry(self, entry):
        standardisers = map(lambda x: x[4], self.get_ordered_fields()[3:])
        for i in range(len(entry)):
            entry[i] = standardisers[i](entry[i])
        return entry

    def prepare_batch(self, args, batch_data, benchmark, is_train=False):
        pair_data = np.array(map(lambda x: x["pair"], batch_data))
        ids, input_data = pair_data[:, 0], pair_data[:, 7:]

        assignments = map(benchmark.get_assignment, ids, pair_data)
        treatment_data, batch_y = zip(*assignments)
        treatment_data = np.array(treatment_data)

        if args["with_propensity_batch"] and is_train:
            propensity_batch_probability = float(args["propensity_batch_probability"])
            num_randomised_neighbours = int(np.rint(args["num_randomised_neighbours"]))
            input_data, treatment_data, batch_y = self.enhance_batch_with_propensity_matches(benchmark,
                                                                                treatment_data,
                                                                                input_data,
                                                                                batch_y,
                                                                                propensity_batch_probability,
                                                                                num_randomised_neighbours)

        input_data = input_data.astype(np.float32)
        input_data = np.array(map(self.standardise_entry, input_data))

        batch_y = np.array(batch_y)
        batch_x = [
            input_data,
            treatment_data,
        ]
        return batch_x, batch_y


import sys
_module = sys.modules[__name__]
del sys
input_data = _module
model = _module
test = _module
word2vec = _module

from _paritybench_helpers import _mock_config, patch_functional
from unittest.mock import mock_open, MagicMock
from torch.autograd import Function
from torch.nn import Module
import abc, collections, copy, enum, functools, inspect, itertools, logging, math, matplotlib, numbers, numpy, pandas, queue, random, re, scipy, sklearn, string, tensorflow, time, torch, torchaudio, torchtext, torchvision, types, typing, uuid, warnings
import numpy as np
from torch import Tensor
patch_functional()
open = mock_open()
yaml = logging = sys = argparse = MagicMock()
ArgumentParser = argparse.ArgumentParser
_global_config = args = argv = cfg = config = params = _mock_config()
argparse.ArgumentParser.return_value.parse_args.return_value = _global_config
yaml.load.return_value = _global_config
sys.argv = _global_config
__version__ = '1.0.0'
xrange = range
wraps = functools.wraps

import torch

from torch.autograd import Variable

import torch.nn as nn

import torch.nn.functional as F

import numpy

import torch.optim as optim

class SkipGramModel(nn.Module):
    """Skip gram model of word2vec.

    Attributes:
        emb_size: Embedding size.
        emb_dimention: Embedding dimention, typically from 50 to 500.
        u_embedding: Embedding for center word.
        v_embedding: Embedding for neibor words.
    """

    def __init__(self, emb_size, emb_dimension):
        """Initialize model parameters.

        Apply for two embedding layers.
        Initialize layer weight

        Args:
            emb_size: Embedding size.
            emb_dimention: Embedding dimention, typically from 50 to 500.

        Returns:
            None
        """
        super(SkipGramModel, self).__init__()
        self.emb_size = emb_size
        self.emb_dimension = emb_dimension
        self.u_embeddings = nn.Embedding(emb_size, emb_dimension, sparse=True)
        self.v_embeddings = nn.Embedding(emb_size, emb_dimension, sparse=True)
        self.init_emb()

    def init_emb(self):
        """Initialize embedding weight like word2vec.

        The u_embedding is a uniform distribution in [-0.5/em_size, 0.5/emb_size], and the elements of v_embedding are zeroes.

        Returns:
            None
        """
        initrange = 0.5 / self.emb_dimension
        self.u_embeddings.weight.data.uniform_(-initrange, initrange)
        self.v_embeddings.weight.data.uniform_(-0, 0)

    def forward(self, pos_u, pos_v, neg_v):
        """Forward process.

        As pytorch designed, all variables must be batch format, so all input of this method is a list of word id.

        Args:
            pos_u: list of center word ids for positive word pairs.
            pos_v: list of neibor word ids for positive word pairs.
            neg_u: list of center word ids for negative word pairs.
            neg_v: list of neibor word ids for negative word pairs.

        Returns:
            Loss of this process, a pytorch variable.
        """
        emb_u = self.u_embeddings(pos_u)
        emb_v = self.v_embeddings(pos_v)
        score = torch.mul(emb_u, emb_v).squeeze()
        score = torch.sum(score, dim=1)
        score = F.logsigmoid(score)
        neg_emb_v = self.v_embeddings(neg_v)
        neg_score = torch.bmm(neg_emb_v, emb_u.unsqueeze(2)).squeeze()
        neg_score = F.logsigmoid(-1 * neg_score)
        return -1 * (torch.sum(score) + torch.sum(neg_score))

    def save_embedding(self, id2word, file_name, use_cuda):
        """Save all embeddings to file.

        As this class only record word id, so the map from id to word has to be transfered from outside.

        Args:
            id2word: map from word id to word.
            file_name: file name.
        Returns:
            None.
        """
        if use_cuda:
            embedding = self.u_embeddings.weight.cpu().data.numpy()
        else:
            embedding = self.u_embeddings.weight.data.numpy()
        fout = open(file_name, 'w')
        fout.write('%d %d\n' % (len(id2word), self.emb_dimension))
        for wid, w in id2word.items():
            e = embedding[wid]
            e = ' '.join(map(lambda x: str(x), e))
            fout.write('%s %s\n' % (w, e))


import pandas as pd
import os

def load_data(table):
    ext = os.path.splitext(table)

    if ext == '.csv':
        df = pd.read_csv(table)
    elif ext == '.tsv':
        df = pd.read_csv(table, sep='\t')
    elif ext == '.xlsx':
        df = pd.read_excel(table)
    else:
        print('Your file format {} is not supported!'.format(ext))
        raise ValueError()

    return df

def uda_formater(raw_df, content, label, ids, mode='r', save_path=None):
    '''
    '''
    if type(ids) == str:
        raw_df[ids] = raw_df[ids].dtype(str)
        raw_df['id'] = raw_df[label].str.cat(raw_df[ids], sep='_')

    elif type(ids) == list:
        for i in ids:
            raw_df[i] = raw_df[i].dtype(str)

        for n, ii in enumerate(ids):
            if n == 0:
                raw_df['id'] = raw_df[label].str.cat(raw_df[ii], sep='_')

            else:
                raw_df['id'] = raw_df['id'].str.cat(raw_df[ii], sep='_')

    save_df = raw_df.rename(columns={content:'content', label:'label'})
    save_df = save_df[['content', 'label', 'id']]

    if mode == 'r':
        return save_df

    elif mode == 'o':
        save_df.to_csv(os.path.join(save_path, 'uda_fomat_data.tsv'), sep='\t')

def train_test_split(df, train_ratio=None, num_train=None, test_ratio=None, num_test=None):
    df = df.sample(frac=1)
    df = df.sample(frac=1)

    if train_ratio != None & num_train == None & test_ratio == None & num_test == None:
        l = int(len(df) * train_ratio)
        train = df[:l]
        test = df[l:]

    elif num_train != None & train_ratio == None & test_ratio == None & num_test == None:
        train = df[:num_train]
        test = df[num_train:]

    elif test_ratio != None & num_train == None & train_ratio == None & num_test == None:
        l = int(len(df) * test_ratio)
        test = df[:l]
        train = df[l:]

    elif num_test != None & train_ratio == None & test_ratio == None & num_train == None:
        test = df[:num_test]
        train = df[num_test:]


from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('sign_up', views.sign_up, name='sign_up'),
    path('sign_in', views.sign_in, name='sign_in'),
    path('sign_out', views.sign_out, name='sign_out'),
    path('post/', views.post_list, name='post_list'),
    path('post/<int:pk>/', views.post_detail, name='post_detail'),
    path('post/new/', views.post_new, name='post_new'),
    path('post/<int:pk>/edit/', views.post_edit, name='post_edit'),
    path('post/<int:pk>/add_comment', views.add_comment, name='add_comment'),
    path('comments/<int:comment_id>/like', views.add_like, name='add_like'),
]


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

import numpy as np
import cmath
hb=1.054*pow(10,-34)
mass=9.1*pow(10,-31)
E=float(input("Enter the energy of the wave (in 10^-34): "))
E=E*pow(10,-34)
k1=np.sqrt(2.0*mass*E)/hb
U=float(input("Enter the energy of the barrier (in 10^-34): "))
U=U*pow(10,-34)
if U > E:
    alpha=np.sqrt(2.0*mass*(U-E))/hb
    length=float(input("value of length in 10^-9: "))
    length=length*pow(10,-9)
    a1=pow(2.303,-1*alpha*length)
    a2=pow(2.303,alpha*length)

    a3=pow(2.303,complex(0,-1*k1*length))
    A = np.array([[1, -1, -1, 0], [0, a1, a2, -a3], [complex(0,1*k1), -1*alpha, alpha, 0], [0, -1*alpha*a1,alpha*a2, complex(0,-1*k1*a3)]])
    b = np.array([-1, 0, complex(0,1)*k1, 0])
    x = np.linalg.solve(A, b)
    f=x[len(x)-1]
    z=f.real
    y=f.imag
    prob=np.sqrt(pow(z,2)+pow(y,2))
    print("transmission probability is "+str(prob))
else:
    print("Energy of Barrier less than wave")


import random  # Set seed
import unittest

from roll import *

class TestParser(unittest.TestCase):
    def test_tokenize_arithmetic(self) -> None:
        self.assertEqual(
            tokenize("1 / 2.72 - (25 + 38) * 3.14"),
            [
                IntegerToken("1"),
                OperatorToken("/"),
                DecimalToken("2.72"),
                OperatorToken("-"),
                OpenExprToken(),
                IntegerToken("25"),
                OperatorToken("+"),
                IntegerToken("38"),
                CloseExprToken(),
                OperatorToken("*"),
                DecimalToken("3.14"),
            ],
        )

    def test_tokenize_roll(self) -> None:
        self.assertEqual(
            tokenize("2 2d12 * 3 + 2"),
            [
                IntegerToken("2"),
                RollToken("2d12"),
                OperatorToken("*"),
                IntegerToken("3"),
                OperatorToken("+"),
                IntegerToken("2"),
            ],
        )

    def test_parse(self) -> None:
        self.assertEqual(
            parse("-2d12 k3+4*(3 / 2) 2d4"),
            [
                UnaryExpr(
                    ResultType.NUMBER,
                    "-",
                    Fixity.PREFIX,
                    OpExpr(
                        ResultType.NUMBER,
                        "+",
                        KeepExpr(RollExpr(2, 12), ConstExpr(3)),
                        OpExpr(
                            ResultType.NUMBER,
                            "*",
                            ConstExpr(4),
                            SuperExpr(
                                [
                                    OpExpr(
                                        ResultType.NUMBER,
                                        "/",
                                        ConstExpr(3),
                                        ConstExpr(2),
                                    )
                                ]
                            ),
                        ),
                    ),
                ),
                RollExpr(2, 4),
            ],
        )

    def test_evaluation(self) -> None:
        self.assertEqual(
            parse("10d1 + 4 ^ 2 * 3 / 2")[0].value, 10 + 4**2 * 3 / 2
        )

    def test_zeroes(self) -> None:
        self.assertRaises(ValueError, get_roll, "d0")
        self.assertEqual(get_roll("0d1").value, 0)

    def test_const_rule(self) -> None:
        self.assertEqual(parse("2 d4"), [RollExpr(1, 4)] * 2)

    def test_advantage(self) -> None:
        exprs = parse("d20a")
        self.assertEqual(len(exprs), 1)
        expr = exprs[0]
        self.assertEqual(len(expr.roll_info()[0][1]), 2)
        self.assertEqual(expr.value, max(expr.roll_info()[0][1]))

    def test_disadvantage(self) -> None:
        exprs = parse("d20d")
        self.assertEqual(len(exprs), 1)
        expr = exprs[0]
        self.assertEqual(expr.value, min(expr.roll_info()[0][1]))

    def test_missing_operand(self) -> None:
        self.assertRaises(ValueError, parse, "+ 2")

    def test_operator_operand(self) -> None:
        self.assertRaises(ValueError, parse, "- + 2")

    def test_max_value(self) -> None:
        self.assertEqual(
            parse(f"{TerminalExpr.MAX_VALUE}"),
            [ConstExpr(TerminalExpr.MAX_VALUE)],
        )
        self.assertRaises(ValueError, parse, f"{TerminalExpr.MAX_VALUE + 1}")

    def test_max_roll_qty(self) -> None:
        self.assertEqual(
            parse(f"{RollExpr.MAX_QTY}d20"), [RollExpr(RollExpr.MAX_QTY, 20)]
        )
        self.assertRaises(ValueError, parse, f"{RollExpr.MAX_QTY + 1}d20")

    def test_max_roll_size(self) -> None:
        self.assertEqual(
            parse(f"d{TerminalExpr.MAX_VALUE}"),
            [RollExpr(1, TerminalExpr.MAX_VALUE)],
        )
        self.assertRaises(ValueError, parse, f"d{TerminalExpr.MAX_VALUE + 1}")

    def test_get_roll(self) -> None:
        self.assertEqual(get_roll("0"), ConstExpr(0))

    def test_rolls_string(self) -> None:
        self.assertEqual(
            rolls_string(get_rolls("4d1")), "4d1\tRolls: 1, 1, 1, 1\tTotal: 4"
        )

    def test_multiple_rolls_string(self) -> None:
        self.assertEqual(
            rolls_string(get_rolls("2 2d1")),
            "2d1\tRolls: 1, 1\tTotal: 2\n"
            "2d1\tRolls: 1, 1\tTotal: 2\n"
            "Grand Total: 4",
        )

    def test_sort_operator(self) -> None:
        random.seed(0)
        self.assertEqual(get_roll("8d8s").roll_str(), "1, 5, 5, 7, 7, 7, 8, 8")

    def test_list_operators(self) -> None:
        random.seed(0)
        self.assertEqual(get_roll("8d8k5s").roll_str(), "7, 7, 7, 8, 8")
        random.seed(0)
        self.assertEqual(get_roll("8d8k5a").value, 8)
        random.seed(0)
        self.assertEqual(get_roll("8d8k5sd").value, 7)
        self.assertRaises(ValueError, get_roll, "8s")
        self.assertRaises(ValueError, get_roll, "8d8ad")

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


#!/bin/python3

import os
import argparse
import torch
import sys

def add_padding_to_image(img, padding_width: int):
    # Array of zeros of shape (img + padding_width)
    img_with_padding = torch.zeros((
        img.shape[0] + padding_width * 2,  # Multiply with two because we need padding on all sides
        img.shape[1] + padding_width * 2
    ))

    # Change the inner elements
    # For example, if img.shape = (224, 224), and img_with_padding.shape = (226, 226)
    # keep the pixel wide padding on all sides, but change the other values to be the same as img
    img_with_padding[padding_width:-padding_width, padding_width:-padding_width] = img

    return img_with_padding

def get_padding_width_per_side(kernel_size: int) -> int:
    # Simple integer division
    return kernel_size // 2  # p = [K/2]

def calculate_target_size(Img_Width, Kernel_Width, Stride, P):
    '''you can use this formula [(W−K+2P)/S]+1.
    W is the input volume - in your case 16
    K is the Kernel size - in your case 5
    P is the padding - 0 for valid and 1 is for same
    S is the stride - which you have not provided.'''
    W = Img_Width
    K = Kernel_Width
    S = Stride
    pixels = ((W - K + 2 * P) // S) + 1  # I added padding to input data, so I removed the 2P in this formula
    return pixels

def mac(img, kernel, dt, mac_flag, vec_flag, cast_flag, cast_to):
    if vec_flag == "false":
        temp = torch.zeros(1, dtype=dt)
        for i in range(img.shape[0]):
            for j in range(img.shape[1]):
                a = img[i][j]
                b = kernel[i][j]
                if cast_flag == "true":
                    if cast_to == "FP16":
                        a = a.type(torch.float16)
                        b = b.type(torch.float16)
                    elif cast_to == "FP16ALT":
                        a = a.type(torch.bfloat16)
                        b = b.type(torch.bfloat16)
                if mac_flag == "true":
                    a = a.type(torch.float32)
                    b = b.type(torch.float32)
                    temp = temp.type(torch.float32)
                temp += a * b
                if mac_flag == "true":
                    temp = temp.type(dt)
                # if cast_flag == "true":
                #     temp = temp.type(dt)
        return temp
    else:
        flag = True
        temp = torch.zeros(1, dtype=dt)
        temp1 = torch.zeros(1, dtype=dt)
        for i in range(img.shape[0]):
            for j in range(0, (img.shape[1] & 0xfffffffe), 2):
                a = img[i][j]
                a1 = img[i][j + 1]
                b = kernel[i][j]
                b1 = kernel[i][j + 1]
                if mac_flag == "true":
                    a = a.type(torch.float32)
                    b = b.type(torch.float32)
                    a1 = a1.type(torch.float32)
                    b1 = b1.type(torch.float32)
                    temp = temp.type(torch.float32)
                    temp1 = temp1.type(torch.float32)
                temp += a * b
                temp1 += a1 * b1
                if mac_flag == "true":
                    temp = temp.type(dt)
                    temp1 = temp1.type(dt)
        if img.shape[1] & 0x00000001:
            for i in range(img.shape[0]):
                a = img[i][img.shape[1] - 1]
                b = kernel[i][img.shape[1] - 1]
                if flag:  # temp
                    if mac_flag == "true":
                        a = a.type(torch.float32)
                        b = b.type(torch.float32)
                        temp = temp.type(torch.float32)
                    temp += a * b
                    if mac_flag == "true":
                        temp = temp.type(dt)
                    flag = False
                else:  # temp1
                    if mac_flag == "true":
                        a = a.type(torch.float32)
                        b = b.type(torch.float32)
                        temp1 = temp1.type(torch.float32)
                    temp1 += a * b
                    if mac_flag == "true":
                        temp1 = temp1.type(dt)
                    flag = True
        return temp + temp1

def convolve(img, kernel, out_width, dt, Stride, mac_flag, vec_flag, cast_flag, cast_to):
    out_img = torch.zeros((out_width, out_width), dtype=dt)
    tgt_size = out_img.shape[0]
    # To simplify things
    k = kernel.shape[0]
    if vec_flag == "false":
        # Iterate over the rows
        for i in range(tgt_size):
            # Iterate over the columns
            for j in range(tgt_size):
                # img[i, j] = individual pixel value
                # Get the current matrix
                mat = img[i * Stride:i * Stride + k, j * Stride:j * Stride + k]
                # Apply the convolution - element-wise multiplication and summation of the result
                # Store the result to i-th row and j-th column of our convolved_img array
                out_img[i, j] = mac(mat, kernel, dt, mac_flag, vec_flag, cast_flag, cast_to)
    else:  # based on the vectorized c code
        # Iterate over the columns
        for j in range(tgt_size):
            # Iterate over the rows
            for i in range(tgt_size):
                # img[i, j] = individual pixel value
                # Get the current matrix
                mat = img[i * Stride:i * Stride + k, j * Stride:j * Stride + k]
                # Apply the convolution - element-wise multiplication and summation of the result
                # Store the result to i-th row and j-th column of our convolved_img array
                out_img[i, j] = mac(mat, kernel, dt, mac_flag, vec_flag, cast_flag, cast_to="false")
    return out_img

def relative_absolute_error(true, pred):
    true_mean = torch.mean(true)
    squared_error_num = torch.sum(torch.abs(true - pred))
    squared_error_den = torch.sum(torch.abs(true - true_mean))
    rae_loss = squared_error_num / squared_error_den
    return rae_loss

def mean_squared_error(true, pred):
    squared_error = torch.square(true - pred)
    sum_squared_error = torch.sum(squared_error)
    size = true.size(dim=0) * true.size(dim=1)
    mse_loss = sum_squared_error / size
    return mse_loss

def matrix_init(IN, dt):
    # iterate through rows of IN
    temp = torch.zeros((IN.shape[0], IN.shape[1]), dtype=dt)
    # iterate through rows of IN
    for i in range(IN.shape[0]):
        # iterate through columns of IN
        for j in range(IN.shape[1]):
            temp[i][j] = IN[i][j]
    return temp

def write_matrix(matrix_to_write, name, len, file_pointer, float_type):
    matrix_string = ''
    sz0 = matrix_to_write.size()[0]
    sz1 = matrix_to_write.size()[1]
    if 'Filter_Kern' in name:
        file_pointer.write("DATA_LOCATION FIL_TYPE %s[%s] = {" % (name, len))
    elif 'ref' in name:
        file_pointer.write("PI_L2 OUT_TYPE %s[%s] = {" % (name, len))
    else:
        file_pointer.write("DATA_LOCATION INP_TYPE %s[%s] = {" % (name, len))

    if float_type == torch.float32:
        name = ")"
    elif float_type == torch.float16:
        name = ", dtype=torch.float16)"
    elif float_type == torch.bfloat16:
        name = ", dtype=torch.bfloat16)"
    for i in range(sz0):
        for j in range(sz1):
            matrix_string += str(matrix_to_write[i][j].item()).replace('tensor(', '').replace(name, '')
            matrix_string += ', '
    file_pointer.write("%s" % matrix_string)
    file_pointer.write("};\n")

def select_dtypes(user_dtypes, num_param):
    types_dict = {
        "FP32": torch.float32,
        "FP16": torch.float16,
        "FP16ALT": torch.bfloat16
    }
    dtypes = []
    if len(user_dtypes) == 1:
        for i in range(num_param):
            dtypes.append(types_dict[user_dtypes[0]])
    elif len(user_dtypes) == num_param:
        for i in range(num_param):
            dtypes.append(types_dict[user_dtypes[i]])
    else:
        for i in range(len(user_dtypes)):
            dtypes.append(types_dict[user_dtypes[i]])
        if 'FP32' in user_dtypes:
            for i in range(len(user_dtypes), num_param):
                dtypes.append(types_dict["FP32"])
        elif 'FP16' in user_dtypes:
            for i in range(len(user_dtypes), num_param):
                dtypes.append(types_dict["FP16"])
        else:
            for i in range(len(user_dtypes), num_param):
                dtypes.append(types_dict["FP16ALT"])
    return dtypes

def check_cast(datatypes):
    result = len(set(datatypes)) == 1
    if result : #All Elements in List are Equal
        return "false"
    else: #All Elements in List are Not Equal
        if torch.float32 in datatypes:
            return "false"
        else:
            return "true"

def get_inital_config():
    # get arguments  and data format
    parser = argparse.ArgumentParser()
    parser.add_argument('--IMG_WIDTH')
    parser.add_argument('--FILT_WIN')
    parser.add_argument('--STRIDE', default=1)
    parser.add_argument('--PADDING', default='valid')
    parser.add_argument('--vec_flag', default="false")
    parser.add_argument('--MAC_flag', default="true")
    parser.add_argument('--float_type', default='FP32')
    args = parser.parse_args()

    IMG_WIDTH = int(args.IMG_WIDTH)
    FILT_WIN = int(args.FILT_WIN)
    STRIDE = int(args.STRIDE)
    PADDING = str(args.PADDING)
    mac_flag = str(args.MAC_flag)
    vec_flag = str(args.vec_flag)
    bits = args.float_type.split(",")
    if PADDING == 'same' and STRIDE != 1:
        sys.exit("ValueError: padding='same' is not supported for strided convolutions")
    return IMG_WIDTH, FILT_WIN, STRIDE, PADDING, bits, mac_flag, vec_flag

def save_data_into_hfile(OUT_WIDTH, IMG_WIDTH, FILT_WIN, STRIDE, res, filter_conv, input_conv):
    # Generate header file
    f = open('data.h', 'w')

    f.write('\
#ifndef _INPUT_IMAGE_ \n\
#define _INPUT_IMAGE_\n\
#pragma GCC diagnostic ignored "-Woverflow"\n\n')
    f.write('\
#define OUT_DIM %s\n\
#define OUT_ROW %s\n\
#define OUT_COL %s\n\
#define INP_COL %s\n\
#define STRIDE %s\n\
#define FILT_WIN %s\n\n' % (OUT_WIDTH * OUT_WIDTH, OUT_WIDTH, OUT_WIDTH, IMG_WIDTH, STRIDE, FILT_WIN))
    write_matrix(input_conv, 'In_Img', IMG_WIDTH * IMG_WIDTH, f, input_conv.dtype)
    write_matrix(filter_conv, 'Filter_Kern', FILT_WIN * FILT_WIN, f, filter_conv.dtype)
    write_matrix(res, 'ref', OUT_WIDTH * OUT_WIDTH, f, res.dtype)
    f.write('\
#endif \n')
    f.close()

    f = open('config.h', 'w')

    f.write('\
#define FILT_WIN %s \n\n' % FILT_WIN)
    f.close()

def error_metric(ref, res):

    # calculate manually because metrics doesn't supprt bfloat16
    d = ref - res
    mse_f = torch.mean(d**2)
    mae_f = torch.mean(abs(d))
    rmse_f = torch.sqrt(mse_f)
    r2_f = 1-(torch.sum(d**2)/torch.sum((ref-torch.mean(ref))**2))
    print("Results of metrics:")
    print("MAE:",mae_f.item())
    print("MSE:", mse_f.item())
    print("RMSE:", rmse_f.item())
    print("R-Squared:", r2_f.item())
    rae = relative_absolute_error(ref, res)
    print("RAE is", rae.item())

def main():
    IMG_WIDTH, FILT_WIN, STRIDE, PADDING, bits, mac_flag, vec_flag = get_inital_config()

    # Create reference matrices
    input_ref = torch.rand((IMG_WIDTH, IMG_WIDTH), dtype=torch.float32)
    filter_ref = torch.randn((FILT_WIN, FILT_WIN), dtype=torch.float32) * 4

    OUT_WIDTH = IMG_WIDTH
    if PADDING == 'same':
        pad = get_padding_width_per_side(kernel_size=FILT_WIN)
        input_ref = add_padding_to_image(img=input_ref, padding_width=pad)
        OUT_WIDTH = IMG_WIDTH
        IMG_WIDTH = input_ref.shape[0]

    elif PADDING == 'valid':
        P = 0
        OUT_WIDTH = calculate_target_size(Img_Width=IMG_WIDTH,
Kernel_Width=FILT_WIN, Stride=STRIDE, P=P )
    # calculate reference output
    ref = convolve(img=input_ref, kernel=filter_ref, dt=torch.float32,
                   out_width=OUT_WIDTH, mac_flag="false", Stride=STRIDE, vec_flag="false", cast_flag="false", cast_to="false")

    # set the data types based on the parser input
    datatypes = select_dtypes(bits, 3)
    cast_flag = check_cast(datatypes[0:2])
    cast_to = "FP16"
    input_conv = matrix_init(input_ref, dt=datatypes[0])
    filter_conv = matrix_init(filter_ref, dt=datatypes[1])
    res = convolve(img=input_conv, kernel=filter_conv, dt=datatypes[2],
                   out_width=OUT_WIDTH, Stride=STRIDE, mac_flag=mac_flag, vec_flag=vec_flag, cast_flag=cast_flag, cast_to = cast_to)

    error_metric(ref, res)

    save_data_into_hfile(OUT_WIDTH, IMG_WIDTH, FILT_WIN, STRIDE, res, filter_conv, input_conv)
    print("############################## Done! ###################################")
    return None

if __name__ == "__main__":
    main()
    pass


import uuid
import subprocess
import dash
from dash import html
from dash import dcc
from dash.dependencies import Output, Input, State
import plotly.graph_objects as go
import base64
import tempfile
import scipy.io.wavfile as wav
import numpy as np
external_stylesheets = [
    'https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css',
]

uploader = html.Div([
    html.Div(
        dcc.Upload(
            id='upload-data',
            children=['Drop a Gerber, and this will convert it to an STL', html.A('Select Files')],
            style={
                'width': '100%',
                'height': '60px',
                'lineHeight': '60px',
                'borderWidth': '1px',
                'borderStyle': 'dashed',
                'borderRadius': '5px',
                'textAlign': 'center',
                'margin': '10px'
            },
            # Allow multiple files to be uploaded
            multiple=False),
        className="col")],
    className="row")

settings = html.Div(
    [
        html.Div(
            [
            ],
            className="col")
    ],
    className="row"
)
downloader = html.Div(
    [dcc.Download(id="downloader")]
    )

footer = html.Div(
    [html.A('Get the Source Code on github', href='https://github.com/ccrome/diy-pcb')]
)

plot_pane = [
    html.Div(html.H1('Gerber to STL converter')),
    uploader, downloader, settings, footer]

plotter_layout = html.Div(
        plot_pane
    , className="container")

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = plotter_layout
server=app.server

@app.callback(Output('downloader', 'data'),
              [
                  Input('upload-data', 'contents'),
              ],
              [State('upload-data', 'filename')])
def update_output(list_of_contents, list_of_fn):
    if list_of_contents is None:
        return None
    else:
        results = ""
        #        for contents, fn in zip(list_of_contents, list_of_fn):
        contents, fn = list_of_contents, list_of_fn
        output_fn = f'/tmp/{uuid.uuid4()}.stl'
        with tempfile.NamedTemporaryFile() as tempfn:
            content_type, content_string = contents.split(",")
            binary_data = base64.b64decode(content_string)
            tempfn.write(binary_data)
            tempfn.flush()
            name = tempfn.name
            r = subprocess.run(['python', '/app/gerber2stl.py', name, output_fn])
            results = open(output_fn, "r").read()
            print("Yay!  Returning a file of length {len(results)}")
            return dict(content=results, filename=f'{fn}.stl')

if __name__ == '__main__':
    app.run_server(debug=True, host="0.0.0.0", port="8050")


#!/usr/bin/python3
"""
BaseModel class that defines all common attributes/methods for other classes
"""
import uuid
from datetime import datetime
import models
import json
time_format = "%Y-%m-%dT%H:%M:%S.%f"

class BaseModel:
    """
        BaseModel: The base or parent class for all the classes
        Features:
        id - the unique identification of the object
        created_at - the datetime in which the object was created
        updated_at - the datetime in which the object was modified
    """
    def __init__(self, *args, **kwargs):
        """
        Initialization of the base model class
            id - the unique identification of the object
            created_at - the datetime in which the object was created
            updated_at - the datetime in which the object was modified
        """
        if kwargs is None or len(kwargs) == 0:
            self.id = str(uuid.uuid4())
            self.created_at = datetime.now()
            self.updated_at = datetime.now()
            models.storage.new(self)
        else:
            for key, value in kwargs.items():
                if key == "id":
                    self.id = value
                elif key == "created_at" or key == "updated_at":
                    self.__dict__[key] = datetime.strptime(value, time_format)
                elif key == "__class__":
                    pass
                elif key != "__class__":
                    self.__dict__[key] = value

    def __str__(self) -> str:
        """This method returns a string of object"""
        return ("[{}] ({}) {}".format(
            self.__class__.__name__, self.id, self.__dict__))

    def save(self):
        """Save method that updates the public instance attribute"""
        self.updated_at = datetime.now()
        models.storage.save()

    def to_dict(self):
        """This method returns a dictionary containing all keys/values
        of __dict__ of the instance"""
        new_obj_dict = self.__dict__.copy()
        new_obj_dict["__class__"] = self.__class__.__name__
        new_obj_dict["created_at"] = self.created_at.isoformat()
        new_obj_dict["updated_at"] = self.updated_at.isoformat()
        return new_obj_dict


import pygame as pg
import math
from enum import Enum

size = width, height = 1400, 1000
num_players = 3

class ImageInsEnum(Enum):
    LEFT = 0
    FORWARD = 1
    RIGHT = 2
    PAUSE = 4

control_mapping = {"0": ImageInsEnum.LEFT, "1": ImageInsEnum.FORWARD, "2": ImageInsEnum.RIGHT, "3": ImageInsEnum.PAUSE}

data_dir = "./game/assets"

def move_to_point(origin, destination, fps):
    dx, dy = (destination[0] - origin[0], destination[1] - origin[1])
    stepx, stepy = (dx/fps , dy/fps )
    return stepx, stepy

def calc_angle(vec1, vec2):
    x1, y1, = vec1
    x2, y2, = vec2
    dot = x1*x2 + y1*y2      # dot product between [x1, y1] and [x2, y2]
    det = x1*y2 - y1*x2      # determinant
    return  math.atan2(det, dot)

def distance(source, target):
    dist = math.sqrt((target[1]-source[1])**2 + (target[0]-source[0])**2)
    return dist


import ctypes
import os
import sys

# Used by EventManager in override.py
from inspect import getargspec

__version__ = "N/A"
build_date  = "Thu Apr 14 18:33:30 2011"

 # Used on win32 and MacOS in override.py
plugin_path = None

if sys.platform.startswith('linux'):
    try:
        dll = ctypes.CDLL('libvlc.so')
    except OSError:  # may fail
        dll = ctypes.CDLL('libvlc.so.5')

elif sys.platform.startswith('win'):
    import ctypes.util as u
    p = u.find_library('libvlc.dll')
    if p is None:
        try:  # some registry settings
            import _winreg as w  # leaner than win32api, win32con
            for r in w.HKEY_LOCAL_MACHINE, w.HKEY_CURRENT_USER:
                try:
                    r = w.OpenKey(r, 'Software\\VideoLAN\\VLC')
                    plugin_path, _ = w.QueryValueEx(r, 'InstallDir')
                    w.CloseKey(r)
                    break
                except w.error:
                    pass
            del r, w
        except ImportError:  # no PyWin32
            pass
        if plugin_path is None:
             # try some standard locations.
            for p in ('Program Files\\VideoLan\\', 'VideoLan\\',
                      'Program Files\\',           ''):
                p = 'C:\\' + p + 'VLC\\libvlc.dll'
                if os.path.exists(p):
                    plugin_path = os.path.dirname(p)
                    break
        if plugin_path is not None:  # try loading
            p = os.getcwd()
            os.chdir(plugin_path)
             # if chdir failed, this will raise an exception
            dll = ctypes.CDLL('libvlc.dll')
             # restore cwd after dll has been loaded
            os.chdir(p)
        else:  # may fail
            dll = ctypes.CDLL('libvlc.dll')
    else:
        plugin_path = os.path.dirname(p)
        dll = ctypes.CDLL(p)
    del p, u

elif sys.platform.startswith('darwin'):
    # FIXME: should find a means to configure path
    d = '/Applications/VLC.app/Contents/MacOS/'
    p = d + 'lib/libvlc.dylib'
    if os.path.exists(p):
        dll = ctypes.CDLL(p)
        d += 'modules'
        if os.path.isdir(d):
            plugin_path = d
    else:  # hope, some PATH is set...
        dll = ctypes.CDLL('libvlc.dylib')
    del d, p

else:
    raise NotImplementedError('%s: %s not supported' % (sys.argv[0], sys.platform))

class VLCException(Exception):
    """Exception raised by libvlc methods.
    """
    pass

try:
    _Ints = (int, long)
except NameError:  # no long in Python 3+
    _Ints =  int

_Seqs = (list, tuple)

_Cfunctions = {}  # from LibVLC __version__

def _Cfunction(name, flags, *types):
    """(INTERNAL) New ctypes function binding.
    """
    if hasattr(dll, name):
        p = ctypes.CFUNCTYPE(*types)
        f = p((name, dll), flags)
        _Cfunctions[name] = f
        return f
    raise NameError('no function %r' % (name,))

def libvlc_get_version():
    '''Retrieve libvlc version.
    Example: "1.1.0-git The Luggage".
    @return: a string containing the libvlc version.
    '''
    f = _Cfunctions.get('libvlc_get_version', None) or \
        _Cfunction('libvlc_get_version', (),
                    ctypes.c_char_p)
    if not __debug__:  # i.e. python -O or -OO
        global libvlc_get_version
        libvlc_get_version = f
    return f()


import sys
sys.path += ["."]  # Python 3 hack

from nose.tools import assert_equal, assert_is_instance, assert_in, assert_not_in, assert_true, assert_false
from GeneratingDataset import *
from Dataset import DatasetSeq
import numpy as np
import os
import unittest

import better_exchook
better_exchook.replace_traceback_format_tb()
from Log import log
log.initialize(verbosity=[5])

def test_init():
  dataset = DummyDataset(input_dim=2, output_dim=3, num_seqs=4)
  assert_equal(dataset.num_inputs, 2)
  assert_equal(dataset.num_outputs, {"classes": [3, 1], "data": [2, 2]})
  assert_equal(dataset.num_seqs, 4)

def test_load_seqs():
  dataset = DummyDataset(input_dim=2, output_dim=3, num_seqs=4)
  dataset.init_seq_order(epoch=1)
  dataset.load_seqs(0, 1)
  dataset.load_seqs(1, 3)

@unittest.skipIf(not os.path.exists("/tmp/enwik8.zip"), "we will not trigger the download")
def test_Enwik8Corpus_batch_num_seqs():
  dataset = Enwik8Corpus(path="/tmp", subset="validation", seq_len=13)
  dataset.init_seq_order(epoch=17)
  data = b""
  n = 0
  while dataset.is_less_than_num_seqs(n) and n < 100:
    dataset.load_seqs(n, n + 1)
    data += bytes(dataset.get_data(n, "data"))
    n += 1

  batch_size = 23
  batch_data = [b"" for i in range(batch_size)]
  dataset = Enwik8Corpus(path="/tmp", subset="validation", seq_len=9, batch_num_seqs=batch_size)
  dataset.init_seq_order(epoch=31)
  n = 0
  while dataset.is_less_than_num_seqs(n) and n < 100:
    dataset.load_seqs(n, n + 1)
    new_data = bytes(dataset.get_data(n, "data"))
    batch_data[n % batch_size] += new_data
    n += 1
  assert data.startswith(batch_data[0])


class Document(object):

    def __init__(self, *, connection, cluster, position, record):
        self.rid = cluster.build_rid(position)

        self.__database__ = DocumentDatabaseConnector(
            connection=connection, cluster=cluster, position=position
        )

        self.append_record_fields(record)

        self.__database__.status = 'loaded'

    def append_record_fields(self, record):
        """
        Sets fields that don't exist, and provides the field the chance
        to update itself if it does. Ignores the rid field if present.
        """

        # Ensure the records rid matches the documents rid.
        if record._rid not in self.rid:
            raise ValueError(
                "The record whose fields are being appended (RID = '{0}')"
                " does not match the document being appended to (RID = '{1}').".\
                format(record._rid, self.rid)
            )

        # Get the fields from the record.
        fields = record.oRecordData.copy()

        # Get the prefix that this documents fields may have been named with.
        prefix = self.__options__.name.lower() + '_'

        for key, value in fields.items():

            # Get the fields attribute, checking if the field's key is prefixed.
            attr = key[len(prefix):] if key.lower().startswith(prefix) else key

            # Attempt to update the field, first as a Property, then a Subquery.
            try:
                self.__properties__[attr].append_db_value(self, attr, value)
            except KeyError:
                pass
            else:
                continue

            try:
                self.__subqueries__[attr].append_db_value(self, attr, value)
            except KeyError:
                pass
            else:
                continue

            # If the field is neither a Property or a Subquery, ignore it.
            continue

    def __repr__(self):
        return "<{0} {1} | {2}.{3} object>".format(
            self.__options__['name'], self.rid,
            self.__class__.__module__, self.__class__.__name__
        )

class DocumentDatabaseConnector(object):

    def __init__(self, *, connection, cluster, position):
        self.engine = connection.engine
        self.connection = connection
        self.cluster = cluster
        self.position = position
        self.status = 'init'


import multiprocessing
import os
import threading
import time
from queue import Queue
from threading import Thread

from psutil import virtual_memory

from grandpa.utils.standard import print_warning, check_debug

class MultiprocessingManager:
    """
    Manages the multiprocessing of the framework.
    """
    def __init__(self):
        self.__task_queue = Queue()
        self.__worker_queue_list = []
        self.__init_workers()

    def add_worker_queue(self, worker_queue):
        """
        Registers a worker Queue.

        Args:
            worker_queue: Worker Queue Object to register.

        Returns:
            None
        """
        self.__worker_queue_list.append(worker_queue)

    def add_task(self, task):
        """
        Adds a task to be processed.

        Args:
            task: Task Object.

        Returns:
            None
        """
        self.__task_queue.put(task)

    def __init_workers(self):
        debug = os.environ["project_x_debug"] if "project_x_debug" in os.environ else False
        if debug == "true":
            worker_count = 1
        else:
            worker_count = multiprocessing.cpu_count() - 2
        for _ in range(worker_count):
            t = Thread(target=self.__work)
            t.daemon = True
            t.start()

    def __work(self):
        while True:
            try:
                if self.__task_queue.qsize() > 0:
                    task = self.__task_queue.get()
                    if task.lock.locked():
                        continue
                    else:
                        task.get_result()
                elif len(self.__worker_queue_list) > 0:
                    task_queue = self.__get_task_queue()
                    if task_queue is None:
                        time.sleep(0.01)
                    else:
                        task_queue.generate()
                else:
                    time.sleep(0.01)
            except Exception as e:
                if check_debug():
                    raise e
                else:
                    print_warning(str(e))

    def __get_task_queue(self):
        target_queue = None
        target_queue_size = float('inf')
        for t_queue in self.__worker_queue_list:
            if t_queue.qsize() / t_queue.target_size < target_queue_size and t_queue.qsize() < t_queue.target_size:
                target_queue_size = t_queue.qsize() / t_queue.target_size
                target_queue = t_queue
        return target_queue

class Task:
    """
    Task Class for Multiprocessing. Will execute once.
    """
    def __init__(self, multiprocessing_manager: MultiprocessingManager, target, *args, **kwargs):
        self.target = target
        self.args = args
        self.kwargs = kwargs
        self.lock = threading.Lock()
        self.result = NoData()
        multiprocessing_manager.add_task(self)

    def get_result(self):
        self.lock.acquire()
        if type(self.result) == NoData:
            self.result = self.target(*self.args, **self.kwargs)
        self.lock.release()
        return self.result

class WorkerQueue(Queue):
    """
    Class for registering a worker queue. Runs constantly until target_size is reached.
    """
    def __init__(self, multiprocessing_manager: MultiprocessingManager, target,
                 target_size: int = int(virtual_memory().total / 1000000000), split_results: bool = False,
                 batches_per_run: int = 1, *args, **kwargs):
        super().__init__()
        self.target = target
        self.args = args
        self.kwargs = kwargs
        self.target_size = target_size
        self.split_results = split_results
        self.batches_per_run = batches_per_run
        self.__pending_batches = 0
        self.static_workers = []
        self.__init_static_workers(1)
        multiprocessing_manager.add_worker_queue(self)

    def __init_static_workers(self, worker_num: int):
        debug = os.getenv("project_x_debug", False)
        if not debug == "true":
            for _ in range(worker_num):
                t = Thread(target=self.__worker_thread)
                t.daemon = True
                t.start()
                self.static_workers.append(t)

    def __worker_thread(self):
        if self.qsize() < self.target_size:
            self.generate()
        else:
            time.sleep(0.1)

    def get(self, block=True, timeout=None):
        debug = os.getenv("project_x_debug", False)
        if self.qsize() > 0:
            return super().get(block, timeout)
        else:
            try:
                self.generate()
            except Exception as e:
                if debug:
                    raise e
                else:
                    print(e)
            return self.get(block, timeout)

    def generate(self):
        self.__pending_batches += self.batches_per_run
        try:
            result = self.target(*self.args, **self.kwargs)
            if self.split_results:
                for r in result:
                    self.put(r)
            else:
                self.put(result)
        except Exception as e:
            if check_debug():
                raise e
            else:
                print_warning(str(e))
                return self.generate()
        self.__pending_batches -= self.batches_per_run

    def qsize_old(self) -> int:
        return super().qsize() + self.__pending_batches

class NoData:
    """
    Helper class. Symbolizes that a Task has not yet been completed.
    """
    pass


from random import randint

n = int(input("Elija el tamaño de la escalera:"))

matrix = []
matrix.append("a" * n)
for k in range(n):
    matrix.append("a")

print(matrix)

b = " "

for k in range(n):
    for j in range(1):
        b += str(matrix[k][j])+ "\t"
    print(b)


from socket import *

s = socket(AF_INET, SOCK_STREAM)
s.connect(('localhost', 3333))

while True:
    exp = input('Expression to send :')
    if exp == 'q':
        break

    s.send(exp.encode())
    print('Answer: ', s.recv(1024).decode())

s.close()


# * ---------------- *
#
#   ** Deep Reinforcement Learning Nano Degree **
#   project: Navigation
#   author:  Matthias Schinacher
#
#   the script implements Q-learning with transitions- replay
#   optionally using priority replay
#
#   the model used for the Q- function approximation is a simple
#   neural network with 3 hidden layers and 2 'relu' activations in between;
#   note: there is no activation/ relu after the third linear function!
#
#   => thus the model has 2 adjustable size- parameters, as the number of
#      incoming values is determined by the sate- size (37) and the number
#      of outgoing values ("activations") is the number of actions (4)
#   => interpretation of the 4 resulting values is simply the Q- values
#      for the 4 actions (of the input-state given)
# * ---------------- *

# * ---------------- *
#    importing the packages we need
# * ---------------- *
import os.path
import sys
import copy
import re
import configparser
import pickle
from unityagents import UnityEnvironment
import numpy as np
import torch
import torch.nn.functional as fct

# * ---------------- *
#   command line arguments:
#    we expect exactly 2, the actual script name and the command-file-name
# * ---------------- *
if len(sys.argv) != 2:
    print('usage:')
    print('   python {} command-file-name'.format(sys.argv[0]))
    quit()

if not os.path.isfile(sys.argv[1]):
    print('usage:')
    print('   python {} command-file-name'.format(sys.argv[0]))
    print('[error] "{}" file not found or not a file!'.format(sys.argv[1]))
    quit()

# * ---------------- *
#   constants:
#    this code is only for the Banana- scenario, no generalization (yet)
# * ---------------- *
STATE_SIZE = int(37)
ACTION_SIZE = int(4)
fzero = float(0)
fone = float(1)

# * ---------------- *
#   the command-file uses the ConfigParser module, thus must be structured that way
#    => loading the config and setting the respective script values
# * ---------------- *
booleanpattern = re.compile('^\\s*(true|yes|1|on)\\s*$', re.IGNORECASE)

config = configparser.ConfigParser()
config.read(sys.argv[1])

# start the logfile
rlfn = 'run.log' # run-log-file-name
if 'global' in config and 'runlog' in config['global']:
    rlfn = config['global']['runlog']
print('!! using logfile "{}"\n'.format(rlfn))
rl = open(rlfn,'w')
rl.write('# ## configuration from "{}"\n'.format(sys.argv[1]))

if 'rand' in config and 'seed' in config['rand']:
    seed = int(config['rand']['seed'])
    rl.write('# [debug] using random seed: {}\n'.format(seed))
    np.random.seed(seed)
    torch.manual_seed(seed)

TRAIN = True   # default to training mode
if 'mode' in config and 'train' in config['mode']:
    train = config['mode']['train']
    TRAIN = True if booleanpattern.match(train) else False
    rl.write('# [debug] using mode.train: {} from "{}"\n'.format(TRAIN,train))
SHOW  = not TRAIN  # default for "show"- mode
if 'mode' in config and 'show' in config['mode']:
    show = config['mode']['show']
    SHOW = True if booleanpattern.match(show) else False
    rl.write('# [debug] using mode.show: {} from "{}"\n'.format(SHOW,show))

# * ---------------- *
#   hyper- parameters
# * ---------------- *
# defaults
EPISODES = int(1000)         # number of episodes (including warm-up)
WARMUP_EPISODES = int(10)    # number of warm-up episodes (training only)
EPSILON_EPISODES = int(100)  # number of episodes, over which we decrease epsilon (training only)
EPSILON_START = float(1)     # start-value for epsilon (training and show- mode!)
EPSILON_END = float(0.01)    # final value for epsilon (training only)
REPLAY_BUFFERSIZE = int(50000) # replay buffer/memory- size (training only)
REPLAY_BATCHSIZE = int(300)  # batch size for replay (training only)
REPLAY_STEPS = int(1)        # replay transisitions- batch each x steps (training only)
PRIO_REPLAY = False          # priority replay flag (training only)
Q_RESET_STEPS = int(50)      # steps, after which to reset Q_ to Q  (training only)
GAMMA = float(0.99)          # gamma- parameter (training only)
LEARNING_RATE = float(0.001) # (training only)

# overwrite defaults
if 'hyperparameters' in config:
    hp = config['hyperparameters']
    EPISODES          = int(hp['episodes'])          if 'episodes'          in hp else EPISODES
    WARMUP_EPISODES   = int(hp['warmup_episodes'])   if 'warmup_episodes'   in hp else WARMUP_EPISODES
    EPSILON_EPISODES  = int(hp['epsilon_episodes'])  if 'epsilon_episodes'  in hp else EPSILON_EPISODES
    EPSILON_START     = float(hp['epsilon_start'])   if 'epsilon_start'     in hp else EPSILON_START
    EPSILON_END       = float(hp['epsilon_end'])     if 'epsilon_end'       in hp else EPSILON_END
    REPLAY_BUFFERSIZE = int(hp['replay_buffersize']) if 'replay_buffersize' in hp else REPLAY_BUFFERSIZE
    REPLAY_BATCHSIZE  = int(hp['replay_batchsize'])  if 'replay_batchsize'  in hp else REPLAY_BATCHSIZE
    REPLAY_STEPS      = int(hp['replay_steps'])      if 'replay_steps'      in hp else REPLAY_STEPS
    if 'prio_replay' in hp:
        PRIO_REPLAY   = True if booleanpattern.match(hp['prio_replay']) else False
    Q_RESET_STEPS     = int(hp['q_reset_steps'])     if 'q_reset_steps'     in hp else Q_RESET_STEPS
    GAMMA             = float(hp['gamma'])           if 'gamma'             in hp else GAMMA
    LEARNING_RATE     = float(hp['learning_rate'])   if 'learning_rate'     in hp else LEARNING_RATE

# model- defaults (only if model is not loaded from file)
MODEL_H1 = int(10)     # hidden layer size 1
MODEL_H2 = int(10)     # hidden layer size 2

# filenames for loading the model and buffer/memory of transistions
load_file = 'Q.model' if not TRAIN else None # only default when not training
load_transitions_file = None
# filenames for saving the model (and the "best model") and buffer/memory of transistions
save_file = 'Q.out.model' if TRAIN else None # only default when training
save_best_file = 'Q.out.best.model' if TRAIN else None # only default when training
save_transitions_file = None

# overwrite defaults
if 'model' in config:
    m = config['model']
    MODEL_H1 = int(m['h1'])  if 'h1' in m else MODEL_H1
    MODEL_H2 = int(m['h2'])  if 'h2' in m else MODEL_H2
    load_file = m['load_file']                         if 'load_file'             in m else load_file
    load_transitions_file = m['load_transitions_file'] if 'load_transitions_file' in m else load_transitions_file
    save_file = m['save_file']                         if 'save_file'             in m else save_file
    save_best_file = m['save_best_file']               if 'save_best_file'        in m else save_best_file
    save_transitions_file = m['save_transitions_file'] if 'save_transitions_file' in m else save_transitions_file

# consistency check, reset values not consistent
if EPSILON_EPISODES <= 0:
    EPSILON_EPISODES = 0
    EPSILON_START = EPSILON_END
    DELTA_EPSILON = 0.0
# computed
else:
    DELTA_EPSILON = (EPSILON_START - EPSILON_END)/float(EPSILON_EPISODES +1)

# * ---------------- *
#   writing the used config to the logfile
# * ---------------- *
rl.write('# TRAIN (mode):      {}\n'.format(TRAIN))
rl.write('# SHOW (mode):       {}\n\n'.format(SHOW))
rl.write('# EPSILON_EPISODES:  {}\n'.format(EPSILON_EPISODES))
rl.write('# EPISODES:          {}\n'.format(EPISODES))
rl.write('# WARMUP_EPISODES:   {}\n'.format(WARMUP_EPISODES))
rl.write('# EPSILON_START:     {}\n'.format(EPSILON_START))
rl.write('# EPSILON_END:       {}\n'.format(EPSILON_END))
rl.write('# DELTA_EPSILON:     {}\n'.format(DELTA_EPSILON))
rl.write('# REPLAY_BUFFERSIZE: {}\n'.format(REPLAY_BUFFERSIZE))
rl.write('# REPLAY_BATCHSIZE:  {}\n'.format(REPLAY_BATCHSIZE))
rl.write('# REPLAY_STEPS:      {}\n'.format(REPLAY_STEPS))
rl.write('# PRIO_REPLAY:       {}\n'.format(PRIO_REPLAY))
rl.write('# Q_RESET_STEPS:     {}\n'.format(Q_RESET_STEPS))
rl.write('# GAMMA:             {}\n'.format(GAMMA))
rl.write('# LEARNING_RATE:     {}\n'.format(LEARNING_RATE))
rl.write('#   -- model\n')
rl.write('# H1: {}\n'.format(MODEL_H1))
rl.write('# H2: {}\n'.format(MODEL_H2))
rl.write('# load_file: {}\n'.format(load_file))
rl.write('# load_transitions_file: {}\n'.format(load_transitions_file))
rl.write('# save_file: {}\n'.format(save_file))
rl.write('# save_best_file: {}\n'.format(save_best_file))
rl.write('# save_transitions_file: {}\n'.format(save_transitions_file))
rl.flush()

# * ---------------- *
#   torch:
#    local computer was a laptop with no CUDA available
#    => feel free to change this, if you have a machine (with GPU)
# * ---------------- *
dtype = torch.float64
torch.set_default_dtype(dtype)
device = torch.device("cpu")
# device = torch.device("cuda:0") # Uncomment this to run on GPU

# * ---------------- *
#   buildung and initializing the torch- models for Q and Q_
# * ---------------- *
if load_file and os.path.isfile(load_file):
    modelQ = torch.load(load_file)
    modelQ_ = torch.load(load_file) # instead of zeros, we initialize with the same model

    rl.write('# [info] loaded model(s) from "{}"\n'.format(load_file))
    rl.write('# [info]   => H1, H2 parameters not used (nn-sizes from file model are implicitly used)\n')
    rl.flush()
elif not TRAIN:
    rl.write('# [error] not training, but model not loaded from file ("{}").\n'.format(load_file))
    rl.close()
    quit()
else:
    L1 = torch.nn.Linear(STATE_SIZE, MODEL_H1)
    torch.nn.init.uniform_(L1.weight) # uniform [0,1) for the actual Q function
    torch.nn.init.uniform_(L1.bias)
    L2 = torch.nn.Linear(MODEL_H1, MODEL_H2)
    torch.nn.init.uniform_(L2.weight)
    torch.nn.init.uniform_(L2.bias)
    L3 = torch.nn.Linear(MODEL_H2, ACTION_SIZE)
    torch.nn.init.uniform_(L3.weight)
    torch.nn.init.uniform_(L3.bias)

    modelQ = torch.nn.Sequential(
        L1
        ,torch.nn.ReLU()
        ,L2
        ,torch.nn.ReLU()
        ,L3
    #    ,torch.nn.LogSoftmax()
    )

    L1_ = torch.nn.Linear(STATE_SIZE, MODEL_H1)
    torch.nn.init.constant_(L1_.weight,fzero) # zeros, for the fixed Q
    torch.nn.init.constant_(L1_.bias,fzero)
    L2_ = torch.nn.Linear(MODEL_H1, MODEL_H2)
    torch.nn.init.constant_(L2_.weight,fzero)
    torch.nn.init.constant_(L2_.bias,fzero)
    L3_ = torch.nn.Linear(MODEL_H2, ACTION_SIZE)
    torch.nn.init.constant_(L3_.weight,fzero)
    torch.nn.init.constant_(L3_.bias,fzero)

    modelQ_ = torch.nn.Sequential(
        L1_
        ,torch.nn.ReLU()
        ,L2_
        ,torch.nn.ReLU()
        ,L3_
    #    ,torch.nn.LogSoftmax()
    )

    L1.weight.requires_grad_(requires_grad=True)
    L2.weight.requires_grad_(requires_grad=True)
    L3.weight.requires_grad_(requires_grad=True)
    L1.bias.requires_grad_(requires_grad=True)
    L2.bias.requires_grad_(requires_grad=True)
    L3.bias.requires_grad_(requires_grad=True)

    L1_.weight.requires_grad_(requires_grad=False)
    L2_.weight.requires_grad_(requires_grad=False)
    L3_.weight.requires_grad_(requires_grad=False)
    L1_.bias.requires_grad_(requires_grad=False)
    L2_.bias.requires_grad_(requires_grad=False)
    L3_.bias.requires_grad_(requires_grad=False)

if TRAIN:
    optimizer = torch.optim.Adam(modelQ.parameters(),lr=LEARNING_RATE)

# * ---------------- *
#   loading the Banana environment, loading the default brain (external)
# * ---------------- *
env = UnityEnvironment(file_name="Banana_Linux/Banana.x86_64")
brain_name = env.brain_names[0]
brain = env.brains[brain_name]

# * ---------------- *
#   the actual algorithm
# * ---------------- *

if TRAIN:
    # a very simple replay memory, a list (of tuples)
    #   - is assumed to never shrink
    #   - only inserts at given index, if next index would be > size, start at 0
    #         => list entries 0..size-1 are occupied
    replay_memory = []   # actual replay memory
    p_array       = []   # priority array
    if PRIO_REPLAY:
        index_array   = [i for i in range(REPLAY_BUFFERSIZE)]
        min_p         = abs(0.00000001) # value added to |delta| for numeric stability
    rm_size = 0          # number of entries in replay memory
    rm_next = 0          # next index to use for insert

    # we always laod/save transitions together with the priority- p_array
    #  ... even if we do not or had not used priority replay
    if load_transitions_file and os.path.isfile(load_transitions_file):
        with open(load_transitions_file, 'rb') as f:
            ( tmpm, tmpp ) = pickle.load(f)

            replay_memory = tmpm if REPLAY_BUFFERSIZE >= len(tmpm) else tmpm[0:REPLAY_BUFFERSIZE]
            rm_size = len(replay_memory)
            rm_next = rm_size if rm_size < REPLAY_BUFFERSIZE else 0

            if PRIO_REPLAY:
                # we need to make certain, that p_array has the same length
                #  as the replay-memory (we pad with the average if necc.)
                p_array = tmpp if tmpp else []
                if len(p_array) > rm_size:
                    p_array = p_array[0:rm_size]
                elif len(p_array) == 0:
                    if rm_size > 0:
                        p_array = [float(1.0) for i in range(rm_size)]
                elif len(p_array) < rm_size:
                    ptmpv = float(sum(p_array))/float(len(p_array))
                    tmplen = len(p_array)
                    for i in range(tmplen,rm_size):
                        p_array.append(ptmpv)
            else:
                p_array = [] # discard if we don't use prio-replay

# score buffer, for the last 100 scores
score_buffer = []
max_score = float('-inf')
best_model = None

epsilon = EPSILON_START
q_steps = 0
r_steps = 0

rl.write('#\n# Episode Score average(last-100-Scores) Steps Epsilon\n')

for episode in range(1,EPISODES+1):
    train_mode = not SHOW
    env_info = env.reset(train_mode=train_mode)[brain_name] # reset the environment
    state = env_info.vector_observations[0]            # get the start state
    score = 0                                          # initialize the episode- score
    step  = 0                                          # step within episodes
    if TRAIN and episode > WARMUP_EPISODES and (epsilon - DELTA_EPSILON + 1e-10) >= EPSILON_END:
        epsilon -= DELTA_EPSILON
    while True:
        step += 1
        rs = np.random.random_sample()
        if TRAIN and episode <= WARMUP_EPISODES:
            action = np.random.randint(ACTION_SIZE)
        elif (epsilon >= fone or rs < epsilon):
            action = np.random.randint(ACTION_SIZE)
        else:
            pred_a = modelQ(torch.tensor(state))
            action = int(torch.argmax(pred_a))

        env_info = env.step(action)[brain_name]        # send the action to the environment
        next_state = env_info.vector_observations[0]   # get the next state
        reward = env_info.rewards[0]                   # get the reward
        done = env_info.local_done[0]                  # see if episode has finished

        #print("Episode: {}; Step: {}; Reward: {}".format(episode,step,reward))

        if TRAIN:
            if PRIO_REPLAY:
                p = abs(float( reward + GAMMA * max(modelQ(torch.tensor(next_state))) - modelQ(torch.tensor(state))[action] )) + min_p
            # store transition in replay memory
            transition = (state,action,reward,next_state,done)
            if rm_size < REPLAY_BUFFERSIZE:
                replay_memory.append(transition)
                if PRIO_REPLAY:
                    p_array.append(p)
                rm_size += 1
            else:
                replay_memory[rm_next] = transition
                if PRIO_REPLAY:
                    p_array[rm_next] = p
            rm_next += 1
            if rm_next >= REPLAY_BUFFERSIZE:
                rm_next = 0

            if rm_size >= REPLAY_BATCHSIZE and episode > WARMUP_EPISODES:
                r_steps += 1
                if r_steps >= REPLAY_STEPS:
                    r_steps = 0

                    # learn with random sampled transitions from the past
                    if PRIO_REPLAY:
                        p_sum = float(sum(p_array))
                        tmp = float(1)/p_sum
                        P = np.array(p_array) * tmp
                        #print('[DEBUG] p_array: ',p_array)
                        #print('[DEBUG] P: ',P)
                        if rm_size < REPLAY_BUFFERSIZE:
                            batch_idx = np.random.choice(index_array[0:rm_size],size=REPLAY_BATCHSIZE,p=P)
                        else:
                            batch_idx = np.random.choice(index_array,size=REPLAY_BATCHSIZE,p=P)
                    else:
                        batch_idx = np.random.randint(rm_size, size=REPLAY_BATCHSIZE)
                    #print('[DEBUG] batch_idx: ',batch_idx)

                    listt  = [replay_memory[idx] for idx in batch_idx] # transitions
                    lists  = torch.tensor([s for s,a,r,ns,d in listt],dtype=torch.float64) # states
                    lista  = torch.tensor([a for s,a,r,ns,d in listt],dtype=torch.int64) # actions
                    listr  = torch.tensor([[r] for s,a,r,ns,d in listt],dtype=torch.float64) # rewards
                    listns = torch.tensor([ns for s,a,r,ns,d in listt],dtype=torch.float64) # next states
                    listd  = torch.tensor([[d] for s,a,r,ns,d in listt],dtype=torch.int64) # "done"- flags
                    tmpzeroes = torch.tensor([0 for i in range(0,len(batch_idx))],dtype=torch.int64)
                    tmpa   = torch.stack([lista] + [tmpzeroes for i in range(1,ACTION_SIZE)])
                    tmpa   = torch.t(tmpa)

                    pred_v = torch.index_select(modelQ(lists).gather(1, tmpa), 1, torch.tensor([0]))

                    pred_v_, _ = torch.max(modelQ_(listns),dim=1,keepdim=True)
                    pred_v_ =  listr  + pred_v_ * GAMMA * torch.tensor((1 - listd),dtype=torch.float64)

                    #quit()

                    loss = fct.mse_loss(pred_v,pred_v_)

                    optimizer.zero_grad()
                    loss.backward()
                    optimizer.step()

        score += reward                                # update the score
        state = next_state                             # roll over the state to next time step

        if TRAIN:
            q_steps += 1
            if q_steps >= Q_RESET_STEPS:
                modelQ_.load_state_dict(modelQ.state_dict())
                q_steps = 0

        if done:                                       # exit loop if episode finished
            break

    if max_score < score:
        max_score = score
        best_model = copy.deepcopy(modelQ)

    score_buffer.append(score)
    while len(score_buffer) > 100:
        score_buffer.pop(0)
    l100_score = float(sum(score_buffer))/float(len(score_buffer)) if len(score_buffer) >= 100 else float(0)

    rl.write('{} {} {} {} {}\n'.format(episode,score,l100_score,step,epsilon))
    rl.flush()
    print("Episode: {}; Score: {} ({}); #Steps: {}; Epsilon: {}".format(episode,score,l100_score,step,epsilon))

env.close()

if TRAIN:
    if save_file:
        rl.write('# .. writing final model to "{}"\n'.format(save_file))
        torch.save(modelQ,save_file)
    if save_best_file:
        rl.write('# .. writing best model to "{}"\n'.format(save_best_file))
        torch.save(best_model,save_best_file)

    if save_transitions_file:
        rl.write('# .. saving transisitions to "{}"\n'.format(save_transitions_file))
        with open(save_transitions_file, 'wb') as f:
            pickledata = ( replay_memory,p_array )
            pickle.dump(pickledata, f, pickle.HIGHEST_PROTOCOL)

rl.close()


import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_core_components as dcc

def footer_layout():
    footer = html.Footer([
        dbc.Container([
            dbc.Row([
                dbc.Col([
                    html.P("Developed by Tiago Duque"), ]),
                dbc.Col([

                    dbc.Row([
                        dbc.Col([dbc.Row([html.A(href="https://www.linkedin.com/in/tfduque/",
                                                 className="btn btn-social-icon btn-linkedin",
                                                 children=[html.Span(className="fab fa-linkedin")])],
                                         style={'margin-top': '7px'}),
                                 dbc.Row([html.A(href="https://tfduque.medium.com",
                                                 className="btn btn-social-icon btn-reddit",
                                                 children=[html.Span(className="fab fa-medium")])],
                                         style={'margin-top': '7px'})]),
                        dbc.Col([dbc.Row([html.A(href="https://www.github.com/sirsirious",
                                                 className="btn btn-social-icon btn-github",
                                                 children=[html.Span(className="fab fa-github")])],
                                         style={'margin-top': '7px'}),
                                 dbc.Row([html.A(href="https://tfduque.medium.com",
                                                 className="btn btn-social-icon btn-pinterest",
                                                 children=[html.Span(className="fab fa-stack-overflow")])],
                                         style={'margin-top': '7px'}), ]), ])
                ]),
                dbc.Col([

                ], align="center")
            ], justify="center", style={'margin-top': '50px'})
        ])]
    )

    return footer


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('geo', '0001_initial'),
        ('events', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='Grantee',
            fields=[
                ('grantee_id', models.CharField(max_length=30, serialize=False, primary_key=True)),
                ('name', models.CharField(max_length=255)),
                ('title', models.CharField(max_length=255, blank=True)),
                ('alt_location', models.ForeignKey(related_name='alt_location', blank=True, to='geo.Place', null=True)),
            ],
        ),
        migrations.CreateModel(
            name='GrantorName',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.CharField(max_length=255)),
                ('title', models.CharField(max_length=255, blank=True)),
                ('event', models.ForeignKey(to='events.Event')),
            ],
        ),
        migrations.CreateModel(
            name='Identifier',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.CharField(max_length=255)),
            ],
        ),
        migrations.AddField(
            model_name='grantee',
            name='identifiers',
            field=models.ManyToManyField(to='people.Identifier', null=True, blank=True),
        ),
        migrations.AddField(
            model_name='grantee',
            name='professional_location',
            field=models.ForeignKey(related_name='professional_location', blank=True, to='geo.Place', null=True),
        ),
        migrations.AddField(
            model_name='grantee',
            name='standard_location',
            field=models.ForeignKey(related_name='standard_location', blank=True, to='geo.Place', null=True),
        ),
    ]


""" Logger for displaying info based on Verbosity """
import time
import global_vars

def log_timer(marker="", verbose=0):
    """ Shows the time since app started """
    if global_vars.VERBOSE >= verbose and marker:
        print("{:.4f} -- {}".format(
            (time.time() - global_vars.START_TIME),
            marker
        ))

def log_output(text, verbose):
    """ Prints log text if it has the right verbosity """
    if global_vars.VERBOSE >= verbose and text:
        print(text)


__author__ = 'Matias'

try:
    import Tkinter  # Python 2
    import ttk
    from Tkconstants import END, INSERT, W, E, S, N, HORIZONTAL
except ImportError:
    import tkinter as Tkinter  # Python 3
    import tkinter.ttk as ttk
    from tkinter.constants import END, INSERT, W, E, S, N, HORIZONTAL

class ProgressDialog:
    # Create Progress Bar
    def __init__(self, parent):
        self.window3 = Tkinter.Toplevel(parent)

        # self.window3.overrideredirect(1)
        self.window3.attributes("-toolwindow", 1)
        self.window3.protocol("WM_DELETE_WINDOW", self.__doNothing)
        self.window3.grab_set()
        self.textoBar = Tkinter.Label(self.window3, text="Doing stuff, please wait")
        self.textoBar.grid(row=0, column=0, pady=(5, 5))
        self.progressbar = ttk.Progressbar(self.window3, orient=HORIZONTAL, mode='indeterminate', length=250)
        self.progressbar.grid(row=1, column=0, pady=(5, 5))
        self.center(self.window3)
        self.progressbar.start()

    # Close Progress Bar
    def close(self):
        self.progressbar.stop()
        self.window3.destroy()

    def __doNothing(self):
        pass

    def center(self, toplevel):
        toplevel.update_idletasks()
        w = toplevel.winfo_screenwidth()
        h = toplevel.winfo_screenheight()
        size = tuple(int(_) for _ in toplevel.geometry().split('+')[0].split('x'))
        x = w/2 - size[0]/2
        y = h/2 - size[1]/2
        toplevel.geometry("%dx%d+%d+%d" % (size + (x, y)))


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

# In[1]:

headers  = {
    'Connection': 'keep-alive',
    'Accept': 'application/json, text/plain, */*',
    'x-nba-stats-token': 'true',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',
    'x-nba-stats-origin': 'stats',
    'Sec-Fetch-Site': 'same-origin',
    'Sec-Fetch-Mode': 'cors',
    'Referer': 'https://stats.nba.com/',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en-US,en;q=0.9',
}
column_names = ["PLAYER_ID",
"PLAYER_NAME",
"NICKNAME",
"TEAM_ID",
"TEAM_ABBREVIATION",
"AGE",
"GP",
"W",
"L",
"W_PCT",
"MIN",
"FGM",
"FGA",
"FG_PCT",
"FG3M",
"FG3A",
"FG3_PCT",
"FTM",
"FTA",
"FT_PCT",
"OREB",
"DREB",
"REB",
"AST",
"TOV",
"STL",
"BLK",
"BLKA",
"PF",
"PFD",
"PTS",
"PLUS_MINUS",
"NBA_FANTASY_PTS",
"DD2",
"TD3",
"WNBA_FANTASY_PTS",
"GP_RANK",
"W_RANK",
"L_RANK",
"W_PCT_RANK",
"MIN_RANK",
"FGM_RANK",
"FGA_RANK",
"FG_PCT_RANK",
"FG3M_RANK",
"FG3A_RANK",
"FG3_PCT_RANK",
"FTM_RANK",
"FTA_RANK",
"FT_PCT_RANK",
"OREB_RANK",
"DREB_RANK",
"REB_RANK",
"AST_RANK",
"TOV_RANK",
"STL_RANK",
"BLK_RANK",
"BLKA_RANK",
"PF_RANK",
"PFD_RANK",
"PTS_RANK",
"PLUS_MINUS_RANK",
"NBA_FANTASY_PTS_RANK",
"DD2_RANK",
"TD3_RANK",
"WNBA_FANTASY_PTS_RANK",
"CFID",
"CFPARAMS"]

cols = ["PLAYER_NAME","W_PCT", "MIN", "GP","FG_PCT_RANK","PTS_RANK", "NBA_FANTASY_PTS_RANK","W_PCT_RANK", "PLUS_MINUS_RANK","REB_RANK","AST_RANK","TOV_RANK","STL_RANK","BLK_RANK","FTA_RANK", "Year"]

# In[1]:

import requests
import pandas as pd
from bs4 import BeautifulSoup

# In[ ]:

d = [*range(96,100,1)]
e = [*range(0,10,1)]
f = [*range(10,23,1)]
for i in range(len(e)):
    e[i] = '%02d' % i

for i in range(len(d)):
    d[i] = str(d[i])

for i in range(len(f)):
    f[i] = str(f[i])

years = d + e + f

for i in range(len(years)-1):
    years[i] = str(years[i]+"-"+years[i+1])

    if years[i][0] == '8' or years[i][0] == '9':
        years[i] = str('19'+years[i])

for i in range(4,len(years)-1,1):
    years[i] = str('20'+years[i])

years.pop()
print(years)

# In[ ]:

urlyearslist = []
i = 0
while i < len(years):
    playerinfourl = 'https://stats.nba.com/stats/leaguedashplayerstats?College=&Conference=&Country=&DateFrom=&DateTo=&Division=&DraftPick=&DraftYear=&GameScope=&GameSegment=&Height=&LastNGames=0&LeagueID=00&Location=&MeasureType=Base&Month=0&OpponentTeamID=0&Outcome=&PORound=0&PaceAdjust=N&PerMode=PerGame&Period=0&PlayerExperience=&PlayerPosition=&PlusMinus=N&Rank=N&Season=' + years[i] + '&SeasonSegment=&SeasonType=Regular+Season&ShotClockRange=&StarterBench=&TeamID=0&TwoWay=0&VsConference=&VsDivision=&Weight='
    urlyearslist.append(str(playerinfourl))
    i = i+1

# In[9]:

years_list = [*range(1997,2023,1)]
print(len(years_list))

# In[ ]:

data_list = []

j = 0
while j < len(urlyearslist):
    tempurl = urlyearslist[j]

    response = requests.get(url=tempurl,headers=headers).json()
    player_info = response['resultSets'][0]['rowSet']

    year_data = pd.DataFrame(player_info, columns = column_names)
    #newdf = year_data[cols]
    year_data["Year"] = years_list[j]

    data_list.append(year_data)

    j = j+1

player_stats_all_years = pd.concat(data_list)

# In[ ]:

player_stats_all_years

# In[ ]:

player_stats_all_years.to_csv("full_player_stats.csv")

# In[ ]:

data_list = []

for year in years_list:
    with open("years_html/{}.html".format(year),encoding="utf-8") as f:
        page = f.read()

    soup = BeautifulSoup(page, "html.parser")
    soup.find('tr', class_="over_header").decompose()
    mvp_table = soup.find(id="mvp")
    mvp = pd.read_html(str(mvp_table))[0]
    mvp["Year"] = year
    data_list.append(mvp)

# In[ ]:

mvp_all_years = pd.concat(data_list)
mvp_all_years.to_csv("mvp_all_years.csv")

# In[ ]:

mvps_df = pd.read_csv("mvp_all_years.csv")

# In[ ]:

mvp_columns = ["Player","Year","Pts Won", "Pts Max", "Share"]
mvps_df = mvps_df[mvp_columns]
mvps_df.rename(columns = {'Player':'PLAYER_NAME'}, inplace = True)
mvps_df["PLAYER_NAME"] = mvps_df["PLAYER_NAME"].str.replace("ć","c", regex=False)
mvps_df["PLAYER_NAME"] = mvps_df["PLAYER_NAME"].str.replace("č","c", regex=False)
mvps_df["PLAYER_NAME"] = mvps_df["PLAYER_NAME"].str.replace("ó","o", regex=False)
mvps_df.head()

# In[ ]:

all_players_df = pd.read_csv("full_player_stats.csv")
#del all_players_df["Unnamed: 0"]

a = mvps_df.loc[(mvps_df['PLAYER_NAME'] == 'Steve Smith')]
a

# In[ ]:

mvps_df = mvps_df[mvps_df['PLAYER_NAME'] != 'Steve Smith']

# In[ ]:

players_and_mvps = all_players_df.merge(mvps_df, how="outer", on=["PLAYER_NAME", "Year"])

# In[ ]:

replace_nan = ["Pts Won", "Pts Max", "Share"]
players_and_mvps[replace_nan] = players_and_mvps[replace_nan].fillna(0)
players_and_mvps.head(10)

# In[ ]:

cols = ["PLAYER_NAME","W_PCT", "MIN", "GP","FG_PCT_RANK","PTS_RANK", "NBA_FANTASY_PTS_RANK","W_PCT_RANK", "PLUS_MINUS_RANK","REB_RANK","AST_RANK","TOV_RANK","STL_RANK","BLK_RANK","FTA_RANK", "Year", "Pts Won", "Pts Max", "Share"]

# In[ ]:

players_and_mvps = players_and_mvps[cols]

# In[ ]:

players_and_mvps

# In[ ]:

players_and_mvps = players_and_mvps[players_and_mvps['PLAYER_NAME'].notna()]
pd.isnull(players_and_mvps).sum()

# In[ ]:

players_and_mvps.to_csv("ml_players_mvp_stats.csv")

# In[ ]:

players_and_mvps.corr()["Share"].sort_values(ascending=False)

# In[2]:

input_data = pd.read_csv("ml_players_mvp_stats.csv")
input_data.columns
del input_data["Unnamed: 0"]

# In[3]:

ml_years = list(range(1997,2023))
all_data = []
for year in ml_years:
    test = input_data[input_data["Year"] == year]
    all_data.append(test)
print(all_data)

# In[4]:

m = 0
while m<len(ml_years):
    if m == 23:
        all_data[m] = all_data[m][all_data[m]['GP']>40]
        all_data[m] = all_data[m][all_data[m]['MIN']>25]
        m = m+1
        continue

    else:
        all_data[m] = all_data[m][all_data[m]['GP']>55]
        all_data[m] = all_data[m][all_data[m]['MIN']>25]

    m = m+1

# In[5]:

input_data = pd.concat(all_data)

# In[6]:

features = ['W_PCT', 'MIN', 'GP', 'FG_PCT_RANK', 'PTS_RANK',
       'NBA_FANTASY_PTS_RANK', 'W_PCT_RANK', 'PLUS_MINUS_RANK', 'REB_RANK',
       'AST_RANK', 'TOV_RANK', 'STL_RANK', 'BLK_RANK', 'FTA_RANK']

# In[23]:

one_year_train = input_data[input_data["Year"]< 2022]
one_year_test = input_data[input_data["Year"] == 2022]

# In[24]:

from sklearn.linear_model import Ridge
sample_reg = Ridge(alpha=.1)
sample_reg.fit(one_year_train[features], one_year_train["Share"])

# In[25]:

sample_predictions = sample_reg.predict(one_year_test[features])
sample_predictions = pd.DataFrame(sample_predictions, columns = ["predictions"], index=one_year_test.index)
sample_playerprediction = pd.concat([one_year_test[["PLAYER_NAME","Share"]],sample_predictions],axis=1)

# In[26]:

sample_playerprediction = sample_playerprediction.sort_values("Share", ascending=False)
sample_playerprediction["rank"] = list(range(1,sample_playerprediction.shape[0]+1))
sample_playerprediction.head(10)

# In[27]:

sample_playerprediction = sample_playerprediction.sort_values("predictions", ascending=False)
sample_playerprediction["predicted_rank"] = list(range(1,sample_playerprediction.shape[0]+1))
sample_playerprediction.head(10)
#ridge regression training on 25 years and testing on 2022 did not show the correct prediction

# In[4]:

ml_years = list(range(1997,2023))
ml_years

# In[28]:

all_predictions = []
for year in ml_years[5:]:
    train = input_data[input_data["Year"] < year]
    test = input_data[input_data["Year"] == year]
    sample_reg.fit(train[features], train["Share"])
    predictions = sample_reg.predict(test[features])
    predictions = pd.DataFrame(predictions, columns = ["predictions"], index=test.index)
    combination = pd.concat([test[["PLAYER_NAME","Share"]],predictions],axis=1)
    all_predictions.append(combination)

# In[8]:

def add_ranks(combination):
    combination = combination.sort_values("Share", ascending=False)
    combination["rank"] = list(range(1,combination.shape[0]+1))
    combination = combination.sort_values("predictions", ascending=False)
    combination["predicted_rank"] = list(range(1,combination.shape[0]+1))
    return combination

# In[9]:

def ml_test(stats,model,years,predictors):
    all_predictions = []
    for year in years:

        train = stats[stats["Year"] < year]
        test = stats[stats["Year"] == year]
        model.fit(train[predictors], train["Share"])
        predictions = model.predict(test[predictors])
        predictions = pd.DataFrame(predictions, columns = ["predictions"], index=test.index)
        combination = pd.concat([test[["PLAYER_NAME","Share"]],predictions],axis=1)
        combination = add_ranks(combination)
        all_predictions.append(combination)
    return all_predictions

# In[31]:

get_ipython().system(' pip install sklearn')

# In[10]:

def scores(predictions):
    correct = 0
    total = 0
    for year in predictions:
        row_1=year.iloc[0]
        if row_1['rank'] == 1 and row_1['predicted_rank'] == 1:
            correct += 1
        total += 1
    score = correct/total
    return score

# In[34]:

alpha_list = [x/10 for x in range(0, 101, 1)]
def ridge_alpha_tuning(stats,alpha_list,years,predictors):
    alpha_tuning_predictions = []
    alpha_scores = pd.DataFrame(columns = ['Alpha', 'Score'])
    for alpha in alpha_list:
        model = Ridge(alpha=alpha)
        for year in years:
            train = stats[stats["Year"] < year]
            test = stats[stats["Year"] == year]
            model.fit(train[predictors], train["Share"])
            predictions = model.predict(test[predictors])
            predictions = pd.DataFrame(predictions, columns = ["predictions"], index=test.index)
            combination = pd.concat([test[["PLAYER_NAME","Share"]],predictions],axis=1)
            combination = add_ranks(combination)
            alpha_tuning_predictions.append(combination)
        score = scores(alpha_tuning_predictions)

        alpha_scores = alpha_scores.append({'Alpha' : alpha, 'Score' : score}, ignore_index = True)
    return alpha_scores

ridge_alpha_tuning_test = ridge_alpha_tuning(input_data,alpha_list,ml_years[5:], features)
print(ridge_alpha_tuning_test)

# In[35]:

print(ridge_alpha_tuning_test.sort_values("Score", ascending=False))
#ridge regression training on 5 years and testing on 21 years produced a best accuracy of 0.52 with small alphas

# In[36]:

ridge_alpha_tuning_test_ten = ridge_alpha_tuning(input_data,alpha_list,ml_years[10:], features)
print(ridge_alpha_tuning_test_ten)
#ridge regression training on 10 years and testing on 16 years produced a best accuracy of 0.63 with small alphas

# In[33]:

from sklearn.linear_model import LinearRegression
linear_reg = LinearRegression()
linear_reg_predictions = ml_test(input_data, linear_reg,ml_years[5:], features)
linear_reg_score = scores(linear_reg_predictions)
print(linear_reg_score)
#Linear regression training on 5 years and testing on 21 years produced an accuracy of 0.52 same as ridge regression

# In[38]:

linear_reg_predictions_ten = ml_test(input_data, linear_reg,ml_years[10:], features)
linear_reg_score_ten = scores(linear_reg_predictions_ten)
print(linear_reg_score_ten)
#Linear regression training on 10 years and testing on 16 years produced an accuracy of 0.625 same as ridge regression

# In[39]:

from sklearn.ensemble import RandomForestRegressor
rf = RandomForestRegressor(n_estimators = 50, random_state=1, min_samples_split=4)
rf_all_predictions = ml_test(input_data, rf,ml_years[5:], features)

rf_score = scores(rf_all_predictions)
print(rf_score)
print(rf_all_predictions)

# random forest regression with the above parameters training on 5 years and testing on 10 years produce an accuracy of 0.67

# In[46]:

rf_all_predictions_ten = ml_test(input_data, rf,ml_years[10:], features)

rf_score_ten = scores(rf_all_predictions_ten)
print(rf_score_ten)
# random forest regression with the above parameters training on 10 years and testing on 21 years produce an accuracy of 0.69

# In[40]:

from sklearn.model_selection import RandomizedSearchCV
import numpy as np

n_estimators = [int(x) for x in range(50,1050,50)]

max_features = ['auto', 'sqrt']

max_depth = [int(x) for x in range(10, 110, 10)]
max_depth.append(None)
print(max_depth)
min_samples_split = [2, 5, 10]
min_samples_leaf = [1, 2, 4]
bootstrap = [True, False]

random_grid = {'n_estimators': n_estimators,
               'max_features': max_features,
               'max_depth': max_depth,
               'min_samples_split': min_samples_split,
               'min_samples_leaf': min_samples_leaf,
               'bootstrap': bootstrap}

# In[41]:

rf_random = RandomizedSearchCV(estimator=rf, param_distributions=random_grid,
                              n_iter = 100, scoring='neg_mean_absolute_error',
                              cv = 3, verbose=2, random_state=42, n_jobs=-1,
                              return_train_score=True)

rf_random.fit(train[features], train["Share"])
rf_random.best_params_

# In[43]:

rf_parameter_tuned = RandomForestRegressor(n_estimators = 100, min_samples_split = 2, min_samples_leaf = 2, max_features = 'auto', max_depth = 50, bootstrap = True)
rf_parameter_tuned_predictions = ml_test(input_data, rf_parameter_tuned,ml_years[5:], features)

rf_parameter_tuned_score = scores(rf_parameter_tuned_predictions)
print(rf_parameter_tuned_score)

#Hyper parameter tuned random forest regressor training for 5 years and testing for 21 makes accurary 67% - no improvement in accuracy

# In[44]:

from sklearn.ensemble import RandomForestRegressor
rf_parameter_tuned = RandomForestRegressor(n_estimators = 100, min_samples_split = 2, min_samples_leaf = 2, max_features = 'auto', max_depth = 50, bootstrap = True)
rf_parameter_tuned_predictions_ten = ml_test(input_data, rf_parameter_tuned, ml_years[10:], features)

rf_parameter_tuned_score_ten = scores(rf_parameter_tuned_predictions_ten)
print(rf_parameter_tuned_score_ten)

#Hyper parameter tuned random forest regressor training for 10 years and testing for 16 makes accurary 75%

# In[11]:

from sklearn.svm import SVR
svm_classifier = SVR()
svm_all_predictions = ml_test(input_data, svm_classifier,ml_years[5:], features)

svm_score = scores(svm_all_predictions)
print(svm_score)
print(svm_all_predictions)
# Support vector regression testing on 5 years and testing on 21 gives an accuracy of 0.52

# In[48]:

svm_all_predictions_ten = ml_test(input_data, svm_classifier,ml_years[10:], features)

svm_score_ten = scores(svm_all_predictions_ten)
print(svm_score_ten)

# Support vector regression testing on 10 years and testing on 16 gives an accuracy of 0.63

# In[ ]:

from sklearn.model_selection import GridSearchCV
param_grid = {'C': [0.1,1, 20, 50], 'epsilon': [1,0.1,0.01,0.001],'kernel': ['rbf', 'poly', 'sigmoid']}
grid = GridSearchCV(svm_classifier,param_grid, return_train_score=True)

grid.fit(train[features], train["Share"])
grid.best_params_

# In[12]:

svm_tuned_regressor = SVR(C=50,epsilon=.001,kernel="rbf")
svm_tuned_all_predictions = ml_test(input_data, svm_tuned_regressor,ml_years[5:], features)

svm_tuned_score = scores(svm_tuned_all_predictions)
print(svm_tuned_score)
print(svm_tuned_all_predictions)
# Hyperparameter Tuned support vector regression testing on 5 years and testing on 21 gives an accuracy of 0.57

# In[13]:

svm_tuned_all_predictions_ten = ml_test(input_data, svm_tuned_regressor,ml_years[10:], features)

svm_tuned_score_ten = scores(svm_tuned_all_predictions_ten)
print(svm_tuned_score_ten)
# Hyperparameter Tuned support vector regression testing on 5 years and testing on 21 gives an accuracy of 0.56
# this is interesting

# In[14]:

from sklearn.tree import DecisionTreeRegressor

decision_tree = DecisionTreeRegressor()
decision_tree_predictions = ml_test(input_data, decision_tree,ml_years[5:], features)

decision_tree_score = scores(decision_tree_predictions)
print(decision_tree_score)
print(decision_tree_predictions)
# Decision Tree regression training on 5 years testing on 21 produces accuracy of 0.47

# In[16]:

decision_tree_predictions_ten = ml_test(input_data, decision_tree,ml_years[10:], features)

decision_tree_score_ten = scores(decision_tree_predictions_ten)
print(decision_tree_score_ten)
# Decision Tree regression training on 10 years testing on 16 produces accuracy of 0.44
# Lower then training on 5 years

# In[17]:

from sklearn.neighbors import KNeighborsRegressor
k_neighbors = KNeighborsRegressor()

k_neighbors_predictions = ml_test(input_data, k_neighbors,ml_years[5:], features)

k_neighbors_score = scores(k_neighbors_predictions)
print(k_neighbors_score)
print(k_neighbors_predictions)
# k_nearest neighbors regression training for 5 years and testing for 21 produces 0.38 accuracy

# In[18]:

k_neighbors_predictions_ten = ml_test(input_data, k_neighbors,ml_years[10:], features)

k_neighbors_score_ten = scores(k_neighbors_predictions_ten)
print(k_neighbors_score_ten)
# k_nearest neighbors regression training for 10 years and testing for 16 produces 0.44 accuracy

# In[ ]:

#Highest accuracy model is hyper parameter tuned random forest regressor training for 10 years and testing for 16 with accurary 75%

NBA MVP Machine Learning Regression Model.py