import datetime
import math
import sys

import numpy as np
import pandas as pd
from sklearn.linear_model import Ridge
import matplotlib.pyplot as plot
from sklearn.metrics import r2_score, mean_squared_error
from sklearn.model_selection import train_test_split, KFold
from sklearn.neighbors import KNeighborsRegressor

# Extract the required data

data = pd.read_csv("../data/dublinbikes_data.csv", usecols=[1, 3, 6], parse_dates=[1])
# UPPER SHERRARD STREET | HANOVER QUAY
df = data[data.NAME == str('HANOVER QUAY')].drop(columns=["NAME"])
print(df.columns)
# Get time difference between records
date_col = pd.DatetimeIndex(df.TIME).view(int) / 10 ** 9
time_diff = date_col[1] - date_col[0]

print(time_diff)

# Extract data between 28th January and March 14
df = df[((pd.DatetimeIndex(df.TIME) > datetime.datetime(2020, 1, 28)) &
         (pd.DatetimeIndex(df.TIME) < datetime.datetime(2020, 3, 14)))]

df = df[((pd.DatetimeIndex(df.TIME).dayofweek != 5) & (pd.DatetimeIndex(df.TIME).dayofweek != 6))]
# Extract the required columns
y = df["AVAILABLE BIKES"]
# y = df["TIME"]

q = 10
lag_weekly = 2
# Find length of feature vector
weekly_len = math.floor(5 * 24 * 60 * 60 / time_diff)
print("Weekly len is:", weekly_len)
q_in_steps = int(q * 60 / time_diff)
length = len(y) - lag_weekly * weekly_len - q_in_steps

X = y[q_in_steps: int(q_in_steps + length)]

for i in range(1, lag_weekly):
    temp = y[q_in_steps + i * weekly_len: int(q_in_steps + i * weekly_len + length)]
    X = np.column_stack((X, temp))

lag_daily = 1
daily_len = math.floor(24 * 60 * 60 / time_diff)

for i in range(lag_daily, 0, -1):
    temp = y[q_in_steps + lag_weekly * weekly_len - i * daily_len: int(
        q_in_steps + lag_weekly * weekly_len - i * daily_len + length)]
    X = np.column_stack((X, temp))

lag = 1
for i in range(lag - 1, -1, -1):
    temp = y[lag_weekly * weekly_len - i * 3: int(lag_weekly * weekly_len - i * 3 + length)]
    X = np.column_stack((X, temp))

yy = y[q_in_steps + lag_weekly * weekly_len: int(q_in_steps + lag_weekly * weekly_len + length)].to_numpy()
np.set_printoptions(threshold=sys.maxsize)

XX = X
w_l = math.floor(7 * 24 * 60 * 60 / time_diff)
l = len(y) - lag_weekly * 7 - q_in_steps

# getting the date series
temp_date_col = pd.DatetimeIndex(df.TIME).view(int) / 10 ** 9

date_range_in_days = (temp_date_col[
                      q_in_steps + lag_weekly * weekly_len: int(q_in_steps + lag_weekly * weekly_len + l)] -
                      temp_date_col[q_in_steps + lag_weekly * weekly_len]) / (24 * 60 * 60)

# Cross validation to find k
mean_error = []
std_error = []
k_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

for k in k_array:
    temp_error = []
    kf = KFold(n_splits=5)
    for train, test in kf.split(XX):
        model = KNeighborsRegressor(n_neighbors=k).fit(XX[train], yy[train])
        y_pred = model.predict(XX[test])
        temp_error.append(mean_squared_error(y_true=yy[test], y_pred=y_pred))
    mean_error.append(np.mean(temp_error))
    std_error.append(np.std(temp_error))
print(mean_error)
plot.errorbar(k_array, mean_error, std_error)
plot.xlabel("Number of Neighbours(k)")
plot.ylabel("Mean Square Error")
plot.show()

# Cross Validation to find gama
gamma_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

mean_error_gamma = []
std_error_gamma = []
for gamma in gamma_array:
    temp_error = []
    kf = KFold(n_splits=5)

    def kernel(d):
        w = np.exp(-d ** 2 / gamma)
        return w

    for train, test in kf.split(XX):
        model = KNeighborsRegressor(n_neighbors=8, weights=kernel).fit(XX[train], yy[train])
        y_pred = model.predict(XX[test])
        temp_error.append(mean_squared_error(y_true=yy[test], y_pred=y_pred))
    mean_error_gamma.append(np.mean(temp_error))
    std_error_gamma.append(np.std(temp_error))

print(mean_error_gamma)
plot.errorbar(gamma_array, mean_error_gamma, std_error_gamma)
plot.xlabel("Gamma")
plot.ylabel("Mean Square Error")
plot.show()

def kernel(d):
    gamma = 7
    w = np.exp(-d ** 2 / gamma)
    return w

# Final Predictions
train, test = train_test_split(np.arange(0, yy.size), test_size=0.2)
model = KNeighborsRegressor(n_neighbors=8, weights=kernel).fit(XX[train], yy[train])
# model = KNeighborsRegressor(n_neighbors=5, weights='uniform').fit(XX[train], yy[train])
y_pred = model.predict(XX[test])
print(r2_score(y_true=yy[test], y_pred=y_pred))
print(mean_squared_error(y_true=yy[test], y_pred=y_pred))

y_pred_full = model.predict(XX)

plot.scatter(date_range_in_days, yy, color="blue")
plot.scatter(date_range_in_days, y_pred_full, color="red")
# Baseline Performance
print("=========================================================================")
print(r2_score(y_true=yy[test], y_pred=X[test][:, 3]))
print(mean_squared_error(y_true=yy[test], y_pred=X[test][:, 3]))
plot.show()


"""Common functions and classes."""
import os
import datetime
import time
import json
import yaml
import sqlite3

CODES = {'CancelledError': 0,  # can appear and this is in normal
         # all below exceptions should not appear, try to decrease load then:
         'ServerDisconnectedError': -1,
         'ClientOSError': -2,
         }

def get_timestamp():
    return time.time()

def timestamp2str(fmt):
    return datetime.datetime.now().strftime(fmt)

def log_timestamp_str():
    return timestamp2str('[%Y-%m-%d %H:%M:%S.%f]')

def generate_test_run_id():
    return timestamp2str('%Y-%m-%d_%H-%M-%S_%f')

def get_last_logs(lines):
    return '\n'.join([line.replace('"', '') for line in lines if 'HTTP/1.1 200' not in line][-10:])

def load_testrun_data(file_name):
    """Test run load is described in a json file <test_run_title>.json.
    A function reads the json file and returns a Python dictionary.
    """
    load = {}
    if os.path.isfile(file_name):
        with open(file_name, 'r+') as _f:
            load = json.loads(_f.read())
    return load

def load_conf(file_name='conf.yaml'):
    """A function reads slaves configuration from a YAML-file stored on master in app folder."""
    hosts = []
    if os.path.isfile(file_name):
        with open(file_name, 'r+') as _f:
            hosts = yaml.load(_f.read())['hosts']
    return hosts

def save_conf(hosts, file_name='conf.yaml'):
    """A function (re)writes slaves configuration in a YAML-file stored on master in app folder."""
    with open(file_name, 'w+') as _f:
       _f.write(yaml.safe_dump({'hosts': hosts}, default_flow_style=False))
    return True

def load_users(file_name='users.txt', folder=None):
    """A function reads users ids from a txt-file stored on master in app/engine folder."""
    lines = []
    folder = folder or os.path.dirname(os.path.abspath(__file__))
    file_name = os.path.join(folder, file_name)
    if os.path.isfile(file_name):
        with open(file_name, 'r') as _f:
            lines = _f.readlines()
    users = list(set([line.strip() for line in lines if line.strip()]))
    if len(lines) != len(users):
        with open(file_name, 'w') as _f:
            _f.write('\n'.join(users))
    return users

def get_db_conn(file_name, folder=None):
    folder = folder or os.path.dirname(os.path.abspath(__file__))
    db = os.path.join(folder, file_name)
    db_conn = sqlite3.connect(db)
    return db_conn

def db_init(db_conn):
    sqls = ['''CREATE TABLE IF NOT EXISTS recs (\
                             id INTEGER PRIMARY KEY, \
                             atomic BOOLEAN default 1, \
                             timestamp TEXT, \
                             action TEXT, \
                             user TEXT, \
                             latency TEXT default NULL, \
                             code INTEGER default NULL, \
                             reason TEXT default NULL);''',
            '''CREATE TABLE IF NOT EXISTS info (\
                             id INTEGER PRIMARY KEY, \
                             test_run_id TEXT NOT NULL, \
                             test_run_status TEXT default 'IN PROGRESS',
                             slave_name TEXT NOT NULL, \
                             timestamp_started TEXT NOT NULL, \
                             timestamp_completed TEXT, \
                             total_load_info TEXT,
                             slave_load_info TEXT);''',
            'DELETE FROM recs;',
            'DELETE FROM info;']
    for sql in sqls:
        db_conn.execute(sql)
    db_conn.commit()
    return True

def db_query(db_conn, sql):
    cur = db_conn.cursor()
    try:
        cur.execute(sql)
        db_conn.commit()
        return cur.lastrowid, cur.fetchall()
    except Exception as err:
        print('ERROR DB: %s' % err)
        return 0, []

def log_sql(func):  # to be applied only to act() methods of classes inherited from Action()
    async def wrapper(*args):
        timestamp = get_timestamp()
        sql = "INSERT INTO recs (atomic, timestamp, action, user) VALUES (0, '%s', '%s', '%s')" \
              % (timestamp, args[0].action, args[0].user)
        row_id = db_query(args[0].conn, sql)[0]  # args[0] is an instance of Action
        code, reason = await func(*args)
        sql = "UPDATE recs SET latency='%s', code=%d, reason='%s' WHERE id=%s" \
              % (get_timestamp() - timestamp, code, reason, row_id)
        db_query(args[0].conn, sql)
        return code, reason
    return wrapper

class LogSQL(object):
    """A class used for logging in atomic_get/atomic_post methods of Action-based classes."""
    def __init__(self, conn, action, user):
        self.conn = conn
        self.action = action
        self.user = user
        self.row_id = None  # id of a row in the database (each request is kept in one row)
        self.code = None    # response code of the atomic HTTP request
        self.reason = None  # returned reason of the atomic HTTP request
        self.timestamp = get_timestamp()

    def __enter__(self):
        sql = "INSERT INTO recs (timestamp, action, user) VALUES ('%s', '%s', '%s')" \
              % (self.timestamp, self.action, self.user)
        self.row_id = db_query(self.conn, sql)[0]
        return self

    def __exit__(self, type, value, traceback):
        sql = "UPDATE recs SET latency='%s', code=%d, reason='%s' WHERE id=%s" \
              % (get_timestamp() - self.timestamp, self.code, self.reason, self.row_id)
        db_query(self.conn, sql)
        return False


# Write a Python function that takes a list and returns a new list with unique elements of the first list.

def unique_element(old):
    new_list =[]
    for element in old:
        if old.count(element) == 1:
            new_list.append(element)
    print(new_list)
    return new_list

list = []
print("Enter total numbers you want to input in your list : ")
n = int(input())
print("Enter numbers")
for i in range(n):
    x = int(input())
    list.append(x)
out = unique_element(list)
print("The list with unique element is : ",out)


from collections import defaultdict
from index_map import IndexMap
import utils
from trie import Trie
from queue import Queue
import numpy as np
import argparse
import time

