# import the required modules for game
import random
import pygame
import tkinter as tk
from tkinter import messagebox

# initialise our game
pygame.init()
# rename our pygame window
pygame.display.set_caption("Snake Game")
# add background music to play throughout our game
music = pygame.mixer.music.load('music.mp3')
pygame.mixer.music.play(-1)  # the -1 ensures our music plays indefinitely

# START PYGAME

# CLASSES
class cube(object):
    rows = 20
    w = 500

    def __init__(self, start, color=(255, 100, 180)):
        self.pos = start
        self.dirnx = 0  # starts the position of the snake on the screen but not moving in either direction
        self.dirny = 0
        self.color = color

    def move(self, dirnx, dirny):  # defines position
        self.dirnx = dirnx
        self.dirny = dirny
        self.pos = (self.pos[0] + self.dirnx, self.pos[1] + self.dirny)

    def draw(self, surface):
        dis = self.w // self.rows  # determines the width/height of each cube
        i = self.pos[0]  # the current row
        j = self.pos[1]  # the current column
        pygame.draw.rect(surface, self.color, (i * dis + 1, j * dis + 1, dis - 2, dis - 2))  # determines where to draw
        # our cube by multiplying the row and column value of our cube

class snake(object):  # everything required for our snake to work
    body = []  # blank list of our snake coordinates
    turns = {}

    def __init__(self, color, pos):
        self.color = color
        self.head = cube(pos)  # Determines the head of the snake will be the front position
        self.body.append(self.head)  # We will add the head to our body list
        self.dirnx = 0  # Represents the direction our snake is moving
        self.dirny = 0

    def move(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:  # Checks if the user has hit the red x to cancel game
                pygame.quit()

            keys = pygame.key.get_pressed()  # Determines which keys are being pressed by user

            for _ in keys:  # Loops through all of the arrow keys
                if keys[pygame.K_LEFT]:
                    self.dirnx = -1  # -1 means the object is moving left
                    self.dirny = 0  # does not move in 2 directions at once (diagonal)
                    self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]  # moves our head position to the direction
                    # of whatever key was pressed (in this case left)
                # elif is used as we don't want to move in more than one direction
                elif keys[pygame.K_RIGHT]:
                    self.dirnx = 1  # 1 means the object is moving right
                    self.dirny = 0
                    self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

                elif keys[pygame.K_UP]:
                    self.dirnx = 0
                    self.dirny = -1  # -1 for y means the object is moving up
                    self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

                elif keys[pygame.K_DOWN]:
                    self.dirnx = 0
                    self.dirny = 1  # 1 for y means the object is moving down
                    self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

# Followed Tech with Tim guide (referenced in report) for the following function:
        for i, c in enumerate(self.body):
            p = c.pos[:]
            if p in self.turns:  # if the copied position above is in the turns, then the object will move/turn
                turn = self.turns[p]
                c.move(turn[0], turn[1])
                if i == len(self.body) - 1:  # if we are on the last cube, we're going to remove the last turn
                    self.turns.pop(p)
            else:  # if position is not in the turn, we still need to move
                # this checks whether or not we have reached the end of the screen
                if c.dirnx == -1 and c.pos[0] <= 0:  # if we're moving left, and the position is less then or equal to 0
                    # then we will change position to go to the right side of the screen
                    c.pos = (c.rows - 1, c.pos[1])
                elif c.dirnx == 1 and c.pos[0] >= c.rows - 1:
                    c.pos = (0, c.pos[1])
                elif c.dirny == 1 and c.pos[1] >= c.rows - 1:
                    c.pos = (c.pos[0], 0)
                elif c.dirny == -1 and c.pos[1] <= 0:
                    c.pos = (c.pos[0], c.rows - 1)
                else:
                    c.move(c.dirnx, c.dirny)

    def reset(self, pos):  # resets our game once you lose
        self.head = cube(pos)  # new position of snake head
        self.body = []  # clears list of snake body
        self.body.append(self.head)
        self.turns = {}
        self.dirnx = 0
        self.dirny = 0

    def addCube(self):  # this function will add a cube onto the snake tail for each snack collected
        tail = self.body[-1]  # this will collect the last cube of the snake (tail)
        dx, dy = tail.dirnx, tail.dirny  # collects the position of tail cube

        # we need to know which side of the snake to add the new cube to (tail)
        # so we need to check the direction we are currently moving in to determine whether we add the tail to the
        # left, right, above or below
        if dx == 1 and dy == 0:
            self.body.append(cube((tail.pos[0] - 1, tail.pos[1])))
        elif dx == -1 and dy == 0:  # e.g. if moving in a left direction, adds cube to the furthest right of the snake
            self.body.append(cube((tail.pos[0] + 1, tail.pos[1])))
        elif dx == 0 and dy == 1:
            self.body.append(cube((tail.pos[0], tail.pos[1] - 1)))
        elif dx == 0 and dy == -1:
            self.body.append(cube((tail.pos[0], tail.pos[1] + 1)))

        self.body[-1].dirnx = dx  # sets the direction of the tail, ensures it moves with the rest of the snake
        self.body[-1].dirny = dy

    def draw(self, surface):
        for i, c in enumerate(self.body):
            c.draw(surface)

# Drawing our grid
def drawGrid(w, rows, surface):
    sizeBtwn = w // rows  # Gives us the distance between the lines (width divided by rows)

    x = 0  # Keeps track of current x
    y = 0  # Keeps track of current y
    for l in range(rows):  # Draws one vertical and one horizontal line for each loop
        x = x + sizeBtwn
        y = y + sizeBtwn

        pygame.draw.line(surface, (255, 255, 255), (x, 0), (x, w))  # vertical line so y value doesn't change
        pygame.draw.line(surface, (255, 255, 255), (0, y), (w, y))  # horizontal line so x value doesn't change

def redrawWindow(surface):
    global rows, width, s, snack
    surface.fill((0, 0, 0))  # Fills the screen with colour black
    s.draw(surface)  # draws our snake object
    snack.draw(surface)  # draws our snack object on the screen
    drawGrid(width, rows, surface)  # Draws our grid lines
    pygame.display.update()  # Updates our screen

def randomSnack(rows, snake):
    positions = snake.body  # gets all of the cube positions of our snake

    while True:  # generates random positions on grid until a valid one is received
        x = random.randrange(rows)
        y = random.randrange(rows)
        if len(list(filter(lambda z: z.pos == (x, y), positions))) > 0:  # checks if the position generated is already
            # occupied by the snake , ensures snack is not put on top of snake
            continue
        else:
            break

    return x, y

def message_box(subject, content):
    root = tk.Tk()  # opens a new window for message box
    root.attributes("-topmost", True)  # creates the window to pop up over any other windows you may have open
    root.withdraw()
    messagebox.showinfo(subject, content)
    try:
        root.destroy()
    except:
        pass

def main():
    # GLOBAL VARIABLES
    global width, rows, s, snack
    width = 500  # Width of our screen
    height = 500  # Height of our screen
    rows = 20  # Amount of rows on our screen
    win = pygame.display.set_mode((width, height))  # This creates our pygame window screen
    s = snake((255, 100, 180), (10, 10))  # Creates our snake object and the figures 10 give it a position on screen
    snack = cube(randomSnack(rows, s), color=(255, 255, 255))  # generates snack object
    flag = True

    clock = pygame.time.Clock()  # Creates our clock object

    while flag:
        # starts our main loop
        pygame.time.delay(50)  # Delays our game to prevent it from running too quickly
        clock.tick(10)  # Ensures our game runs at no more than 10 frames per second
        s.move()
        if s.body[0].pos == snack.pos:  # checks if or snake has hit the snack object
            s.addCube()  # if it has, it adds another cube onto the snake tail
            snack = cube(randomSnack(rows, s), color=(255, 255, 255))  # generates a new snack

        for x in range(len(s.body)):
            if s.body[x].pos in list(map(lambda z: z.pos, s.body[x + 1:])):  # checks for collision of snake's body
                print('Score: ', len(s.body))  # prints score
                message_box('GAME OVER!', 'Try again?')
                s.reset((10, 10))  # resets game to start over
                break

        redrawWindow(win)  # This will refresh our screen

main()


"""
Modified implementation of Snurr Group's EQeq method for generation partial
atomic charges.
"""

from __future__ import print_function, division

import argparse
import sys

import numpy
from numpy import linalg

from main import chemistry, config, inputdata
from reference import ionization

# Define a fundamental constant
# K = (electronic charge ^2) / ( 4 * pi * vacuum permittivity)
K = 14.4

