import numpy as np

import torch
import torch.optim as optim
import torch.nn as nn
import torch.nn.functional as F

from agents.BaseAgent import BaseAgent
from networks.networks import ActorCriticAtari
from utils.RolloutStorage import RolloutStorage

from timeit import default_timer as timer

class Model(BaseAgent):
    def __init__(self, static_policy=False, env=None, config=None, log_dir='/tmp/gym'):
        super(Model, self).__init__(config=config, env=env, log_dir=log_dir)
        self.config = config
        self.static_policy = static_policy
        self.num_feats = env.observation_space.shape
        self.num_actions = env.action_space.n
        self.env = env

        self.declare_networks()

        if not self.config.recurrent_policy_grad:
            self.optimizer = optim.RMSprop(self.model.parameters(), lr=self.config.LR, alpha=0.99, eps=1e-5)
        else:
            self.optimizer = optim.Adam(self.model.parameters(), lr=self.config.LR, amsgrad=True)

        #move to correct device
        self.model = self.model.to(self.config.device)

        if self.static_policy:
            self.model.eval()
        else:
            self.model.train()

        self.config.rollouts = RolloutStorage(self.config.rollout, self.config.num_agents,
            self.num_feats, self.env.action_space, self.model.state_size,
            self.config.device, config.USE_GAE, config.gae_tau)

        self.value_losses = []
        self.entropy_losses = []
        self.policy_losses = []

    def declare_networks(self):
        self.model = ActorCriticAtari(self.num_feats, self.num_actions, self.config.recurrent_policy_grad, self.config.gru_size)

    def get_action(self, s, states, masks, deterministic=False):
        logits, values, states = self.model(s, states, masks)
        dist = torch.distributions.Categorical(logits=logits)

        if deterministic:
            actions = dist.probs.argmax(dim=1, keepdim=True)
        else:
            actions = dist.sample().view(-1, 1)

        log_probs = F.log_softmax(logits, dim=1)
        action_log_probs = log_probs.gather(1, actions)

        return values, actions, action_log_probs, states

    def evaluate_actions(self, s, actions, states, masks):
        logits, values, states = self.model(s, states, masks)

        dist = torch.distributions.Categorical(logits=logits)

        log_probs = F.log_softmax(logits, dim=1)
        action_log_probs = log_probs.gather(1, actions)

        dist_entropy = dist.entropy().mean()

        return values, action_log_probs, dist_entropy, states

    def get_values(self, s, states, masks):
        _, values, _ = self.model(s, states, masks)

        return values

    def compute_loss(self, rollouts, next_value):
        obs_shape = rollouts.observations.size()[2:]
        action_shape = rollouts.actions.size()[-1]
        num_steps, num_processes, _ = rollouts.rewards.size()

        rollouts.compute_returns(next_value, self.config.GAMMA)

        values, action_log_probs, dist_entropy, states = self.evaluate_actions(
            rollouts.observations[:-1].view(-1, *obs_shape),
            rollouts.actions.view(-1, 1),
            rollouts.states[0].view(-1, self.model.state_size),
            rollouts.masks[:-1].view(-1, 1))

        values = values.view(num_steps, num_processes, 1)
        action_log_probs = action_log_probs.view(num_steps, num_processes, 1)

        advantages = rollouts.returns[:-1] - values
        value_loss = advantages.pow(2).mean()

        action_loss = -(advantages.detach() * action_log_probs).mean()

        loss = action_loss + self.config.value_loss_weight * value_loss
        loss -= self.config.entropy_loss_weight * dist_entropy

        return loss, action_loss, value_loss, dist_entropy

    def update(self, rollout, next_value):
        loss, action_loss, value_loss, dist_entropy = self.compute_loss(rollout, next_value)

        self.optimizer.zero_grad()
        loss.backward()
        torch.nn.utils.clip_grad_norm_(self.model.parameters(), self.config.grad_norm_max)
        self.optimizer.step()

        #self.save_loss(loss.item(), action_loss.item(), value_loss.item(), dist_entropy.item())

        return value_loss.item(), action_loss.item(), dist_entropy.item()

    def save_distance(self, max_dist, tstep):
        pass

    '''def save_loss(self, loss, policy_loss, value_loss, entropy_loss):
        super(Model, self).save_loss(loss)
        self.policy_losses.append(policy_loss)
        self.value_losses.append(value_loss)
        self.entropy_losses.append(entropy_loss)'''


from django.db import models
from . import fields
from operator import iand, ior

class Offer(models.Model):
    coupon_code = models.CharField(max_length=30)
    slug = models.SlugField(max_length=30, unique=True)
    short_description=models.CharField(max_length=50)

    popularity=models.IntegerField()
    description=models.CharField(max_length=500)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    valid_from=models.DateTimeField()
    expire_at=models.DateTimeField()

    class Meta:
        ordering = ('popularity', )
        index_together = (('id', 'slug'),)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('offers:offer_detail', args=[self.id, self.slug])

class Discount(models.Model):
    """
    Abstract model representing one of several types of monetary
    reductions, as well as a date range they're applicable for, and
    the products and products in categories that the reduction is
    applicable for.
    """

    title = models.CharField(max_length=100)
    active = models.BooleanField(_("Active"), default=False)
    popularity=models.IntegerField()

    products = models.ManyToManyField("Product", blank=True,
                                      verbose_name=_("Products"))
    categories = models.ManyToManyField("Category", blank=True,
                                        related_name="%(class)s_related",
                                        verbose_name=_("Categories"))
    discount_deduct = fields.MoneyField(_("Reduce by amount"))
    discount_percent = fields.PercentageField(_("Reduce by percent"),
                                           max_digits=5, decimal_places=2,
                                           blank=True, null=True)
    max_user_usage=models.IntegerField()

    discount_exact = fields.MoneyField(_("Reduce to amount"))
    valid_from = models.DateTimeField(_("Valid from"), blank=True, null=True)
    valid_to = models.DateTimeField(_("Valid to"), blank=True, null=True)

    class Meta:
        abstract = True

    def __str__(self):
        return self.title

    def all_products(self):
        """
        Return the selected products as well as the products in the
        selected categories.
        """
        filters = [category.filters() for category in self.categories.all()]
        filters = reduce(ior, filters + [Q(id__in=self.products.only("id"))])
        return Product.objects.filter(filters).distinct()


import numpy as np

import sys
sys.path.append('C:\\Users\\Nick\\Desktop\\Ava\\Programs')
from Library.General import DataThings as DT
from Library.General import FileThings as FT
from Library.NeuralNetworks import TrainUtils as TU
from Library.NeuralNetworks.Autoencoder import TestAutoencoder as TA

### TRAIN AUTO ###

def train_data_iter(network, data, h, w, a=1e-3, n_train=100, do_subdata=False,
                    n_plot=16, plot_i=False, plot_r=False, b=1.0,
                    kmax_cost=10, kmax_img=10):
    """ iterate dataset to train newtork """
    costs = []
    for k in range(n_train):
        ds = TU.subdata_me(data, h, w, do_subdata)
        network.train_network(ds, a, b)
        costs = check_auto_cost(network, ds, costs, k, kmax_cost)
        check_auto_plot(network, ds, n_plot, plot_i, plot_r, k, kmax_img)

def train_path_iter(network, files, h, w, n_train=100, a=1e-3, do_subdata=True,
                    n_plot=16,  plot_i=False, plot_r=False,
                    kmax_cost=10, kmax_img=20):
    """ iterate filepaths to train newtork """
    costs, ms = [], []
    ds = TU.subdata_me(FT.load_images(DT.get_subset(files, n_plot*4, True)),
                       h, w, do_subdata)
    for k in range(n_train):
        ds = np.concatenate((TU.subdata_me(FT.load_images(DT.get_subset(files,
                                                                       n_plot*4, True))
                                          ,h, w, do_subdata), ds[:n_plot*4]))
        network.train_network(ds, a)
        costs = check_auto_cost(network, ds, costs, k, kmax_cost)
        check_auto_plot(network, ds, n_plot, plot_i, plot_r, k, kmax_img)

### HELPER ###

def check_auto_cost(network, ds, costs, k=1, k_max=1, max_len=30):
    """ run every n iterations to check network cost  """
    if k % k_max == 0:
        costs.append([network.get_loss(ds), network.get_io_loss(ds),
                      network.get_kl_loss(ds)])
        if len(costs) > max_len:
            costs.pop(0)
        params = ([k] + costs[-1])
        print('Iter {}  Loss {:.5f}  IO {:.5f}  KL {:.5f}'.format(*params))
    return costs

def check_auto_plot(network, data, n_plot, plot_i, plot_r, k=1, k_max=1):
    """ for every n iterations, plot data before/after/middle data """
    if k_max != 0 and k % k_max == 0:
        if plot_i:
            TA.plot_middle_train(network, data, n_plot, False, count=k)
        if plot_r:
            TA.plot_middle_train(network, data, n_plot, True, count=k)


import time, psutil, asyncio
import globals, emformat
from discord import __version__ as discordversion
from discord.ext import commands,tasks

# ['stats']=['stats']

class Stats(commands.Cog):
	def __init__(self,bot):
		self.bot=bot

		self.status='online'
		self.exposure="populating..."
		self.responses="0/0 messages responded to since last reboot."
		self.sentcount=0
		self.recievedcount=0
		self.starttime=time.time()
		self.uptime="calculating..."
		self.d=self.h=self.m=self.s=0
		self.modules='populating...'
		self.library="discord.py v"+discordversion
		self.core="merelybot v"+globals.ver
		self.memes="unavailable"
		self.cpu_usage='0%'
		self.ram_usage='0MB/0MB (0%)'
		self.hardware='merely is running on a custom windows server.'
		self.gentime='please wait...'
		self.lastuptime=0

		self.inituptime()
		self.runstats.start()

	def cog_unload(self):
		self.runstats.cancel()

	@commands.command(pass_context=True, no_pm=False, aliases=['status','ver','version'])
	async def stats(self,ctx):
		if globals.verbose:print('stats command')
		await emformat.make_embed(ctx.message.channel,'for constantly updating stats, go to '+globals.apiurl+'stats.html',
		'merely stats','',color=0x2C5ECA,thumbnail=globals.emurl+'greet.gif',
		fields={
			'exposure': self.exposure,
			'responses': self.responses,
			'uptime': self.uptime,
			'modules': self.modules,
			'library': self.library,
			'core': self.core,
			#'memes': self.memes,
			'cpu usage': self.cpu_usage,
			'ram usage': self.ram_usage,
			'hardware': self.hardware,
			'generated time': self.gentime
		},
		icon=globals.iconurl,footer="merely v"+globals.ver+" - created by Yiays#5930",link=globals.apiurl)

	def inituptime(self):
		with open(globals.store+'uptime.txt','r') as f:
			line=f.readline() #get starting point
			savelines=[]
			self.upmins=0
			self.downmins=0
			i=0
			sprint=0
			for line in f.readlines():
				ii=[int(x) for x in line.split('-')]
				if ii[0]>i+2:
					self.upmins+=i-sprint
					self.downmins+=ii[0]-i
					savelines.append(str(sprint)+'-'+str(i))
					sprint=ii[0]
				i=ii[-1]
			savelines.append(str(sprint)+'-'+str(i))
		with open(globals.store+'uptime.txt','w') as f:
			for line in savelines:
				f.write(line+'\n')

	@tasks.loop(seconds=1.0)
	async def runstats(self):
		try:
			if round(time.time())%60==0 and round(time.time()/60)!=self.lastuptime:
				self.lastuptime=round(time.time()/60)
				with open(globals.store+'uptime.txt','a') as f:
					f.write(str(round(time.time()/60)-26394323)+'\n')
				self.upmins+=1

			self.m, self.s = divmod(time.time()-self.starttime, 60)
			self.h, self.m = divmod(self.m, 60)
			self.d, self.h = divmod(self.h, 24)

			self.exposure="**"+str(len(self.bot.guilds))+"** servers with **"+str(sum([len(s.members) for s in self.bot.guilds]))+"** members."
			self.responses=str(self.sentcount)+"/"+str(self.recievedcount)+" messages responded to since last reboot."
			self.modules=', '.join(list(globals.modules.keys()))
			self.uptime=str(round((self.upmins*100)/max(self.upmins+self.downmins,1),2))+'%'
			self.cpu_usage=str(psutil.cpu_percent())+'%'
			self.ram_usage=str(round(psutil.virtual_memory().used/1000000))+'MB ('+str(round((psutil.virtual_memory().used*100)/psutil.virtual_memory().total))+'%)'
			self.gentime=time.asctime(time.localtime())+'+1300'
		except Exception as e:
			print(repr(e))