class LM:
  """Represents the main entry point of the language model"""

  def __init__(self, data_train, vocabs_file=None):

    self.data_train = data_train

    self.corpus = IndexMap()
    if vocabs_file:
      self.vocabs = IndexMap(vocabs_file)

    self.running_wrds_num = 0
    self.sent_num = 0
    self.sent_len_sum = 0
    self.sent_len_to_freq = defaultdict(int)
    self.prepare_lm()
    self.avg_sent_len = (1.0 * self.sent_len_sum)/self.sent_num

    self.unk_cnt = 0
    self.oov = 0.0 # out-of-vocabulary rate

    # NOTE: The purpose of creating this dict of roots is only
    # for the following experiment: Comparing the computation of bigrams
    # and unigrams probs using trigram counts vs the computation of bigrams
    # and unigrams probs using their own tries. You should not create multiple
    # trie trees usually since you have prefix information

    self.ngrams_root = {} # contains the root of (key)-gram trie

    self.b = {} # contain b discounting params of (gram_rank -> b)

  def prepare_lm(self):
    """Prepare the language model for analysis and computations"""

    print('Reading corpus for analysis...')

    with open(self.data_train, 'r') as read_corpus:
      for line in read_corpus:
        words = line.strip().split(' ')
        sent_len = len(words)
        self.sent_len_sum += sent_len
        self.sent_len_to_freq[sent_len] += 1
        self.sent_num += 1
        for wrd in words:
          self.corpus.add_wrd(wrd)
          self.running_wrds_num += 1

  ################################ Ex1 (a)-(b)-(c) ################################

  def show_corpus_analysis(self):
    """Show corpus data analysis"""

    print('Size of vocabulary: %d' % self.vocabs.get_num_of_words())
    print('Number of running words: %d' % self.running_wrds_num)
    print('Number of sentences: %d' % self.sent_num)
    print('Average sentence length: %.2f' % self.avg_sent_len)

    utils.plot_kv_iterable(self.sent_len_to_freq,
                           xlabel='Sentence length',
                           ylabel='Frequency',
                           xticks=5)

  ################################ Ex2 (a) ################################

  def get_word_freq_dict(self):
    """Return a dict where key is a word and value is it's frequency

      It transforms the wrd_freq dict from index-based key to word-based key
      so that it can be used for retrieving the top k frequent words

    :return: A dict, word to freq mapping
    """

    res = {}
    for idx, freq in self.corpus.get_wrd_freq_items():
      wrd = self.corpus.get_wrd_by_idx(idx)
      res[wrd] = freq
    return res

  @staticmethod
  def get_top_10_freq_words(res):
    """Return the top 10 frequent words

    :return: A list, top 10 frequent words
    """

    return utils.get_top_k_freq_items(res, k=10)

  ############################# Ex2 (b)-(c)-(d)-(e) ####################################

  def get_corpus_tokens(self, vocabulary):
    """Read corpus and store the tokens in a list

    If with_unk is True, then unk_cnt is used to store the number
    of OOV words to compute it's rate later

    :param vocabulary: IndexMap, either corpus or vocabs
    :return: A list of word tokens with start and end symbols
    """

    tokens = []
    start_id = vocabulary.get_start_id()
    end_id = vocabulary.get_end_id()
    unk_id = vocabulary.get_unk_id()
    with open(self.data_train, 'r') as read_corpus:
      for line in read_corpus:
        sent = line.strip().split(' ')
        tokens.append(start_id)
        for wrd in sent:
          idx = vocabulary.get_idx_by_wrd(wrd)
          if idx == unk_id:
            self.unk_cnt += 1
          tokens.append(idx)
        tokens.append(end_id)
    return tokens

  def generate_ngrams(self, n, vocabulary):
    """Generate ngrams from the given vocabulary (corpus or vocabs)
       and store them in a Trie data structure

    :param n: An integer, the rank of the grams that are generated
    :param vocabulary: An IndexMap, either corpus or vocabs
    :return: A Trie representing the ngrams
    """

    start_id = vocabulary.get_start_id()
    end_id = vocabulary.get_end_id()
    unk_id = vocabulary.get_unk_id()

    print('Generating %d-grams from %s' % (n, 'corpus' if vocabulary == self.corpus else 'vocabulary'))

    self.ngrams_root[n] = Trie()
    with open(self.data_train, 'r') as read_corpus:
      for line in read_corpus:
        sent = line.strip().split(' ')
        ngram = [start_id]
        for wrd in sent:
          if len(ngram) == n:
            self.ngrams_root[n].add_ngram(ngram)
            ngram = ngram[1:]
          idx = vocabulary.get_idx_by_wrd(wrd)
          if idx == unk_id:
            self.unk_cnt += 1
          ngram.append(idx)
        if len(ngram) == n:
          self.ngrams_root[n].add_ngram(ngram)
          ngram = ngram[1:]
        ngram.append(end_id)
        self.ngrams_root[n].add_ngram(ngram)

    print('%d-grams are now stored in a Trie' % n)

    if vocabulary != self.corpus:
      self.oov = (self.unk_cnt / self.running_wrds_num) * 100.0
      print('OOV rate: %.02f %%' % self.oov)

  def extract_ngrams_and_freq(self, n, vocabulary):
    """Extract ngrams and their frequencies, display top 10 frequent ngrams,
      plot the count of counts distribution

    :param n: An integer, the rank of the gram
    :param vocabulary: An indexMap, either corpus or vocabs
    """

    if n not in self.ngrams_root:
      self.generate_ngrams(n, vocabulary)

    print('Extracting %d-grams with their frequencies using %s' % \
          (n, 'corpus' if vocabulary == self.corpus else 'vocabulary'))

    res = self.ngrams_root[n].bfs(n)

    print('Extraction is done.')

    if n not in self.b:
      self.compute_b(n, vocabulary=self.corpus)
      print('Discounting parameters:')
      for k, v in self.b.items():
        print('b_{} = {}'.format(k, v))

    return res

  def get_top_10_ngram_freq(self, n, vocabulary):
    """Return the top 10 frequent ngrams

    :param res: A dict, keys are ngrams and values are counts
    :return: A list of top 10 frequent ngrams
    """

    top_10_ngrams = utils.get_top_k_freq_items(self.extract_ngrams_and_freq(n, vocabulary), k=10)

    # map to words
    res = []
    for kv in top_10_ngrams:
      ngram_wrds = []
      for idx in kv[0]:
        ngram_wrds.append(vocabulary.get_wrd_by_idx(idx))
      res.append((ngram_wrds, kv[1]))
    return res

  ############################# Ex3 ####################################

  def get_summed_counts(self, n, vocabulary):
    """Calculate bi-/uni- grams from trigrams and compare to directly extracted bi-/uni- grams

    :param n: An integer, the rank of the source n-gram
    :param vocabulary: An indexMap, either corpus or vocabs
    """

    assert n >= 3, 'n should be at least 3'

    res_trigram = self.extract_ngrams_and_freq(n, vocabulary)
    res_bi = self.extract_ngrams_and_freq(n-1, vocabulary)
    res_uni = self.extract_ngrams_and_freq(n-2, vocabulary)

    summed_bigrams = defaultdict(int)
    summed_unigrams = defaultdict(int)

    for k, v in res_trigram.items():
      summed_bigrams[k[1:]] += v
      summed_unigrams[k[-1]] += v

    print("bigram difference: ")
    for k, v in res_bi.items():
      if v != summed_bigrams[k]:
        print("bigram: {} extracted value: {} summed value: {}".format(k, v ,summed_bigrams[k]))

    print("unigram difference: ")
    for k, v in res_uni.items():
      if v != summed_unigrams[k]:
        print("unigram: {} extracted value: {} summed value: {}".format(k, v, summed_unigrams[k]))

  ########################### Ex4 ##################################

  def compute_b(self, n, vocabulary):
    """Computes the discounting parameters for up to n-gram
       e.g if n = 2, then it will compute b_uni, and b_bi

    :param n: An integer, the rank of gram
    :param vocabulary: An IndexMap, either corpus or vocabs
    """

    if n in self.b: return

    print('Computing discounting parameters...')

    # ngrams are not added to the trie yet
    if n not in self.ngrams_root:
      self.generate_ngrams(n, vocabulary)

    q = Queue()
    q.put(self.ngrams_root[n]) # add root
    for i in range(n):
      singeltons = 0
      doubletons = 0
      next_q = Queue()
      while not q.empty():
        u = q.get()
        for idx, child in u.get_children().items():
          next_q.put(child)
          if child.get_freq() == 1:
            singeltons += 1
          elif child.get_freq() == 2:
            doubletons += 1
      self.b[i+1] = (singeltons/(singeltons + 2.0 * doubletons))
      q = next_q

  def compute_prob(self, w, h, n):
    """Computes the bigram probability p(w|h) using absolute discounting with
       interpolation where h is word history

    :param w: An integer, the index of word w
    :param h: A list containing the indexes of word history
    :param n: An integer, the rank of the grams
    :return: A float, p(w|h)
    """

    # backoff to unigram (base case)
    if len(h) == 0:
      prob = self.b[1]
      prob *= self.ngrams_root[n].get_num_of_children() # W - N_0(.)
      prob /= float(self.vocabs.get_num_of_words() * self.ngrams_root[n].get_freq()) # W * N

      w_node = self.ngrams_root[n].get_ngram_last_node([w])
      if w_node is not None:
        w_freq = w_node.get_freq()
        prob += max(float(w_freq - self.b[1]) / self.ngrams_root[n].get_freq(), 0.0)

      return prob

    h_node = self.ngrams_root[n].get_ngram_last_node(h)

    # history is not found so backoff
    if h_node is None:
      return self.compute_prob(w, h[1:], n)

    prob = self.b[len(h)+1]
    prob *= float(h_node.get_num_of_children()) / h_node.get_freq() # (W - N_0(v,.))/N(v)
    prob *= self.compute_prob(w, h[1:], n) # recursively backoff

    # add the first term of the interpolation
    w_node = h_node.get_ngram_last_node([w])
    if w_node is not None:
      w_h_freq = w_node.get_freq()
      prob += max(float(w_h_freq - self.b[len(h)+1]) / h_node.get_freq(), 0.0)

    return prob

  def verify_normalization(self, n):
    """Verify the normalization of bigram and unigram probabilities

    :return: True if the probabilities are normalized and False otherwise
    """

    print('Verifying probability normalization...')

    bigram_probs = 0.0
    unigram_probs = 0.0
    for w in range(0, self.vocabs.get_num_of_words()):
      bigram_probs += self.compute_prob(w, [10], n) # any word for history
      unigram_probs += self.compute_prob(w, [], n)

    print('bigram_probs: {}, unigram_probs: {}'.format(bigram_probs, unigram_probs))
    return abs(1.0 - bigram_probs) <= 1e-02 and abs(1.0 - unigram_probs) <= 1e-02

  ########################### Ex5 ##################################

  def perplexity(self, corpus_file, n):
    """Compute the perplexity of the language model on the given corpus
       using n-grams

    :param corpus_file: A string, the path of the corpus
    :param n: An integer, the rank of the grams to be used for computing PP
    :return: A float, perplexity of the LM
    """

    print('Computing model perplexity...')

    LL = 0.0
    norm = 0
    with open(corpus_file, 'r') as test_corpus:
      for line in test_corpus:
        sent = line.strip().split()
        h = [self.corpus.get_start_id()]
        for wrd in sent:
          w = self.corpus.get_idx_by_wrd(wrd)
          if len(h) == n-1:
            prob = self.compute_prob(w, h, n)
            LL += np.log(prob)
            h.append(w)
            h = h[1:]
          else:
            h.append(w)
        LL += np.log(self.compute_prob(self.corpus.get_end_id(), h, n))
        norm += len(sent)+1
    return np.exp(-LL/norm)