class EQeq:
    """Calculate partial charges from preprocessed input data"""

    def __init__(self, h0_value, s_charge):
        self.h0_value = -h0_value
        self.s_charge = s_charge

    def ip_list(self, element):
        """
        Read in the list of ionization potentials for an element from
        reference data.
        :type element: chemistry.Element
        """
        # Return ip_list immediately if cached.
        # REMEMBER that if self.h0_value is being optimised, this hasattr()
        # must be commented out since elements are persistent across steps.
        if hasattr(element, "ip_list"):
            return element.ip_list

        if element.atomic_number >= len(ionization.data):
            print("Error: No IP data available for", element.symbol)
            sys.exit()

        if element.atomic_number == 0:
            ip_list = [self.h0_value, 13.598]
        else:
            ip_list = ionization.data[element.atomic_number][1:]

        element.ip_list = ip_list
        return ip_list

    def electronegativity(self, element):
        """
        Calculate the Mulliken electronegativity from ionization potential
        data.
        :rtype : float
        :type element: chemistry.Element
        """
        if hasattr(element, "electronegativity"):
            return element.electronegativity

        ip_list = self.ip_list(element)

        x_0 = ip_list[0]
        x_1 = ip_list[1]
        x = 0.5 * (x_1 + x_0)

        element.electronegativity = x
        return x

    def chemical_hardness(self, element):
        """
        Calculate the chemical hardness / idempotential from ionization
        potential data.
        :rtype : float
        :type element: chemistry.Element
        """
        if hasattr(element, "chemical_hardness"):
            return element.chemical_hardness

        ip_list = self.ip_list(element)
        j_0 = ip_list[0]
        j_1 = ip_list[1]
        j = j_1 - j_0

        element.chemical_hardness = j
        return j

    def j_ij(self, atom1, atom2):
        """
        Calculate J values including scaling for distance

        :rtype : float
        :type atom1: chemistry.Atom
        :type atom2: chemistry.Atom
        """
        if atom1 == atom2:
            return self.chemical_hardness(atom1.element)
        else:
            j_i = self.chemical_hardness(atom1.element)
            j_j = self.chemical_hardness(atom2.element)

            r_ab = atom1.separation(atom2)

            # Nishimoto-Mataga
            j_ab = 1 / (r_ab + (2 / (j_i + j_j)))

            j_ab *= (K / 2)

            return j_ab

    def partial_charges(self, atoms, total_charge):
        """Calculate the partial atomic charges for every atom
        :type total_charge: int
        :type atoms: list
        """

        def construct_j_matrix(atom_list):
            """
            Take the list of atom objects and return the matrix of J
            (and modified J) values.
            :rtype : scipy.array
            :type atom_list: list
            """
            matrix_lh = []
            matrix_rh = []

            for row in range(len(atom_list) - 1):
                temp_row = []
                for column in range(len(atom_list)):
                    temp_row.append(self.j_ij(atom_list[row],
                                              atom_list[column]))
                matrix_lh.append(temp_row)

            for row in range(1, len(atom_list)):
                temp_row = []
                for column in range(len(atom_list)):
                    temp_row.append(self.j_ij(atom_list[row],
                                              atom_list[column]))
                matrix_rh.append(temp_row)

            matrix_lh = numpy.array(matrix_lh)
            matrix_rh = numpy.array(matrix_rh)

            ones_row = numpy.array([[1 for x in range(0, len(atom_list))]])
            j_matrix = numpy.subtract(matrix_lh, matrix_rh)
            final_matrix = numpy.concatenate((ones_row, j_matrix))

            return final_matrix

        def construct_x_matrix(atom_list, charge):
            """
            Take the list of atom objects and return the matrix of X values.
            :type atom_list: list
            :type charge: int
            :rtype : scipy.array
            """
            x_matrix = numpy.array([[charge]])
            for x in range(1, len(atom_list)):
                element0 = atom_list[x - 1].element
                element1 = atom_list[x].element
                difference = self.electronegativity(element1) - \
                             self.electronegativity(element0)
                x_matrix = numpy.concatenate((x_matrix, [[difference]]))
            return x_matrix

        # atom_lists = [[] for _ in range(atoms[-1].molecule + 1)]
        atom_lists = [[]]

        for atom in atoms:
            # atom_lists[atom.molecule].append(atom)
            atom_lists[0].append(atom)

        partials = []
        for molecule in atom_lists:
            j_matrix = construct_j_matrix(molecule)
            x_matrix = construct_x_matrix(molecule, total_charge)
            q_matrix = linalg.solve(j_matrix, x_matrix)

            for x in range(len(molecule)):
                partial_charge = q_matrix[x][0] * self.s_charge
                partials.append(partial_charge)
                molecule[x].partialcharge = partial_charge

        return partials

    @staticmethod
    def system_energy(pairs):
        """
        Return the sum of the pairwise electrostatic interactions between
        all atoms in the system.
        :type pairs: list
        :rtype : float
        """

        def pairwise_term(pair_in):
            """
            Return the coulombic energy between two point charges.

            :type pair_in: chemistry.AtomPair
            :rtype : float
            """
            q1 = pair_in.atom1.partialcharge
            q2 = pair_in.atom2.partialcharge

            r_ab = pair_in.separation()

            term_out = (q1 * q2) / r_ab

            return term_out

        total = 0
        for pair in pairs:
            if pair.atom1.molecule != pair.atom2.molecule:
                term = K * pairwise_term(pair)
                total += term
        energy = total * chemistry.ev_to_kcal

        return energy

def run_program(file_in, h0_value=1.839111328, s_charge=4.834350586):
    """
    Run the program and return the total electrostatic energy

    :type file_in: str
    :type h0_value: float
    :type s_charge: float
    :rtype : float
    """

    data = inputdata.InputData(file_in)
    data.get_all()

    eqeq = EQeq(h0_value, s_charge)
    eqeq.partial_charges(data.atoms(), data.total_charge_value)

    energy = eqeq.system_energy(data.pairs())

    return energy

if __name__ == "__main__":

    eqeq_description = "Calculate EQeq Electrostatic interaction energy"
    verbose_help = "Print all data verbosely."
    parameters_help = "Manually specify the parameters used in EQeq."

    parser = argparse.ArgumentParser(description=eqeq_description)
    parser.add_argument("-v", "--verbose", action="store_true",
                        help=verbose_help)
    parser.add_argument("-p", "--parameters", type=float, nargs=2,
                        default=False, help=parameters_help,
                        metavar=('h0_value', 's_charge'))
    parser.add_argument("file", type=str, nargs="+",
                        help="A Gaussian input file.")
    args = parser.parse_args()

    if args.verbose:
        config.verbose = True

    for filename in args.file:
        if args.parameters:
            print(run_program(filename, *args.parameters))
        else:
            print(run_program(filename))


# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------

"""The data layer used during training to train a Fast R-CNN network.

RoIDataLayer implements a Caffe Python layer.
"""

import caffe
from fast_rcnn.config import cfg
from vrd.wsd.mini_batch import get_minibatch
import numpy as np
import yaml
#from multiprocessing import Process, Queue
import pdb
import zl_config as C
import glog
class RoIDataLayerEbBinaryLogLoss(caffe.Layer):
    """Fast R-CNN data layer used for training."""

    def _shuffle_roidb_inds(self):
        """Randomly permute the training roidb."""
        if cfg.TRAIN.ASPECT_GROUPING:
            widths = np.array([r['width'] for r in self._roidb])
            heights = np.array([r['height'] for r in self._roidb])
            horz = (widths >= heights)
            vert = np.logical_not(horz)
            horz_inds = np.where(horz)[0]
            vert_inds = np.where(vert)[0]
            inds = np.hstack((
                np.random.permutation(horz_inds),
                np.random.permutation(vert_inds)))
            inds = np.reshape(inds, (-1, 2))
            row_perm = np.random.permutation(np.arange(inds.shape[0]))
            inds = np.reshape(inds[row_perm, :], (-1,))
            self._perm = inds
        else:
            self._perm = np.random.permutation(np.arange(len(self._roidb)))
        self._cur = 0

    def _get_next_minibatch_inds(self):
        """Return the roidb indices for the next minibatch."""
        if self._cur + cfg.TRAIN.IMS_PER_BATCH >= len(self._roidb):
            self._shuffle_roidb_inds()

        db_inds = self._perm[self._cur:self._cur + cfg.TRAIN.IMS_PER_BATCH]
        self._cur += cfg.TRAIN.IMS_PER_BATCH
        return db_inds

    def _get_next_minibatch(self):
        """Return the blobs to be used for the next minibatch.
        If cfg.TRAIN.USE_PREFETCH is True, then blobs will be computed in a
        separate process and made available through self._blob_queue.
        """
        if cfg.TRAIN.USE_PREFETCH:
            return self._blob_queue.get()
        else:
            db_inds = self._get_next_minibatch_inds()
            minibatch_db = [self._roidb[i] for i in db_inds]
            return get_minibatch(minibatch_db, self._num_classes)

    def set_roidb(self, roidb):
        """Set the roidb to be used by this layer during training."""
        self._roidb = roidb
        self._shuffle_roidb_inds()

    def setup(self, bottom, top):
        """Setup the RoIDataLayer."""

        # parse the layer parameter string, which must be valid YAML
        layer_params = yaml.load(self.param_str)

        self._num_classes = layer_params['num_classes']
        self._name_to_top_map = {}

        # data blob: holds a batch of N images, each with 3 channels
        idx = 0
        top[idx].reshape(cfg.TRAIN.IMS_PER_BATCH, 3,
                         max(cfg.TRAIN.SCALES), cfg.TRAIN.MAX_SIZE)
        self._name_to_top_map['data'] = idx
        idx += 1

        ##todo necessary?
        # top[idx].reshape(1, 3)
        # self._name_to_top_map['im_info'] = idx
        # idx += 1
        # rois blob: holds R regions of interest, each is a 5-tuple
        # (n, x1, y1, x2, y2) specifying an image batch index n and a
        # rectangle (x1, y1, x2, y2)
        top[idx].reshape(1, 5, 1, 1)
        self._name_to_top_map['gt_boxes'] = idx
        idx += 1

        # labels blob: R categorical labels in [0, ..., K] for K foreground
        # classes plus background
        top[idx].reshape(1, 1, 1, 1)
        self._name_to_top_map['labels'] = idx
        idx += 1

        top[idx].reshape(1, 20, 1, 1)
        self._name_to_top_map['labels_v'] = idx
        idx += 1
        #top[idx].reshape(1, 1000, 1, 1)
        #self._name_to_top_map['word_embeddings'] = idx
        #idx += 1

        #top[idx].reshape(1, 20, 1, 1)
        #self._name_to_top_map['regression_targets'] = idx
        #idx += 1

        #print 'RoiDataLayer: name_to_top:', self._name_to_top_map
        #assert len(top) == len(self._name_to_top_map)

    def forward(self, bottom, top):
        """Get blobs and copy them into this layer's top blob vector."""
        # todo: modify mini_batch
        blobs = self._get_next_minibatch()
        labels = blobs['labels']
        gt_boxes = blobs['gt_boxes']
        im_info = blobs['im_info']
        #gt_boxes = gt_boxes
        #blobs['labels']=blobs['gt_boxes']
        #blobs['word_embeddings'] = np.zeros((1,1,1,1),np.float32)
        #blobs['regression_targets'] = np.zeros((1,20,1,1),np.float32)

        #for blob_name, blob in blobs.iteritems():
        #    top_ind = self._name_to_top_map[blob_name]
        #    shape = blob.shape
        #    top[top_ind].reshape(*(blob.shape))
        #    # Copy data into net's input blobs
        #    top[top_ind].data[...] = blob.astype(np.float32, copy=False)

        top[0].reshape(*blobs['data'].shape)
        top[0].data[...] = blobs['data']

        gt_boxes = gt_boxes.reshape((gt_boxes.shape[0],gt_boxes.shape[1],1,1))
        zeros = np.zeros((gt_boxes.shape[0],1,1, 1), dtype=gt_boxes.dtype)
        all_rois = np.concatenate((zeros, gt_boxes),axis=1)

        top[1].reshape(*all_rois.shape)
        top[1].data[...] = all_rois
        #labels = np.concatenate((labels,np.array([0,0,0])))
        labels = np.unique(labels)
        labels_v = np.zeros((20))

        labels_v[...]=-1
        labels_v[labels.astype(np.int32)-1]=1
        #labels_v = np.tile(labels_v,labels.shape[0])

        labels_v = labels_v.reshape((1,20))
        #for i in xrange(labels.shape[0]):
        #    labels_v[i,labels[i]]=1
        labels = labels.reshape((labels.shape[0],1,1,1))
        #labels[-1,0,0,0]=0
        top[2].reshape(*labels.shape)
        top[2].data[...] = labels

        top[3].reshape(*labels_v.shape)
        top[3].data[...] =labels_v# labels

        #embeddings = np.zeros((gt_boxes.shape[0],1,1, 1), dtype=gt_boxes.dtype)
        #top[3].reshape(*embeddings.shape)
        #top[3].data[...] = embeddings

        #regression_targets = np.zeros((gt_boxes.shape[0],20,1, 1), dtype=gt_boxes.dtype)
        #top[4].reshape(*regression_targets.shape)
        #top[4].data[...] = regression_targets
        #glog.info('here')
        #pdb.set_trace()

    def backward(self, top, propagate_down, bottom):
        """This layer does not propagate gradients."""
        pass

    def reshape(self, bottom, top):
        """Reshaping happens during the call to forward."""
        pass


import requests