from copy import deepcopy

from rest_framework import serializers

class TimetableSlotSerializer(serializers.BaseSerializer):
    """
    Serialize slot data for timetable endpoint output.

    This serialization converts the spectrum information of slot, which
    consist of start and end time, to only slot information, which only
    consist of start time in discrete hour.

    If a slot has a non-zero minute start time, two slots are created,
    one with the hour equals to the hour in start time, and another
    with the hour for the previous slot created, incremented by one.

    This serializer has to be instantiated with a Slot instance, or a
    list of Slot instances when serializing multiple instances of Slot.

    Additional context is required:
        - 'tz': The ``tzinfo`` object representing local timezone.
        - 'current_day': The ``datetime`` object representing local
            date.

    Data returns:

        dict -  'id': ID of slot.
                'hour': Numeric string representation of hour.
                'machine': ID of machine which the slot belongs to.
                'user': Name of the user who owns the slot.
    """

    def to_representation(self, instance):
        _data_template = {
            'id': instance.id,
            'hour': -1,
            'machine': instance.machine.id,
            'user': instance.user,
        }
        tz = self.context.get('tz')
        current_day = self.context.get('current_day')
        current_day = current_day.replace(tzinfo=tz)

        # Localize UTC start time to local datetime
        s_start = instance.start.replace(tzinfo=None)
        s_start += tz.utcoffset(s_start)
        s_start = s_start.replace(tzinfo=tz)

        # When start time has non-zero minute, two slots will be
        # created. This requires additional check when the second slot
        # to be created is 00, which is the start of the next day.
        # If the slot is on previous day, return only slot with hour
        # '00', instead of '23' and '00'.
        # If the slot is on current day, return only slot with hour
        # '23'.
        if s_start.minute != 0 and (s_start.hour + 1) == 24:
            _data = deepcopy(_data_template)

            if s_start < current_day:
                _data['hour'] = '00'
            else:
                _data['hour'] = '23'

        # Check only minute, since Slot creation is guaranteed to be
        # made discretely on an hour. This only changes when slot is
        # created on region with non-zero minute timezone offset, hence
        # the check here.
        elif s_start.minute != 0:
            _data = []

            for i in range(2):
                d = deepcopy(_data_template)
                d['hour'] = str(s_start.hour + i).zfill(2)
                _data.append(d)

        else:
            _data = deepcopy(_data_template)
            _data['hour'] = str(s_start.hour).zfill(2)

        return _data


from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup
import re
import os
import csv
from configparser import ConfigParser

parser = ConfigParser()
parser.read(os.path.join(os.path.dirname(__file__),
                         '..', 'config.cfg'), encoding='utf-8')
driverLocation = parser.get('linkscraper settings', 'driverLocation')
startDate = parser.get('linkscraper settings', 'startDate')
endDate = parser.get('linkscraper settings', 'endDate')
county = parser.get('linkscraper settings', 'county')
countyKey = parser.get('linkscraper settings', 'countyKey')

outputLocation = os.path.join(os.path.dirname(__file__),
                              '..',
                              'input',
                              'URLs.csv')

class driver:
    """Driver instance"""

    def __init__(self, chromedriverPath,
                 startDate='',
                 endDate='',
                 county='',
                 countyKey='',
                 headless=False):
        """
        Initialize driver instance
        """
        self._default = (
            'http://www.landchina.com/default.aspx?tabid=263&ComName=default'
        )
        self._startDate = startDate
        self._endDate = endDate
        self._county = county
        self._countyKey = countyKey
        options = Options()
        if headless:
            options.headless = True
        self._driver = webdriver.Chrome(chromedriverPath, options=options)
        self._URLList = []

    # Getters and Setters
    @property
    def startDate(self):
        return self._startDate

    @startDate.setter
    def startDate(self, newStartDate):
        self._startDate = newStartDate

    @property
    def endDate(self):
        return self._endDate

    @endDate.setter
    def endDate(self, newEndDate):
        self._endDate = newEndDate

    @property
    def county(self):
        return self._county

    @county.setter
    def county(self, newCounty):
        self._county = newCounty

    @property
    def countyKey(self):
        return self._countyKey

    @countyKey.setter
    def countyKey(self, newCountyKey):
        self._countyKey = newCountyKey

    @property
    def URLList(self):
        return self._URLList

    @URLList.setter
    def URLList(self, newURLList):
        self._URLList = newURLList

    def _goToLocation(self):
        self._driver.get(self._default)

    def _enterSearchParams(self):
        """Enter search filter parameters"""
        # Enter parameters
        WebDriverWait(self._driver, 20).until(
            EC.element_to_be_clickable(
                (By.ID, 'TAB_QueryConditionItem270')
            )
        ).click()
        self._driver.find_element_by_id('TAB_queryDateItem_270_1').clear()
        self._driver.find_element_by_id(
            'TAB_queryDateItem_270_1').send_keys(self._startDate)
        self._driver.find_element_by_id('TAB_queryDateItem_270_2').clear()
        self._driver.find_element_by_id(
            'TAB_queryDateItem_270_2').send_keys(self._endDate)
        self._driver.find_element_by_id('TAB_queryTblEnumItem_256').clear()
        self._driver.find_element_by_id(
            'TAB_queryTblEnumItem_256').send_keys(self._county)
        self._driver.find_element_by_id('TAB_QueryConditionItem256').click()
        self._driver.execute_script(
            ("document.getElementById('TAB_queryTblEnumItem_256_v')"
             ".setAttribute('type', 'text');")
        )
        self._driver.find_element_by_id('TAB_queryTblEnumItem_256_v').clear()
        self._driver.find_element_by_id(
            'TAB_queryTblEnumItem_256_v').send_keys(self._countyKey)
        self._driver.find_element_by_id('TAB_QueryButtonControl').click()

    def search(self):
        self._goToLocation()
        self._enterSearchParams()

    def _getPages(self):
        """Get current page and total pages"""
        p = self._driver.find_elements_by_css_selector('.pager')
        # If list is not empty
        if p:
            text = p[1].text
            reg = re.findall(r'\d+', text)
            totalPages = int(reg[0])
            pageSelector = self._driver.find_elements_by_css_selector(
                ".pager>input")
            currentPage = int(pageSelector[0].get_attribute('value'))
        # If list is empty there is only one page
        else:
            totalPages = 1
            currentPage = 1
            pageSelector = None
        return currentPage, totalPages, pageSelector

    def _getLinksFromTable(self):
        html = self._driver.find_element_by_id(
            'TAB_contentTable').get_attribute('innerHTML')
        soup = BeautifulSoup(html, 'html.parser')
        href = soup.select('.queryCellBordy a')
        for line in href:
            url = 'http://www.landchina.com/' + line['href']
            self._URLList.append(url)
            print('Added URL: ', url, '. Total urls')

    def scrapeLinks(self):
        """Recursive function to cycle through pages"""
        currentPage, totalPages, pageSelector = self._getPages()
        print('On page ', currentPage, ' of ', totalPages, 'total pages')
        self._getLinksFromTable()
        if currentPage < totalPages:
            pageSelector[0].clear()
            pageSelector[0].send_keys(currentPage + 1)
            pageSelector[1].click()
            self.scrapeLinks()
        else:
            print('Done!')

    def getCSV(self, outputLocation):
        """Export CSV file with links from URLList"""
        with open(outputLocation, 'w', newline='') as csvResults:
            writer = csv.writer(csvResults, dialect='excel')
            for u in self._URLList:
                writer.writerow([u])
        print('Exported CSV to ', outputLocation)

    def quitDriver(self):
        """Quit selenium driver"""
        self._driver.quit()

if __name__ == "__main__":
    driver = driver(chromedriverPath=driverLocation,
                    startDate=startDate,
                    endDate=endDate,
                    county=county,
                    countyKey=countyKey,
                    headless=True)
    driver.search()
    driver.scrapeLinks()
    driver.getCSV(outputLocation)
    driver.quitDriver()


# Random Forest Classification

# Importing the libraries
import pandas as pd

# Importing the dataset
dataset = pd.read_csv('train.csv')
X_train = dataset.iloc[:, [0,2, 4,5,6,7]].values
y_train = dataset.iloc[:, 1].values

test_dataset = pd.read_csv('test.csv')
X_test= test_dataset.iloc[:, [0,1,3,4,5,6]].values

# taking care of missing values
from sklearn.preprocessing import Imputer
imputer = Imputer(missing_values = 'NaN', strategy = 'mean', axis = 0)
imputer = imputer.fit(X_train[:, 3:4])
X_train[:, 3:4] = imputer.transform(X_train[:, 3:4])
imputer_test = imputer.fit(X_test[:, 3:4])
X_test[:, 3:4] = imputer_test.transform(X_test[:, 3:4])

# One hot encoder
from sklearn.preprocessing import LabelEncoder , OneHotEncoder
labelEncoder_X = LabelEncoder()
X_train[:, 2] = labelEncoder_X.fit_transform(X_train[:, 2])
oneHotEncoder= OneHotEncoder(categorical_features = [2])
X_train = oneHotEncoder.fit_transform(X_train).toarray()

X_test[:, 2] = labelEncoder_X.fit_transform(X_test[:, 2])
oneHotEncoder= OneHotEncoder(categorical_features = [2])
X_test = oneHotEncoder.fit_transform(X_test).toarray()

# Splitting the dataset into the Training set and Test set
'''from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = 0)'''

# Feature Scaling
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

# Fitting Random Forest Classification to the Training set
from sklearn.ensemble import RandomForestClassifier
classifier = RandomForestClassifier(n_estimators = 10, criterion = 'entropy', random_state = 0)
classifier.fit(X_train, y_train)

# Predicting the Test set results
y_pred = classifier.predict(X_test)


from distutils.core import setup, Extension
import shutil, os, sys

# from ..config import CPotentialCompilerConfig as cpcc

lib_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
src_dir = os.path.join(lib_dir, "src")
libname = "ZachLib"

def get_macros():
    macs = []
    # if cpcc["UseMPI"]:
    #     macs.append(("USE_MPI", None))
    return macs

def get_extension():
    return Extension(
        libname,
        sources=[libname + '.cpp', "PyExtLib.cpp"],
        define_macros=get_macros()
    )

def setup_compile():
    return setup(
        name=libname,
        version='1.0',
        description='Performance critical parts of Zachary',
        ext_modules=[get_extension()],
        language="c++"
    )

def compile():
    curdir = os.getcwd()
    try:
        os.chdir(src_dir)

        sysargv1 = sys.argv
        sys.argv = ['build', 'build_ext', '--inplace']
        try:
            setup_compile()
        finally:
            sys.argv = sysargv1
    finally:
        os.chdir(curdir)

def find_source():
    ext = ""
    target = os.path.join(lib_dir, libname)
    src = None
    for f in os.listdir(os.path.join(lib_dir, "src")):
        if f.startswith(libname) and f.endswith(".so"):
            ext = ".so"
            src = os.path.join(lib_dir, "src", f)
            target += ext
            break
        elif f.startswith(libname) and f.endswith(".pyd"):
            ext = ".pyd"
            src = os.path.join(lib_dir, "src", f)
            target += ext
            break

    return src, target