#######################################################################

if __name__ == '__main__':
  parser = argparse.ArgumentParser()

  parser.add_argument('--train_file', type=str, default='./data/train.corpus',
                      help='training data path')
  parser.add_argument('--vocab_file', type=str, default='./data/vocabulary',
                      help='vocabulary file path')
  parser.add_argument('--test_file', type=str, default='./data/test.corpus',
                      help='test file.')
  parser.add_argument('--gram_rank', type=int, default=2,
                      help='e.g 2 for bigram')

  args = parser.parse_args()

  start = time.time()

  lm = LM(args.train_file, args.vocab_file)
  lm.extract_ngrams_and_freq(n=args.gram_rank, vocabulary=lm.corpus)
  # if lm.verify_normalization(args.gram_rank):
  #   print('Probabilities are normalized!')
  # else:
  #   print('Probabilities are not normalized!')
  print('Test PP: {}'.format(lm.perplexity(corpus_file=args.test_file, n=args.gram_rank)))
  print('Execution time: %.3f min' % ((time.time()-start)/60))


from AST import *
from Visitor import *
from Utils import Utils
from StaticError import *
from dataclasses import dataclass

class Raiser:
    def __init__(self, e: Exception):
        raise e

@dataclass
class Symbol:
    pass

class StaticChecker(BaseVisitor, Utils):

    def __init__(self, ast):
        self.ast = ast

    def check(self):
        self.visit(self.ast, None)

    def visitProgram(self, ctx: Program, o):
        o = []
        exp = ctx.exp
        decl_list = ctx.decl
        for decl in decl_list:
            self.visit(decl, o)
        self.visit(exp, o)

    def visitVarDecl(self, ctx: VarDecl, o):
        o.append(ctx)

    def visitBinOp(self, ctx: BinOp, o):
        left = ctx.e1
        right = ctx.e2
        literals = [BoolType, FloatType, IntType]
        # recursive left & right till it become literals
        while not (type(left) in literals):
            left = self.visit(left, o)
        while not (type(right) in literals):
            right = self.visit(right, o)

        if (ctx.op in ["+", "-", "*"]):
            # Check TypeMismatchInExpression
            if (not (type(left) in [FloatType, IntType])) or (not (type(right) in [FloatType, IntType])):
                raise TypeMismatchInExpression(ctx)
            # Output
            if (type(left) is FloatType or type(right) is FloatType):
                return FloatType()
            return IntType()

        elif (ctx.op in ["/"]):
            # Check TypeMismatchInExpression
            if (not (type(left) in [FloatType, IntType])) or (not (type(right) in [FloatType, IntType])):
                raise TypeMismatchInExpression(ctx)
            # Output
            return FloatType()

        elif (ctx.op in ['&&', '||']):
            # Check TypeMismatchInExpression
            if (not (type(left) in [BoolType])) or (not (type(right) in [BoolType])):
                raise TypeMismatchInExpression(ctx)
            # Output
            return BoolType()

        elif (ctx.op in ["<", '>', '==', '!=']):
            # Check TypeMismatchInExpression
            if (not (type(left) is type(right))):
                raise TypeMismatchInExpression(ctx)
            # Output
            return BoolType()

    def visitUnOp(self, ctx: UnOp, o):
        val = ctx.e
        literals = [BoolType, FloatType, IntType]
        # recursive left & right till it become literals
        while not (type(val) in literals):
            val = self.visit(val, o)

        if (ctx.op in ['!']):
            # Check TypeMismatchInExpression
            if (not (type(val) in [BoolType])):
                raise TypeMismatchInExpression(ctx)
            # Output
            return BoolType()
        elif (ctx.op in ["-"]):
            # Check TypeMismatchInExpression
            if (not (type(val) in [FloatType, IntType])):
                raise TypeMismatchInExpression(ctx)
            # Output
            if (type(val) is FloatType):
                return FloatType()
            return IntType()

    def visitIntLit(self, ctx: IntLit, o):
        return IntType()

    def visitFloatLit(self, ctx, o):
        return FloatType()

    def visitBoolLit(self, ctx, o):
        return BoolType()

    def visitId(self, ctx, o):
        if not ([el.typ for el in o if ctx.name == el.name]):
            raise UndeclaredIdentifier(ctx.name)
        for el in o:
            if ctx.name == el.name:
                return el.typ


import datetime

from libcloud import __version__ as libcloud_version
from libcloud.dns.types import RecordType

from libcloud_to_bind.utils import get_record_id

__version__ = '0.1.0'
__all__ = [
    '__version__',
    'libcloud_zone_to_bind_zone_file'
]

def get_record_line(record):
    parts = []

    if record.name:
        name = '%(name)s.%(domain)s' % {'name': record.name,
                                        'domain': record.zone.domain}
    else:
        name = record.zone.domain

    name += '.'

    ttl = record.extra['ttl'] if 'ttl' in record.extra else record.zone.ttl
    ttl = str(ttl)
    record_type = RecordType.__repr__(record.type)
    data = record.data

    if record.type in [RecordType.CNAME, RecordType.DNAME, RecordType.MX,
                       RecordType.PTR, RecordType.SRV]:
        # Make sure trailing dot is present
        if data[len(data) - 1] != '.':
            data += '.'

    if record.type in [RecordType.TXT, RecordType.SPF] and ' ' in data:
        # Escape the quotes
        data = data.replace('"', '\\"')

        # Quote the string
        data = '"%s"' % (data)

    if record.type in [RecordType.MX, RecordType.SRV]:
        priority = str(record.extra['priority'])
        parts = [name, ttl, 'IN', record_type, priority, data]
    else:
        parts = [name, ttl, 'IN', record_type, data]

    line = '\t'.join(parts)
    return line

def libcloud_zone_to_bind_zone_file(zone):
    if zone.type != 'master':
        raise ValueError('You can only generate BIND file for master zones')

    lines = []

    # For consistent output, records are sorted based on the id
    records = zone.list_records()
    records = sorted(records, key=get_record_id)

    date = datetime.datetime.now().strftime('%Y-%m-%d %H:%m:%S')
    values = {'version': libcloud_version, 'date': date}

    lines.append('; Generated by Libcloud v%(version)s on %(date)s' % values)
    lines.append('$ORIGIN %(domain)s.' % {'domain': zone.domain})
    lines.append('$TTL %(domain_ttl)s\n' % {'domain_ttl': zone.ttl})

    for record in records:
        line = get_record_line(record=record)
        lines.append(line)

    output = '\n'.join(lines)
    return output


from flask import (Flask, g, render_template, flash, redirect, url_for, request, make_response, jsonify)
from flask.ext.login import (LoginManager, login_user, logout_user, login_required, current_user)
from flask.ext.bcrypt import check_password_hash
from blueprints.usuarios import usuarios
from blueprints.competencias import competencias
from blueprints.preguntas import preguntas
from blueprints.respuestas import respuestas
import models
from werkzeug import secure_filename
import os
import json
import ast
DEBUG = True
PORT = 5000
HOST = '127.0.0.1'
UPLOAD_FOLDER = os.path.dirname(os.path.abspath(__file__)) + '/static/media/uploads'
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.secret_key = 'niggersan'
app.register_blueprint(usuarios, url_prefix='/api/usuarios')
app.register_blueprint(competencias, url_prefix='/api/competencias')
app.register_blueprint(preguntas, url_prefix='/api/preguntas')
app.register_blueprint(respuestas, url_prefix='/api/respuestas')
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = '/'

@login_manager.user_loader
def cargar_usuario(usuarioid):
    try:
        return models.Usuario.get(models.Usuario.id == usuarioid)
    except models.DoesNotExist:
        return None

@app.before_request
def antes_request():
	"""Conectarse a la base de datos """
	g.db = models.DATABASE
	g.db.connect()
	g.user = current_user

@app.after_request
def despues_request(response):
	"""Cerrar la conexion despues de cada request"""
	g.db.close()
	return response

@app.route('/')
def main():
	usuario=g.user._get_current_object()
	#return make_response(open('templates/index.html').read())
	return render_template('index.html')

@app.route('/usuario')
@login_required
def get_usuario():
	return json.dumps(g.user._get_current_object().to_json())

####
####    seleccionar a los que te permitiran evaluarlos
####

@app.route('/seleccionar_colegas')
@login_required
def seleccionar_colegas():

	return render_template('seleccionar_colegas.html')

@app.route('/colegas')
@login_required
def colegas():
	usuarios = models.Usuario.select().where(
		(models.Usuario.puesto==g.user.puesto) &
		(models.Usuario.id != g.user.id) )
	colegas = list()
	for usuario in usuarios:
		colegas.append(usuario.to_json())
	return json.dumps(colegas)

@app.route('/get_colegas_evaluar')
@login_required
def get_colegas():
	evaluadores = models.Usuario.get(models.Usuario.id**g.user._get_current_object().id)
	colegas = list()
	for evaluador in evaluadores.evaluan():
		colegas.append(evaluador.to_json())
	return json.dumps(colegas)

@app.route('/get_subordinados')
@login_required
def get_subordinados():
	usuario = g.user._get_current_object()
	subordinados = list()
	for subordinado in usuario.subordinados():
		subordinados.append(subordinado.to_json())
	return json.dumps(subordinados)

@app.route('/get_superiores')
@login_required
def get_superiores():
	usuario = g.user._get_current_object()
	superiores = list()
	for superior in usuario.superiores():
		superiores.append(superior.to_json())
	return json.dumps(superiores)

@app.route('/puede_evaluarme', methods=['POST'])
@login_required
def puede_evaluarme():
	colega = request.get_json()
	get_modelo = models.Usuario.get(models.Usuario.nombre**colega['nombre'])
	models.PermisoEvaluar.create(
		evaluado=g.user._get_current_object(),
		evaluador=get_modelo
		)
	string = "{} ahora podra ser evaluada por {}".format(g.user.nombre, colega['nombre'])
	return json.dumps({'response': string})

@app.route('/numero_evaluadores')
@login_required
def numero_evaluadores():
	numero = models.PermisoEvaluar.select().where(models.PermisoEvaluar.evaluado==g.user._get_current_object()).count()
	ids = models.PermisoEvaluar.select().where(models.PermisoEvaluar.evaluado==g.user._get_current_object())

	lista_ids = list()
	for Id in ids:
		lista_ids.append(Id.evaluador.rpe)
	return json.dumps({
	                  "cantidad": numero,
	                  "seleccionados": lista_ids,
	                  })

@app.route('/evaluando', methods=['POST'])
@login_required
def evaluando():
	evaluacion = request.get_json()
	usuario = g.user._get_current_object()
	colega = models.Usuario.get(models.Usuario.nombre**evaluacion['colega']['nombre'])
	competencia = models.Competencias.get(models.Competencias.nombre**evaluacion['competencia']['nombre'])
	tipo = models.TipoCompetencia.get(models.TipoCompetencia.nombre**evaluacion['tipo'])
	models.Evaluando.nuevo(
		empleado=usuario,
		colega=colega,
		competencia=competencia,
		tipo=tipo
		)

	return json.dumps(
		{
		"response" : "{} evaluo a {} decidiendo que la competencia: {} es {}".format(
			usuario.nombre, colega.nombre, competencia.nombre, tipo.nombre)
		}
	)

@app.route('/evaluando_neutras', methods=['POST'])
@login_required
def evaluando_neutras():

	evaluacion = request.get_json()

	for competencia in evaluacion['competencias']:
		usuario = g.user._get_current_object()
		colega = models.Usuario.get(models.Usuario.nombre**evaluacion['colega']['nombre'])
		competencia = models.Competencias.get(models.Competencias.nombre**competencia['nombre'])
		tipo = models.TipoCompetencia.get(models.TipoCompetencia.nombre**'Neutras')

		models.Evaluando.nuevo(
			empleado=usuario,
			colega=colega,
			competencia=competencia,
			tipo=tipo

			)
	return "ok"