class WhatPulse:
    # WhatPulse uses different terms for `username`, this list is used to convert them all
    # to `name`
    NAME_SYNONYMS = ['name', 'account_name', 'user_name', 'username']

    class API:
        HOST = 'http://api.whatpulse.org/'
        PATHS = {
            'user': 'user.php',
            'team': 'team.php',
            'pulses': 'pulses.php'
        }

        def __getitem__(self, item):
            return WhatPulse.API.HOST + WhatPulse.API.PATHS[item]

    def __init__(self):
        self.http = requests.Session()
        self.paths = WhatPulse.API()

    def request(self, url, object=None, method='get', params={}, return_json=False):
        if method == 'get':
            if params:
                params.setdefault('format', 'json')
            response = self.http.get(url, params=params)
            if return_json:
                # Return raw JSON data
                return response

            if object is not None:
                dictionary = response.json()
                if 'error' in dictionary.keys():
                    raise WhatPulseError(dictionary['error'])

                return self._make_object(object, dictionary)
        else:
            response = self.http.post(url, params=params)
            dictionary = response.json()
            if 'error' in dictionary.keys():
                raise WhatPulseError(dictionary['error'])

    def _make_snake_case(self, value):
        # Converts the camel case provided by WhatPulse to snake case
        if len(value) == 0:
            return value

        word = ''
        for char in value:
            if word == '':
                word += char.lower()
            elif word != '' and char.isupper():
                word += '_'
                word += char.lower()
            else:
                word += char
        return word

    def _convert_to_int_float(self, value):
        # Tries to convert values to integers or floats for convenience
        if not isinstance(value, str):
            return value

        if value.isdigit():
            return int(value)

        try:
            return float(value)
        except ValueError:
            return value

    def _make_object(self, object, dict):

        instance = object()
        for key, item in dict.items():
            key = self._make_snake_case(key)
            item = self._convert_to_int_float(item)

            if isinstance(instance, User):
                if key == 'team':
                    key = 'team_name'
                    if item == 0:
                        # No team
                        item = None
                    else:
                        item = item['Name']

                elif key == 'computers':
                    item = [self._make_object(Computer, data) for computer, data in item.items()]
                    for computer in item:
                        computer.owner = instance

                elif key in self.NAME_SYNONYMS:
                    key = 'name'

            elif isinstance(instance, Team):
                if key == 'founder':
                    key = 'founder_name'

                elif key == 'members':
                    try:
                        key = 'member_data'
                        item = [self._make_object(User, data) for member, data in item.items()]
                        try:
                            for member in item:
                                member.team = instance
                        except AttributeError:
                            # Fetched from team.members
                            pass
                    except AttributeError:
                        key = 'users'

                elif key == 'sub_teams':
                    item = [self._make_object(Team, data) for team, data in item.items()]
                    for team in item:
                        team.sub_team = True
                        team.name = team.sub_team_name
                        del team.sub_team_name

            elif isinstance(instance, Pulse):
                if key == 'computer':
                    key = 'computer_name'

            if key == 'ranks':
                item = self._make_object(Rank, item)

            if not hasattr(instance, key):
                setattr(instance, key, item)

        return instance

    def get_user(self, userid):
        params = {'user': userid}
        user = self.request(self.paths['user'], params=params, object=User)
        return user

    def get_team(self, teamid, get_members=False):
        params = {'team': teamid}
        if get_members:
            params['members'] = 'yes'
        team = self.request(self.paths['team'], params=params, object=Team)
        return team

    def get_pulses(self, userid):
        params = {'user': userid}
        pulses = self.request(self.paths['pulses'], params=params, object=Pulse, return_json=True).json()
        pulse_objs = []

        for pulse, data in pulses.items():
            obj = self._make_object(Pulse, data)
            obj.pulse_id = int(pulse.split('-')[1])
            pulse_objs.append(obj)
        return pulse_objs

class WhatPulseBaseObject:
    def __init__(self):
        self.wp = WhatPulse()

class User(WhatPulseBaseObject):
    def __init__(self):
        super(User, self).__init__()
        self._team = None

    @property
    def team(self):
        # Only make call to API if / when necessary and return team instance
        if not self._team:
            self._team = self.wp.get_team(self.team_name)
        return self._team

    def get_pulses(self):
        return self.wp.get_pulses(self.name)

    def __repr__(self):
        return '<WhatPulse User %s>' % self.name

class Team(WhatPulseBaseObject):
    def __init__(self):
        super(Team, self).__init__()
        self.sub_team = False
        self._founder = None
        self._members = None

    @property
    def founder(self):
        if not self._founder:
            self._founder = self.wp.get_user(self.founder_name)
        return self._founder

    @property
    def members(self):
        if not self._members:
            self._members = self.wp.get_team(self.name, True).member_data
        return self._members

    def __repr__(self):
        return '<WhatPulse Team %s>' % self.name

class Pulse(WhatPulseBaseObject):
    def __init__(self):
        super(Pulse, self).__init__()
        self._computer = None
        self._user = None

    @property
    def user(self):
        if not self._user:
            self._user = self.wp.get_user(self.username)
        return self._user

    def __repr__(self):
        return 'WhatPulse Pulse %s of %s' % (self.pulse_id, self.user.name)

class Computer(WhatPulseBaseObject):
    def __repr__(self):
        return '<WhatPulse Computer %s>' % self.name

class Rank(WhatPulseBaseObject):
    def __repr__(self):
        return '<WhatPulse Ranks>'

class Totals(WhatPulseBaseObject):
    def __repr__(self):
        return '<WhatPulse Totals>'

class WhatPulseError(Exception):
    pass

class WhatPulseLocal(WhatPulse):
    class API:
        PATHS = {
            'totals': '/v1/account-totals',
            'unpulsed': '/v1/unpulsed',
            'pulse': '/v1/pulse'
        }

        def __init__(self, host):
            self.HOST = host

        def __getitem__(self, item):
            return self.HOST + self.PATHS[item]

    def __init__(self, host='http://localhost:3490'):
        super(WhatPulseLocal, self).__init__()
        self.host = host
        self.http = WhatPulse().http
        self.paths = WhatPulseLocal.API(self.host)

    def _make_object(self, object, dict):
        instance = object()

        for key, item in dict.items():
            key = self._make_snake_case(key)
            item = self._convert_to_int_float(item)

            if key == 'ranks':
                item = self._make_object(Rank, item)

            if key.startswith('rank_'):
                key = key.replace('rank_', '')

            if not hasattr(instance, key):
                setattr(instance, key, item)

        return instance

    # Attributes below are 'private'.
    def get_user(self):
        raise NotImplemented("'WhatPulseLocal' has no attribute 'get_user")

    def get_team(self):
        raise NotImplemented("'WhatPulseLocal' has no attribute 'get_team")

    def get_pulses(self):
        raise NotImplemented("'WhatPulseLocal' has no attribute 'get_pulses")

    def get_totals(self):
        return self.request(self.paths['totals'], object=Totals)

    def get_unpulsed(self):
        return self.request(self.paths['unpulsed'], object=Totals)

    def pulse(self):
        requests.post(self.paths['pulse'])


import requests
from sys import argv
from requests_futures.sessions import FuturesSession
from concurrent.futures import ThreadPoolExecutor

class Check():

    def __init__(self):
        self.session = FuturesSession(max_workers=30)
        # Quick and dirty
        self.fileIn = argv[1]
        self.fileOut = argv[2]
        self.bigURL = argv[3] if len(argv) >= 3 else "https://www.soundcloud.com/"

    def fetch(self,url):
        # Need to spoof
        header = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'}
        resp =  requests.get(url,headers=header,timeout=5.0,stream=False)
        # Not sure if we need to do this because of stream=False
        resp.close()

        return resp

    def run(self):
        #our list
        usernames = []

        with open(self.fileIn,"r") as f:
            for line in f:
                line = str(line).rstrip()
                if len(line) >= 3:
                    usernames.append(self.bigURL+line)
        f.close()

        # Cutting down any unnecessary requests
        usernames = list(set(usernames))

        responses = []
        out = []
        with ThreadPoolExecutor() as executor:
            for url in executor.map(self.fetch, usernames):
                responses.append(url)

        for re in responses:
            if re.status_code == 404:
                out.append(re.url)

        with open(self.fileOut,"w+r") as f:
            for line in out:
                f.write(line+"\n")

checking = Check()
checking.run()


from discord.ext import commands
from collections import Counter
from utils import checks
from utils.db.datatype import *

import logging
import discord
import datetime
import psutil

from config import LOGGING_CHANNEL

client = discord.Client()
log = logging.getLogger(__name__)

class ActionReason(commands.Converter):
    async def convert(self, ctx, argument):
        ret = f'{ctx.author} (ID: {ctx.author.id}): {argument}'

        if len(ret) > 512:
            reason_max = 512 - len(ret) - len(argument)
            raise commands.BadArgument(f'reason is too long ({len(argument)}/{reason_max})')
        return ret

class BannedMember(commands.Converter):
    async def convert(self, ctx, argument):
        ban_list = await ctx.guild.bans()

        try:
            member_id = int(argument, base=10)
            entity = discord.utils.find(lambda u: u.user.id == member_id, ban_list)
        except ValueError:
            entity = discord.utils.find(lambda u: str(u.user.name) == argument, ban_list)

        if entity is None:
            raise commands.BadArgument("Not a valid previously-banned member.")
        return entity