def load():
    compile()
    src, target = find_source()
    if src is not None:
        try:
            os.remove(target)
        except:
            pass
        os.rename(src, target)
        shutil.rmtree(os.path.join(src_dir, "build"))
        return src
    else:
        return None

if __name__ == "__main__":
    loaded = load()
    if loaded is None:
        raise ImportError("{}: library didn't compile".format(libname))


import os
os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
import pickle
import glob
import string
import time
import math
import argparse
from shutil import copyfile, rmtree

import tqdm
import numpy as np
from numpy.random import RandomState

"""
###############################################################################################
#                                       REFERENCES                                            #
###############################################################################################

https://github.com/meijieru/crnn.pytorch
https://github.com/sbillburg/CRNN-with-STN/blob/master/CRNN_with_STN.py
https://github.com/keras-team/keras/blob/master/examples/image_ocr.py
https://github.com/keras-team/keras-applications/blob/master/keras_applications/mobilenet.py
Sliced RNN:
https://github.com/zepingyu0512/srnn/blob/master/SRNN.py
Attention block:
https://github.com/philipperemy/keras-attention-mechanism.git
Spatial transformer network:
https://github.com/oarriaga/STN.keras

###############################################################################################
# LOGS:
###############################################################################################

 - casual convs: 8857k params; 16 epochs, 500k training examples: ctc_loss - ~0.91
 - depthwise separable convs and dropouts: 2785k params; 20 epochs, 500k training
   examples; 3181s; 429ms/step; 63592 s.; ctc_loss: ~0.85

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

#######################################################
# TESTs section (from the inside of Deepo universal): #
#######################################################

python3 train.py --G 1 --path /data/data/OCR/data/mjsynth/mnt/ramdisk/max/90kDICT32px --training_fname imlist.txt \
--save_path /data/data/OCR/data --model_name OCR_mjsynth_test --nbepochs 2 \
--norm --mjsynth --opt sgd --time_dense_size 128 --lr 0.002 --batch_size 64 --max_train_length 10000

Check pretrained model init:
python3 train.py --G 1 --path /data/data/OCR/data/mjsynth/mnt/ramdisk/max/90kDICT32px --training_fname imlist.txt \
--save_path /data/data/OCR/data --model_name OCR_mjsynth_test_TL --nbepochs 2 \
--norm --mjsynth --opt sgd --time_dense_size 128 --lr 0.002 --batch_size 64 --max_train_length 10000 \
--pretrained_path /data/data/OCR/data/OCR_mjsynth_test/single_gpu_weights.h5

python3 train.py --G 1 --path /data/data/OCR/data/mjsynth/mnt/ramdisk/max/90kDICT32px --training_fname imlist.txt \
--save_path /data/data/OCR/data --model_name OCR_IAM_test --nbepochs 2 \
--norm --opt sgd --time_dense_size 128 --lr 0.002 --batch_size 64 \
--max_train_length 10000 --pretrained_path /data/data/OCR/data/OCR_mjsynth_test/single_gpu_weights.h5

########
# RUN: #
########

docker build -t crnn_ocr:latest -f Dockerfile .
nvidia-docker run --rm -it -v /data/OCR/data/mjsynth/mnt/ramdisk/max/90kDICT32px:/input_data -v /data/OCR/data:/save_path -p 8000:8000 crnn_ocr

python3 train.py --G 1 --path /data/data/OCR/data/mjsynth/mnt/ramdisk/max/90kDICT32px --training_fname annotation_train.txt \
--val_fname annotation_test.txt --save_path /data/data/OCR/data --model_name OCR_mjsynth_FULL --nbepochs 2 \
--norm --mjsynth --opt sgd --time_dense_size 128 --lr .0001 --batch_size 64 --lr_schedule --STN

##########
# TO DO: #
##########

 - pretrain model on Mjsynth dataset;
 - make deslant algorithm;
 - finish preprocessing for IAM dataset (insert in Readf function);
 - train model with IAM dataset with weights from mjsynth model;
 - check prediction and add WER/CER metrics inside the predict.py;
 - problem with N batches in inference mode - why it's need to multiply by 2 the number of steps?;
 - add GPU / CPU options in predict.py

"""

if __name__ == '__main__':

    parser = argparse.ArgumentParser(description='crnn_ctc_loss')
    parser.add_argument('-p', '--path', type=str, required=True)
    parser.add_argument('--training_fname', type=str, required=False, default=None)
    parser.add_argument('--val_fname', type=str, required=False, default="")
    parser.add_argument('--save_path', type=str, required=True)
    parser.add_argument('--model_name', type=str, required=True)
    parser.add_argument('--pretrained_path', default=None, type=str, required=False)
    parser.add_argument('--nbepochs', type=int, default=20)
    parser.add_argument('--G', type=str, default="1")
    parser.add_argument('--trsh', type=int, default=100)
    parser.add_argument('--fill', type=int, default=255)
    parser.add_argument('--offset', type=int, default=4)
    parser.add_argument('--random_state', type=int, default=42)
    parser.add_argument('--length_sort_mode', type=str, default='target')
    parser.add_argument('--train_portion', type=float, default=0.9)
    parser.add_argument('--max_train_length', type=int, default=None)
    parser.add_argument('--time_dense_size', type=int, default=128)
    parser.add_argument('--n_units', type=int, default=256)
    parser.add_argument('--batch_size', type=int, default=64)
    parser.add_argument('--opt', type=str, default="sgd")
    parser.add_argument('--lr', type=float, default=0.001)
    parser.add_argument('--norm', action='store_true')
    parser.add_argument('--mjsynth', action='store_true')
    parser.add_argument('--GRU', action='store_true')
    parser.add_argument('--STN', action='store_true')
    parser.add_argument('--lr_schedule', action='store_true')
    parser.add_argument('--reorder', action='store_true')

    # default values set according to mjsynth dataset rules
    parser.add_argument('--imgh', type=int, default=100)
    parser.add_argument('--imgW', type=int, default=32)

    args = parser.parse_args()
    globals().update(vars(args))

    os.environ["CUDA_VISIBLE_DEVICES"] = G

    import tensorflow as tf
    from keras import backend as K
    from keras.callbacks import ModelCheckpoint, LearningRateScheduler
    from keras.utils.training_utils import multi_gpu_model
    from keras.models import load_model, clone_model
    from keras.layers import Lambda
    from utils import *

    try:
        rmtree(save_path+"/"+model_name)
    except:
        pass
    os.mkdir(save_path+"/"+model_name)
    with open(save_path+'/'+model_name+"/arguments.txt", "w") as f:
        f.write(str(args))

    lexicon = get_lexicon()

    classes = {j:i for i, j in enumerate(lexicon)}
    inverse_classes = {v:k for k, v in classes.items()}
    print(" [INFO] %s" % classes)

    img_size = (imgh, imgW) + (1,)
    reader = Readf(
        path, training_fname, img_size=img_size, trsh=trsh, normed=norm,
        mjsynth=mjsynth, offset=offset, fill=fill, random_state=random_state,
        length_sort_mode=length_sort_mode, classes=classes, reorder=reorder, max_train_length=max_train_length
    )
    if reorder:
        train = np.array(list(reader.names.keys()))
    else:
        train = np.array(reader.names)

    if val_fname:
        val = np.array(open(path+'/'+val_fname, "r").readlines())

    else:
        length = len(train)
        train, val = train[:int(length*train_portion)], train[int(length*train_portion):]

    print(" [INFO] Number of classes: {}; Max. string length: {} ".format(len(reader.classes)+1, reader.max_len))

    init_model = CRNN(num_classes=len(classes)+1, shape=img_size, GRU=GRU, STN=STN,
        time_dense_size=time_dense_size, n_units=n_units, max_string_len=reader.max_len)

    model = init_model.get_model()
    save_model_json(model, save_path, model_name)
    if pretrained_path is not None:
        model.load_weights(pretrained_path)

    train_steps = len(train) // batch_size
    if (len(train) % batch_size) > 0:
        train_steps += 1
    test_steps = len(val) // batch_size
    if (len(val) % batch_size) > 0:
        test_steps += 1

    start_time = time.time()

    with open(save_path+'/'+model_name + '/model_summary.txt','w') as f:
        model.summary(print_fn=lambda x: f.write(x + '\n'))

    model.summary()

    if opt == "adam":
        optimizer = optimizers.Adam(lr=lr, beta_1=0.5, beta_2=0.999, clipnorm=5)
    elif opt == "sgd":
        optimizer = optimizers.SGD(lr=lr, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5)

    model.compile(loss={"ctc": lambda y_true, y_pred: y_pred}, optimizer=optimizer)
    callbacks_list = []
    callbacks_list.append(ModelCheckpoint(filepath=save_path+'/%s/checkpoint_weights.h5'%model_name, verbose=1,
                                          save_best_only=True, save_weights_only=True))
    if lr_schedule:
        if mjsynth:
            schedule = {
                600 : 0.1,
                train_steps // 4 : 0.002,
                train_steps // 2 : 0.001,
                train_steps : 0.0005,
                train_steps * nbepochs : lr
            }
        else:
            # edit this schedule accroding to IAM train dataset
            schedule = {
                train_steps * nbepochs : lr
            }

        callbacks_list.append(LR_Schedule(schedule))

    H = model.fit_generator(
        generator=reader.run_generator(train, downsample_factor=2**init_model.pooling_counter_h),
        steps_per_epoch=train_steps,
        epochs=nbepochs,
        validation_data=reader.run_generator(val, downsample_factor=2**init_model.pooling_counter_h),
        validation_steps=test_steps,
        shuffle=False, verbose=1,
        callbacks=callbacks_list
    )

    pickle.dump(H.history, open(save_path+'/'+model_name+'/loss_history.pickle.dat', 'wb'))

    print(" [INFO] Training finished in %i sec.!" % (time.time() - start_time))

    model.save_weights(save_path+'/'+model_name+"/final_weights.h5")
    model.save(save_path+'/'+model_name+"/final_model.h5")

    print(" [INFO] Models and history saved! ")


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__author__ = 'zxy'

import re
def is_var(str):
	if str=='int' or str=='(int' or str=='(int)' or str=='for(int':
		return True
	if str=='short' or str=='(short' or str=='(short)' or str=='for(short':
		return True
	if str=='long' or str=='(long' or str=='(long)' or str=='for(long':
		return True
	if str=='char' or str=='(char' or str=='(char)' or str=='for(char':
		return True
	if str=='bool' or str=='(bool' or str=='(bool)' or str=='for(bool':
		return True
	if str=='void' or str=='(void' or str=='(void)' or str=='for(void':
		return True
	if str=='string' or str=='(string' or str=='(string)' or str=='for(string':
		return True
	return False

pattern1 = re.compile('/\*{1,2}[\s\S]*?\*/') #去除块级注释
pattern2 = re.compile('//[\s\S]*?\n') #去除行级注释
pattern3 = re.compile('^\s*\n')  #去除空白符
pattern4 = re.compile('[^\x00-\xff]+')  #去除中文
pattern5 = re.compile('[_a-zA-Z][_a-zA-Z0-9]*')  #匹配变量名
class filter(object):
	def clear_note(self,str):
		result = re.sub(pattern1,'', str)
		result = re.sub(pattern2,'',result)
		result = re.sub(pattern3,'',result)
		result = re.sub(pattern4,'',result)
		return result

	def rep(self,str):
		result = re.sub(pattern5,'T',str)
		return result

	def rep_name(self,str):
		result = re.findall(pattern5,str)
		return result

	def rep_name2(self,str):
		result = re.findall(pattern5,str)
		if result==[]:
			return -1
		return result[0]

	def no_blank(self,str):
		str1 = ''
		for i in str:
			if i=='\r' or i=='\n' or i=='\t':
				pass
			else: str1 += i
		return str1

	def unnite_var(self,str):
		code = re.split(r'[\s]+',str)
		len1 = len(code)
		str1 = ''
		book = {}; temp = []
		for i in range(len1):
			if is_var(code[i]):
				if i!=len1-1:
					temp = self.rep_name(code[i+1])
					for j in temp:
						book[j] = 1;
		for i in range(len1):
			if self.rep_name2(code[i]) in book:
				str1 += self.rep(code[i])
			else:
				str1 += code[i]
		return str1

	def to_lower_case(self,str):
		code = str.lower();
		return code;

	def filter(self,str):
		str = self.clear_note(str)
		str = self.unnite_var(str)
		str = self.no_blank(str)
		str = self.to_lower_case(str);
		return str