# @app.route('/nuevo', methods['POST'])
# def registrarUsuario():
# 	try:
# 		Usuario.nuevo(
# 	    	rpe=request.form['rpe'],
# 	    	nombre=request.form['nombre'],
# 	    	puesto=request.form['puesto'],
# 	    	departamento=request.form['departamento'],
# 	    	correo=request.form['correo'],
# 	    	zona=request.form['zona'])
# 		return "OK!", 200
# 	except:
# 		return "Error!", 404

@app.route('/iniciar_sesion', methods=['POST'])
def iniciar_sesion():
	print(request.form['correo'])
	usuario = models.Usuario.get(models.Usuario.correo**request.form['correo'])
	if request.form['password'] == usuario.rpe:
		session['login_user(usuario)']=True
		status= True
		return 'Login successfull'
	else:
		status = False
		return 'Login failed.'

@app.route('/get_competencias')
@login_required
def get_competencias():
	competencias = models.Competencias.select()
	lista_competencias = list()
	for competencia in competencias:
		lista_competencias.append(competencia.to_json())
	return json.dumps(lista_competencias)

@app.route('/get_competencias/existentes', methods=['POST'])
@login_required
def existentes():
	respuesta = list()
	resultados = list()
	peticion = request.get_json()
	empleado = g.user._get_current_object()
	tipo = models.TipoCompetencia.get(models.TipoCompetencia.nombre ** peticion['tipo'])
	colega = models.Usuario.get(models.Usuario.nombre**peticion['colega']['nombre'])
	evaluaciones = models.Evaluando.select().where(
	    (models.Evaluando.empleado == g.user._get_current_object()) &
		(models.Evaluando.colega == colega) &
		(models.Evaluando.tipo == tipo)
		)
	for evaluacion in evaluaciones:
		resultados.append(models.Competencias.get(models.Competencias.id**evaluacion.competencia))
	for resultado in resultados:
		respuesta.append(resultado.to_json())
	return json.dumps(respuesta)

@app.route('/get_competencias/inexistentes', methods=['POST'])
@login_required
def inexistentes():
	respuesta = list()
	resultados = list()
	peticion = request.get_json()
	empleado = g.user._get_current_object()
	tipo = models.TipoCompetencia.get(models.TipoCompetencia.nombre ** peticion['tipo'])
	colega = models.Usuario.get(models.Usuario.nombre**peticion['colega']['nombre'])
	evaluaciones = models.Evaluando.select().where(
	    (models.Evaluando.empleado == g.user._get_current_object()) &
		(models.Evaluando.colega == colega) &
		(models.Evaluando.tipo == tipo)
		)
	for evaluacion in evaluaciones:
		resultados.append(models.Competencias.get(models.Competencias.id**evaluacion.competencia))
	for resultado in resultados:
		respuesta.append(resultado.to_json())
	return json.dumps(respuesta)

@app.route('/get_competencias/neutras', methods=['POST'])
@login_required
def neutras():
	respuesta = list()
	resultados = list()
	peticion = request.get_json()
	existente = models.TipoCompetencia.get(models.TipoCompetencia.nombre ** 'Existentes')
	inexistente = models.TipoCompetencia.get(models.TipoCompetencia.nombre ** 'Inexistentes')

	colega = models.Usuario.get(models.Usuario.nombre**peticion['colega']['nombre'])
	evaluaciones_inexistentes = models.Evaluando.select().where(
	    (models.Evaluando.empleado == g.user._get_current_object()) &
		(models.Evaluando.colega == colega) &
		(models.Evaluando.tipo == inexistente)
		)
	evaluaciones_existentes = models.Evaluando.select().where(
	    (models.Evaluando.empleado == g.user._get_current_object()) &
		(models.Evaluando.colega == colega) &
		(models.Evaluando.tipo == existente)
		)
	for evaluacion in evaluaciones_existentes:
		resultados.append(models.Competencias.get(models.Competencias.id**evaluacion.competencia))

	for evaluacion in evaluaciones_inexistentes:
		resultados.append(models.Competencias.get(models.Competencias.id**evaluacion.competencia))

	for resultado in resultados:
		respuesta.append(resultado.to_json())

	return json.dumps(respuesta)

@app.route('/reportes')
@login_required
def reportes():
	competencias = models.Competencias.select()
	tipocompetencia = models.TipoCompetencia.select()
	datos = {
		"nombre" : g.user._get_current_object().nombre,
		"competencias": [
		{
			"nombre": competencia.nombre,
			"numero" : competencia.get_numero_por_usuario(g.user._get_current_object()),
			"tipo": [{
				"nombre": tipo.nombre,
				"numero": tipo.numero_tipo_competencia(competencia,g.user._get_current_object())
			} for tipo in tipocompetencia
			]
		} for competencia in competencias
		]
	}
	return json.dumps(datos)

@app.route('/get_preguntas', methods=['POST'])
@login_required
def get_preguntas():
	competencia =  models.Competencias.select().where(models.Competencias.nombre == request.get_json()['nombre']).get()
	return json.dumps(competencia.preguntas())

@app.route('/respuestas_preguntas', methods=['POST'])
@login_required
def respuestas_preguntas():
	print(request.form)
	return "ok"

if __name__ == '__main__':
	#models.drop()

	models.initialize()
	app.run(
    	debug=DEBUG,
    	port=PORT,
    	host=HOST
    )


class Solver:

    """
    Puzzle: Find the resulting number after adding/subtracing
    all numbers from input.txt together.
    """

    def __init__(self):
        self.frequency = 0

    def solve(self, input_file):
        for i in input_file:
            self.frequency += int(i)

if __name__ == "__main__":

    with open("input.txt") as f:
        input_file = f.readlines()

    solver = Solver()
    solver.solve(input_file)

    print("Resulting Frequency: {}".format(solver.frequency))


#!/bin/env python3

import sys

OPEN_SYMBOLS = '([{<'
CLOSE_SYMBOLS = ')]}>'

ERR_PTS = {
    ')' : 3,
    ']' : 57,
    '}' : 1197,
    '>' : 25137
}

ERR_MULTS = {
    ')': 1,
    ']': 2,
    '}': 3,
    '>': 4
}

def main():

    lines = sys.stdin.readlines()
    scores = []
    for i, line in enumerate(lines):
        stk = []
        for ch in line.strip():
            if ch in OPEN_SYMBOLS:
                idx = OPEN_SYMBOLS.index(ch)
                stk.append(CLOSE_SYMBOLS[idx])
            elif ch in CLOSE_SYMBOLS:
                if stk[-1] != ch:
                    break
                else:
                    stk.pop()
        else:
            score = 0
            for ch in reversed(stk):
                score *= 5
                score += ERR_MULTS[ch]

            print(f'line[{i}]: ', score)
            scores.append(score)

    scores.sort()
    idx = len(scores)//2

    print('middle score: ', scores[idx])

if __name__ == '__main__':
    main()


import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split
from lightgbm.sklearn import LGBMClassifier
import time
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import f1_score
import lightgbm as lgb
from mpl_toolkits.mplot3d import Axes3D
import logging
from sklearn.ensemble import IsolationForest

t = time.time()
logging.basicConfig(level=logging.INFO, filename='wuli.log',
                    filemode='a', format='%(asctime)s - %(name)s - %('
                                         'levelname)s - %(message)s')
logger = logging.getLogger(__name__)
logging.info('---------------New Training Start------------------')
train_df_source = pd.read_csv('C://Users//Lin//Desktop//PolyU//competition//turing_wuli//train.csv')
test_df_source = pd.read_csv('C://Users//Lin//Desktop//PolyU//competition//turing_wuli//test.csv')
event_df_source = pd.read_csv('C://Users//Lin//Desktop//PolyU//competition//turing_wuli//event.csv')

# flag 0: 0.370793 1: 0.629207
# test = df.groupby('flag').count()
# test = test['x'].apply(lambda x: x/test['x'].sum())

# 噪声数量比较稳定，真实信号数量随event_id变化较大
# test = df.groupby(['flag','event_id']).count()['x']
# test = df[df['flag']==0].groupby('event_id').count()['x']
# plt.plot(test)
# plt.show()

# # 把t加上合成三维坐标图，点的大小用q表示
# df_event = train_df_source[train_df_source['event_id']==18]
# fig = plt.figure()
# ax = Axes3D(fig)
# ax.scatter(df_event[df_event['flag']==1]['x'], df_event[df_event['flag']==1]['y'], df_event[df_event['flag']==1]['t'], c='r', s= df_event[df_event['flag']==1]['q'], label='signal')
# ax.scatter(df_event[df_event['flag']==0]['x'], df_event[df_event['flag']==0]['y'], df_event[df_event['flag']==0]['t'], c='g',s= df_event[df_event['flag']==0]['q'], label='noise')
# ax.legend(loc='best')
# ax.set_zlabel('Z', fontdict={'size': 15, 'color': 'red'})
# ax.set_ylabel('Y', fontdict={'size': 15, 'color': 'red'})
# ax.set_xlabel('X', fontdict={'size': 15, 'color': 'red'})
# plt.show()

print(
    '============================================== feature analysis ==============================================')

def f_ana(df):
    analysis = []
    for col in df.columns.values.tolist():
        analysis.append(df[col].min())
        analysis.append(df[col].max())
        analysis.append(df[col].mean())
        analysis.append(df[col].quantile(0.25))
        analysis.append(df[col].quantile(0.5))
        analysis.append(df[col].quantile(0.75))
        analysis.append(df[col].std())
    analysis = pd.DataFrame(np.array(analysis).reshape(df.shape[1], int(len(analysis) / df.shape[1])).T)
    analysis.columns = df.columns.values.tolist()
    analysis['index'] = ['min', 'max', 'mean', '1/4', '1/2', '3/4', 'std']
    analysis.set_index(["index"], inplace=True)
    return analysis

tmp = f_ana(train_df_source)
print('runtime:', time.time() - t)

print(
    '============================================== feature engineering ==============================================')

def get_stati_feature(df, col):
    for func in ['mean', 'quantile', 'skew', 'median', 'max', 'min', 'std']:
        dic = df[col].groupby(df['event_id']).agg(func).to_dict()
        col_name = col + '_' + func
        df[col_name] = df['event_id'].map(dic).values