class utility:

    def __init__(self, bot):
        self.bot = bot
        self.process = psutil.Process()

    @commands.command(hidden=False)
    async def ping(self, ctx):
        await ctx.send('pong !')

    @commands.command(hidden=False)
    async def back(self, ctx):
        '''Set an afk reason'''
        afk_back(str(ctx.guild.id), ctx.author.name)
        await ctx.send(f"{ctx.author.mention} is back !")

    @commands.command(hidden=False)
    async def afk(self, ctx):
        reason = "Afk"
        if len(ctx.message.content.split(' ')[1:]):
            reason = " ".join(ctx.message.content.split(' ')[1:])
        afk_reason(str(ctx.guild.id), ctx.author.name, reason)
        await ctx.send(f"{ctx.author.name} is afk :\"{reason}\"")

    @client.event
    async def on_message(self, message: discord.Message):
        if not message.guild:
            return
        if message.author == message.guild.me:
            return
        for mention in message.mentions:
            reason = is_afk(message.guild.id, mention.name)
            if reason:
               await message.channel.send( f'{mention.name} is AFK : {reason}')

    @commands.command()
    @commands.guild_only()
    @checks.has_permissions(kick_members=True)
    async def kick(self, ctx, member: discord.Member, *, reason: ActionReason = None):
        """Kicks a member from the server.

        In order for this to work, the bot must have Kick Member permissions.

        To use this command you must have Kick Members permission.
        """

        if reason is None:
            reason = f'Action done by {ctx.author} (ID: {ctx.author.id})'

        await member.kick(reason=reason)
        await ctx.send('\N{OK HAND SIGN}')

    @commands.command()
    @commands.guild_only()
    @checks.has_permissions(ban_members=True)
    async def ban(self, ctx, member: discord.Member, *, reason: ActionReason = None):
        """Ban a member from the server.

        In order for this to work, the bot must have Ban Member permissions.

        To use this command you must have Ban Members permission.
        """

        if reason is None:
            reason = f'Action done by {ctx.author} (ID: {ctx.author.id})'

        await member.ban(reason=reason)
        await ctx.send('\N{OK HAND SIGN}')

    @commands.command()
    @commands.guild_only()
    @checks.has_permissions(ban_members=True)
    async def unban(self, ctx, member: BannedMember, *, reason: ActionReason = None):
        """Unbans a member from the server.

        You can pass either the ID of the banned member or the Name#Discrim
        combination of the member. Typically the ID is easiest to use.

        In order for this to work, the bot must have Ban Member permissions.

        To use this command you must have Ban Members permissions.
        """

        if reason is None:
            reason = f'Action done by {ctx.author} (ID: {ctx.author.id})'

        await ctx.guild.unban(member.user, reason=reason)
        if member.reason:
            await ctx.send(f'Unbanned {member.user} (ID: {member.user.id}), previously banned for {member.reason}.')
        else:
            await ctx.send(f'Unbanned {member.user} (ID: {member.user.id}).')

    async def _full_cleanup_strategy(self, ctx, search):
        prefixes = tuple('!') # thanks startswith

        def check(m):
            return m.pinned == False

        deleted = await ctx.channel.purge(limit=search, check=check, before=ctx.message)
        return Counter(m.author.display_name for m in deleted)

    @commands.command()
    @checks.has_permissions(manage_messages=True)
    async def clear(self, ctx, search=100):
        """Cleans up the bot's messages from the channel.

        If a search number is specified, it searches that many messages to delete.
        If the bot has Manage Messages permissions then it will try to delete
        messages that look like they invoked the bot as well.

        After the cleanup is completed, the bot will send you a message with
        which people got their messages deleted and their count. This is useful
        to see which users are spammers.

        You must have Manage Messages permission to use this.
        """

        strategy = self._full_cleanup_strategy

        spammers = await strategy(ctx, search)
        deleted = sum(spammers.values())
        messages = [f'{deleted} message{" was" if deleted == 1 else "s were"} removed.']
        if deleted:
            messages.append('')
            spammers = sorted(spammers.items(), key=lambda t: t[1], reverse=True)
            messages.extend(f'- **{author}**: {count}' for author, count in spammers)

        await ctx.message.delete()
        await ctx.send('\n'.join(messages), delete_after=10)

async def on_error(self, event, *args, **kwargs):
    e = discord.Embed(title='Event Error', colour=0xa32952)
    e.add_field(name='Event', value=event)
    e.description = f'```py\n{traceback.format_exc()}\n```'
    e.timestamp = datetime.datetime.utcnow()
    ch = self.get_channel(LOGGING_CHANNEL)
    try:
        await ch.send(embed=e)
    except:
        pass

def setup(bot):
    if not hasattr(bot, 'command_stats'):
        bot.command_stats = Counter()

    if not hasattr(bot, 'socket_stats'):
        bot.socket_stats = Counter()

    bot.add_cog(utility(bot))
    commands.Bot.on_error = on_error


import torch
import torch.nn.functional as F
from libs import InPlaceABN, InPlaceABNSync
from torch import nn
from torch.nn import init
import math