'''
def test(path):
	str = ''
	with open(path,'r') as fr:
		str = fr.read()

	ft = filter()
	print(str)
	print("new line begin")
	print(ft.filter(str))
if __name__=='__main__':
	import sys
	args = sys.argv
	test('/media/zsy/WORK/mywork/test/e.cpp')
'''


import sys

N = int(sys.stdin.readline())
arr = [i + 1 for i in range(N)]

while len(arr) > 1:
    if len(arr) % 2:
        t = [arr[-1]]
        t.extend(arr[1::2])
        arr = t
    else:
        arr = arr[1::2]

print(arr[0])


import pandas
import config
from sklearn.utils import resample
import MachineLearning

def binary_to_char(value):
    return 'N' if value == 0 else 'Y'

ml = MachineLearning.MachineLearning()

data = pandas.read_csv(config.DATA_PATH + 'ortopedia.csv', sep=';')

# Convertendo coluna de classificação para caractere
data.Fusao_de_Vertebras = data.Fusao_de_Vertebras.map(binary_to_char)

# Verificando balanceamento de classes
print(data.Fusao_de_Vertebras.value_counts())

# Separando dados das classes
minor = data[data['Fusao_de_Vertebras'] == 'Y']
major = data[data['Fusao_de_Vertebras'] == 'N']

# Rebalanceando a classe com menor número de registros
minor_up_sample = resample(minor, replace=True, n_samples=7900, random_state=None)

# Criando novo dataframe com os dados balanceados
balanced_data = pandas.concat([major, minor_up_sample])

# Separando as colunas de dados da coluna de classificação
attributes = balanced_data.drop(['#', 'Fusao_de_Vertebras'], axis=1)
classes = balanced_data['Fusao_de_Vertebras']

data = minor = major = minor_up_sample = balanced_data = None

attributes = pandas.get_dummies(attributes)

# LOGISTIC REGRESSION
filename = 'orthopedics_lr'

x_training, x_testing, y_training, y_testing = ml.train_test_split(attributes, classes)

# Módulo indutor
print("\nGerando modelo de Regressão Logística")
response, y_predict = ml.generate_logistic_regression(
    x_training, x_testing, y_training, filename
)

print(response)

matrix = MachineLearning.conf_matrix(y_testing, y_predict)

MachineLearning.report(y_testing, y_predict)

print("\nAcurácia")
acc = MachineLearning.accuracy(matrix)
print(acc)

print("\nSensibilidade")
sen = MachineLearning.sensitivity(matrix)
print(sen)

print("\nEspecificidade")
spe = MachineLearning.specificity(matrix)
print(spe)

print("\nValidando modelo")
validate = MachineLearning.validate_model(filename, x_testing, y_testing)
print(validate)


import re
from string import punctuation

class NegationAnnotator(object):
    def __init__(self, sentence, phrase, tfile):
        self._sentence = sentence
        self._phrase = phrase
        self._tfile = tfile

    def preprocess(self, text):
        text = text.lower()
        text = ''.join(char for char in text if char not in punctuation)
        return text

    def format_triggers(self):
        '''Returns list of triggers sorted by length in descending order.
        Sorting ensures correct rule tagging in next steps. Triggers
        must be in tab-delimited format: 'rule\t\t[four letter negation tag]'.
        In addition, the function splits each rule into components,
        converts pattern to regular expression, and appends it to the end
        of the rule.'''
        with open(self._tfile) as f:
            triggers = f.readlines()
        triggers.sort(key = len, reverse = True)
        formated = []
        for rule in triggers:
            r = rule.strip().split('\t')
            rsplit = r[0].split()
            trigger = r'\s+'.join(rsplit)
            pattern = r'\b' + trigger + r'\b'
            r.append(re.compile(pattern, re.IGNORECASE))
            formated.append(r)
        return formated

    def tag_sentence(self, sentence, phrase):
        '''Returns sentence where triggers are tagged, e.g. wrapped by [NEG],
        [POS], [CONJ], or [PSEU] tags. Phrase is replaced by [PHRASE].'''
        tagged = sentence.replace(phrase, '[PHRASE]')
        filler = '_'
        triggers = self.format_triggers()
        for trig in triggers:
            reformat = re.sub(r'\s+', filler, trig[0].strip())
            tagged = trig[3].sub(trig[2].strip() + reformat + trig[2].strip(), tagged)
        return tagged

    def phrase_index(self, tagged, phrase):
        '''Returns the index of the input phrase. Returns None if phrase not found.'''
        try: return tagged.index('[PHRASE]')
        except ValueError: return None

    def normalize_sentence(self, tagged, pindex):
        '''If the [CONJ] tag is found in the input sentence, the function
        extracts the relevant sub-sentence given the position of the phrase.'''
        normalized = tagged
        for i in range(len(tagged)):
            if i > pindex: normalized = tagged[:i]
            elif i < pindex: normalized = tagged[i+1:]
        return normalized

    def word_distance(self, rindex, pindex, distance = 5):
        if abs(rindex - pindex):
            return True
        return False

    def search_scope(self, normalized, pindex, possible = False):
        '''Returns True if concept is affirmed, False if negated. To tag
        possible negation terms, set possible = True. The follow method can
        be easily adjusted to accommodate additional rules or considations.'''
        pre = post = 0

        if possible: tags = ['[POS]', '[NEG]']
        else: tags = ['[NEG]']

        for i in range(len(normalized)):
            if i < pindex and normalized[i][:5] in tags:
                pre += 1
            elif i > pindex and normalized[i][:5] in tags:
                if self.word_distance(i, pindex):
                    post += 1

        if pre == 1 or post == 1: return False
        return True

    def aggregate(self):
        '''Aggregates function results and returns negation status. If input text
        has not been preprocessed, adapt a version of the follow two lines of
        code process your incoming data.'''
        self._sentence = self.preprocess(self._sentence)
        self._phrase = self.preprocess(self._phrase)

        tagged = self.tag_sentence(self._sentence, self._phrase).split()
        pindex = self.phrase_index(tagged, self._phrase)

        if not pindex:
            print("error: phrase not found in sentece")
            return None

        normalized = self.normalize_sentence(tagged, pindex)
        pindex = self.phrase_index(normalized, self._phrase)
        return self.search_scope(normalized, pindex)

if __name__ == '__main__':
    # pseudo negation, phrase affirmed (True)
    s1 = "There has been no increase in nitrogen levels over the last decade."
    p1 = "nitrogen levels"
    n1 = NegationAnnotator(s1, p1, "rules.txt")
    print(n1.aggregate())

    # conjection considered, phrase affirmed (True)
    s2 = "Patient does not enjoy social interaction, but wishes to return to school."
    p2 = "return to school"
    n2 = NegationAnnotator(s2, p2, "rules.txt")
    print(n2.aggregate())

    # phrase negation (False)
    s3 = "Rule Out ADHD, hyperactivity subtype."
    p3 = "ADHD"
    n3 = NegationAnnotator(s3, p3, "rules.txt")
    print(n3.aggregate())


#!/usr/bin/env python

'''
script.py: part of singularity command line tool
Runtime executable, "shub"

'''

from singularity.package import package, docker2singularity
from singularity.runscript import get_runscript_template
from singularity.utils import check_install
from singularity.app import make_tree
from glob import glob
import argparse
import sys
import os

def main():
    parser = argparse.ArgumentParser(
    description="package Singularity containers for singularity hub.")
    parser.add_argument("--image", dest='image', help="full path to singularity image (for use with --package)", type=str, default=None)
    parser.add_argument("--docker2singularity", dest='docker', help="name of Docker image to export to Singularity (does not include runscript cmd)", type=str, default=None)
    parser.add_argument("--outfolder", dest='outfolder', help="full path to folder for output, if not specified, will go to pwd", type=str, default=None)
    parser.add_argument("--runscript", dest='runscript', help="specify extension to generate a runscript template in the PWD, or include --outfolder to change output directory. Currently supported types are py (python).", type=str, default=None)
    parser.add_argument('--package', help="package a singularity container for singularity hub", dest='package', default=False, action='store_true')
    parser.add_argument('--tree', help="view the guts of an image or package.", dest='tree', default=False, action='store_true')
    try:
        args = parser.parse_args()
    except:
        parser.print_help()
        sys.exit(0)

    # Output folder will be pwd if not specified
    if args.outfolder == None:
        output_folder = os.getcwd()
    else:
        output_folder = args.outfolder

    # If the user wants a runscript template.
    if args.runscript != None:
        get_runscript_template(output_folder=output_folder,
                               script_name="singularity",
                               language=args.runscript)

    # If the user wants to export docker2singularity!
    if args.docker != None:
        docker2singularity(output_folder=output_folder,
                           docker_image=args.docker)

    # We can only continue if singularity is installed
    if check_install() == True:

       # We also must have an image to work with
       if args.image !=None:
           image = os.path.abspath(args.image)

           # Make sure the image exists!
           if os.path.exists(image):

               # the user wants to make a tree for an image
               if args.tree == True:
                   make_tree(image)

               # The user wants to package the image
               elif args.package == True:
                   package(image_path=image,
                           output_folder=output_folder,
                           runscript=True,
                           software=True)

       else:
          print("Please specify a singularity image with --image.")

if __name__ == '__main__':
    main()


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

# In[ ]:

import time
import subprocess
import datetime
from threading import Thread
from queue import Queue, Empty

# main_cmd = '/home/yamaguchi/bin/fc_client -h 192.168.16.5 -i 3000 -u db_admin -p db_admin'
main_cmd = 'ghci'
interval_time = 0.1         # INSERT文発行間隔（だいたい）
# success_keyword = '--QUERY RESULT--'
success_keyword = '0'

# プログラム終了まで標準出力を監視続け、
# なんか来たら出力キューに入れておくスレッド
def enqueue_output(out, queue):
    for line in iter(out.readline, b''):
        queue.put(line)
    #out.close()

# 出力キューの内容を全部吐き出させる関数
def out_allelements_queue(que):
    while True:
        try:
            line = que.get(timeout=0.001)
        except Empty:
            break
        else:
            print(line.decode().strip())

# fc_client にSQLを投げた後、fc_clientが何か出力するまで待って
# それを全部吐き出してから帰る関数
def run_sql(proc, que, sql):
    # コマンドを投げる前に出力キューの内容を全部吐き出しておく。
    out_allelements_queue(que)

    # コマンドを投げる
    print('---- run:{0} ----'.format(sql.strip()))
    start_time = time.time()
    proc.stdin.write(sql.encode())
    proc.stdin.flush()

    # 返事があるまで待つ
    while True:
        try:
            line = q.get_nowait()
        except Empty:
            time.sleep(0.001)
        else:
            line = line.decode().strip()
            #print(line)
            if success_keyword in line:
                break
    elapsed_time = time.time() - start_time

    # 返事を全部吐き出す
    out_allelements_queue(que)
    print('---- end:{0}  {1}(secs) ----'.format(sql.strip(), elapsed_time))