def f_eng(df, event_df, is_train=True):
    df = pd.merge(df, event_df.loc[:, ['event_id', 'energymc', 'thetamc', 'phimc', 'xcmc', 'ycmc']], how='left',
                  on='event_id')
    # 当前hit和当前event统计值作差
    df['t_minus_terror'] = df['t'] - df['terror']
    df['t_plus_terror'] = df['t'] + df['terror']
    df['q_minus_mean'] = df['q'] - df['q'].groupby(df['event_id']).transform(np.mean)
    df['t_minus_mean'] = df['t'] - df['t'].groupby(df['event_id']).transform(np.mean)

    # 当前hit和当前事件触发hit的距离
    df['x_minus_xcmc'] = df['x'] - df['xcmc']
    df['y_minus_ycmc'] = df['y'] - df['ycmc']
    df['dis'] = np.sqrt(df['x_minus_xcmc'] ** 2 + df['y_minus_ycmc'] ** 2 )
    df['dis_3dim'] = np.sqrt(df['x_minus_xcmc'] ** 2 + df['y_minus_ycmc'] ** 2 + (df['t'] * 29.98*100) ** 2)

    # 按照公式，拟合簇射前峰面
    l = np.sin(df['thetamc']) * np.cos(df['phimc'])
    m = np.sin(df['thetamc']) * np.sin(df['phimc'])
    df['surface_fitting'] = df['t'] - (l * df['x'] + m * df['y'])/0.2998

    # 原初粒子的能量和次级粒子电量的比例关系，min-max数据标准化放大差距.q为负电荷全部都是信号，不知道什么原因
    df['q_divide_energymc'] = df['q'] / df['energymc']
    df['q_divide_energymc'] = (df['q_divide_energymc'] - df['q_divide_energymc'].min()) / (
                df['q_divide_energymc'].max() - df['q_divide_energymc'].min())

    # 测试后留下来的统计特征x_std, x_mean, x_skew, y_std, y_mean, y_skew, t_std, t_skew, q_quantile, q_min, q_skew, q_mean
    # get_stati_feature(df,'x')

    feature = ['x_std', 'x_mean', 'x_skew', 'y_std', 'y_mean', 'y_skew', 't_std', 't_skew', 'q_quantile', 'q_min',
               'q_skew', 'q_mean']
    for fea in feature:
        col = fea.split('_')[0]
        func = fea.split('_')[1]
        dic = df[col].groupby(df['event_id']).agg(func).to_dict()
        df[fea] = df['event_id'].map(dic).values

    if is_train:
        df = df.drop('flag', axis=1)
    df = df.drop(['hit_id', 'z', 'event_id'], axis=1)

    # # isolation forest先预测一下，预测结果作为一个特征输入
    # rng = np.random.RandomState(42)
    # clf = IsolationForest(behaviour='new', max_samples=100,
    #                       random_state=rng, contamination='auto')
    # clf.fit(df)
    # df['iso_pre'] = clf.decision_function(df)

    return df

labels = train_df_source['flag']
train_df = f_eng(train_df_source, event_df_source)

test_df = f_eng(test_df_source, event_df_source, False)


"""2022 KAKAO BLIND RECRUITMENT"""

from copy import deepcopy

tmp_answer = []
answer = []
apeach = 0
ryan = 0
score_diff = 0

def solution(n, info):
    def DFS(cnt, order):
        global ryan, apeach, score_diff, answer

        if order == 11:
            if cnt > 0:
                tmp_answer[-1] = cnt

            if score_diff < ryan - apeach:
                score_diff = ryan - apeach
                answer = deepcopy(tmp_answer)
            elif score_diff == ryan - apeach and len(answer) > 0:
                for i in range(10, -1, -1):
                    if tmp_answer[i] < answer[i]:
                        break
                    elif tmp_answer[i] > answer[i]:
                        answer = deepcopy(tmp_answer)
                        break
            return

        if info[order] < cnt:
            tmp_answer.append(info[order] + 1)
            ryan += 10 - order
            DFS(cnt - info[order] - 1, order + 1)
            tmp_answer.pop()
            ryan -= 10 - order
        tmp_answer.append(0)
        if info[order] > 0:
            apeach += 10 - order
        DFS(cnt, order + 1)
        tmp_answer.pop()
        if info[order] > 0:
            apeach -= 10 - order

    DFS(n, 0)

    return [-1] if len(answer) == 0 else answer

print(solution(5, [2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]))

tmp_answer = []
answer = []
apeach = 0
ryan = 0
score_diff = 0

print(solution(1, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]))

tmp_answer = []
answer = []
apeach = 0
ryan = 0
score_diff = 0

print(solution(9, [0, 0, 1, 2, 0, 1, 1, 1, 1, 1, 1]))

tmp_answer = []
answer = []
apeach = 0
ryan = 0
score_diff = 0

print(solution(10, [0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 3]))


from group_divider import group_divider

file1 = 'test_classe.csv'
file2 = 'test_1.csv'
file3 = 'test_2.csv'

# Crezione della classe e setup con il file
grd = group_divider()
grd.carica_csv(file1)
#grd.carica_csv(file2)
#grd.carica_csv(file3)
grd.stampa_matrice()

# Calcolo della media dei due gruppi
a, b, med = grd.dividi_in_due_gruppi_media()
if [a,b,med]:
    print("\nI gruppi:\n",a," e ", b, "\nCon una media di ", med)
else:
    print("Il file non è stato caricato correttamente")


from django.db.models import query
from django.shortcuts import render
from rest_framework import viewsets
from rest_framework import generics
from rest_framework.serializers import Serializer
from api_lojinha import serializers
from rest_framework.generics import get_object_or_404
from produto import models
#from pedido import models
from .serializers import OpcoesSerializer,CategoriaSerializer,ProdutoSerializer,AdicionalSerializer

class ListarOpcoesViewSet(generics.ListCreateAPIView):
    serializer_class =OpcoesSerializer
    queryset = models.Opcoes.objects.all()

class OpcoesAPIView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = OpcoesSerializer
    queryset = models.Opcoes.objects.all()

class ListarProdutoAPIView(generics.ListCreateAPIView):
    serializer_class = ProdutoSerializer
    queryset = models.Produto.objects.all()

class ProdutoAPIView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = ProdutoSerializer
    queryset = models.Produto.objects.all()

class ListarCategoriaAPIView(generics.ListCreateAPIView):
    serializer_class = CategoriaSerializer
    queryset = models.Categoria.objects.all()

class CategoriaAPIView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = CategoriaSerializer
    queryset = models.Categoria.objects.all()

class ListarAdicionaisAPIView(generics.ListCreateAPIView):
    serializer_class = AdicionalSerializer
    queryset = models.Adicional.objects.all()

class AdicionalAPIView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = AdicionalSerializer
    queryset = models.Adicional.objects.all()

#class PedidoAPIView(generics.ListCreateAPIView):
    #serializer_class = PedidoSerializer
    #queryset = models.Pedido.objects.all()

#class ItemPedidoAPIView(generics.RetrieveUpdateDestroyAPIView):
    #serializer_class = ItemPedidoSerializer
    #queryset = models.ItemPedido.objects.all()
    #def get_queryset(self):
        #if self.kwargs.get('pedido_pk'):
            #return self.queryset.filter(pedido_id=self.kwargs.get('pedido_pk'))
        #return self.queryset.all()
# Create your views here.


import pygeoip, os
from django import template
from .. import constants

register = template.Library()

@register.inclusion_tag('uecookie9/message.html', takes_context=True)
def uecookie9(context):
    show = False
    request = context['request']
    closed = request.COOKIES.get('uecookie_closed')

    if not closed:
        ip = request.META.get('HTTP_X_REAL_IP') or request.META.get('REMOTE_ADDR')
        filename = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'resources/GeoIP.dat')
        g = pygeoip.GeoIP(filename)
        result = g.country_name_by_addr(ip)

        if result in constants.UE_MEMBERS:
            show = True

    return {'show' : show}


# def PrintNum(n):
#     if(n==0):
#         return
#     print(n)
#     PrintNum(n-1)
#
# from sys import setrecursionlimit
# setrecursionlimit(11000)
# def main():
#     n=int(input())
#     PrintNum(n)
#
# if __name__ =="__main__":
#     main()

####Factorial#######
# def Fact(n):
#     if(n==1 or n==0):
#         return 1
#     return n*Fact(n-1)
#
# from sys import setrecursionlimit
# setrecursionlimit(11000)
# def main():
#     T=int(input())
#     while(T>0):
#       n=int(input())
#       print(Fact(n))
#       T=T-1
#
# if __name__ =="__main__":
#     main()

#####Sum of first N numbers######
# def SumofN(n):
#     if (n==1 or n==0):
#         return n
#     return n+SumofN(n-1)
#
# from sys import setrecursionlimit
# setrecursionlimit(11000)
# def main():
#     T=int(input())
#     while(T>0):
#       n=int(input())
#       print(SumofN(n))
#       T=T-1
#
# if __name__ =="__main__":
#     main()

####Print the pattern###
# def printPattern(n):
#     if (n == 0 or n < 0):
#         print(n, end=" ")
#         return
#     print(n, end=" ")
#     printPattern(n - 5)
#     print(n, end=" ")
#
#
# T = int(input())
# while (T > 0):
#     n = int(input())
#     k = printPattern(n)
#     if k:
#         print(k)
#     T = T - 1

######Sum of digits######
# def findsum(n):
#     sum1=0
#     if (n<=0):
#         return 0
#     return n%10+findsum(n//10)
#
#
# def main():
#     n=int(input())
#     print(findsum(n))
# if __name__ == '__main__':
#     main()
#

#####Fibonacci Numbers######
# def fibonacci(n):
#     if (n==1 or n==0):
#         return n
#     else:
#         return fibonacci(n-1) +fibonacci(n-2)
#
# from sys import setrecursionlimit
# setrecursionlimit(11000)
# def main():
#     T=int(input())
#     while(T>0):
#       n=int(input())
#       print(fibonacci(n))
#       T=T-1
#
# if __name__ =="__main__":
#     main()

######Binary numbers#####
# def binary(n,prev,output,i):
#     if(n==0):
#         for j in range(len(output)):
#             print(output[j],end="")
#         print()
#         return
#     if(prev==0 or prev==-1):
#         output[i]=0
#         binary(n-1,0,output,i+1)
#         output[i]=1
#         binary(n-1,1,output,i+1)
#     else:
#         output[i]=0
#         binary(n-1,0,output,i+1)
#
# def main():
#     T=int(input())
#     while(T>0):
#         n=int(input())
#         output=[-1]*n
#         binary(n,-1,output,0)
#         T=T-1
#
# if __name__=="__main__":
#     main()

#######GCD of numbers########
'''Basic Euclidean Algorithm for GCD
The algorithm is based on the below facts.

If we subtract a smaller number from a larger (we reduce a larger number), GCD doesn’t change. So if we keep subtracting
repeatedly the larger of two, we end up with GCD.
Now instead of subtraction, if we divide the smaller number, the algorithm stops when we find remainder 0.
Below is a recursive function to evaluate gcd using Euclid’s algorithm. We can also use modulo operator to work like subtraction'''
# def GCD(a,c):
#     if (c == 0):
#         return a
#     return GCD(c,a%c)
#
# def main():
#     T=int(input())
#     while(T>0):
#         N,P=map(int,input().split())
#         print(GCD(N,P))
#         T=T-1
# if __name__=="__main__":
#     main()

###Combination of numbers#####
# def recurCombi(arr,op,i,index,n,k):
#     if(k==0):
#         for j in range(len(op)):
#             print(op[j],end=' ')
#         print()
#         return
#     for j in range(i,n):
#         op[index]=arr[j]
#         recurCombi(arr,op,j+1,index+1,n,k-1)
# def main():
#     n=int(input())
#     arr=list(map(int,input().split()))
#     k=int(input())
#     op=[0]*k
#     #(arr,op,2indexes for each recursion call,to insert elements in the output list)
#     recurCombi(arr,op,0,0,n,k)
#
# if __name__ == '__main__':
#     main()

####Same String#####
# def isSame(st1):
#     l=len(st1)
#     if l<2:
#         return True
#     elif(st1[0]==st1[l-1]):
#         return isSame(st1[1:l-1])
#     else:
#         return False
# def main():
#     T=int(input())
#     while(T>0):
#         st1=input()
#         ans=isSame(st1)
#         if ans:
#             print("Yes")
#         else:
#             print("No")
#         T=T-1
#
# if __name__ == '__main__':
#     main()