class _NonLocalNdGc(nn.Module):

    def __init__(self, dim, inplanes, planes, downsample, use_gn, lr_mult, use_out, add_conv):
        assert dim in [1, 2, 3], "dim {} is not supported yet".format(dim)
        assert add_conv in [None, 'one_fc', 'two_fc']
        if dim == 3:
            conv_nd = nn.Conv3d
            if downsample:
                max_pool = nn.MaxPool3d(kernel_size=(1, 2, 2), stride=(1, 2, 2))
            else:
                max_pool = None
            bn_nd = nn.BatchNorm3d
        elif dim == 2:
            conv_nd = nn.Conv2d
            if downsample:
                max_pool = nn.MaxPool2d(kernel_size=(2, 2), stride=(2, 2))
            else:
                max_pool = None
            bn_nd = nn.BatchNorm2d
        else:
            conv_nd = nn.Conv1d
            if downsample:
                max_pool = nn.MaxPool1d(kernel_size=2, stride=2)
            else:
                max_pool = None
            bn_nd = nn.BatchNorm1d

        super(_NonLocalNdGc, self).__init__()
        self.conv_query = conv_nd(inplanes, planes, kernel_size=1)
        self.conv_key = conv_nd(inplanes, planes, kernel_size=1)
        self.conv_mask = conv_nd(inplanes, 1, kernel_size=1)
        if add_conv == 'one_fc':
            self.channel_add_conv=nn.Sequential(
                nn.Conv2d(inplanes, inplanes, kernel_size=1),
                nn.LayerNorm([inplanes, 1, 1]))
        elif add_conv == 'two_fc':
            self.channel_add_conv = nn.Sequential(
                nn.Conv2d(inplanes, inplanes//4, kernel_size=1),
                nn.LayerNorm([inplanes//4, 1, 1]),
                nn.ReLU(inplace=True),  # yapf: disable
                nn.Conv2d(inplanes//4, inplanes, kernel_size=1))
        if use_out:
            self.conv_value = conv_nd(inplanes, planes, kernel_size=1)
            self.conv_out = conv_nd(planes, inplanes, kernel_size=1, bias=False)
        else:
            self.conv_value = conv_nd(inplanes, inplanes, kernel_size=1, bias=False)
            self.conv_out = None
        self.softmax = nn.Softmax(dim=2)
        self.downsample = max_pool
        # self.norm = nn.GroupNorm(num_groups=32, num_channels=inplanes) if use_gn else InPlaceABNSync(num_features=inplanes)
        self.gamma = nn.Parameter(torch.zeros(1))
        self.scale = math.sqrt(planes)
        self.add_conv = add_conv

        self.reset_parameters()
        self.reset_lr_mult(lr_mult)

    def reset_parameters(self):

        for m in self.modules():
            if isinstance(m, nn.Conv3d) or isinstance(m, nn.Conv2d) or isinstance(m, nn.Conv1d):
                init.normal_(m.weight, 0, 0.01)
                if m.bias is not None:
                    init.zeros_(m.bias)
                m.inited = True
        #init.constant_(self.norm.weight, 0)
        #init.constant_(self.norm.bias, 0)
        #self.norm.inited = True

    def reset_lr_mult(self, lr_mult):
        if lr_mult is not None:
            for m in self.modules():
                m.lr_mult = lr_mult
        else:
            print('not change lr_mult')

    def forward(self, x):
        # [N, C, T, H, W]
        residual = x
        # [N, C, T, H', W']
        if self.downsample is not None:
            input_x = self.downsample(x)
        else:
            input_x = x

        # [N, C', T, H, W]
        query = self.conv_query(x)
        # [N, C', T, H', W']
        key = self.conv_key(input_x)
        value = self.conv_value(input_x)
        # [N, 1, H', W']
        mask = self.conv_mask(input_x)

        # [N, C', H x W]
        query = query.view(query.size(0), query.size(1), -1)
        # [N, C', H' x W']
        key = key.view(key.size(0), key.size(1), -1)
        value = value.view(value.size(0), value.size(1), -1)
        # [N, 1, H'x W']
        mask = mask.view(mask.size(0), mask.size(1), -1)

        # [N, T x H x W, T x H' x W']
        sim_map = torch.bmm(query.transpose(1, 2), key)
        sim_map = sim_map/self.scale
        sim_map = self.softmax(sim_map)
        # [N, 1, H'x W']
        mask = self.softmax(mask)

        # [N, T x H x W, C']
        out_sim = torch.bmm(sim_map, value.transpose(1, 2))
        # [N, C', T x H x W]
        out_sim = out_sim.transpose(1, 2)
        # [N, C', T,  H, W]
        out_sim = out_sim.view(out_sim.size(0), out_sim.size(1), *x.size()[2:])
        # [N, C, T,  H, W]
        if self.conv_out is not None:
            out_sim = self.conv_out(out_sim)
        # if self.norm is not None:
        #     out = self.norm(out)
        out_sim = self.gamma * out_sim

        # [N, C', 1, 1]
        out_gc = torch.bmm(value, mask.permute(0,2,1)).unsqueeze(-1)

        if self.add_conv is not None:
            out_gc = self.channel_add_conv(out_gc)

        out = residual + out_sim + out_gc
        return out

class NonLocal2dGc(_NonLocalNdGc):

    def __init__(self, inplanes, planes, downsample=False, use_gn=False, lr_mult=None, use_out=False, add_conv=None):
        super(NonLocal2dGc, self).__init__(dim=2, inplanes=inplanes, planes=planes, downsample=downsample, use_gn=use_gn, lr_mult=lr_mult, use_out=use_out, add_conv=add_conv)

class NonLocal3dGc(_NonLocalNdGc):

    def __init__(self, inplanes, planes, downsample, use_gn, lr_mult, use_out):
        super(NonLocal3dGc, self).__init__(dim=3, inplanes=inplanes, planes=planes, downsample=downsample, use_gn=use_gn, lr_mult=lr_mult, use_out=use_out)


import os

from flask import url_for

from werkzeug.utils import secure_filename

from utils import allowed_file

class UploadFileLogic(object):
    """Logic class for taking an HTML uploaded from a flask form, and placing it in a folder"""
    def __init__(self, config):
        self._config = config

    def upload(self, request):
        # check if the post request has the file part
        if 'file' not in request.files:
            print(f"No file part. Redirecting to {request.url}")
            return request.url

        file = request.files['file']
        # if user does not select file, browser also
        # submit an empty part without filename
        if file.filename == '':
            print(f"No file selected. Redirecting to {request.url}")
            return request.url

        if file and allowed_file(file.filename):
            filename_secured = secure_filename(file.filename)

            if not os.path.isdir(os.path.join(self._config['UPLOAD_FOLDER'], request.form['ticker'])):
                os.mkdir(os.path.join(self._config['UPLOAD_FOLDER'], request.form['ticker']))

            file.save(os.path.join(
                f"{self._config['UPLOAD_FOLDER']}/{request.form['ticker']}",
                filename_secured
            ))
            return url_for('process_file', ticker=request.form['ticker'], filename=filename_secured)


import logging
import random
import re
from types import SimpleNamespace

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F

import stanza.models.classifiers.classifier_args as classifier_args
import stanza.models.classifiers.data as data
from stanza.models.common.vocab import PAD_ID, UNK_ID
from stanza.models.common.data import get_long_tensor, sort_all
# TODO: move CharVocab to common
from stanza.models.pos.vocab import CharVocab

"""
The CNN classifier is based on Yoon Kim's work:

https://arxiv.org/abs/1408.5882

The architecture is simple:

- Embedding at the bottom layer
  - separate learnable entry for UNK, since many of the embeddings we have use 0 for UNK
- Some number of conv2d layers over the embedding
- Maxpool layers over small windows, window size being a parameter
- FC layer to the classification layer

One experiment which was run and found to be a bit of a negative was
putting a layer on top of the pretrain.  You would think that might
help, but dev performance went down for each variation of
  - trans(emb)
  - relu(trans(emb))
  - dropout(trans(emb))
  - dropout(relu(trans(emb)))
"""

logger = logging.getLogger('stanza')

class CNNClassifier(nn.Module):
    def __init__(self, pretrain, extra_vocab, labels,
                 charmodel_forward, charmodel_backward,
                 args):
        """
        pretrain is a pretrained word embedding.  should have .emb and .vocab

        extra_vocab is a collection of words in the training data to
        be used for the delta word embedding, if used.  can be set to
        None if delta word embedding is not used.

        labels is the list of labels we expect in the training data.
        Used to derive the number of classes.  Saving it in the model
        will let us check that test data has the same labels

        args is either the complete arguments when training, or the
        subset of arguments stored in the model save file
        """
        super(CNNClassifier, self).__init__()
        self.labels = labels
        # we build a separate config out of the args so that we can easily save it in torch
        self.config = SimpleNamespace(filter_channels = args.filter_channels,
                                      filter_sizes = args.filter_sizes,
                                      fc_shapes = args.fc_shapes,
                                      dropout = args.dropout,
                                      num_classes = len(labels),
                                      wordvec_type = args.wordvec_type,
                                      extra_wordvec_method = args.extra_wordvec_method,
                                      extra_wordvec_dim = args.extra_wordvec_dim,
                                      extra_wordvec_max_norm = args.extra_wordvec_max_norm,
                                      char_lowercase = args.char_lowercase,
                                      charlm_projection = args.charlm_projection,
                                      model_type = 'CNNClassifier')

        if args.char_lowercase:
            self.char_case = lambda x: x.lower()
        else:
            self.char_case = lambda x: x

        self.unsaved_modules = []

        emb_matrix = pretrain.emb
        self.add_unsaved_module('embedding', nn.Embedding.from_pretrained(torch.from_numpy(emb_matrix), freeze=True))
        self.vocab_size = emb_matrix.shape[0]
        self.embedding_dim = emb_matrix.shape[1]

        self.add_unsaved_module('charmodel_forward', charmodel_forward)
        if charmodel_forward is not None:
            self.add_unsaved_module('charmodel_forward_vocab', charmodel_forward.char_vocab())
            logger.debug("Got forward char model of dimension {}".format(charmodel_forward.hidden_dim()))
        self.add_unsaved_module('charmodel_backward', charmodel_backward)
        if charmodel_backward is not None:
            self.add_unsaved_module('charmodel_backward_vocab', charmodel_backward.char_vocab())
            logger.debug("Got backward char model of dimension {}".format(charmodel_backward.hidden_dim()))

        # The Pretrain has PAD and UNK already (indices 0 and 1), but we
        # possibly want to train UNK while freezing the rest of the embedding
        # note that the /10.0 operation has to be inside nn.Parameter unless
        # you want to spend a long time debugging this
        self.unk = nn.Parameter(torch.randn(self.embedding_dim) / np.sqrt(self.embedding_dim) / 10.0)

        self.vocab_map = { word: i for i, word in enumerate(pretrain.vocab) }

        if self.config.extra_wordvec_method is not classifier_args.ExtraVectors.NONE:
            if not extra_vocab:
                raise ValueError("Should have had extra_vocab set for extra_wordvec_method {}".format(self.config.extra_wordvec_method))
            if not args.extra_wordvec_dim:
                self.config.extra_wordvec_dim = self.embedding_dim
            if self.config.extra_wordvec_method is classifier_args.ExtraVectors.SUM:
                if self.config.extra_wordvec_dim != self.embedding_dim:
                    raise ValueError("extra_wordvec_dim must equal embedding_dim for {}".format(self.config.extra_wordvec_method))

            self.extra_vocab = list(extra_vocab)
            self.extra_vocab_map = { word: i for i, word in enumerate(self.extra_vocab) }
            # TODO: possibly add regularization specifically on the extra embedding?
            self.extra_embedding = nn.Embedding(num_embeddings = len(extra_vocab),
                                                embedding_dim = self.config.extra_wordvec_dim,
                                                max_norm = self.config.extra_wordvec_max_norm,
                                                padding_idx = 0)
            logger.debug("Extra embedding size: {}".format(self.extra_embedding.weight.shape))
        else:
            self.extra_vocab = None
            self.extra_vocab_map = None
            self.config.extra_wordvec_dim = 0
            self.extra_embedding = None

        # Pytorch is "aware" of the existence of the nn.Modules inside
        # an nn.ModuleList in terms of parameters() etc
        if self.config.extra_wordvec_method is classifier_args.ExtraVectors.NONE:
            total_embedding_dim = self.embedding_dim
        elif self.config.extra_wordvec_method is classifier_args.ExtraVectors.SUM:
            total_embedding_dim = self.embedding_dim
        elif self.config.extra_wordvec_method is classifier_args.ExtraVectors.CONCAT:
            total_embedding_dim = self.embedding_dim + self.config.extra_wordvec_dim
        else:
            raise ValueError("unable to handle {}".format(self.config.extra_wordvec_method))

        if charmodel_forward is not None:
            if args.charlm_projection:
                self.charmodel_forward_projection = nn.Linear(charmodel_forward.hidden_dim(), args.charlm_projection)
                total_embedding_dim += args.charlm_projection
            else:
                self.charmodel_forward_projection = None
                total_embedding_dim += charmodel_forward.hidden_dim()

        if charmodel_backward is not None:
            if args.charlm_projection:
                self.charmodel_backward_projection = nn.Linear(charmodel_backward.hidden_dim(), args.charlm_projection)
                total_embedding_dim += args.charlm_projection
            else:
                self.charmodel_backward_projection = None
                total_embedding_dim += charmodel_backward.hidden_dim()

        self.conv_layers = nn.ModuleList([nn.Conv2d(in_channels=1,
                                                    out_channels=self.config.filter_channels,
                                                    kernel_size=(filter_size, total_embedding_dim))
                                          for filter_size in self.config.filter_sizes])

        previous_layer_size = len(self.config.filter_sizes) * self.config.filter_channels
        fc_layers = []
        for shape in self.config.fc_shapes:
            fc_layers.append(nn.Linear(previous_layer_size, shape))
            previous_layer_size = shape
        fc_layers.append(nn.Linear(previous_layer_size, self.config.num_classes))
        self.fc_layers = nn.ModuleList(fc_layers)

        self.max_window = max(self.config.filter_sizes)

        self.dropout = nn.Dropout(self.config.dropout)

    def add_unsaved_module(self, name, module):
        self.unsaved_modules += [name]
        setattr(self, name, module)

    def build_char_reps(self, batch_chars, batch_offsets, device, forward=True):
        if forward:
            model = self.charmodel_forward
            vocab = self.charmodel_forward_vocab
            projection = self.charmodel_forward_projection
        else:
            model = self.charmodel_backward
            vocab = self.charmodel_backward_vocab
            projection = self.charmodel_backward_projection

        batch_charlens = [len(x) for x in batch_chars]
        chars_sorted, char_orig_idx = sort_all([batch_chars, batch_offsets], batch_charlens)
        batch_chars, batch_offsets = chars_sorted
        batch_charlens = [len(x) for x in batch_chars]
        chars = get_long_tensor(batch_chars, len(batch_chars),
                                pad_id=vocab.unit2id(' ')).to(device=device)
        char_reps = model.get_representation(chars, batch_offsets,
                                             batch_charlens, char_orig_idx)
        char_reps = char_reps.data
        if projection is not None:
            char_reps = projection(char_reps)
        char_reps = torch.reshape(char_reps, [max(len(x) for x in batch_offsets), len(batch_chars), char_reps.shape[-1]])
        char_reps = torch.transpose(char_reps, 0, 1)

        return char_reps

    def forward(self, inputs, device=None):
        if not device:
            # assume all pieces are on the same device
            device = next(self.parameters()).device

        # we will pad each phrase so either it matches the longest
        # conv or the longest phrase in the input, whichever is longer
        max_phrase_len = max(len(x) for x in inputs)
        if self.max_window > max_phrase_len:
            max_phrase_len = self.max_window

        batch_indices = []
        batch_unknowns = []
        extra_batch_indices = []
        batch_forward_chars = []
        batch_forward_offsets = []
        batch_backward_chars = []
        batch_backward_offsets = []
        for phrase in inputs:
            # we use random at training time to try to learn different
            # positions of padding.  at test time, though, we want to
            # have consistent results, so we set that to 0 begin_pad
            if self.training:
                begin_pad_width = random.randint(0, max_phrase_len - len(phrase))
            else:
                begin_pad_width = 0
            end_pad_width = max_phrase_len - begin_pad_width - len(phrase)

            # the initial lists are the length of the begin padding
            sentence_indices = [PAD_ID] * begin_pad_width
            # the "unknowns" will be the locations of the unknown words.
            # these locations will get the specially trained unknown vector
            sentence_unknowns = []

            for word in phrase:
                if word in self.vocab_map:
                    sentence_indices.append(self.vocab_map[word])
                    continue
                new_word = word.replace("-", "")
                # google vectors have words which are all dashes
                if len(new_word) == 0:
                    new_word = word
                if new_word in self.vocab_map:
                    sentence_indices.append(self.vocab_map[new_word])
                    continue

                if new_word[-1] == "'":
                    new_word = new_word[:-1]
                    if new_word in self.vocab_map:
                        sentence_indices.append(self.vocab_map[new_word])
                        continue

                # TODO: split UNK based on part of speech?  might be an interesting experiment
                sentence_unknowns.append(len(sentence_indices))
                sentence_indices.append(PAD_ID)

            sentence_indices.extend([PAD_ID] * end_pad_width)
            batch_indices.append(sentence_indices)
            batch_unknowns.append(sentence_unknowns)

            if self.extra_vocab:
                extra_sentence_indices = [PAD_ID] * begin_pad_width
                for word in phrase:
                    if word in self.extra_vocab_map:
                        # the extra vocab is initialized from the
                        # words in the training set, which means there
                        # would be no unknown words.  to occasionally
                        # train the extra vocab's unknown words, we
                        # replace 1% of the words with UNK
                        # we don't do that for the original embedding
                        # on the assumption that there may be some
                        # unknown words in the training set anyway
                        # TODO: maybe train unk for the original embedding?
                        if self.training and random.random() < 0.01:
                            extra_sentence_indices.append(UNK_ID)
                        else:
                            extra_sentence_indices.append(self.extra_vocab_map[word])
                    else:
                        extra_sentence_indices.append(UNK_ID)
                extra_sentence_indices.extend([PAD_ID] * end_pad_width)
                extra_batch_indices.append(extra_sentence_indices)

            if self.charmodel_forward is not None:
                start_id, end_id = self.charmodel_forward_vocab.unit2id('\n'), self.charmodel_forward_vocab.unit2id(' ') # special token
                processed_phrase = ([[end_id]] * begin_pad_width +
                                    [self.charmodel_forward_vocab.map([self.char_case(x) for x in w]) + [end_id] for w in phrase] +
                                    [[end_id]] * end_pad_width)
                chars = [start_id]
                offsets = []
                for word in processed_phrase:
                    # -1 because we want the position of the last character
                    chars.extend(word)
                    offsets.append(len(chars)-1)
                batch_forward_chars.append(chars)
                batch_forward_offsets.append(offsets)

            if self.charmodel_backward is not None:
                start_id, end_id = self.charmodel_backward_vocab.unit2id('\n'), self.charmodel_backward_vocab.unit2id(' ') # special token
                processed_phrase = ([[end_id]] * begin_pad_width +
                                    [self.charmodel_backward_vocab.map([self.char_case(x) for x in w[::-1]]) + [end_id] for w in phrase[::-1]] +
                                    [[end_id]] * end_pad_width)
                chars = [start_id]
                offsets = []
                for word in processed_phrase:
                    # -1 because we want the position of the last character
                    chars.extend(word)
                    # backwards because that seems to be what get_representation wants
                    offsets = [len(chars)-1] + offsets
                batch_backward_chars.append(chars)
                batch_backward_offsets.append(offsets)

        # creating a single large list with all the indices lets us
        # create a single tensor, which is much faster than creating
        # many tiny tensors
        # we can convert this to the input to the CNN
        # it is padded at one or both ends so that it is now num_phrases x max_len x emb_size
        # there are two ways in which this padding is suboptimal
        # the first is that for short sentences, smaller windows will
        #   be padded to the point that some windows are entirely pad
        # the second is that a sentence S will have more or less padding
        #   depending on what other sentences are in its batch
        # we assume these effects are pretty minimal
        batch_indices = torch.tensor(batch_indices, requires_grad=False, device=device)
        input_vectors = self.embedding(batch_indices)
        # we use the random unk so that we are not necessarily
        # learning to match 0s for unk
        for phrase_num, sentence_unknowns in enumerate(batch_unknowns):
            for unknown in sentence_unknowns:
                input_vectors[phrase_num, unknown, :] = self.unk

        if self.extra_vocab:
            extra_batch_indices = torch.tensor(extra_batch_indices, requires_grad=False, device=device)
            extra_input_vectors = self.extra_embedding(extra_batch_indices)
            if self.config.extra_wordvec_method is classifier_args.ExtraVectors.CONCAT:
                all_inputs = [input_vectors, extra_input_vectors]
            elif self.config.extra_wordvec_method is classifier_args.ExtraVectors.SUM:
                all_inputs = [input_vectors + extra_input_vectors]
            else:
                raise ValueError("unable to handle {}".format(self.config.extra_wordvec_method))
        else:
            all_inputs = [input_vectors]

        if self.charmodel_forward is not None:
            char_reps_forward = self.build_char_reps(batch_forward_chars, batch_forward_offsets, device, forward=True)
            all_inputs.append(char_reps_forward)

        if self.charmodel_backward is not None:
            char_reps_backward = self.build_char_reps(batch_backward_chars, batch_backward_offsets, device, forward=False)
            all_inputs.append(char_reps_backward)

        if len(all_inputs) > 1:
            input_vectors = torch.cat(all_inputs, dim=2)
        else:
            input_vectors = all_inputs[0]

        # reshape to fit the input tensors
        x = input_vectors.unsqueeze(1)

        conv_outs = [self.dropout(F.relu(conv(x).squeeze(3)))
                     for conv in self.conv_layers]
        pool_outs = [F.max_pool1d(out, out.shape[2]).squeeze(2) for out in conv_outs]
        pooled = torch.cat(pool_outs, dim=1)

        previous_layer = pooled
        for fc in self.fc_layers[:-1]:
            previous_layer = self.dropout(F.relu(fc(previous_layer)))
        out = self.fc_layers[-1](previous_layer)
        return out

# TODO: make some of the following methods part of the class

# TODO: all this code is basically the same as for POS and NER.  Should refactor
def save(filename, model, skip_modules=True):
    model_state = model.state_dict()
    # skip saving modules like pretrained embeddings, because they are large and will be saved in a separate file
    if skip_modules:
        skipped = [k for k in model_state.keys() if k.split('.')[0] in model.unsaved_modules]
        for k in skipped:
            del model_state[k]
    params = {
        'model': model_state,
        'config': model.config,
        'labels': model.labels,
        'extra_vocab': model.extra_vocab,
    }
    try:
        torch.save(params, filename, _use_new_zipfile_serialization=False)
        logger.info("Model saved to {}".format(filename))
    except (KeyboardInterrupt, SystemExit):
        raise
    except BaseException as e:
        logger.warning("Saving failed to {}... continuing anyway.  Error: {}".format(filename, e))

def load(filename, pretrain, charmodel_forward, charmodel_backward):
    try:
        checkpoint = torch.load(filename, lambda storage, loc: storage)
    except BaseException:
        logger.exception("Cannot load model from {}".format(filename))
        raise
    logger.debug("Loaded model {}".format(filename))

    # TODO: should not be needed when all models have this value set
    setattr(checkpoint['config'], 'char_lowercase', getattr(checkpoint['config'], 'char_lowercase', False))
    setattr(checkpoint['config'], 'charlm_projection', getattr(checkpoint['config'], 'charlm_projection', None))

    # TODO: the getattr is not needed when all models have this baked into the config
    model_type = getattr(checkpoint['config'], 'model_type', 'CNNClassifier')
    if model_type == 'CNNClassifier':
        extra_vocab = checkpoint.get('extra_vocab', None)
        model = CNNClassifier(pretrain=pretrain,
                              extra_vocab=extra_vocab,
                              labels=checkpoint['labels'],
                              charmodel_forward=charmodel_forward,
                              charmodel_backward=charmodel_backward,
                              args=checkpoint['config'])
    else:
        raise ValueError("Unknown model type {}".format(model_type))
    model.load_state_dict(checkpoint['model'], strict=False)

    logger.debug("-- MODEL CONFIG --")
    for k in model.config.__dict__:
        logger.debug("  --{}: {}".format(k, model.config.__dict__[k]))

    logger.debug("-- MODEL LABELS --")
    logger.debug("  {}".format(" ".join(model.labels)))

    return model

def label_text(model, text, batch_size=None, reverse_label_map=None, device=None):
    """
    Given a list of sentences, return the model's results on that text.
    """
    model.eval()
    if reverse_label_map is None:
        reverse_label_map = {x: y for (x, y) in enumerate(model.labels)}
    if device is None:
        device = next(model.parameters()).device

    text = [data.update_text(s, model.config.wordvec_type) for s in text]

    if batch_size is None:
        intervals = [(0, len(text))]
    else:
        # TODO: results would be better if we sort by length and then unsort
        intervals = [(i, min(i+batch_size, len(text))) for i in range(0, len(text), batch_size)]
    labels = []
    for interval in intervals:
        if interval[1] - interval[0] == 0:
            # this can happen for empty text
            continue
        output = model(text[interval[0]:interval[1]], device)
        predicted = torch.argmax(output, dim=1)
        labels.extend(predicted.tolist())

    logger.debug("Found labels")
    for (label, sentence) in zip(labels, text):
        logger.debug((label, sentence))

    return labels


# print("Hello! Please complete this survey for me.")
# print("What is your name?")

# new_dict = {"name": "trang", 13: "tiger", "may":5}

# print(new_dict["name"])

# for each in new_dict:
#     print(new_dict[each])

# dict = {"name": 23}

import time
import json

ls = []

print("Hello please complete this survey.")
dict = {}

def questions(dict):
    answer = input("what's your name?")
    dict["name"] = answer
    time.sleep(0.5)
    answer = input("when is your birthday? (MM/DD/YYYY)")
    dict["bday"] = answer
    time.sleep(0.5)
    answer = input("what is your favorite boba place?")
    dict["boba"] = answer
    time.sleep(0.5)
    answer = input("Who is your celebrity crush?")
    dict["celeb crush"] = answer
    time.sleep(0.5)
    answer = input("What is your biggest fear?")
    dict["fear"] = answer
    time.sleep(0.5)

for i in range(2):
    dict = {}
    questions(dict)
    ls.append(dict)
tojson = json.dumps(ls)

print(tojson)
print(ls)

with open('dictionary.json', 'w') as outfile:
        json.dump(ls, outfile)


import numpy as np
import multiprocessing as mp

from . import utility
from . import constants
from .agents import SparringAgent

class DataGenerator:
    def __init__(self, num_workers=constants.NUM_WORKERS):
        self.num_workers = num_workers

    def agent_simulation(self, worker_id, num_games, sparrer_type):
        # NOTE: may need more imports for network agents
        np.random.seed()

        raw_training_examples = []
        for _ in range(num_games):
            agent = SparringAgent(sparrer_type=sparrer_type, agent_id = worker_id % constants.MAX_PLAYERS)
            raw_training_examples += agent.simulate()

        print('Worker {} Generated {} examples'.format(worker_id, len(raw_training_examples)))
        return raw_training_examples

    def generate_agent_data(self, num_games, sparrer_type):
        process_pool = mp.Pool(processes=self.num_workers)
        workers_results = []

        for i in range(self.num_workers):
            data_async = process_pool.apply_async(self.agent_simulation, args=(i, num_games, sparrer_type))
            workers_results.append(data_async)

        try:
            training_data_X = []
            training_data_y = []
            for res in workers_results:
                worker_data = res.get()
                for X, y, agent_id in worker_data:
                    X = utility.convert_to_model_input(agent_id, X)
                    training_data_X.append(X)
                    training_data_y.append(y)

            process_pool.close()
            process_pool.join()

            # training_data_X = np.array(training_data_X)
            # training_data_y = np.array(training_data_y)

            # # Augment training data
            # X_augment = []
            # y_augment = []
            # for i in range(len(training_data_X)):
            #     X, y = utility.augment_data(training_data_X[i], training_data_y[i])
            #     X_augment.append(X)
            #     y_augment.append(y)

            # X_augment = np.concatenate(X_augment)
            # y_augment = np.concatenate(y_augment)

            return training_data_X, training_data_y

        except KeyboardInterrupt:
            print('SIGINT caught, exiting')
            process_pool.terminate()
            process_pool.join()
            exit()

    def generate_simple_agent_data(self, num_games):
        return self.generate_agent_data(num_games, sparrer_type=constants.SIMPLE_SPARRER)

if __name__ == '__main__':
    generator = DataGenerator(num_workers=constants.NUM_WORKERS)
    training_data_X, training_data_y = generator.generate_simple_agent_data(1)


import os
import random

os.environ["KERAS_BACKEND"] = "tensorflow"

with_gpu = True # not massive difference in speed, but faster with GPU
if not with_gpu:
    os.environ["CUDA_VISIBLE_DEVICES"] = ""

import numpy as np
import tensorflow as tf

from keras.callbacks import ModelCheckpoint, TensorBoard
from keras.models import Sequential, load_model
from keras.layers.core import Dense, Dropout, Flatten, Lambda
from keras.layers.convolutional import Conv2D, Cropping2D
from keras.layers.pooling import AveragePooling2D, MaxPooling2D

from sklearn.model_selection import train_test_split
from sklearn.utils import shuffle

import csv
import cv2

FLAGS = tf.app.flags.FLAGS

tf.app.flags.DEFINE_string(
    'data_dir',
    'data/',
    "directory containing driving_log.csv and IMG/*.jpg"
)

tf.app.flags.DEFINE_string(
    'model_file',
    'model.h5',
    "file where model should be saved"
)

tf.app.flags.DEFINE_float(
    'correction',
    0.025, # previously 0.015
    "correction to be applied to center-steering on left and right images"
) #TODO: calibrate further

tf.app.flags.DEFINE_bool(
    'include_sides',
    True,
    "determines whether the images taken from left/right sides are used"
)

tf.app.flags.DEFINE_bool(
    'augment_data',
    False,
    "determines whether data augmentation is used"
)

tf.app.flags.DEFINE_integer(
    'epochs',
    3,
    "number of training epochs"
)

tf.app.flags.DEFINE_integer(
    'raw_batch_size',
    64,
    "batches are constructed from this many base pictures (pre-augmentation)"
) # with flipping + side views, augmented b.s. is 6 * FLAGS.raw_batch_size

tf.app.flags.DEFINE_bool(
    'reset',
    True,
    "If False, previous model will be loaded at the start."
)

def get_data():
    print("Loading data in directory {}...".format(FLAGS.data_dir))
    data = []
    with open(os.path.join(FLAGS.data_dir, "driving_log.csv"), 'r') as f:
        reader = csv.reader(f)
        next(reader, None) # skip headers
        for row in reader:
            data.append(row)
    return data

def get_augmentation(images):
    hsvs = np.array([cv2.cvtColor(img, cv2.COLOR_RGB2HSV) for img in images])
    for i in range(hsvs.shape[0]):
        hsv = (np.random.randint(low=0.5, high=1.5) * hsvs[i,:,:,2]).round()
        hsv = np.minimum.reduce([hsv, 255*np.ones_like(hsv)]) # avoid overflow
        hsvs[i,:,:,2] = hsv.astype(np.uint8)
    return [cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB) for hsv in hsvs]

def generator(data):
    while True:
        random.shuffle(data)
        for first in range(0, len(data), FLAGS.raw_batch_size):
            last = min(first + FLAGS.raw_batch_size, len(data))
            center_images = []
            left_images = []
            right_images = []
            steering_measurements = []
            for c, l, r, steering, throttle, brake, speed in data[first:last]:
                # strip is used to remove leading whitespace
                img_c = cv2.imread(os.path.join(FLAGS.data_dir, c.strip()))
                img_c = cv2.cvtColor(img_c, cv2.COLOR_BGR2RGB)
                img_l = cv2.imread(os.path.join(FLAGS.data_dir, l.strip()))
                img_l = cv2.cvtColor(img_l, cv2.COLOR_BGR2RGB)
                img_r = cv2.imread(os.path.join(FLAGS.data_dir, r.strip()))
                img_r = cv2.cvtColor(img_r, cv2.COLOR_BGR2RGB)
                center_images.append(img_c)
                left_images.append(img_l)
                right_images.append(img_r)
                steering = float(steering)
                steering_measurements.append(steering)
            images = np.array(center_images)
            steering_measurements = np.array(steering_measurements)
            if FLAGS.include_sides:
                images = np.concatenate((
                    images,
                    np.array(left_images),
                    np.array(right_images)
                ))
                steering_measurements = np.concatenate((
                    steering_measurements,
                    steering_measurements + FLAGS.correction,
                    steering_measurements - FLAGS.correction
                ))
            if FLAGS.augment_data:
                augmented = get_augmentation(images)
                images = np.concatenate((images, augmented))
                steering_measurements = np.concatenate((
                    steering_measurements,
                    steering_measurements
                ))
            X_batch = np.concatenate((images, np.fliplr(images)))
            y_batch = np.concatenate(
                (steering_measurements, -steering_measurements)
            )
            yield X_batch, y_batch

def commaai_net():
    model = Sequential()
    model.add(Cropping2D(
        cropping=((60, 30), (0, 0)),
        input_shape=(160, 320, 3)
    ))
    model.add(Lambda(lambda x: x/127.5 - 1.0))
    model.add(Conv2D(filters=4,kernel_size=3,strides=(1,2),activation='elu'))
    model.add(Conv2D(filters=4,kernel_size=3,strides=(1,2),activation='elu'))
    model.add(Conv2D(filters=4,kernel_size=5,strides=(2,3),activation='elu'))
    model.add(Flatten())
    model.add(Dropout(0.2))
    model.add(Dense(512, activation='elu'))
    model.add(Dropout(0.5))
    model.add(Dense(1))
    return model

def nvidia_net():
    # https://arxiv.org/pdf/1604.07316.pdf
    model = Sequential()
    model.add(Cropping2D(
        cropping=((60, 30), (0, 0)), # lectures suggest ((50,20),(0,0))
        input_shape=(160, 320, 3)
    )) # shape (70,320,3)
    model.add(Lambda(lambda img: tf.image.resize_images(img, (35, 160))))
    model.add(Lambda(lambda x: x/127.5 - 1.0))
    model.add(Conv2D(
        filters=24,
        kernel_size=5,
        strides=(1,2), # paper uses (2,2) but our input dims are different
        activation='relu',
        padding="valid"
    ))
    model.add(Conv2D(
        filters=36,
        kernel_size=5,
        strides=(2,2),
        activation='relu',
        padding="valid"
    ))
    model.add(Conv2D(
        filters=48,
        kernel_size=3,
        strides=(2,2),
        activation='relu',
        padding="valid"
    ))
    model.add(Conv2D(
        filters=64,
        kernel_size=3,
        strides=(2,2),
        activation='relu',
        padding="valid"
    ))
    model.add(Conv2D(
        filters=64,
        kernel_size=1,
        strides=(2,2),
        activation='relu',
        padding="valid"
    ))
    model.add(Flatten())
    model.add(Dense(1164, activation='relu'))
    model.add(Dense(100, activation='relu'))
    model.add(Dense(50, activation='relu'))
    model.add(Dense(10, activation='relu'))
    model.add(Dense(1))
    return model

def mod_lenet():
    model = Sequential()
    model.add(Cropping2D(
        cropping=((60, 30), (0, 0)),
        input_shape=(160, 320, 3)
    )) # shape (70,320,3)
    model.add(Lambda(lambda img: tf.image.resize_images(img, (35, 160))))
    model.add(Lambda(lambda x: x/127.5 - 1.0))
    model.add(Conv2D(
        filters=32,
        kernel_size=5,
        strides=(1,2),
        activation='relu',
        padding="valid"
    ))
    model.add(AveragePooling2D())
    model.add(Conv2D(
        filters=32,
        kernel_size=5,
        strides=(1,2),
        activation='relu',
        padding="same"
    ))
    model.add(AveragePooling2D())
    model.add(Dropout(0.2))
    model.add(Flatten())
    model.add(Dense(32, activation='relu'))
    model.add(Dense(32, activation='relu'))
    model.add(Dense(32, activation='relu'))
    model.add(Dense(1))
    return model

def encoder_net():
    model = Sequential()
    model.add(Cropping2D(
        cropping=((60, 30), (0, 0)),
        input_shape=(160, 320, 3)
    )) # shape (70,320,3)
    model.add(Lambda(lambda img: tf.image.resize_images(img, (35, 160))))
    model.add(Lambda(lambda x: x/127.5 - 1.0))
    model.add(Dropout(0.2))
    model.add(Conv2D(
        filters=32,
        kernel_size=5,
        strides=(1,2),
        activation='relu',
        padding="valid"
    ))
    model.add(AveragePooling2D())
    model.add(Conv2D(
        filters=32,
        kernel_size=5,
        strides=(1,2),
        activation='relu',
        padding="same"
    ))
    model.add(AveragePooling2D())
    model.add(Flatten())
    model.add(Dense(16, activation='relu'))
    model.add(Dense(4, activation='relu'))
    model.add(Dense(16, activation='relu'))
    model.add(Dense(16, activation='relu'))
    model.add(Dense(16, activation='relu'))
    model.add(Dense(1))
    return model

def get_model():
    #return commaai_net()
    #return nvidia_net()
    #return mod_lenet()
    return encoder_net()

def main(_):
    data = get_data()
    random.shuffle(data)
    training_data = data[:int(0.8*len(data))]
    validation_data = data[int(0.8*len(data)):]
    train_gen = generator(training_data)
    valid_gen = generator(validation_data)
    model = get_model()
    if not FLAGS.reset:
        model = load_model(FLAGS.model_file)
    print(model.summary())
    model.compile(loss='mse', optimizer='adam')
    model.fit_generator(
        generator=train_gen,
        steps_per_epoch=int(np.ceil(len(training_data)/FLAGS.raw_batch_size)),
        epochs=FLAGS.epochs,
        callbacks=[
            ModelCheckpoint(FLAGS.model_file),
            TensorBoard(
                write_images=True,
                batch_size=FLAGS.raw_batch_size
            )
        ],
        verbose=1,
        validation_data=valid_gen,
        validation_steps=int(np.ceil(len(validation_data)/FLAGS.raw_batch_size))
    )

if __name__ == '__main__':
    tf.app.run()


# Uses python3
import sys
from collections import namedtuple

Segment = namedtuple('Segment', 'start end')

def intersect(a, b):
    """ return the intersection of two lists """
    return list(set(a) & set(b))

def optimal_points(segments):
    points = []
    #write your code here
    segments.sort()
    previous =segments[0]

    for segment in segments[1:]:
        current=list(range(segment.start,segment.end+1))
        if intersect(previous , current) :
            previous = intersect(previous, current)
        else:
            points.append(previous[-1])
            previous = current

    if intersect(previous, current):
        points.append(previous[-1])
return points

if __name__ == '__main__':
    input = sys.stdin.read()
    n, *data = map(int, input.split())
    segments = list(map(lambda x: Segment(x[0], x[1]), zip(data[::2], data[1::2])))
    points = optimal_points(segments)
    print(len(points))
    for p in points:
        print(p, end=' ')


import threading

from collections import defaultdict
from flask import Flask, render_template
from flips.ahflips import find_profitable_flips, bin_auctions
from flips.utils import get_key, keys

app = Flask(__name__)

KEY = get_key()
KEY_RESPONSES = defaultdict(list)

@app.route('/')
def index():
    return render_template(
        'index.html',
        key=KEY.__next__()
    )

def flips_thread(key):
    for auction in bin_auctions(key):
        KEY_RESPONSES[key].append(auction)

@app.route('/rpc/start_flips/<string:key>')
def start_flips(key):
    KEY_RESPONSES[key] = []
    thread = threading.Thread(target=flips_thread, args=[key])
    thread.start()
    return {"success": True}

@app.route('/rpc/get_flips/<string:key>')
def get_flips(cookie, key):
    if key not in keys:
        return 'Invalid Key'
    return find_profitable_flips(KEY_RESPONSES.get(key))

if __name__ == '__main__':
    app.run('0.0.0.0', 8080)


#!/usr/bin/env python2
# Import libraries
try:
    import pygame_sdl2
    pygame_sdl2.import_as_pygame()
    import pygame, sys, menu, math, random
    from pygame.locals import *
except:
    import pygame, sys, menu, math, random
    from pygame.locals import *

def play(fps):
    # Set the width and height of the window
    width, height = 640, 480
    # Create the window
    screen = pygame.display.set_mode((width, height), pygame.HWSURFACE | pygame.DOUBLEBUF)
    # Set pressed keys
    keys = [False, False, False, False]
    # Set player position
    playerpos=[100,100]
    # Make an list for the accuracy
    acc=[0,0]
    # Make an list for where the arrows are
    arrows=[]
    # Set the timer for spawning badgers
    badtimer=100
    badtimer1=0
    # Make an list for where the badgers are
    badguys=[[800,100]]
    # Set your health value
    healthvalue=194
    # Set the wait times
    waitforexit=0
    waitforarrows=0
    waitforballoons=0
    waitforballoons2=2
    # Set displaying balloon on/off
    balloon1display = False
    balloon2display = False
    # Set start ticks
    startticks = pygame.time.get_ticks()
    # Set title
    pygame.display.set_caption("Bunny and Badgers")

    # Load images
    # Load the players image
    player = pygame.image.load("resources/images/dude.png").convert_alpha()
    # Load the background image
    grass = pygame.image.load("resources/images/grass.png").convert()
    # Load the image of the castles
    castle = pygame.image.load("resources/images/castle.png").convert_alpha()
    # Load the image for the arrows
    arrow = pygame.image.load("resources/images/bullet.png").convert_alpha()
    # Load the image for the badgers
    badguyimg1 = pygame.image.load("resources/images/badguy.png").convert_alpha()
    badguyimg2 = pygame.image.load("resources/images/badguy2.png").convert_alpha()
    badguyimg3 = pygame.image.load("resources/images/badguy3.png").convert_alpha()
    badguyimg4 = pygame.image.load("resources/images/badguy4.png").convert_alpha()
    badguyimg = badguyimg1
    # Load the overlays
    greenoverlay = pygame.image.load("resources/images/greenoverlay.png").convert_alpha()
    redoverlay = pygame.image.load("resources/images/redoverlay.png").convert_alpha()
    # Load the healthbar images
    healthbar = pygame.image.load("resources/images/healthbar.png").convert_alpha()
    health = pygame.image.load("resources/images/health.png").convert_alpha()
    # Load the text balloons
    balloon1 = pygame.image.load("resources/images/balloon1.png").convert_alpha()
    balloon2 = pygame.image.load("resources/images/balloon2.png").convert_alpha()

    # Set positions
    castle1 = (0,height/16)
    castle2 = (0,height/3.5)
    castle3 = (0,height/2)
    castle4 = (0,height/1.4)

    # Create a clock
    clock = pygame.time.Clock()

    # Keep looping through
    running = 1
    exitcode = 0
    while running:
        badtimer-=1
        # Draw the background
        for x in range(width/grass.get_width()+1):
            for y in range(height/grass.get_height()+1):
                screen.blit(grass,(x*100,y*100))
        # Draw the castles
        screen.blit(castle, castle1)
        screen.blit(castle, castle2)
        screen.blit(castle, castle3)
        screen.blit(castle, castle4)
        # Set player position and rotation
        if True:
            position = pygame.mouse.get_pos()
            angle = math.atan2(position[1]-(playerpos[1]+32),position[0]-(playerpos[0]+26))
            playerrot = pygame.transform.rotate(player, 360-angle*57.29)
            playerpos1 = (playerpos[0]-playerrot.get_rect().width/2, playerpos[1]-playerrot.get_rect().height/2)
            screen.blit(playerrot, playerpos1)

        # Draw arrows
        for bullet in arrows:
            index=0
            velx=math.cos(bullet[0])*10
            vely=math.sin(bullet[0])*10
            bullet[1]+=velx
            bullet[2]+=vely
            if bullet[1]<-64 or bullet[1]>width or bullet[2]<-64 or bullet[2]>height:
                arrows.pop(index)
            index+=1
            for projectile in arrows:
                arrow1 = pygame.transform.rotate(arrow, 360-projectile[0]*57.29)
                screen.blit(arrow1, (projectile[1], projectile[2]))

        # Change the image of the badgers
        if badguyimg == badguyimg1:
            badguyimg = badguyimg2
        elif badguyimg == badguyimg2:
            badguyimg = badguyimg3
        elif badguyimg == badguyimg3:
            badguyimg = badguyimg4
        elif badguyimg == badguyimg4:
            badguyimg = badguyimg1

        # Draw badgers
        if badtimer==0:
            badheight1 = height/9.6
            badheight2 = height/1.1
            badheight = random.randint(int(badheight1), int(badheight2))
            badguys.append([width, badheight])
            badtimer=100-(badtimer1*2)
            if badtimer1>=35:
                badtimer1=35
            else:
                badtimer1+=5
        index=0
        for badguy in badguys:
            if badguy[0]<-64:
                badguys.pop(index)
            badguy[0]-=7
            # Attack castle
            badrect=pygame.Rect(badguyimg.get_rect())
            badrect.top=badguy[1]
            badrect.left=badguy[0]
            if badrect.left<64:
                healthvalue -= random.randint(5,20)
                badguys.pop(index)
            # Check for collisions
            index1=0
            for bullet in arrows:
                bullrect=pygame.Rect(arrow.get_rect())
                bullrect.left=bullet[1]
                bullrect.top=bullet[2]
                if badrect.colliderect(bullrect):
                    acc[0]+=1
                    badguys.pop(index)
                    arrows.pop(index1)
                index1+=1
            # Next bad guy
            index+=1
        # Draw badgers
        for badguy in badguys:
            screen.blit(badguyimg, badguy)
        # Draw clock
        font = pygame.font.Font("freesansbold.ttf", 24)
        survivedtext = font.render(str((90000-pygame.time.get_ticks()+startticks)/60000)+":"+str((90000-pygame.time.get_ticks()+startticks)/1000%60).zfill(2), True, (0,0,0))
        textRect = survivedtext.get_rect()
        textRect.topright=[width-5, 5]
        screen.blit(survivedtext, textRect)
        # Draw health bar
        screen.blit(healthbar, (5,5))
        for health1 in range(healthvalue):
            screen.blit(health, (health1+8,8))
        # Loop through the events
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                # Move up
                if event.key in (K_w, K_UP):
                    keys[0]=True
                # Move left
                elif event.key in (K_a, K_LEFT):
                    keys[1]=True
                # Move down
                elif event.key in (K_s, K_DOWN):
                    keys[2]=True
                # Move right
                elif event.key in (K_d, K_RIGHT):
                    keys[3]=True
                # Quit by pressing back
                elif event.key==K_AC_BACK:
                    menu.launch()
            if event.type == pygame.KEYUP:
                # Move up
                if event.key in (K_w, K_UP):
                    keys[0]=False
                # Move left
                elif event.key in (K_a, K_LEFT):
                    keys[1]=False
                # Move down
                elif event.key in (K_s, K_DOWN):
                    keys[2]=False
                # Move right
                elif event.key in (K_d, K_RIGHT):
                    keys[3]=False
            # Check if you pressed a mouse button for shooting arrows
            if event.type==pygame.MOUSEBUTTONDOWN:
                if waitforarrows == 0:
                    position=pygame.mouse.get_pos()
                    acc[1]+=1
                    arrows.append([math.atan2(position[1]-(playerpos1[1]+32),position[0]-(playerpos1[0]+26)),playerpos1[0]+32,playerpos1[1]+32])
                    # Set wait time for arrows in frames
                    waitforarrows=15
                    if waitforballoons2:
                        waitforballoons2-=1
                    else:
                        # Choose balloon
                        balloonnr = random.randint(1, 2)
                        if balloonnr == 1:
                            balloon1display = True
                        elif balloonnr == 2:
                            balloon2display = True
                        waitforballoons2=2
        if waitforarrows:
            waitforarrows-=1
            waitforballoons = waitforarrows
        # Display balloon
        if waitforballoons:
            waitforballoons-=1
            if balloon1display:
                screen.blit(balloon1, (playerpos[0]+10, playerpos[1]-60))
            elif balloon2display:
                screen.blit(balloon2, (playerpos[0]+10, playerpos[1]-60))
        else:
            balloon1display = False
            balloon2display = False

        # Move player
        # Up
        if keys[0]:
            playerpos[1]-=5
        # Down
        elif keys[2]:
            playerpos[1]+=5
        # Left
        if keys[1]:
            playerpos[0]-=5
        # Right
        elif keys[3]:
            playerpos[0]+=5

        # Win/Lose check
        # Win
        if (pygame.time.get_ticks()-startticks)>=90000:
            running=0
            exitcode=1
        # Lose
        if healthvalue<=0:
            running=0
            exitcode=0
        if acc[1]!=0:
            accuracy=acc[0]*1.0/acc[1]*100
        else:
            accuracy=0

        # Flip the display
        pygame.display.flip()

        # Lock fps
        clock.tick(fps)

    # Win/lose display
    # Lose
    if exitcode==0:
        # Initialize the font
        pygame.font.init()
        # Set font
        font = pygame.font.Font("freesansbold.ttf", 24)
        bigfont = pygame.font.Font("freesansbold.ttf", 48)
        # Render text
        gameover = bigfont.render("Game over!", True, (255,0,0))
        gameoverRect = gameover.get_rect()
        gameoverRect.centerx = screen.get_rect().centerx
        gameoverRect.centery = screen.get_rect().centery-24
        text = font.render("Accuracy: "+str(accuracy)+"%", True, (255,0,0))
        textRect = text.get_rect()
        textRect.centerx = screen.get_rect().centerx
        textRect.centery = screen.get_rect().centery+24
        # Draw red overlay
        for x in range(width/redoverlay.get_width()+1):
            for y in range(height/redoverlay.get_height()+1):
                screen.blit(redoverlay,(x*100,y*100))
        # Draw text
        screen.blit(gameover, gameoverRect)
        screen.blit(text, textRect)
    # Win
    else:
        # Initialize the font
        pygame.font.init()
        # Set font
        font = pygame.font.Font("freesansbold.ttf", 24)
        bigfont = pygame.font.Font("freesansbold.ttf", 48)
        # Render text
        youwin = bigfont.render("You win!", True, (0,255,0))
        youwinRect = youwin.get_rect()
        youwinRect.centerx = screen.get_rect().centerx
        youwinRect.centery = screen.get_rect().centery-24
        text = font.render("Accuracy: "+str(accuracy)+"%", True, (0,255,0))
        textRect = text.get_rect()
        textRect.centerx = screen.get_rect().centerx
        textRect.centery = screen.get_rect().centery+24
        # Draw green overlay
        for x in range(width/greenoverlay.get_width()+1):
            for y in range(height/greenoverlay.get_height()+1):
                screen.blit(greenoverlay,(x*100,y*100))
        # Draw text
        screen.blit(youwin, youwinRect)
        screen.blit(text, textRect)
    # Exit automatic when the game is stopped
    while 1:
        waitforexit+=1
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        if waitforexit == 1000:
            menu.launch()
        # Update the screen
        pygame.display.flip()