# 適当な値でINSERT文を作成して標準入力に書き込み、
# → 返事を待って出力
def task_insert(i):
    sql = 'INSERT INTO TBL80B VALUES ('
    for c in range(9):
        sql += str(i + c)
        sql += ','
    sql += str(i + 10)
    sql += ');'
    sql += '\n'
    run_sql(p, q, sql)

# コミット発行 → 返事を待って出力
def task_commit():
    sql = 'COMMIT;' + '\n'
    run_sql(p, q, sql)

# 対象テーブルの行数を取得して出力
def task_count():
    sql = 'SELECT count(*) FROM TBL80B;' + '\n'
    run_sql(p, q, sql)

# 時間がかかるSQLをお試し実行
def task_test():
    sql = 'select avg(p1), sum(p2) from TBL80B;' + '\n'
    run_sql(p, q, sql)

def task_ghci01():
    cmd = '12345678901234567890 * 9876543210' + '\n'
    run_sql(p, q, cmd)

# ここからメイン処理
p = subprocess.Popen(main_cmd.split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE)
q = Queue()
t = Thread(target=enqueue_output, args=(p.stdout, q))
t.daemon = True
t.start()

#last_time = time.time()
#i = 1
#while i <= 1000:
#    if time.time() - last_time > interval_time:
#        last_time = time.time()
#        task_insert(i)
#        i += 1
#    else:
#        time.sleep(interval_time / 5)

#task_commit()
#time.sleep(0.1)

#task_count()
#time.sleep(0.1)

#task_test()
#time.sleep(0.1)

task_ghci01()
time.sleep(0.1)

# fc_client にEXITを発行して終了
# sql = 'exit\n'
sql = ':exit\n'

p.stdin.write(sql.encode())
p.stdin.flush()
p.terminate()

# In[ ]:


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def sumOfLeftLeaves(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        ret, q = 0, root and [root]
        while q:
            top = q.pop()
            if top.left:
                ret += top.left.val if not top.left.right and not top.left.left else 0
                q.append(top.left)
            if top.right:
                q.append(top.right)
        return ret


# -*- coding: utf-8 -*-
"""
Created on Fri May  8 09:57:05 2020

@author: 17814
"""

from xpinyin import Pinyin
import urllib.request as r
if __name__=="__main__":
    city=str(input('请输入需要查询的城市：'))
    p = Pinyin()
    city_pinyin = p.get_pinyin(city, '')
    url='http://api.openweathermap.org/data/2.5/weather?q={}&mode=json&units=metric&lang=zh_cn&APPID=6a67ed641c0fda8b69715c43518b6996'.format(city_pinyin)
    data=r.urlopen(url).read().decode('utf-8')
    import json
    data=json.loads(data)
    print(city+'的温度为：'+str(data['main']['temp'])+'℃')
    print(city+'的天气情况为：'+str(data['weather'][0]['description']))
    print(city+'的气压为：'+str(data['main']['pressure'])+'P')
    input("Prease <enter>")


'''
Creates the LISTFILE used as input to the convert_imageset tool of caffe
'''

import sys, os

if len(sys.argv) < 3:
  print ("Insufficient arguments. Usage : python prog.py <Root> <MODE>.\nMODE=Img, Fnt, Hnd or All\nRoot folder must contain the MODE folder (except All)")
  sys.exit(1)

ROOT = sys.argv[1]
MODE = sys.argv[2]
# Labes are deterministic - In the order [0-9][A-Z][a-z]
FOLDER_PREFIX = "Sample0"
# Maps folder name to label
LABELS = {}

cnt = 1

# Labels must be sequentially numbered, starting from zero
for i in range(10):
  if cnt < 10:
    LABELS[FOLDER_PREFIX + "0" + str(cnt)] = cnt-1
  else:
    LABELS[FOLDER_PREFIX + str(cnt)] = cnt-1

  cnt += 1

for i in range(26):
  LABELS[FOLDER_PREFIX + str(cnt)] = cnt - 1
  cnt += 1

for i in range(26):
  LABELS[FOLDER_PREFIX + str(cnt)] = cnt - 1
  cnt += 1

subdirs = [MODE]

if MODE.lower() == "all":
  subdirs = ["Img", "Fnt", "Hnd"]

for subdir in subdirs:
  relative = subdir

  # Fix for Img subdir
  if subdir.lower() == "img":
    relative = os.path.join (relative, "GoodImg")
    relative = os.path.join (relative, "Bmp")
  elif subdir.lower() == "hnd":
    relative = os.path.join (relative, "Img")

  for folder_name, label in LABELS.iteritems():
    relative_folder = os.path.join(relative, folder_name)
    folder = os.path.join(ROOT, relative_folder)

    for fl in os.listdir(folder):
      if fl.endswith(".png"):
        relative_path = os.path.join(relative_folder, fl)
        print("%s %s" % (relative_path, label))


class Solution():
    def isValid(self,testString):
        pmap = {
            "(":")",
            "[":"]",
            "{":"}"
        }
        revmap = {c:v for v,c in pmap.items()}
        stack = []

        for char in testString:
            if char in pmap:
                stack.append(char)
            elif char in revmap and stack.pop() != revmap[char] :
                return False

        if len(stack) == 0 :
            return True
        else: return False

print(Solution().isValid("([{}])"))
print(Solution().isValid("((([{}])"))


def likes(mylist):
	howmany = len(mylist)
	if howmany<=0:
		return 'no one likes this'
	elif howmany==1:
		return mylist[0]+' likes this'
	elif howmany==2:
		return mylist[0]+' and '+mylist[1]+' like this'
	elif howmany==3:
		return '%s, %s and %s like this' % (mylist[0],mylist[1],mylist[2])
	else:
		return mylist[0]+', '+mylist[1]+' and '+str(len(mylist)-2)+' others like this'

print(likes(['1','2','2']))


from __future__ import division, print_function
import re, math, nltk
import FeatureExtractor
from collections import Counter

WORDS = re.compile(r'\w+')

def string_similarity(q, answers):
	#split question into words remove artefacts

	qs = list(set(q))
	qlength = len(qs)

	#create a list of string similarity values
	N = {}
	values=[]
	for answer in answers:
		n= 0
		for word in qs:
			if word in answers[answer]:
				n+=1
		N[answer] = (float(n)/qlength)

	# best10 = []
	# for (num,ans) in N:
	# 	if num <= 0.6 :

	# 		best10 += [ans]

	# return best10
	return N

def min_edit_distance(qs, answers):

	#split question into words remove artefacts
	qlength = len(qs)

	#create a list of MED values
	N = {}
	for answer in answers:
		sentenceanswer = answers[answer]
		salength= len(sentenceanswer)
		n = nltk.metrics.edit_distance(qs,sentenceanswer)
		N[answer] = n/salength
	# best10 = []
	# for (num,ans) in N:
	# 	if num <= sorted(values)[10]:
	# 		best10 += [answers[ans][2]]

	#return best10
	return N

#cosine similarity on pure token frequency
def cosine_similarity(qs, answervectors, FreqDist):

	#split question into words remove artefacts
	qlength = len(qs)

	# FreqDist = {}
	Nwords = len(FreqDist.keys())
	# for w in answers.keys():
	# 	sentence = answers[w]
	# 	for word in sentence:
	# 		if word in FreqDist:
	# 			FreqDist[word] = FreqDist[word] + 1
	# 			Nwords += 1
	# 		else:
	# 			FreqDist[word] = 1
	# 			Nwords += 1

	#question vector using idf
	qv =[]
	qcounter = Counter(qs)
	sortedFD = sorted(FreqDist.keys())
	for w in sortedFD:
		if w in qcounter:
			qv+=[qcounter[w]*FreqDist[w]]

		else:
			qv += [0]
		# if w in qcounter:
		# 	qv+=[qcounter[w]*math.log(Nwords/(FreqDist[w]/qcounter[w]))]

		# else:
		# 	qv += [0]

	N = {}

	for avs in answervectors:
		av = answervectors[avs]
		numerator = sum([qv[x]*av[x] for x in range(Nwords)])

		sum1 = sum([qv[x]**2 for x in range(Nwords)])
		sum2 = sum([av[x]**2 for x in range(Nwords)])
		denominator = math.sqrt(sum1) * math.sqrt(sum2)

		if not denominator:
			N[avs] = 0.0

		else:
			N[avs]= (float(numerator)/denominator)

	# best10 = []

	# for (num,ans) in N:
	# 	if num >= sorted(values)[-10]:
	# 		best10 += [answers[ans]]

	# return best10
	return N


import re

def main(text):
    def fn_capital_after_fullstop(mo):
        return ". {}".format(mo.group(1).upper())

    regexp_fs = re.compile(r"\.\s+([a-z])")
    regexp_cm = re.compile(r"\,\s+")
    regexp_qm = re.compile(r"\?\?\s*")
    regexp_ex = re.compile(r"!!\s*")
    regexp_ld = re.compile(r"…")

    text = regexp_fs.sub(fn_capital_after_fullstop, text)
    text = regexp_cm.sub(", ", text)
    text = regexp_qm.sub(u"¿", text)
    text = regexp_ex.sub(u"¡", text)
    text = regexp_ld.sub(u"\\ldots", text)
    return text

if __name__ == '__main__':
    inname = "contents.in.txt"
    outname = "contents.out.txt"
    with open(inname, encoding="utf-8") as fh:
        text = fh.read()
    with open(outname, "w", encoding="utf-8") as fh:
        fh.write(main(text))


from datetime import date, datetime

from django.test import TestCase
from django_dynamic_fixture import get as get_ddf

from django.core.urlresolvers import reverse, reverse_lazy

from ledger.accounts.models import Profile

from wildlifelicensing.apps.applications.views.entry import LICENCE_TYPE_NUM_CHARS, LODGEMENT_NUMBER_NUM_CHARS
from wildlifelicensing.apps.applications.models import Application, Assessment, Condition
from wildlifelicensing.apps.main.tests.helpers import create_random_customer, create_licence_type, \
    SocialClient, get_or_create_default_assessor_group, get_or_create_default_officer

def create_profile(user):
    return get_ddf(Profile, user=user)

def create_application(user=None, **kwargs):
    if user is None:
        user = create_random_customer()
    if 'applicant' not in kwargs:
        kwargs['applicant'] = user
    if 'applicant_profile' not in kwargs:
        kwargs['applicant_profile'] = create_profile(user)
    if 'licence_type' not in kwargs:
        kwargs['licence_type'] = create_licence_type()
    if 'data' not in kwargs:
        kwargs['data'] = {}
    application = get_ddf(Application, **kwargs)
    return application

def lodge_application(application):
    """
    :param application:
    """
    client = SocialClient()
    client.login(application.applicant.email)
    client.get(reverse('wl_applications:edit_application', args=[application.pk]))
    url = reverse_lazy('wl_applications:preview')
    client.post(url)
    application.refresh_from_db()
    client.logout()
    return application

def create_and_lodge_application(user=None, **kwargs):
    application = create_application(user, **kwargs)
    application.processing_status = 'new'
    application.customer_status = 'under_review'
    application.lodgement_sequence += 1
    application.lodgement_date = datetime.now().date()
    application.lodgement_number = '%s-%s' % (str(application.licence_type.pk).zfill(LICENCE_TYPE_NUM_CHARS),
                                              str(application.pk).zfill(LODGEMENT_NUMBER_NUM_CHARS))
    application.save()

    return application

def get_or_create_assessment(application):
    """
    First assessment for the given application or create one
    :param application:
    :return:
    """
    group = get_or_create_default_assessor_group()
    assessment = Assessment.objects.filter(application=application).first()
    if assessment is None:
        assessment = Assessment.objects.create(application=application, assessor_group=group,
                                               officer=get_or_create_default_officer())
    return assessment

def get_or_create_condition(code, defaults):
    return Condition.objects.get_or_create(code=code, defaults=defaults)[0]

class HelpersTest(TestCase):
    def test_create_profile(self):
        user = create_random_customer()
        profile = create_profile(user)
        self.assertIsNotNone(profile)
        self.assertEquals(user, profile.user)
        self.assertEquals(profile, user.profiles.first())

    def test_create_application(self):
        application = create_application()
        self.assertIsNotNone(application)


# string concatenation
youtuber = "Pewdiepie"

print("subscribe to " + youtuber)
print("subscribe to {}".format(youtuber))
# f string --> add an f before the string
print(f"subscribe to {youtuber}")

adj = input("Adjective: ")
verb1 = input("Verb: ")
verb2 = input("Verb: ")
famous_person = input("Famous person:")

madlib = f"Computer programming is so {adj}! It makes me so excited all the time \
because I love to {verb1}. Stay hydrated and {verb2} like you are {famous_person}"

print(madlib)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019-01-30 18:17
# @Author  : pang
# @Software: PyCharm
import re
import os
import time
import asyncio
import datetime
import aiohttp
from motor.motor_asyncio import AsyncIOMotorClient
from pymongo import UpdateOne

from ruia import Spider, Response

try:
    from items import FundItem
    from settings import *
except ImportError:
    import sys
    sys.path[0] = os.path.dirname(os.path.abspath(__file__))
    from items import FundItem
    from settings import *

def make_task_persist_update_detail(_id, source='jfz', update_time=None):
    """
    插入净值更新时间, 方便查询爬取净值
    :param _id:
    :param source:
    :param update_time:
    :return:
    """
    update_time = update_time or datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    return UpdateOne({'%s_id' % source: _id}, {'$set': {'%s_update_time' % source: update_time}}, upsert=True)

class NavSpider(Spider):
    request_config = {
        'RETRIES': 0,
        'DELAY': 5,
        'TIMEOUT': 20
    }
    concurrency = 3
    name = 'full_nav_spider'
    kwargs = {
        'proxy': HTTP_PROXY,
    }
    headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate, br',
               'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'max-age=0', 'Connection': 'keep-alive',
               'Host': 'www.jfz.com', 'Upgrade-Insecure-Requests': '1',
               'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36'}

    def __init__(self, middleware=None, loop=None, is_async_start=False):
        super().__init__(middleware, loop, is_async_start)
        self.logger.info('MONGODB_URL:%s' % MONGODB_URL)
        self.client = AsyncIOMotorClient(MONGODB_URL, io_loop=loop)
        self.db_name = DB_NAME
        self.nav_collection = self.client[self.db_name]['%s:nav' % SOURCE]
        self.id_map_collection = self.client[self.db_name]['fund_id_map']
        self.token = None
        self.request_session = None
        self.sem = asyncio.Semaphore(self.concurrency, loop=self.loop)

    async def login(self):
        url = "https://passport.jinfuzi.com/passport/user/loginAjax?cb=" \
              "jQuery1102013622709964876956_1533719058287&LoginForm%5Busername%5D=13608228554" \
              "&LoginForm%5Bpassword%5D=z123456&_=1533719058293"
        request = self.make_requests_from_url(url=url)
        resp = await request.fetch()
        if resp.status != 200:
            return False
        text = resp.html
        pattern = r'.*?\(\[(\d+),.*"authToken":"(.*?)"\}\]\)'
        m = re.match(pattern, text)
        if not m:
            return False
        if m.group(1) != '10000':
            return False
        self.token = m.group(2)
        headers = {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36',
            'Host': 'www.jfz.com',
        }
        url = "https://www.jfz.com/public/login/index?authToken=%s" % self.token
        request = self.make_requests_from_url(url=url, headers=headers)
        resp = await request.fetch()
        result = resp.status == 200
        if not result:
            return False
        return True

    async def get_all_fund(self):
        try:
            limit = int(os.environ.get('LIMIT', 0))
            limit = 0
            print("test")       # todo
            self.logger.info("LIMIT:%s" % limit)
        except ValueError:
            limit = 0
        cursor = self.id_map_collection.find(limit=limit)
        cursor.sort('%s_update_time' % SOURCE, 1)
        # cursor = self.client[self.db_name][self.id_map_collection].find()
        count = 0
        async for doc in cursor:
            yield doc
            count += 1
            # break

    async def start_requests(self):
        self.request_session = aiohttp.ClientSession()
        if await self.login():
            self.logger.info("登录成功")
        else:
            self.logger.warning("登录失败")
            return
        headers = {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36',
            'Host': 'www.jfz.com',
        }
        now_time = datetime.datetime.now()
        async for doc in self.get_all_fund():
            if '%s_id' % SOURCE not in doc.keys():
                continue
            _id, jfz_id = doc['_id'], doc['%s_id' % SOURCE]
            if '%s_update_time' % SOURCE in doc.keys():
                str_update_time = doc['%s_update_time' % SOURCE]
                update_time = datetime.datetime.strptime(str_update_time, '%Y-%m-%d %H:%M:%S')
                if (now_time - update_time).days <= 1:
                    # 如果当天天内采集过的, 则跳过
                    self.logger.debug("最近更新过,跳过. ID: %s, 上次更新时间:%s" % (jfz_id, str_update_time))
                    continue
            url = 'https://www.jfz.com/simu/simuProductNew/GetPrdNetWorthDrawDown?prdCode=%s' % jfz_id
            # url = "https://www.jfz.com/simu/chart?id=%s" % jfz_id
            metadata = {'_id': _id, 'jfz_id': jfz_id}
            yield self.make_requests_from_url(url=url, res_type='json', metadata=metadata, headers=headers)
            self.logger.info("生成采集请求. ID:%s" % jfz_id)

    async def parse(self, response: Response):
        try:
            data = response.html
            if data is None:
                self.logger.info("采集失败. url:%s" % response.url)
                return None
            if not data[2]['isLogin']:
                self.logger.warning("登录超时, 需要重新登录!")
                await self.login()
                return
            if data[0] != 10000:
                self.logger.info("采集失败. url:%s" % response.url)
                return None
            else:
                data = data[2]
            self.logger.debug('开始解析响应. url:%s' % response.url)
            if data['isLogin'] and data['isVerify']:
                data = data['hcData']
                _id = response.metadata['_id']
                jfz_id = response.metadata['jfz_id']
                tasks = []
                tasks_flag = []
                update_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                for item in data:
                    date = datetime.datetime.fromtimestamp(item['x'] / 1000).strftime('%Y%m%d')
                    row = {
                        'nav': float(item['unitNet']),
                        'sum_nav': float(item['accNet']),
                        'update_time': update_time
                    }
                    tasks.append(UpdateOne({'fund_id': _id, 'date': date}, {'$set': row}, upsert=True))
                    task = make_task_persist_update_detail(_id=jfz_id, source='jfz', update_time=update_time)
                    tasks_flag.append(task)
                async with self.sem:
                    s = time.time()
                    await self.id_map_collection.bulk_write(tasks_flag)
                    await self.nav_collection.bulk_write(tasks)
                    e = time.time()
                    self.logger.info("采集基金[%s]数据, 条数: [%s], 存储耗时:%s s" % (jfz_id, len(data), round(e-s, 2)))
                return
            else:
                self.logger.info("采集失败. url:%s" % response.url)
                return
        except Exception as e:
            self.logger.warning("采集失败. url:%s" % response.url)
            self.logger.exception(e)
            return