###Sum of subsets###
# def SumOfSubset(a, n):
#     times = pow(2, n - 1)
#
#     Sum = 0
#
#     for i in range(n):
#         Sum = Sum + (a[i] * times)
#
#     return Sum
#
# def main():
#     # Driver Code
#     T=int(input())
#     while(T>0):
#         n = int(input())
#         arr = list(map(int, input().split()))
#         print(SumOfSubset(arr, n))
#         T=T-1
#
# if __name__ == '__main__':
#     main()

#####Equivalent Strings########
# def equal(s):
#     if(len(s)%2!=0):
#         return s
#     a1=equal(s[0:int(len(s)/2)])
#     a2=equal(s[int(len(s)/2):len(s)])
#     if(a1<a2):
#         return a1+a2
#     else:
#         return a2+a1
#
# def main():
#     a=input()
#     b=input()
#     k=int(len(a))
#     if ((equal(a)==equal(b))):
#         print("YES")
#     else:
#         print("NO")
#
# if __name__ == '__main__':
#     main()

###Solution of equation#####
# def count(n,z):
#     total=0
#     if(n==1 and z>=0):
#         return 1
#     for i in range (z+1):
#         total+=count(n-1,z-i)
#     return total
#
# def main():
#     T=int(input())
#     while(T>0):
#         n, z = map(int, input().split())
#         print(count(n, z))
#         T=T-1
# if __name__ == '__main__':
#     main()

###power set###
# def permuterec(str1,n,index=-1,curr=""):
#     if(index==n):
#         return
#     if len(curr)>0:
#         print(curr)
#     for i in range(index+1,n):
#         curr+=str1[i]
#         permuterec(str1,n,i,curr)
#
#         curr=curr[:len(curr)-1]
#
# def powerset(str1):
#     str1="".join(sorted(str1))
#     permuterec(str1,len(str1))
#
#
# def main():
#     str1= input()
#     powerset(str1)
#
# if __name__ == '__main__':
#     main()

####Remove adjacent duplicates######
# def removeAdjDup(str):
#     if(len(str)==1):
#         return str
#     if(str[0]==str[1]):
#         return removeAdjDup(str[1:])
#     return str[0]+removeAdjDup(str[1:])
#
# def main():
#     T=int(input())
#     while(T>0):
#         str=input()
#         print(removeAdjDup(str))
#         T=T-1
# if __name__ == '__main__':
#     main()

###Tower of Hanoi######
# def TowerofHanoi(n,source,destination,helper):
#     if(n==1):
#         print("Move disk from",source," to ",destination)
#         return
#     TowerofHanoi(n-1,source,helper,destination)
#     print("Move disk from", source, " to ", destination)
#     TowerofHanoi(n-1,helper,destination,source)
#
# def main():
#     n = int(input())
#     print(TowerofHanoi(n,1,3,2))
#
# if __name__ == '__main__':
#     main()
global total
total=0
def subsetsum(arr,i,n,sum):
    global total
    if(i>=n):
        total+=sum
        print(total)
        return total
    print(i+1)
    subsetsum(arr,i+1,n,sum+arr[i])
    subsetsum(arr,i+1,n,sum)
def main():
    T=int(input())
    k=0
    while(T>0):
        n = int(input())
        arr = list(map(int, input().split()))
        k=subsetsum(arr,0, n,0)
        print(k)
        T=T-1

if __name__ == '__main__':
    main()


########################################################################################################################
########################################################################################################################
#                                              SEGMENTATION DES POUMONS                                                #
########################################################################################################################
########################################################################################################################

import os
import numpy as np
import pandas as pd
from random import sample
from keras.utils import to_categorical
from keras.callbacks import EarlyStopping
import model
import data
import utils
import sys

# Choix de path
console = False
if console:
    ROOT_DIR = os.path.abspath("/home/achauviere/Bureau/Projet_Detection_Metastase_Souris/deepmeta-master/")
    sys.path.append(ROOT_DIR)
    PATH_GIT = os.path.join(ROOT_DIR, "../deepmeta-master/")
    PATH_DATA = os.path.join(ROOT_DIR, "../DATA/")
    PATH_Synth = os.path.join(ROOT_DIR, "../Data_Synthetique/")
else:
    PATH_GIT = "../deepmeta-master/"
    PATH_DATA = "../DATA/"
    PATH_Synth = "../Data_Synthetique/"

path_souris = os.path.join(PATH_DATA, "Poumons/Souris/")
path_mask = os.path.join(PATH_DATA, "Poumons/Masques/")
path_img = os.path.join(PATH_DATA, "Poumons/Image/")
path_lab = os.path.join(PATH_DATA, "Poumons/Label/")
tab = pd.read_csv(os.path.join(PATH_DATA, "Poumons/Tableau_General.csv")).values

# Ensemble de Souris présente pour l'entrainement :
numSouris = utils.calcul_numSouris(path_souris)

####################################################################################
  ##################### MODELE 2D DETECTION + SEGMENTATION #####################
####################################################################################

"""
Detection Poumons :
"""

data_seg, label_seg, ind_seg = data.create_data_detect_poum(path_img, tab, numSouris)

no = np.arange(len(ind_seg)) ; no_sample = sample(list(no), len(no))

data_seg = data_seg.reshape(-1, 128, 128, 1)[no_sample].astype('float32')
label_seg = to_categorical(label_seg[no_sample])

model_detect = model.model_detection()
es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=3)
model_detect.fit(data_seg, label_seg, validation_split=0.2, batch_size=264, epochs=20, callbacks=[es])
model_detect.save(os.path.join(PATH_GIT, "Poumons/model/model_detect.h5"))

"""
Segmentation Poumons :
"""

data_2D, label_2D, ind_2D = data.create_data_seg_poum(path_img, path_lab, tab)

N = np.arange(len(ind_2D)) ; N_sample = sample(list(N), len(N))

data_2D = data_2D.reshape(-1, 128, 128, 1)[N_sample]
label_2D = label_2D.reshape(-1, 128, 128,1)[N_sample]

input_shape = (128,128,1)

model_seg = model.model_unet_2D(input_shape)
earlystopper = EarlyStopping(patience=5, verbose=1)
model_seg.fit(data_2D, label_2D, validation_split=0.2, batch_size=32, epochs=50,callbacks=[earlystopper])
model_seg.save(os.path.join(PATH_GIT, "Poumons/model/model_seg.h5"))

####################################################################################
        ##################### MODELE 2D MULTI-AXES #####################
####################################################################################

"""
Multi-Axes
    Chargement des images de souris annotées + amélioration du contraste
    Chargement des masques + complétions par masque vide
"""

data_3D, label_3D, ind_3D = data.crate_data_3D(path_img, path_lab, tab, numSouris)

#Data selon axe
data_ax = []; data_sag = []; data_cor = []
label_ax = []; label_sag = []; label_cor = []

for k in np.arange(len(numSouris)):

    for i in np.arange(128):
        data_ax.append(data_3D[k][i, :, :])
        label_ax.append(label_3D[k][i, :, :])

        data_sag.append(data_3D[k][:, i, :])
        label_sag.append(label_3D[k][:, i, :])

        data_cor.append(data_3D[k][:, :, i])
        label_cor.append(label_3D[k][:, :, i])

n = np.arange(len(ind_3D)) ; n_sample = sample(list(n), len(n))

data_ax = np.array(data_ax).reshape(-1, 128, 128, 1)[n_sample]
label_ax = np.array(label_ax, dtype=np.bool).reshape(-1, 128, 128, 1)[n_sample]

data_sag = np.array(data_sag).reshape(-1, 128, 128, 1)[n_sample]
label_sag = np.array(label_sag, dtype=np.bool).reshape(-1, 128, 128, 1)[n_sample]

data_cor = np.array(data_cor).reshape(-1, 128, 128, 1)[n_sample]
label_cor = np.array(label_cor, dtype=np.bool).reshape(-1, 128, 128, 1)[n_sample]

input_shape = (128, 128, 1)

## Modele axial
earlystopper = EarlyStopping(patience=5, verbose=1)
model_axial = model.model_unet_2D(input_shape)
model_axial.fit(data_ax, label_ax, validation_split=0.2, batch_size=32, epochs=50,
                                callbacks=[earlystopper])
model_axial.save(os.path.join(PATH_GIT, "Poumons/model/model_axial.h5"))

## Modele sagital
earlystopper = EarlyStopping(patience=5, verbose=1)
model_sagital = model.model_unet_2D(input_shape)
model_sagital.fit(data_sag, label_sag, validation_split=0.2, batch_size=32, epochs=50,
                  callbacks=[earlystopper])
model_sagital.save(os.path.join(PATH_GIT, "Poumons/model/model_sagital.h5"))

## Modele corronal
earlystopper = EarlyStopping(patience=5, verbose=1)
model_corronal = model.model_unet_2D(input_shape)
model_corronal.fit(data_cor, label_cor, validation_split=0.2, batch_size=32, epochs=50,
                     callbacks=[earlystopper])
model_corronal.save(os.path.join(PATH_GIT, "Poumons/model/model_corronal.h5"))

####################################################################################
        ##################### MODELE RESNET #####################
####################################################################################

resnet = model.ResNet50(input_shape=(128, 128, 1))
resnet.compile(optimizer='adam', loss='binary_crossentropy', metrics=[utils.mean_iou])
# En faite, il est possible de construire un U-Net avec encodeur resNet avec la librairie segmentation_models
# Cela peut être utile à essayer.

####################################################################################
        ##################### UNET PLUS PLUS #####################
####################################################################################

data_2D, label_2D, ind_2D = data.create_data_seg_poum(path_img, path_lab, tab)

N = np.arange(len(ind_2D)) ; N_sample = sample(list(N), len(N))

data_2D = data_2D.reshape(-1, 128, 128, 1)[N_sample]
label_2D = label_2D.reshape(-1, 128, 128, 1)[N_sample]

input_shape = (128, 128, 1)

model_seg = model.unet_plusplus(input_shape)
earlystopper = EarlyStopping(patience=5, verbose=1)
model_seg.fit(data_2D, label_2D, validation_split=0.2, batch_size=32, epochs=50,callbacks=[earlystopper])
model_seg.save(os.path.join(PATH_GIT, "model/model_unet_plusplus.h5"))

####################################################################################
        ##################### Small U-Net #####################
####################################################################################

data_2D, label_2D, ind_2D = data.create_data_seg_poum(path_img, path_lab, tab)

N = np.arange(len(ind_2D)) ; N_sample = sample(list(N), len(N))

data_2D = data_2D.reshape(-1, 128, 128, 1)[N_sample]
label_2D = label_2D.reshape(-1, 128, 128, 1)[N_sample]

input_shape = (128,128,1)

# model_seg = model.small_unet(input_shape)
model_seg = model.unetCoupe2Max(input_shape)

earlystopper = EarlyStopping(patience=5, verbose=1)
model_seg.fit(data_2D, label_2D, validation_split=0.2, batch_size=32, epochs=50,callbacks=[earlystopper])

# model_seg.save(os.path.join(PATH_GIT, "Poumons/model/small_unet.h5"))
model_seg.save(os.path.join(PATH_GIT, "Poumons/model/unetCoupe2Max.h5"))

####################################################################################
    ##################### AMELIORATION AVEC CREATIVE DATA #####################
####################################################################################

"""
Segmentation Poumons :
"""

# Charge les anciennes images
data_2D, label_2D, ind_2D = data.create_data_seg_poum(path_img, path_lab, tab)

# Charge les nouvelles images
path_new = os.path.join(PATH_Synth, "Nouvelles_Images/")
newData, newPoum, newMeta = data.recup_new_data(path_new)

# On concatene le tout
Data = utils.concat_data(data_2D, newData)
MaskPoum = utils.concat_data(label_2D, newPoum)

# Puis on procède comme précedemment
N = np.arange(Data.shape[0]) ; N_sample = sample(list(N), len(N))

Data = Data.reshape(-1, 128, 128, 1)[N_sample]
MaskPoum = MaskPoum.reshape(-1, 128, 128, 1)[N_sample]

input_shape = (128, 128, 1)

model_seg = model.unet_plusplus(input_shape)
earlystopper = EarlyStopping(patience=5, verbose=1)
model_seg.fit(Data, MaskPoum, validation_split=0.2, batch_size=32, epochs=50,callbacks=[earlystopper])
model_seg.save(os.path.join(PATH_GIT, "Poumons/model/model_seg_poum_creat.h5"))


# -*- coding: utf-8 -*-
"""
Created on Wed Mar 10 17:38:32 2021

@author: Not Your Computer
"""

import os
import numpy as np
import pandas as pd
import random
import itertools
from scipy.ndimage.filters import convolve
from skimage.transform import resize, rescale
import matplotlib.pyplot as plt
from PIL import Image

def Invert(img):
    img = img + 1
    img[np.where(img == 2)] = 0
    return img

def RemoveStrayPixels(img, k = 3):
    h,w = np.shape(img)
    rows = []
    cols = []
    for i in range(k,h-k):
        for j in range(k,w-k):
            if img[i,j] == 1:
                if np.sum(img[i-k:i+k,j-k:j+k]) == 1:
                    rows.append(i)
                    cols.append(j)
    img[rows,cols] = 0
    return img

# Calculate bounds occupied by pixels
def PixelBounds(img, buffer = 10, k = 3):
    h,w = np.shape(img)
    img = RemoveStrayPixels(img, k = k)
    xmin = np.where(img.sum(axis = 0) > 0)[0][0] - buffer
    ymin = np.where(img.sum(axis = 1) > 0)[0][0] - buffer
    xmax = np.where(img.sum(axis = 0) > 0)[0][-1] + buffer
    ymax = np.where(img.sum(axis = 1) > 0)[0][-1] + buffer
    return max(0,xmin), max(0,ymin), min(xmax,w), min(ymax,h)

def IOU(boxA, boxB):
	# determine the (x, y)-coordinates of the intersection rectangle
	xA = max(boxA[0], boxB[0])
	yA = max(boxA[1], boxB[1])
	xB = min(boxA[2], boxB[2])
	yB = min(boxA[3], boxB[3])
	# compute the area of intersection rectangle
	interArea = max(0, xB - xA + 1) * max(0, yB - yA + 1)
	# compute the area of both the prediction and ground-truth
	# rectangles
	boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1)
	boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1)
	# compute the intersection over union by taking the intersection
	# area and dividing it by the sum of prediction + ground-truth
	# areas - the interesection area
	iou = interArea / float(boxAArea + boxBArea - interArea)
	# return the intersection over union value
	return iou

# Save all logged annotations as image chips in separate folder
def SaveChips(entry, outdir = r'D:\DataStuff\bms\chips'):
    entry = entry.split(',')
    path = entry[0]
    fname = os.path.basename(os.path.dirname(path))
    n_entries = int(len(entry[3:]) / 9)
    img = plt.imread(path)
    for i in range(n_entries):
        x,y,w,h,label,pxmin,pymin,pxmax,pymax = entry[3+9*i:3+9*(i+1)]
        x = int(float(x)); y = int(float(y))
        w = int(float(w)/2); h = int(float(h)/2)

        chip = img[y-h:y+h, x-w:x+w]
        plt.imshow(chip, cmap = 'gray')
        plt.show()
        outfile = '{}\\{}_{}_{}.png'.format(outdir, fname, label, i)
        plt.imsave(outfile, chip, cmap = 'gray')

# Create a new image w/ image chips
def AlphabetSoup(labels,
                 srcdir = r'D:\DataStuff\bms\chips',
                 target_shape = (640,640),
                 output_type = 'yolo',
                 size_thresh = 100,
                 preprocess = True,
                 min_size = 10,
                 buffer = 100,
                 S = (10,10),
                 B = 1,
                 C = 0):

    flist = os.listdir(srcdir)
    sf = random.random() * 1.5 + 1
    img = np.zeros(target_shape)
    boxes = []

    if output_type == 'yolo':
        annotations = np.zeros((S[0], S[1], (5*B+C)))
        grid_h = target_shape[0] / S[0]
        grid_w = target_shape[1] / S[1]

    if output_type == 'unet':
        mask = np.zeros(target_shape)

    for fname in random.sample(flist, random.randint(1,15)):
        fpath = os.path.join(srcdir, fname)
        label = fpath.split('.')[0].split('_')[-2]
        chip = Invert(plt.imread(fpath)[:,:,0])

        x = int(random.random() * (target_shape[1] - 2*buffer)) + buffer
        y = int(random.random() * (target_shape[0] - 2*buffer)) + buffer

        # Convolve the image to flesh out broken lines
        if preprocess:
            chip = convolve(chip, [[1,1,1],[1,1,1],[1,1,1]])
            chip = chip / np.max(chip)
            chip = convolve(chip, [[1,1,1],[1,1,1],[1,1,1]])
            chip = chip / np.max(chip)

        chip = rescale(chip, sf)
        h,w = np.shape(chip)
        chip_box = [x,y,x+w,y+h]

        no_overlap = True
        for box in boxes:
            if IOU(chip_box, box) > 0.10:
                no_overlap = False
                break

        if no_overlap:
            img[y:y+h, x:x+w] = chip
            boxes.append(chip_box)

            if output_type == 'yolo':
                row = int(np.floor(y / grid_h))
                col = int(np.floor(x / grid_w))

                x = x - col*grid_w
                y = y - row*grid_h

                x = x / grid_w
                y = y / grid_h

                h = min(h/(size_thresh-min_size),1)
                w = min(w/(size_thresh-min_size),1)
                annotations[row,col,:] = [x,y,w,h,1]

            if output_type == 'unet':
#                mask[y:y+h,x:x+w] = labels.index(label)
                mask[y:y+h,x:x+w] = 1

    if output_type == 'yolo':
        return img, annotations

    if output_type == 'unet':
        return img, mask

#
## Create a new image w/ image chips
#def AlphabetSoup(srcdir = r'D:\DataStuff\bms\chips', target_shape = (640,640), size_thresh = 100, buffer = 100, S = (10,10), B = 1, C = 0, preprocess = True, min_size = 10):
#    flist = os.listdir(srcdir)
#    fnames = random.sample(flist, random.randint(1,15))
#    sf = random.random() * 1 + 1
#    img = np.zeros(target_shape)
#    boxes = []
#    annotations = np.zeros((S[0], S[1], (5*B+C)))
#    grid_h = target_shape[0] / S[0]
#    grid_w = target_shape[1] / S[1]
#
#    for fname in fnames:
#        fpath = os.path.join(srcdir, fname)
#        label = fpath.split('.')[0].split('_')[-2]
#        chip = Invert(plt.imread(fpath)[:,:,0])
#
#        x = int(random.random() * (target_shape[1] - 2*buffer)) + buffer
#        y = int(random.random() * (target_shape[0] - 2*buffer)) + buffer
#
#        # Convolve the image to flesh out broken lines
#        if preprocess:
#            chip = convolve(chip, [[1,1,1],[1,1,1],[1,1,1]])
#            chip = chip / np.max(chip)
#            chip = convolve(chip, [[1,1,1],[1,1,1],[1,1,1]])
#            chip = chip / np.max(chip)
#
#        chip = rescale(chip, sf)
#        h,w = np.shape(chip)
#
#        chip_box = [x,y,x+w,y+h]
#
#        no_overlap = True
#        for box in boxes:
#            if IOU(chip_box, box) > 0.10:
#                no_overlap = False
#                break
#
#        if no_overlap:
#            img[y:y+h, x:x+w] = chip
#            boxes.append(chip_box)
#            row = int(np.floor(y / grid_h))
#            col = int(np.floor(x / grid_w))
#
#            x = x - col*grid_w
#            y = y - row*grid_h
#
#            x = x / grid_w
#            y = y / grid_h
#
#            h = min(h/(size_thresh-min_size),1)
#            w = min(w/(size_thresh-min_size),1)
#
#            annotations[row,col,:] = [x,y,w,h,1]
#
#    return img, annotations


import os
import mcubes
import numpy as np
import open3d as o3d
from tqdm import tqdm

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from pytorch3d.loss import chamfer_distance
from torch.utils.tensorboard import SummaryWriter

from model import Assembler
from data import ChairDataset, collate_fn
from pointnet2_cls_ssg import get_model_encoder
from utils import farthest_point_sample, compute_sampling_metrics, pc_normalize_sphere, assemble_from_multiple_batch, assemble_chairs

def voxel_grid_to_sparse(voxel_grid):
    voxels = voxel_grid.get_voxels()
    coords = []
    for voxel in voxels:
        coord = np.array(voxel.grid_index).astype(np.int32)
        coords.append(coord)
    coords = np.array(coords)
    return coords

def sparse_to_volume(coords):
    model = np.zeros(list(coords.max(0)+1))
    for i in range(coords.shape[0]):
        coord = coords[i]
        x, y, z = coord[0], coord[1], coord[2]
        model[x, y, z] = 1
    return model

def show_chairs(chairs):
    for i in range(chairs.shape[0]):
        pc = chairs[i]

        pcd = o3d.geometry.PointCloud()
        pcd.points = o3d.utility.Vector3dVector(pc)
        o3d.visualization.draw_geometries([pcd])

hidden_dim = 256

pointnet2 = get_model_encoder(hidden_dim).cuda()
assembler = Assembler(hidden_dim).cuda()

pointnet2.load_state_dict(torch.load('./checkpoints_gan/pointnet2_13.pth'))
assembler.load_state_dict(torch.load('./checkpoints_gan/assembler_13.pth'))

############################################################################################################################################################################
"""
Set A
"""
bs = 5
num_workers = 8
val_dir = '../dataset/SetC'
val_dataset = ChairDataset(val_dir)
val_dataloader = DataLoader(val_dataset, collate_fn=collate_fn, batch_size=bs, num_workers=num_workers, drop_last=False, shuffle=True)

count = 0
final_eval = {}
pointnet2.eval()
assembler.eval()
with torch.no_grad():
    for batch in tqdm(val_dataloader):
        batch_size = batch['mask'].shape[0]
        print(batch_size)

        fake_batch = assemble_from_multiple_batch(batch)
        mask = fake_batch['mask'].float().cuda().unsqueeze(-1)
        parts = fake_batch['parts'].permute(0, 2, 1).float().cuda()

        part_f, _ = pointnet2(parts)
        obj_f = torch.zeros((batch_size, 5, hidden_dim)).cuda()

        select_idx = (fake_batch['mask'] == 1).nonzero(as_tuple=False)
        select_idx = select_idx[:, 0] * 5 + select_idx[:, 1]
        obj_f = obj_f.reshape(-1, hidden_dim)
        obj_f[select_idx] = part_f
        obj_f = obj_f.reshape(batch_size, 5, hidden_dim)

        obj_f = obj_f.reshape(batch_size, -1)
        pred = assembler(obj_f)

        fake_pc = assemble_chairs(parts, mask, pred).detach().cpu().numpy()
        show_chairs(fake_pc)
        print(fake_pc.shape)
        exit()

############################################################################################################################################################################


import numpy as np
import math
import time
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import sys
import time
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
import mnist
from sklearn.metrics import accuracy_score, precision_score, recall_score