"""
累计净值接口:
https://www.jfz.com/simu/chart?id=P6281mbsw2
所有净值接口(需要登录):
https://www.jfz.com/simu/simuProductNew/GetPrdNetWorthDrawDown?prdCode=P6281mbsw2

"""

async def before_stop(spider):
    if spider.request_session:
        await spider.request_session.close()

if __name__ == '__main__':
    NavSpider.start(before_stop=before_stop)


#random choice
#hw = {'reading': 1, 'grammar': 2}
import random
print('Please type your two choices below')

c1 = input('choice 1 = ')
c2 = input('choice 2 = ')
hwp = []

for i in range(1000):
    hwc = random.randint(0,2)
    hwp.append(hwc)
    i += 1

if sum(hwp)/ 1000 >= 1:
    print(c1)
else:
    print(c2)


# 삼성전자에 입사한 종민이는 회사 근처로 이사를 하게 되었다.
# 그런데 집의 위치가 두 수도 회사 A, B 중간에 위치하기에 원하는 수도 회사를 선택할 수 있게 되었는데, 두 회사 중 더 적게 수도 요금을 부담해도 되는 회사를 고르려고 한다.
# 종민이가 알아본 결과 두 회사의 수도 요금은 한 달 동안 사용한 수도의 양에 따라 다음과 같이 정해진다.

# A사 : 1리터당 P원의 돈을 내야 한다.
# B사 : 기본 요금이 Q원이고, 월간 사용량이 R리터 이하인 경우 요금은 기본 요금만 청구된다. 하지만 R 리터보다 많은 양을 사용한 경우 초과량에 대해 1리터당 S원의 요금을 더 내야 한다.

# 종민이의 집에서 한 달간 사용하는 수도의 양이 W리터라고 할 때, 요금이 더 저렴한 회사를 골라 그 요금을 출력하는 프로그램을 작성하라.

# [입력]
# 첫 번째 줄에 테스트 케이스의 수 T가 주어진다.
# 각 테스트 케이스마다 첫 번째 줄에 위 본문에서 설명한 대로 P, Q, R, S, W(1 ≤ P, Q, R, S, W ≤ 10000, 자연수)가 순서대로 공백 하나로 구분되어 주어진다.

t = int(input())
for tc in range(1, t+1):
    answer = 0

    P, Q, R, S, W = map(int, input().split())
    costA = P*W
    costB = Q if R>=W else Q+S*(W-R)

    answer = costA if costA < costB else costB
    print("#{} {}".format(tc, answer))


import pygame
from pygame import freetype
import json
import os
import random
from math import sin, cos, pi, atan2, degrees
import os.path
from os import path
import xlsxwriter
import xlrd

pygame.init()
if not pygame.display.get_init():
    pygame.display.init()
if not pygame.freetype.was_init():
    pygame.freetype.init()
if not pygame.mixer.get_init():
    pygame.mixer.init()

#---------Globals
clock = pygame.time.Clock() #sets up a clock used for throttleing the fps
global origin
origin = ''

YELLOW = (255, 255, 0)
RED = (255, 0, 0)
GREEN = (12, 255, 0)
DK_GREEN = (51, 102, 0)
BLUE = (18, 0, 255)
ORANGE = (255, 186, 0)
SKYBLUE = (39, 145, 251)
PURPLE = (153, 51, 255)
DK_PURPLE = (102, 0, 204)
BROWN = (204, 153, 0)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

SCREEN_WIDTH = 224 * 2
SCREEN_HEIGHT = 288 * 2

explosion_anim = []

def set_explo():
    for i in range(82):
        filename = 'images/round_vortex/frame00{}.png'.format(i)
        img = get_image(filename)
        explosion_anim.append(img)

def get_angle(origin, destination):
    """Returns angle in radians from origin to destination.
    This is the angle that you would get if the points were
    on a cartesian grid. Arguments of (0,0), (1, -1)
    return .25pi(45 deg) rather than 1.75pi(315 deg).
    """
    x_dist = destination[0] - origin[0]
    y_dist = destination[1] - origin[1]
    return atan2(-y_dist, x_dist) % (2 * pi)

def project(pos, angle, distance):
    """Returns tuple of pos projected distance at angle
    adjusted for pygame's y-axis.
    """
    return (pos[0] + (cos(angle) * distance),
            pos[1] - (sin(angle) * distance))

#-----Classes

#TODO create enemy grid for enemies to take up positions in
#enemy_grid = {pos1: [], }