class Network_nn(nn.Module):
	def __init__(self,hidden_units,dropout_rate):
		super(Network_nn,self).__init__()
		self.hidden_units=hidden_units
		self.fc1=nn.Linear(784,self.hidden_units)
		self.fc = nn.Linear(self.hidden_units,self.hidden_units)
		self.fc2=nn.Linear(self.hidden_units,10)
		self.dropout=nn.Dropout(p=dropout_rate)
		self.softmax = nn.Softmax(dim=1)

	def forward(self,x):
		x = F.tanh(self.fc1(x))
		x = F.tanh(self.fc(x))
		x = self.dropout(x)
		x = self.fc2(x)
		x = self.softmax(x)
		return x

def getbatch(bsize):
	seed = np.random.choice(X_train.size()[0], size = bsize, replace = False)
	xb = X_train[seed,:]
#	yb = Y_train[seed,:]	#regression
	yb = Y_train[seed]     #classification
	return xb,yb

def train(model,steps,epochs,bsize,X_train,Y_train):
	criterion = nn.CrossEntropyLoss()
	optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.1)
	for epoch in range(epochs):
		for step in range(steps):
			x,y = getbatch(bsize)
			optimizer.zero_grad()
			outputs = model.forward(x)
		#loss = criterion(outputs,y)
		#loss = torch.sum(torch.sum(torch.pow(torch.sub(outputs,y),2),dim=0)/bsize)/n_outputs
#		loss = torch.sum(torch.sum(torch.pow(torch.sub(outputs,y),2),dim=0)/bsize)#new loss according to paper large values of loss
			loss = criterion(outputs,y)
			loss.backward()
			optimizer.step()
		outputs = model.forward(X_train)
		lossepoch = criterion(outputs,Y_train)
		print('epoch:',epoch+1,'loss:',lossepoch.item())

n_hidden = 100
dropout_rate = 0.25
num_particles = 50

n_inputs= 784
n_outputs = 10
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
model = Network_nn(n_hidden,dropout_rate)
model.to(device)

a = mnist.train_images()
X_train = mnist.train_images().reshape(a.shape[0], (a.shape[1]*a.shape[2]))
Y_train = mnist.train_labels()
a = mnist.test_images()
X_test = mnist.test_images().reshape(a.shape[0], (a.shape[1]*a.shape[2]))
Y_test = mnist.test_labels()

X_train = torch.from_numpy(X_train).type(torch.FloatTensor).to(device)
Y_train = torch.from_numpy(Y_train).type(torch.FloatTensor).to(device)
Y_train = Y_train.long()
X_test = torch.from_numpy(X_test).type(torch.FloatTensor).to(device)
Y_test = torch.from_numpy(Y_test).type(torch.FloatTensor).to(device)

train(model,200,200,128,X_train,Y_train)

predict_out = model.forward(X_test)
_, predict_y = torch.max(predict_out, 1)
Y_test = Y_test.cpu()
predict = predict_y.cpu()
print ('prediction accuracy', accuracy_score(Y_test, predict))


import errno
import json
import os.path

import tornado.ioloop
import tornado.web

import GamesManager
import Sessions
import utils
from ActionHandler import ActionHandler
from AuthHandlers import LoginHandler, LogoutHandler, BaseAuthHandler
from GameBoard import BoardState
from GameConnection import GameConnection, GameSocketRouter
from GameHandler import GameHandler
from LobbyConnection import LobbySocketRouter, LobbyConnection
from LobbyHandlers import (
    LobbyHandler,
    LobbyCreateHandler,
    LobbyGameHandler,
    LobbyGameInfoHandler,
    LobbyGameJoinHandler,
    LobbyGameBeginHandler,
    LobbyGameUpdateHandler,
    LobbyGameDeleteHandler,
)
from MapEditorHandler import MapEditorHandler
from ModuleListHandler import ModuleListHandler
from SaveHandler import SaveHandler
from UserInfoHandlers import UserInfoHandler

class IndexHandler(tornado.web.RequestHandler):
    def initialize(self, html_path):
        self.HTML_PATH = html_path

    def get(self):
        self.redirect("/lobby")

class BoardsHandler(BaseAuthHandler):
    #TODO: Consider spliting this class to handle the different scenarios
    actions = utils.Enum(["NEW", "ID", "GET_FIELDS"])
    nextBoardId = 0

    def initialize(self, config, action, gamesManager):
        super(BoardsHandler, self).initialize(config=config)
        self.config = config
        self.action = action
        self.gamesManager = gamesManager

        self.setAuthenticateUser = config.USER_AUTH

    @tornado.web.authenticated
    def get(self, **params):
        if self.action == self.actions.ID:
            #Return info about board with id boardId
            game = self.gamesManager.getGame(int(params["boardId"]))
            if not game:
                self.set_status(404)
                self.write("Board not found")
                return

            board = game.board

            # Return the board info as json
            boardInfo = BoardState.exportBoardToClient(board)

            #See if it is the user's turn
            userSession = Sessions.SessionManager.getSession(self.current_user)
            boardInfo["isPlayerTurn"] = board.isPlayersTurn(userSession.getValue("userid"))

            self.write(json.dumps(boardInfo))

        elif self.action == self.actions.GET_FIELDS:
            requestedFields = [f.decode("utf-8") for f in self.request.arguments.get("fieldNames[]")]
            board = self.gamesManager.getBoard(int(params["boardId"]))
            response = BoardState.getFields(board, requestedFields)
            self.write(json.dumps(response))

    @tornado.web.authenticated
    def post(self, **params):
        self.set_status(405)
        self.write("Method Not Allowed")
        return

def createSaveFileIfMissing():
    # http://stackoverflow.com/a/10979569
    flags = os.O_CREAT | os.O_EXCL | os.O_WRONLY

    try:
        file_handle = os.open('saveGames.json', flags)
    except OSError as e:
        if e.errno == errno.EEXIST:  # Failed as the file already exists.
            pass
        else:  # Something unexpected went wrong so reraise the exception.
            raise
    else:  # No exception, so the file must have been created successfully.
        with os.fdopen(file_handle, 'w') as file_obj:
            # Using `os.fdopen` converts the handle to an object that acts like a
            # regular Python file object, and the `with` context manager means the
            # file will be automatically closed when we're done with it.
            file_obj.write("{}")

class Server:
    def __init__(self, config):
        html_path = os.path.join(config.STATIC_CONTENT_PATH, "html")
        port = 8888
        gameSocketRouter = GameSocketRouter(GameConnection, '/gameStream')
        lobbySocketRouter = LobbySocketRouter(LobbyConnection, '/lobbyStream')

        self.gamesManager = GamesManager.GamesManager()

        createSaveFileIfMissing()

        def saveHandlerOptions(action):
            baseOptions = dict(config=config, gamesManager=self.gamesManager, html_path=html_path)
            baseOptions["action"] = action
            return baseOptions
        self.app = tornado.web.Application([
            (r"/", IndexHandler, dict(html_path=html_path)),

           # module handler
           (r"/modules/list", ModuleListHandler, dict(config=config)),

            #Map editor (Consider moving into a sub-list in MapEditorHandler)
            (r"/mapEditor", MapEditorHandler, dict(config=config, action=MapEditorHandler.actions.MODULE_SELECTOR, html_path=html_path)),
            (r"/mapEditor/(?P<moduleName>[A-z]+)", MapEditorHandler, dict(config=config, action=MapEditorHandler.actions.PAGE, html_path=html_path)),
            (r"/mapEditor/modules/info/(?P<moduleName>[A-z]+)", MapEditorHandler, dict(config=config, action=MapEditorHandler.actions.MODULE_INFO, html_path=html_path)),
            (r"/modules/create/?", MapEditorHandler, dict(config=config, action=MapEditorHandler.actions.CREATE)),
            (r"/modules/(?P<moduleName>[A-z]+)", MapEditorHandler, dict(config=config, action=MapEditorHandler.actions.MODULE)),

            (r"/listImages", MapEditorHandler, dict(config=config, action=MapEditorHandler.actions.LIST_IMAGES, html_path=html_path)),

            #Board control
            #Consider renaming to /games/
            (r"/boardInfo/(?P<boardId>[0-9]+)/?", BoardsHandler, dict(config=config, action=BoardsHandler.actions.ID, gamesManager=self.gamesManager)), #Consider using named regex here
            (r"/getFields/(?P<boardId>[0-9]+)/?", BoardsHandler, dict(config=config, action=BoardsHandler.actions.GET_FIELDS, gamesManager=self.gamesManager)),
            (r"/boards/(?P<boardId>[0-9]+)/action/?", ActionHandler, dict(config=config, gamesManager=self.gamesManager, gameSocket=gameSocketRouter)),

            #Serve the static game page
            (r"/game/?", GameHandler, dict(config=config)),
            (r"/game/(?P<boardId>[0-9]+)/?", GameHandler, dict(config=config, gamesManager=self.gamesManager)),

            #User auth
            (r"/login/?", LoginHandler),
            (r"/logout/?", LogoutHandler),

            #Lobby web routes
            (r"/lobby/?", LobbyHandler, dict(config=config, gamesManager=self.gamesManager)),
            (r"/lobby/create/?", LobbyCreateHandler, dict(config=config, gamesManager=self.gamesManager)),
            (r"/lobby/(?P<gameId>[0-9]+)/?", LobbyGameHandler, dict(config=config, gamesManager=self.gamesManager)),

            ##API ROUTES
            #Lobby API routes
            (r"/lobby/(?P<gameId>[0-9]+)/info/?", LobbyGameInfoHandler, dict(config=config, gamesManager=self.gamesManager)),
            (r"/lobby/(?P<gameId>[0-9]+)/join/?", LobbyGameJoinHandler, dict(config=config, gamesManager=self.gamesManager, lobbySocket=lobbySocketRouter)),
            (r"/lobby/(?P<gameId>[0-9]+)/begin/?", LobbyGameBeginHandler, dict(config=config, gamesManager=self.gamesManager, lobbySocket=lobbySocketRouter)),
            (r"/lobby/(?P<gameId>[0-9]+)/update/?", LobbyGameUpdateHandler, dict(config=config, gamesManager=self.gamesManager, lobbySocket=lobbySocketRouter)),
            (r"/lobby/(?P<gameId>[0-9]+)/delete/?", LobbyGameDeleteHandler, dict(config=config, gamesManager=self.gamesManager)),

            (r"/userinfo/?", UserInfoHandler, dict(config=config)),
            ##END API ROUTES

            #Load/Save games
            (r"/save/?", SaveHandler, saveHandlerOptions(SaveHandler.actions.SAVE)),
            (r"/load/(?P<saveGameId>[A-z0-9\-]+)/?", SaveHandler, saveHandlerOptions(SaveHandler.actions.LOAD)),
            (r"/saves/?", SaveHandler, saveHandlerOptions(SaveHandler.actions.LIST_SAVES)),
            (r"/saves/(?P<saveGameId>[A-z0-9\-]+)/delete/?", SaveHandler, saveHandlerOptions(SaveHandler.actions.DELETE)),

            #Static files
            (r"/shared/(.*)", utils.NoCacheStaticFileHandler, {"path": config.SHARED_CONTENT_PATH}),
            (r"/static/(.*)", utils.NoCacheStaticFileHandler, {"path": config.STATIC_CONTENT_PATH}), #This is not a great way of doing this TODO: Change this to be more intuative
        ] + gameSocketRouter.urls + lobbySocketRouter.urls,
        cookie_secret=config.COOKIE_SECRET,
        login_url="/login",
        debug=True
        )

        self.app.listen(port)
        print("Listening on port {}".format(port))
        self.ioloop = tornado.ioloop.IOLoop.instance()

    def start(self):
        print("Starting Server")
        self.ioloop.start()