class Enemy(pygame.sprite.Sprite):

    def __init__(self, start_pos, tar_pos):
        super().__init__()
        self.en_images = []
        img = get_image('./images/player_ship/1.png')
        img = pygame.transform.scale(img, (SCREEN_WIDTH // 10, SCREEN_WIDTH // 10))
        self.en_images.append(img)
        self.image = self.en_images[0]
        self.rect = self.image.get_rect()
        #TODO xy position will be taken out and referenced through the entry paths
        self.speed = 2
        self.hp = 1
        self.pos = start_pos
        self.target_pos = tar_pos
        self.angle = get_angle(self.pos, self.target_pos)
        self.rect.center = self.pos

        self.moving = True
        self.cooldown = 2000
        self.now = pygame.time.get_ticks()

        self.last = 0

    def set_target_pos(self, tar_pos):
        self.target_pos = tar_pos

    def update(self):
        # updates the location
        self.angle = get_angle(self.pos, self.target_pos)
        self.pos = project(self.pos, self.angle, self.speed)
        self.rect.center = self.pos
        self.now = pygame.time.get_ticks()

        #TODO fix the damn movement - seriously

        if self.rect.y < (SCREEN_HEIGHT - (SCREEN_HEIGHT//3)):
            if self.now - self.last >= self.cooldown:
                self.last = self.now
                self.fire_at_ply(x = self.rect.x, y = self.rect.y)

    def fire_at_ply(self, x, y):
        fire = Enemy_bullet([x,y], [game.player.rect.x, game.player.rect.y])
        game.all_sprites_list.add(fire)
        game.enemy_bullet_list.add(fire)
        pass

        #TODO flush out the enemy class

#TODO handles the moving of the group as a whole
class Enemy_group(object):
    def __init__(self):

        pass

#see functions below

#TODO add fire bullet to the player class

class Player(pygame.sprite.Sprite):
    #class for the player
    def __init__(self):
        super().__init__()
        self.creation_time = pygame.time.get_ticks()
        self.images = []
        img = get_image('./images/player_ship/8.png')
        img = pygame.transform.scale(img, (SCREEN_WIDTH // 10, SCREEN_WIDTH//10))
        self.images.append(img)
        self.image = self.images[0]
        img = get_image('./images/player_ship/7.png')
        img = pygame.transform.scale(img, (SCREEN_WIDTH // 10, SCREEN_WIDTH // 10))
        self.images.append(img)
        alpha = 255
        img = get_image('./images/player_ship/9.png').convert_alpha()
        img = pygame.transform.scale(img, (SCREEN_WIDTH // 10, SCREEN_WIDTH // 10))
        self.images.append(img)
        self.rect = self.image.get_rect()
        self.rect.x = (SCREEN_WIDTH // 2)
        self.rect.y = (SCREEN_HEIGHT - (img.get_height() + 20))
        self.width = self.image.get_rect().width
        self.speed = 2
        self.lives = 2
        self.previous_x = 0
        self.last = pygame.time.get_ticks()

    def update(self):
        #updates the location
        if self.rect.x > SCREEN_WIDTH - (SCREEN_WIDTH//10):
            self.rect.x = SCREEN_WIDTH - (SCREEN_WIDTH//10)
        if self.rect.x < 0:
            self.rect.x = 0
        if self.rect.x == self.previous_x:
            self.no_move()
        self.rect.x = self.rect.x
        self.rect.y = self.rect.y
        self.previous_x = self.rect.x

    def no_move(self):
        self.image = self.images[0]

    def move_x(self, val):
        self.previous_x = self.rect.x
        self.rect.x = self.rect.x + (val * self.speed)
        if val > 0:
            self.image = self.images[1]
        elif val < 0:
            self.image = self.images[2]

    def get_y(self):
        return self.rect.centery

    def get_x(self):
        return self.rect.centerx

class Enemy_bullet(pygame.sprite.Sprite):
    def __init__(self, pos, target_pos):
        super().__init__()
        self.images = []
        img = get_image('./images/fx/pl_lazer.png')
        img = pygame.transform.scale(img, (img.get_rect().width//2, img.get_rect().height//2))
        self.rot = degrees(get_angle(pos, target_pos))
        img = pygame.transform.rotate(img, self.rot)
        self.images.append(img)
        self.image = self.images[0]
        self.rect = self.image.get_rect()
        self.rect.x = pos[0]
        self.rect.y = pos[1]
        self.speed = 2
        pygame.mixer.Sound('./sounds/effect/en_lsz.ogg').play()
        self.pos = pos
        self.target_pos = target_pos
        self.angle = get_angle(self.pos, [game.player.rect.x, SCREEN_HEIGHT + 100])

    def update(self):
        self.pos = project(self.pos, self.angle, self.speed)
        self.rect.center = self.pos

        self.rect.y += (2 * self.speed)

        if self.rect.y > (SCREEN_HEIGHT + 10):
            self.kill()

class Bullet(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.images = []
        img = get_image('./images/fx/pl_lazer.png')
        img = pygame.transform.scale(img, (img.get_rect().width//2, img.get_rect().height//2))
        self.rot = 90
        img = pygame.transform.rotate(img, self.rot)
        self.images.append(img)
        self.image = self.images[0]
        self.rect = self.image.get_rect()
        self.rect.x = pos[0]
        self.rect.y = pos[1]
        self.speed = 2
        pygame.mixer.Sound('./sounds/effect/pl_lsz.ogg').play()
        self.pos = pos

    def update(self):
        self.rect.y -= (2 * self.speed)
        if self.rect.y < -10:

            self.kill()

#TODO flush out level object
class Level(object):
    def __init__(self):
        self.num_of_enemies = 40
        self.level_num = 1
        self.max_level = 255

    def level_start(self):
        pass

    def level_finish(self):
        pass

#TODO finish highscore object (CWI)
class high_score(object):

    def __init__(self):
        self.default_hs = [['aaa', 20000]]
        self.high_scores =[]
        self.load_hs_info()

    def check_score(self, score):
        self.high_scores.append(['bbb', score])
        l = len(self.high_scores)
        for i in range(0, l):
            for j in range(0, l - i - 1):
                if (self.high_scores[j][1] > self.high_scores[j+1][1]):
                    tempo = self.high_scores[j]
                    self.high_scores[j] = self.high_scores[j+1]
                    self.high_scores[j+1] = tempo

        return self.high_scores[0][1]

    def display_hs():

        pass

    def hs_enter_name():
        pass

    def save_hs_info(self):
        #writing to xlsx files - https://xlsxwriter.readthedocs.io/
        l = len(self.high_scores)
        for i in range(0, l):
            for j in range(0, 1-i-1):
                if (self.high_scores[j][1] == 'bbb'):
                    self.high_scores[j][0] = hs_enter_name()

        hs_workbook = xlsxwriter.Workbook('./data/hsdata.xlsx')
        hs_worksheet = hs_workbook.add_worksheet()

        row = 0
        col = 0

        for hs_p, hs in (self.high_scores):
            hs_worksheet.write(row, col, hs_p)
            hs_worksheet.write(row, col + 1, hs)
        hs_workbook.close()

    def load_hs_info(self):
        #reading xlsx files - https://www.geeksforgeeks.org/reading-excel-file-using-python/
        try:
            xlrd_loc = ('./data/hsdata.xlsx')
            xlrd_wb = xlrd.open_workbook(xlrd_loc)
            xlrd_sheet = xlrd_wb.sheet_by_index(0)
            xlrd_sheet.cell_value(0, 0)
        except FileNotFoundError:
            self.high_scores = self.default_hs
            self.save_hs_info()
            self.load_hs_info()
        else:
            pass

        xlrd_loc = ('./data/hsdata.xlsx')
        xlrd_wb = xlrd.open_workbook(xlrd_loc)
        xlrd_sheet = xlrd_wb.sheet_by_index(0)
        xlrd_sheet.cell_value(0,0)

        tot_num_rows = xlrd_sheet.nrows
        tot_num_col = xlrd_sheet.ncols

        for row in range(tot_num_rows):
            self.high_scores.append(xlrd_sheet.row_values(row))

        if self.high_scores == []:
            self.high_scores = self.default_hs

        pass

#TODO add high score to game object as a sprite and display it :D

class Explosion(pygame.sprite.Sprite):
    def __init__(self, pos1, pos2):
        pygame.sprite.Sprite.__init__(self)
        self.image = explosion_anim[0]
        self.rect = self.image.get_rect()
        self.rect.centerx = pos1
        self.rect.centery = pos2
        self.frame = 0
        self.last_update = pygame.time.get_ticks()
        self.frame_rate = 15

    def update(self):
        now = pygame.time.get_ticks()
        if now - self.last_update > self.frame_rate:
            self.last_update = now
            self.frame += 1
            if self.frame == len(explosion_anim):
                self.kill()

            else:
                pos1 = self.rect.centerx
                pos2 = self.rect.centery
                self.image = explosion_anim[self.frame]
                self.rect = self.image.get_rect()
                self.rect.centerx = pos1
                self.rect.centery = pos2

class Score_exp(pygame.sprite.Sprite):
    def __init__(self, pos1, pos2):
        pygame.sprite.Sprite.__init__(self)
        self.images = []
        img = get_image('./images/100score.png')
        self.images.append(img)
        self.image = self.images[0]
        self.rect = self.image.get_rect()
        self.pos2 = pos2
        self.rect.x = pos1
        self.rect.y = pos2

    def update(self):
        if self.rect.y < self.pos2 - 30:
            self.kill()
        else:
            self.rect.y -= 0.25

class Game(object):                                     #class reps an instance of the game
    def __init__(self):                                 #creates all attributes of the game
        set_explo()
        self.score = 0
        self.high_score = high_score()
        self.score_list = pygame.sprite.Group()
        self.game_over = False

        #create sprite lists
        self.all_sprites_list = pygame.sprite.Group()
        self.enemy_bullet_list = pygame.sprite.Group()
        self.bullet_list = pygame.sprite.Group()
        self.enemy1 = Enemy(start_pos = [(SCREEN_WIDTH + 20), (SCREEN_HEIGHT - 10)], tar_pos = [(SCREEN_WIDTH//2), 100])

                                                        #todo remove and replace enemy creation in the level object
        self.player = Player()  #create the player
        self.player_list = pygame.sprite.Group()
        self.player_list.add(self.player)
        self.enemy1 = Enemy(start_pos=[(SCREEN_WIDTH + 20), (SCREEN_HEIGHT - 10)], tar_pos=[(SCREEN_WIDTH // 2), 100])
        self.enemy_list = pygame.sprite.Group()
        self.enemy_list.add(self.enemy1)                #todo remove and add elsewhere...
        #self.all_sprites_list.add(self.hscore)         #todo impliment
        self.all_sprites_list.add(self.player)
        self.all_sprites_list.add(self.enemy1)

    def process_events(self):                           #process all the events and return true if we close the window
        pygame.event.pump()
        keyinput = pygame.key.get_pressed()
        if keyinput[pygame.K_ESCAPE]:
            print(self.high_score.check_score(self.score))
            self.high_score.save_hs_info()
            raise SystemExit
        if keyinput[pygame.K_LEFT]:
            self.player.move_x(-1)

        if keyinput[pygame.K_RIGHT]:
            self.player.move_x(1)

        if keyinput[pygame.K_SPACE]:
            self.cooldown = 400                         #cool down for bullet firing
            now = pygame.time.get_ticks()
            if now - self.player.last >= self.cooldown:
                self.player.last = now

                bullet = Bullet(pos = [self.player.get_x(), self.player.get_y()])

                self.all_sprites_list.add(bullet)
                self.bullet_list.add(bullet)

        return False

    def run_logic(self):                                #method runs each frame and updates positions
        if not self.game_over:                          #and checks for collisions

            self.all_sprites_list.update()              #move all sprites

            #see if the player block has collided with stuff
            #Checks to see if fire - aka enemy bullets hit player
            for fire in self.enemy_bullet_list:
                player_hit_list = pygame.sprite.spritecollide(fire, self.player_list, True)
                for self.player in player_hit_list:
                    self.player.lives -= 1
                    self.enemy_bullet_list.remove(fire)
                    self.explo = Explosion(self.player.rect.centerx, self.player.rect.centery)
                    self.all_sprites_list.add(self.explo)
                    self.player.kill()

            #checks to see if player has hit something.
            for self.player in self.player_list:
                enemy_hit_list = pygame.sprite.spritecollide(self.player, self.enemy_list, True)
                for self.enemy in enemy_hit_list:
                    if self.player.creation_time > 20:
                        self.explo = Explosion(self.player.rect.centerx, self.player.rect.centery)
                        self.player.lives -= 1
                        self.player.kill()
                        #todo fix player respawn after death

            for bullet in self.bullet_list:
                enemy_hit_list = pygame.sprite.spritecollide(bullet, self.enemy_list, True)
                for self.enemy in enemy_hit_list:
                    self.bullet_list.remove(bullet)
                    self.all_sprites_list.remove(bullet)
                    self.score_up = 100
                    self.score += self.score_up
                    self.high_score.check_score(self.score)
                    self.enemy.hp -= 1
                    if self.enemy.hp <= 0:
                        self.explo = Explosion(self.enemy.rect.centerx, self.enemy.rect.centery)
                        self.all_sprites_list.add(self.explo)
                        score_fly = Score_exp(self.enemy.rect.centerx, self.enemy.rect.centery)
                        self.all_sprites_list.add(score_fly)
                        self.enemy.kill()
                        print(self.score)
                        self.enemy1 = Enemy(start_pos=[(SCREEN_WIDTH + 20), (SCREEN_HEIGHT - 10)],
                                            tar_pos=[(SCREEN_WIDTH // 2), 100])
                        self.enemy_list.add(self.enemy1)  # todo remove and add elsewhere...
                        #print(self.hscore)

                if bullet.rect.y < -10:
                    self.bullet_list.remove(bullet)
                    self.all_sprites_list.remove(bullet)

            #
            # TODO if len(self.enemy_list) == 0:
            #     self.level_over = True

    def display_frame(self, screen):
            screen.fill(WHITE)
            screen.blit(BG1, [0,0])

            #self.hscore.display_hs()
            #self.player.display_lives()
            #todo display player lives and level information

            if self.game_over:                      #game over text on screen
                text_var = pygame.freetype.Font('./images/font/future_thin.ttf', 16, False, False)
                text_var2 = text_var.render("Game Over, click to restart", fgcolor = BLACK)
                center_x = (SCREEN_WIDTH // 2) - (text_var2[0].get_width() // 2)
                center_y = (SCREEN_HEIGHT // 2) - (text_var2[0].get_height() // 2)
                screen.blit(text_var2[0], [center_x, center_y])

            if not self.game_over:
                self.all_sprites_list.draw(screen)

            pygame.display.flip()

_image_library = {}

def get_image(path):
    global _image_library
    image = _image_library.get(path)
    if image == None:
        canonicalized_path = path.replace('/', os.sep).replace('\\', os.sep)
        image = pygame.image.load(canonicalized_path)
    return image

#TODO define functions for enemies to call for movment

def main():
    size = [SCREEN_WIDTH, SCREEN_HEIGHT]
    screen = pygame.display.set_mode(size)

    pygame.display.set_caption("My Game - fuck that")
    pygame.mouse.set_visible(False)

    #create our objects and set data
    done = False
    clock = pygame.time.Clock()

    #creates gme instance
    global game
    game = Game()

    #TODO title screen insert here

    #main game loop
    while not done:
        #process events
        done = game.process_events()
        #update stuff
        game.run_logic()
        #draw
        game.display_frame(screen)
        #pause for the next frame
        clock.tick(60)

    pygame.quit() # closes window and exits

BG1 = get_image('./images/bg/bg1.png')
#call the main function and start up the game

if __name__ == '__main__':
    main()

#TODO add sounds
#TODO add challenge level logic
#TODO add boss level, sprites, logic
#TODO add powerups
#TODO add logic for ship capture and two ship fighting


# import necessary libraries
from sqlalchemy import func
import datetime as dt
import numpy as np
import pandas as pd

from flask import (
    Flask,
    render_template,
    jsonify,
    request,
    redirect)
from flask import Flask, jsonify, render_template, request, flash, redirect
from flask_sqlalchemy import SQLAlchemy

import sqlite3

#################################################
# Flask Setup
#################################################
app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False  # default
#################################################
# Data Setup
#################################################

# This is how you make a connection
conn = sqlite3.connect("Wine.DB")

# Write to DB
wine_data = pd.read_csv("Data/clean_winemag-data.csv")
wine_data.to_sql("wine", conn, if_exists="replace")

# This will read
query = "select * from wine"
wine_df = pd.read_sql(query, conn)
# # otu_id
# Otu_id = pd.read_csv("DataSets/Belly_Button_Biodiversity_otu_id.csv")
# otu_id_df = pd.DataFrame(Otu_id)

# #samples
# Samples = pd.read_csv("DataSets/Belly_Button_Biodiversity_samples.csv")
# samples_df = pd.DataFrame(Samples)
# # Fill NAN values in 'samples' dataframe with 0
# samples_df = samples_df.fillna(0)

#################################################
# Flask Routes
#################################################
@app.route("/")
# """Return the dashboard homepage."""
def home():
    return render_template("index.html")

@app.route('/names')
# """List of wine variety names.
# Returns a list of sample names in the format
# [
    # "Champagne Blend",
    # "Champagne Blend",
    # "Champagne Blend",
    # "Champagne Blend",
    # "Champagne Blend",
    # "Champagne Blend",
    # "Champagne Blend",
    # ...
# ]

# """
def names():
    names = list(set(list(wine_df['variety'])))
    return jsonify(names)

@app.route('/price_points/<variety>')
# """List of prices, points and country for a certain wine variety.

# Returns a list of OTU descriptions in the following format

# [
    # 20,
    # 40,
    # 121,
    # 15,
    # 65,
    # ...
# ]
# """
def price_points(variety):
    prices = list(wine_df[wine_df['variety']==variety]['price'])
    points = list(wine_df[wine_df['variety']==variety]['points'])
    countries = list(wine_df[wine_df['variety']==variety]['country'])
    return jsonify({"points": list(map(int,points)), "prices": list(map(int,prices)), 'countries':countries})

@app.route('/metadata/<variety>')
# """MetaData for a given sample.

# Returns a json dictionary of sample metadata in the format

# {
    # Rating_Count: 200,
    # Min_Price: 4,
    # Max_Price: 2000,
    # Highest_Rating: "Winery Name"
    # Lowest_Rating; "Winery Name",
# }
# """
def meta(variety):
    prices = list(wine_df[wine_df['variety']==variety]['price'])
    points = list(wine_df[wine_df['variety']==variety]['points'])
    Rating_Count = len(points)
    Min_Price = min(prices)
    Max_Price = max(prices)
    variety_df = wine_df.loc[wine_df['variety']==variety,['points','winery']]
    Highest_Rating = list(set(variety_df[variety_df['points']==max(points)]['winery']))
    Lowest_Rating = list(set(variety_df[variety_df['points']==min(points)]['winery']))
    # all_meta = wine_df[wine_df['SAMPLEID'] == sampleID]
    # age = int(all_meta.AGE)
    # BBTYPE = all_meta.iloc[0]["BBTYPE"]
    # ETHNICITY = all_meta.iloc[0]["ETHNICITY"]
    # gender = all_meta.iloc[0]["GENDER"]
    # location = all_meta.iloc[0]["LOCATION"]
    sample_metadata = {}
    sample_metadata['Vareity Name'] = variety
    sample_metadata['Rating_Count'] = Rating_Count
    sample_metadata['Min_Price (USD)'] = Min_Price
    sample_metadata['Max_Price (USD)'] = Max_Price
    sample_metadata['Highest Rating Winery'] = Highest_Rating
    sample_metadata['Lowest Rating Winery'] = Lowest_Rating
    return jsonify(sample_metadata)

if __name__ == "__main__":
    app.run(debug=True)

##############################################################################################################33


import math
from panda3d.core import Fog, LVecBase4
from direct.particles.ParticleEffect import *
from . import ParticleDefs

# EffectsManager.fog.loadFog(arg)?
particleModel = None

def getParticleModel():
    global particleModel

    if particleModel is None:
        particleModel = loader.loadModel('phase_3.5/models/props/suit-particles')

    return particleModel

def getParticle(name):
    return getParticleModel().find('**/{0}'.format(name))

def loadParticleFile(name):
    setupParticle = ParticleDefs.ParticleTable[name]
    effect = ParticleEffect()

    setupParticle(effect)
    return effect

def __makeGearExplosion(numParticles = None, style = 'Normal'):
    if style == 'Normal':
        effect = loadParticleFile('gearExplosion')
    elif style == 'Big':
        effect = loadParticleFile('gearExplosionBig')
    elif style == 'Wide':
        effect = loadParticleFile('gearExplosionWide')

    if numParticles:
        particles = effect.getParticlesNamed('particles-1')
        particles.setPoolSize(numParticles)

    return effect

def createParticleEffect(name = None, file = None, numParticles = None):
    if not name:
        return loadParticleFile(file)
    if name == 'GearExplosion':
        return __makeGearExplosion(numParticles)
    elif name == 'BigGearExplosion':
        return __makeGearExplosion(numParticles, 'Big')
    elif name == 'WideGearExplosion':
        return __makeGearExplosion(numParticles, 'Wide')

def setEffectTexture(effect, name, color = None):
    particles = effect.getParticlesNamed('particles-1')
    np = getParticle(name)

    if color:
        particles.renderer.setColor(color)

    particles.renderer.setFromNode(np)

def loadShaders():
    normalsBuffer = base.win.makeTextureBuffer("normalsBuffer", 0, 0)
    normalsBuffer.setClearColor(LVecBase4(0.5, 0.5, 0.5, 1))
    normalsBuffer = normalsBuffer
    normalsCamera = base.makeCamera(
        normalsBuffer, lens=base.cam.node().getLens())
    normalsCamera.node().setScene(render)

    drawnScene = normalsBuffer.getTextureCard()
    drawnScene.setTransparency(1)
    drawnScene.setColor(1, 1, 1, 0)
    drawnScene.reparentTo(render2d)
    print("loading shaders...")
    return drawnScene

def toggleAmbientOcclusion(AOEnabled):
    if not AOEnabled:
        filters.setAmbientOcclusion()
        return True
    else:
        filters.delAmbientOcclusion()
        return False

def toggleInvert():
    if not invertEnabled:
        filters.setInverted()
        invertEnabled = True
    else:
        filters.delInverted()
        invertEnabled = False

def toggleBloom():
    if not bloomEnabled:
        filters.setBloom()
        bloomEnabled = True
    else:
        filters.delBloom()
        bloomEnabled = False

def toggleCamera():
    if not mouseEnabled:
        base.enableMouse()
        mouseEnabled = True
    else:
        base.disableMouse()
        camera.setPosHpr(0, 0, 0, 0, 0, 0)
        mouseEnabled = False

def toggleFog(fog, fogEnabled, FogDensity):
    if not fogEnabled:
        return fog.setExpDensity(FogDensity)
        #return True
    else:
        return fog.setExpDensity(0)
        #return False

def toggle_xray_mode():
    """Toggle X-ray mode on and off. This is useful for seeing the
    effectiveness of the portal culling."""
    xray_mode = not xray_mode
    if xray_mode:
        scene.setColorScale((1, 1, 1, 0.5))
        scene.setTransparency(TransparencyAttrib.MDual)
    else:
        scene.setColorScaleOff()
        scene.setTransparency(TransparencyAttrib.MNone)

def toggle_model_bounds():
    """Toggle bounding volumes on and off on the models."""
    show_model_bounds = not show_model_bounds
    if show_model_bounds:
        for model in objectList:
            model.showBounds()
    else:
        for model in objectList:
            model.hideBounds()