# SPDX-License-Identifier: LGPL-2.1-or-later
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
import numpy as np

class DataBase(object):

    def __init__(self, data, mask):
        self.mask = None
        self._mask_slice = None
        self.data = data
        if mask:
            self._cut_out_data(mask)

    def _find_mask_indices(self, mask, column_name):
        arr = np.array(self.data[column_name])

        if len(mask) >= 2:
            starttime = mask[0]
            endtime = mask[-1]
        elif len(args) == 1:
            starttime = min(self.data[column_name])
            endtime = mask[0]
        else:
            return (0, len(arr) - 1)
        idcs = np.where((arr >= starttime) & (arr < endtime))[0]
        if len(idcs) >= 2:
            return (idcs[0], idcs[-1] + 1)
        if len(idcs) == 1:
            return (idcs[0], idcs[0] + 1)
        return (0, 0)

    def mask_data(self, args, column_name):
        """mask_data(endtime) or mask_data(starttime, endtime)
        All future queries will be clipped to the visits starting between
        starttime and endtime."""
        arr = np.array(self.data[column_name])
        if isinstance(args, int) or isinstance(args, float):
            start = min(arr)
            end = args[0]
        elif len(args) >= 2:
            start = args[0]
            end = args[-1]
        elif len(args) == 1:
            start = min(arr)
            end = args[0]
        else:
            start = min(arr)
            end = max(arr)

        self.mask = (start, end)
        self._mask_slice = self. _find_mask_indices(self.mask,
                                                    column_name)

    def unmask_data(self):
        """Remove the mask - future queries will not be clipped"""
        self.mask = None
        self._mask_slice = None

    def _cut_out_data(self, new_mask):
        mask = self._find_mask_indices(new_mask)
        for key in self.data.keys():
            self.data[key] = self.data[key][mask[0]: mask[1]]

    def getproperty(self, mice, propname, astype=None):
        if sys.version_info < (3, 0):
            if isinstance(mice, (str, unicode)):
                mice = [mice]
        else:
            if isinstance(mice, str):
                mice = [mice]

        if self.mask is None:
            if astype is None:
                return [x[0] for x in zip(self.data[propname],
                        self.data['Tag']) if x[1] in mice]
            elif astype == 'float':
                return [float(x[0]) for x in zip(self.data[propname],
                        self.data['Tag']) if x[1] in mice]
        else:
            mask_0, mask_1 = self._mask_slice[0], self._mask_slice[1]
            if astype is None:
                return [x[0] for x in zip(self.data[propname][mask_0:mask_1],
                                          self.data['Tag'][mask_0:mask_1])
                        if x[1] in mice]
            elif astype == 'float':
                return [float(x[0]) for x in zip(
                    self.data[propname][mask_0:mask_1],
                    self.data['Tag'][mask_0:mask_1])
                        if x[1] in mice]

class Data(DataBase):
    def __init__(self, data, mask):
        super(Data, self).__init__(data, mask)

    def get_antennas(self, mice):
        return self.getproperty(mice, 'Antenna')

    def get_times(self, mice):
        return self.getproperty(mice, 'Time', 'float')

    def get_durations(self, mice):
        return self.getproperty(mice, 'Duration')

    def mask_data(self, mask):
        super(Data, self).mask_data(mask, column_name="Time")

class Visits(DataBase):
    def __init__(self, data, mask):
        super(Visits, self).__init__(data, mask)

    def get_starttimes(self, mice):
        return self.getproperty(mice, 'AbsStartTimecode', 'float')

    def get_endtimes(self, mice):
        return self.getproperty(mice, 'AbsEndTimecode', 'float')

    def get_durations(self, mice):
        return self.getproperty(mice, 'VisitDuration', 'float')

    def get_visit_addresses(self, mice):
        return self.getproperty(mice, 'Address')

    def mask_data(self, mask):
        super(Visits, self).mask_data(mask, column_name="AbsStartTimecode")


"""
    v1.0.0

    Author: Rick Nunes
    Email: sanunes.ricardo@gmail.com

    Tag: Quick and dirty

    Features:
        1. Parsing tweets
        2. Generalizing for up to 9 groups of files

    Assumptions:
        1. node_id's are exclusive to each node_file
        2. Words are exclusive to each terms file
        3. No duplicate tweets

"""
from collections import defaultdict
from datetime import datetime
import argparse
import jsonlines as jsonl
import gzip
from functools import wraps, partial
import multiprocessing as mp
from os import (
    stat,
    environ,
    popen,
    path,
    makedirs,
    listdir,
    remove
)
import threading
from sys import exit
from .utils import (
    get_node_ids,
    get_terms,
    compress_jsonl,
    get_temp_jsonl_files,
    archive,
    logging,
    log_process,
)

from .config import config

logger = logging.getLogger('MAIN')

class CategoriesDontMatchError(Exception):
    """ Raised when node and terms categories don't match """
    pass

class TweetMatcher(object):
    """
        Matches node ids in different cathegories to terms in equivalent
        cathegories, parsing tweets and matching n-grams found in terms
    """
    temp_dir = config['TEMP_DIR']
    matches = set()
    tweets = dict()

    def __init__(
        self,
        nodes_dir,
        terms_dir,
        tweets_file,
        output_dir,
        partition_to_jsonl_by=config['PARTITION_BY'],
        is_concurrent=config['IS_CONCURRENT'],
    ):
        self.nodes_dir = nodes_dir
        self.terms_dir= terms_dir
        self.is_concurrent = is_concurrent
        self.partition_to_jsonl_by = partition_to_jsonl_by
        self.tweets_file = tweets_file
        self.output_dir = output_dir

    def get_nodes_and_terms(self):
        self.nodes = get_node_ids(self.nodes_dir)
        self.terms, self.max_gram_length = get_terms(self.terms_dir)
        if len(self.nodes) != len(self.terms):
            raise CategoriesDontMatchError
        self.category_count = len(self.nodes)
        for c in range(self.category_count):
            #tweets_in_category = dict()
            self.tweets[c] = dict()

    @log_process
    def run(self):
        if not self.is_concurrent or stat(self.tweets_file).st_size < config['MAX_SIZE']:
            self.process()
        else:
            self.process_concurrent()
        self.write_matches()

    @log_process
    def process_concurrent(self):
        """
            Handles compressed tweets file in parallel after partitioning
        """
        logger.info(f"Processing {self.tweets_file}")
        lines = []
        total_partitions = 0
        partitioner = self.partition_to_jsonl_by
        with gzip.open(self.tweets_file, 'rb') as f:
            for index, line in enumerate(f):
                lines.append(line)
                if index > partitioner:
                    total_partitions += 1
                    partition_file = f"{self.temp_dir}/tweets_up_to_{partitioner}.jsonl.gz"
                    compress_jsonl(partition_file, lines)
                    partitioner += self.partition_to_jsonl_by
                    lines = []

        if lines:
            total_partitions += 1
            partitioner = partitioner - (self.partition_to_jsonl_by + len(lines)) if total_partitions > 1 else len(lines)
            last_partition_file = f"{self.temp_dir}/tweets_up_to_{partitioner}.jsonl.gz"
            compress_jsonl(last_partition_file, lines)

        logger.info(f"Partitions created: {total_partitions}")
        self.jsonl_files = get_temp_jsonl_files(self.temp_dir)
        self.get_matches_concurrent()
        self.clean_up()

    @log_process
    def process(self):
        """
            Reads compressed file sequentially and gets matches on the go
        """
        logger.info(f"Processing {self.tweets_file}")
        count_lines = 0
        count_filtered = 0
        with gzip.open(self.tweets_file, 'rb') as f:
            reader = jsonl.Reader(f)
            for i, tweet in enumerate(reader.iter(type=dict, skip_invalid=True)):
                count_lines += 1
                pp_tweet = self.pre_process_tweet(tweet['text'])
                if len(pp_tweet) < 2: continue
                count_filtered += 1
                self.get_match(pp_tweet, tweet['node_id'])
        logger.info(f"# TWEETS | PROCESSED {count_lines} | FILTERED {count_filtered} ")

    @log_process
    def read_to_memory(self):
        with gzip.open(self.tweets_file, 'rb') as f:
            reader = jsonl.Reader(f)
            for tweet in reader.iter(type=dict, skip_invalid=True):
                for i, node_set in enumerate(self.nodes):
                    if int(tweet['node_id']) in node_set:
                        pp_tweet = self.pre_process_tweet(tweet['text'])
                        # Ignore empty preprocessed tweets and single characters
                        if len(pp_tweet) < 2 and not tweet['message_id']: continue
                        try:
                            self.tweets[i][tweet['node_id']].add((tweet['message_id'], tweet['text']))
                        except KeyError:
                            self.tweets[i][tweet['node_id']] = set([(tweet['message_id'], tweet['text']),])

    @staticmethod
    def pre_process_tweet(tweet_text):
        """
            Removes some special characters, makes lower case and
            ignores embedded links
        """
        return [word.lower().strip().replace("‘", "").replace("’", "")\
                .replace(",","").replace(":","").replace("!","")\
                .replace("#","").replace("...","").replace('"','')
                for word in tweet_text.split(' ')
                if "http" not in word and len(word) > 1]

    def get_n_grams_in_text(self, pp_tweet):
        """
            Iterates over each word in tweet text and
            generates sets of n-grams starting with each
        """
        n_grams_in_text = defaultdict(set)
        for a in range(len(pp_tweet)):
            """ Creating n-gram sets """
            for step in range(1, self.max_gram_length+1):
                n_gram = " ".join(pp_tweet[a:a+step])
                try:
                    n_grams_in_text[step-1].add(n_gram)
                except IndexError as e:
                    logger.warning(e, step, self.max_gram_length)
        return n_grams_in_text

    def match_text_n_grams_with_terms(
        self,
        node_id,
        node_c,
        n_grams_in_text,
        matches_set
    ):
        """
            Matches generated n-grams from tweet text with stored terms
            in given category
        """
        for n, n_grams in n_grams_in_text.items():
            for gram in n_grams:
                try:
                    if gram in self.terms[node_c][n]:
                        matches_set.add((node_id, gram))
                except IndexError as e:
                    logger.warning(f"{e} in terms {i}, {j}")

    def get_match(self, pp_tweet, node_id, matches_set=None):
        """
            Processes match considering node id category
        """
        matches_set = self.matches if not matches_set else matches_set
        for node_category, id_set in enumerate(self.nodes):
            if int(node_id) in id_set:
                n_grams_in_text = self.get_n_grams_in_text(pp_tweet)
                self.match_text_n_grams_with_terms(
                    node_id,
                    node_category,
                    n_grams_in_text,
                    matches_set
                )

    @log_process
    def get_matches_concurrent(self):
        for file in self.jsonl_files:
            t = threading.Thread(target=self.get_matches_in_jsonl, args=(file, self.matches))
            t.start()

        main_thread = threading.currentThread()
        for t in threading.enumerate():
            if t is not main_thread:
                t.join()

    def get_matches_in_jsonl(self, file, matches_set):
        logger.info(f"Started: {file}")
        with gzip.open(file) as f:
            reader = jsonl.Reader(f)
            for tweet in reader.iter(type=dict, skip_invalid=True):
                pp_tweet = self.pre_process_tweet(tweet['text'])
                if len(pp_tweet) < 2: continue
                self.get_match(pp_tweet, tweet['node_id'],  matches_set)
        logger.info(f"Finished: {file}")

    @log_process
    def write_matches(self):
        if len(self.matches):
            output_file = self.output_dir + "result_"+datetime.today().strftime("%Y_%m_%d")+".txt"
            if not path.exists(self.output_dir): makedirs(self.output_dir[:-1])
            with open(output_file, 'w+') as w:
                for (node_id, term) in self.matches:
                    w.write(f"{node_id} {term}\n")
        else:
            logger.warning("No matches found")

    @log_process
    def clean_up(self):
        for file in self.jsonl_files:
            remove(file)
        logger.info("Removed temporary jsonl")
        logger.info("Job completed successfully")

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-p",
        help="Partition gz file by p tweets, default is 100000",
        type=int,
        default=100000
    )
    parser.add_argument(
        "-rpt",
        help="Read from partition",
        type=bool,
        default=False
    )
    parser.add_argument("-pgz", help="Parse from gz", type=bool, default=True)
    parser.add_argument("-nd", help="Path to nodes directory")
    parser.add_argument("-td", help="Path to terms directory")
    parser.add_argument("-tw", help="Path to tweets file")
    parser.add_argument("-od", help="Path to output directory")
    parser.add_argument("-ard", help="Path to archive")
    parser.add_argument("-cc", help="Make matching concurrent", default=False)
    args = parser.parse_args()

    tm = TweetMatcher(
        nodes_dir=args.nd,
        terms_dir=args.td,
        tweets_file=args.tw,
        output_dir=args.od,
        partition_to_jsonl_by=args.p,
        is_concurrent=args.cc
    )
    try:
        tm.get_nodes_and_terms()
    except (
        IsADirectoryError,
        FileNotFoundError,
        CategoriesDontMatchError
    ) as e:
        # TODO: Implement email alert
        logger.warning(e)
        logger.warning("Exiting program,  directories are not properly set")
        exit()
    tm.run()


import subprocess
import os
import os.path
import sys
from RLTest import Env
from includes import *
from test_info_modules import info_modules_to_dict

if 'EXT_TEST_PATH' in os.environ:
    EXTPATH = os.environ['EXT_TEST_PATH']
else:
    EXTPATH = 'tests/ctests/ext-example/libexample_extension.so'

def testExt(env):
    if env.env == 'existing-env' or NO_LIBEXT:
        env.skip()

    if os.path.isabs(EXTPATH):
        ext_path = EXTPATH
    else:
        modpath = env.module[0]
        ext_path = os.path.abspath(os.path.join(os.path.dirname(modpath), EXTPATH))

    if not os.path.exists(ext_path):
        raise Exception("Path ({}) does not exist. "
            "Run from the build directory or set EXT_TEST_PATH in the environment".format(ext_path))

    env = Env(moduleArgs='EXTLOAD %s' % ext_path)

    N = 100
    env.expect('ft.create', 'idx', 'ON', 'HASH', 'schema', 'f', 'text').ok()
    for i in range(N):
        env.assertOk(env.cmd('ft.add', 'idx', 'doc%d' % i, 1.0, 'fields',
                                         'f', 'hello world'))
    res = env.cmd('ft.search', 'idx', 'hello world')
    env.assertEqual(N, res[0])
    res = env.cmd('ft.search', 'idx', 'hello world', 'scorer', 'filterout_scorer')
    env.assertEqual(0, res[0])

    info = info_modules_to_dict(env)
    env.assertTrue('search_extension_load' in info['search_runtime_configurations'])

    if not env.isCluster():
        res = env.cmd('ft.config', 'get', 'EXTLOAD')[0][1]
        env.assertContains('libexample_extension', res)


import discord, motor, Core.utils as util, asyncio
from discord.ext import commands, tasks
from colorama import Fore as f

class pojcog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.db = self.bot.db["pingonjoin"]
        self.urgecolor = 0xF3DD6C
        self.errorcol = 0xA90F25 # error color
        self.success = discord.Colour.blurple() #theme
        self.checkmoji = "<:blurple_check:921544108252741723>" # success emoji
        self.xmoji = "<:yy_yno:921559254677200957>" # unsuccessful emoji
        self.urgentmoji = "<:n_:921559211366838282>" # exclamation emoji
        self.cache = {}
        self.pings = {}
        self.clearPings.start()

    @tasks.loop(minutes=100)
    async def cachePings(self):
        cache = self.db.find({})
        guilds = []
        channels = []
        for i in await cache.to_list(length=999999):
            guild = i['guild_id']
            chan = i['channel']
            guilds.append(guild)
            channels.append(chan)
        self.cache = {guilds}

    @tasks.loop(seconds=15)
    async def clearPings(self):
        self.pings.clear()

    @clearPings.before_loop
    async def before_clearPings(self):
        await self.bot.wait_until_ready()

    @commands.group(
        aliases = ['poj', 'pingjoin'],
        usage = "Manage_channels",
        description = "Set a channel in which new members will get pinged at upon joining.",
        brief = "subcommand, arg, subarg",
        help = "```Syntax: poj [subcommand] <arg> <subarg>\nExample: poj add #rules``` "
    )
    async def pingonjoin(self, ctx):
        try:
            if ctx.invoked_subcommand is None:
                embed = discord.Embed(title="Command: pingonjoin", description="Set a channel in which new memers will get pinged at upon joining.\n```Syntax: poj [subcommand] <arg> <subarg>\nExample: poj #rules 3```", color = discord.Color.blurple())
                embed.set_author(name="pingonjoin help", icon_url=ctx.me.avatar.url)
                embed.set_footer(text=f"Page 1/{len([sc for sc in self.bot.get_command('pingonjoin').walk_commands()])} ・ pingonjoin")
                return await ctx.reply(embed=embed)
        except Exception as e:
            print(e)

    @pingonjoin.command(
        aliases = ['set'],
        usage = "Manage_channels",
        description = "Set a channel in which new members will get pinged at upon joining.",
        brief = "channel",
        help = "```Syntax: poj add [channel]\nExample: poj add #rules```"
    )
    #async def add(self, ctx, channel: discord.TextChannel, delete:int=None):
    @commands.has_permissions(manage_channels=True)
    async def add(self, ctx, channel: discord.TextChannel):
        try:
            get = await self.db.count_documents({ "guild_id": ctx.guild.id})
            if len(get) > 20:
                return await ctx.reply(embed=discord.Embed(description=f"{self.urgentmoji} {ctx.author.mention} This **guild** has reached it's **maximum limit** of ``20`` ping on joins.", color=self.urgecolor))
        except:
            pass
            data = await self.db.find_one({ "guild_id": ctx.guild.id, "channel": channel.id})
            print("hi")
            if data:
                return await ctx.reply(embed=discord.Embed(description=f"{self.urgentmoji} A pingonjoin already **exists** for that channel", color=self.urgecolor))
            else:
                await self.db.insert_one({
                    "guild_id": ctx.guild.id,
                    "channel": channel.id

                })
                return await ctx.reply(embed=discord.Embed(description=f"<:check:921544057312915498> **Ping on join** created for {channel.mention}", color = 0x43B581))

    @pingonjoin.command(
        aliases = ['del', 'remove'],
        usage = "Manage_channels",
        description = "Remove a current pingonjoin you have for a channel",
        brief = 'channel',
        help = "```Syntax: poj remove [channel]\nExample: poj remove #rules```"
    )
    @commands.has_permissions(manage_channels=True)
    async def delete(self, ctx, channel: discord.TextChannel=None):
        check = await self.db.find_one({ "guild_id": ctx.guild.id})
        if check:
            findchan = await self.db.find_one({ "guild_id": ctx.guild.id, "channel": channel.id})
            if findchan:
                await self.db.delete_one({ "guild_id": ctx.guild.id, "channel": channel.id})
                return await ctx.reply(embed=discord.Embed(description=f"<:check:921544057312915498> **pingonjoin removed** for channel {channel.mention} and will no longer be sent", color = 0x43B581))
            else:
                return await ctx.reply(embed=discord.Embed(description=f"{self.urgentmoji} **No pingonjoin exists for that channel**", color=self.urgecolor))
        else:
            return await ctx.reply(embed=discord.Embed(description=f"{self.urgentmoji} **No pingonjoin's have been created yet**, use ``poj add`` to **create one**", color=self.urgecolor))

    @pingonjoin.command(
        aliases = ['show', 'list'],
        usage = "Manage_channels",
        description = "View the current existing pinginjoin's in your server",
        brief = "None",
        help = "```Example: poj view```"
    )
    @commands.has_permissions(manage_channels=True)
    async def view(self, ctx):
        check = await self.db.find_one({ "guild_id": ctx.guild.id})
        try:
            if check:
                check_existing = self.db.find({ "guild_id": ctx.guild.id})
                channellist = []
                rows = []
                for doc in await check_existing.to_list(length = 25):
                    channels = doc['channel']
                    channellist.append(channels)
                content = discord.Embed(title="Ping On Join's", description="", color=discord.Color.blurple())
                content.set_author(name=ctx.author.display_name, icon_url=ctx.author.display_avatar.url)
                for count, i in enumerate(channellist, start=1):
                    rows.append(f"``{count})`` <#{i}>")
                content.set_footer(text=f"({count}/{count}) Ping On Joins", icon_url=ctx.guild.icon.url)
                await util.send_as_pages(ctx, content, rows)
            else:
                return await ctx.reply(embed=discord.Embed(description=f"{self.urgentmoji} **No pingonjoin's have been created yet**, use ``poj add`` to **create one**", color=self.urgecolor))
        except Exception as e:
            print(e)

    @commands.Cog.listener()
    async def on_member_join(self, member):
        try:
            guild = member.guild
            check = await self.db.find_one({ "guild_id": guild.id})
            try:
                self.pings[member.guild.id]
            except KeyError:
                self.pings[member.guild.id] =1
            guild2 = self.pings[member.guild.id]
            self.pings[member.guild.id] = self.pings[member.guild.id]+1
            if check and not self.pings[member.guild.id] == 5:
                check_existing = self.db.find({ "guild_id": guild.id })
                for channels in await check_existing.to_list(length=25):
                    channel = guild.get_channel(channels["channel"])
                    await channel.send(member.mention, delete_after=0.8)
            else:
                return
        except:
            pass; return

async def setup(bot):
    await bot.add_cog(pojcog(bot))


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import absl
import absl.flags as flags
import tensorflow as tf
from tensorflow.python.keras.losses import LossFunctionWrapper

import reader
from lstm import RNNLMModel, RNNLMModelTrainer

# flags.DEFINE_integer("hidden_size", 200, "hidden dim of RNN")
#
# flags.DEFINE_string("data_path", None,
#                     "Where the training/test data is stored.")
# flags.DEFINE_string("vocab_path", None,
#                     "Where the wordlist file is stored.")
# flags.DEFINE_string("save_path", "export",
#                     "Model output directory.")
# flags.DEFINE_bool("use_fp16", False,
#                   "Train using 16-bit floats instead of 32bit floats")

FLAGS = flags.FLAGS

class Config(object):
  """Small config."""
  init_scale = 0.1
  learning_rate = 1
  max_grad_norm = 5
  num_layers = 2
  num_steps = 20
  hidden_size = 200
  max_epoch = 4
  max_max_epoch = 13
  keep_prob = 1.0
  lr_decay = 0.8
  batch_size = 64

def data_type():
  return tf.float16 if FLAGS.use_fp16 else tf.float32

# this new "softmax" function we show can train a "self-normalized" RNNLM where
# the sum of the output is automatically (close to) 1.0
# which saves a lot of computation for lattice-rescoring
def new_softmax(labels, logits):
  flatten_labels = tf.reshape(labels, [-1])
  n_samples = tf.shape(flatten_labels)[0]
  flatten_logits = tf.reshape(logits, shape=[n_samples, -1])
  f_logits = tf.exp(flatten_logits)
  row_sums = tf.reduce_sum(f_logits, -1) # this is the negative part of the objf

  t2 = tf.expand_dims(flatten_labels, 1)
  range = tf.expand_dims(tf.range(n_samples), 1)
  ind = tf.concat([range, t2], 1)
  res = tf.gather_nd(flatten_logits, ind)

  return -res + row_sums - 1

class MyFastLossFunction(LossFunctionWrapper):
  def __init__(self):
    super().__init__(new_softmax)

class FastRNNLMModel(RNNLMModel):
  def __init__(self, config):
    super().__init__(config, tf.constant_initializer(-9))

  def get_loss(self, word_ids, labels, is_training=False):
    logits = self.get_logits(word_ids, is_training)
    loss_obj = MyFastLossFunction()
    return loss_obj(labels, logits)

  def get_score(self, logits):
    # In this implementation, logits can be used as dist output
    return logits

def get_config():
  return Config()

def main(_):
  # Turn this on to try the model code with this source file itself!
  __TESTING = False

  if __TESTING:
    (train_data, valid_data), word_map = reader.rnnlm_gen_data(__file__, reader.__file__)
  else:
    if not FLAGS.data_path:
      raise ValueError("Must set --data_path to RNNLM data directory")

    raw_data = reader.rnnlm_raw_data(FLAGS.data_path, FLAGS.vocab_path)
    train_data, valid_data, _, word_map = raw_data

  config = get_config()
  config.hidden_size = FLAGS.hidden_size
  config.vocab_size = len(word_map)

  if __TESTING:
    # use a much smaller scale on our tiny test data
    config.num_steps = 8
    config.batch_size = 4

  model = FastRNNLMModel(config)
  train_producer = reader.RNNLMProducer(train_data, config.batch_size, config.num_steps)
  trainer = RNNLMModelTrainer(model, config)

  valid_producer = reader.RNNLMProducer(valid_data, config.batch_size, config.num_steps)

  # Save variables to disk if you want to prevent crash...
  # Data producer can also be saved to preverse feeding progress.
  checkpoint = tf.train.Checkpoint(trainer=trainer, data_feeder=train_producer)
  manager = tf.train.CheckpointManager(checkpoint, "checkpoints/", 5)

  for i in range(config.max_max_epoch):
    lr_decay = config.lr_decay ** max(i + 1 - config.max_epoch, 0.0)
    lr = config.learning_rate * lr_decay
    trainer.train_one_epoch(train_producer, lr)
    manager.save()

    eval_loss = trainer.evaluate(valid_producer)
    print("validating: loss={}".format(eval_loss))

  # Export
  print("Saving model to %s." % FLAGS.save_path)
  spec = [tf.TensorSpec(shape=[config.num_layers, 2, 1, config.hidden_size], dtype=data_type(), name="context"),
          tf.TensorSpec(shape=[1, 1], dtype=tf.int32, name="word_id")]
  cfunc = model.single_step.get_concrete_function(*spec)
  cfunc2 = model.get_initial_state.get_concrete_function()
  tf.saved_model.save(model, FLAGS.save_path, signatures={"single_step": cfunc, "get_initial_state": cfunc2})

if __name__ == "__main__":
  absl.app.run(main)


import numpy as np
import pandas as pd
# Importing the dataset
dataset = pd.read_csv('Employee_Data.csv')
X = dataset.iloc[:, 0:4].values
y = dataset.iloc[:, 4].values
print(X)
#Encoding categorical data
from sklearn.preprocessing import LabelEncoder
labelencoder = LabelEncoder()
X[:, 0] = labelencoder.fit_transform(X[:, 0])
print("##########After Label Encoding###########")
print(X)
from sklearn.model_selection import train_test_split
#from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test =train_test_split(X, y,
                    test_size = .25, random_state = 42)
from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(X_train, y_train)
y_pred=regressor.predict(X_test)

from sklearn import metrics
print("Error:",np.sqrt(metrics.mean_squared_error
                       (y_test,y_pred)))
print("C=",regressor.intercept_)
m=regressor.coef_
print("m=",m)

print("result2",
      regressor.predict([[1, 2700, 0, 2.3]]))

accuracy = (regressor.score(X_test,y_pred))
print("Accuracy=",accuracy)


import tkinter as tk
from tkinter import messagebox
from pyVmomi import vim
from GUI.scrollable_frame import scrollable_frame
# from core_functions.add_nic_to_vm import add_nic

def wait_for_task(task):
    """ wait for a vCenter task to finish """
    task_done = False
    while not task_done:
        if task.info.state == 'success':
            return task.info.result

        if task.info.state == 'error':
            print("there was an error")
            task_done = True

def get_obj(content, vimtype, name):
    """
    Return an object by name, if name is None the
    first found object is returned
    """
    obj = None
    container = content.viewManager.CreateContainerView(
        content.rootFolder, vimtype, True)
    for c in container.view:
        if name:
            if c.name == name:
                obj = c
                break
        else:
            obj = c
            break

    return obj

def _clone_vm(
        content, template, vm_name, si,
        datacenter_name, vm_folder, datastore_name,
        cluster_name, resource_pool, power_on, datastorecluster_name):
    """
    Clone a VM from a template/VM, datacenter_name, vm_folder, datastore_name
    cluster_name, resource_pool, and power_on are all optional.
    """

    # if none git the first one
    datacenter = get_obj(content, [vim.Datacenter], datacenter_name)

    if vm_folder:
        destfolder = get_obj(content, [vim.Folder], vm_folder)
    else:
        destfolder = datacenter.vmFolder

    if datastore_name:
        datastore = get_obj(content, [vim.Datastore], datastore_name)
    else:
        datastore = get_obj(
            content, [vim.Datastore], template.datastore[0].info.name)

    # if None, get the first one
    cluster = get_obj(content, [vim.ClusterComputeResource], cluster_name)

    if resource_pool:
        resource_pool = get_obj(content, [vim.ResourcePool], resource_pool)
    else:
        resource_pool = cluster.resourcePool

    vmconf = vim.vm.ConfigSpec()

    if datastorecluster_name:
        podsel = vim.storageDrs.PodSelectionSpec()
        pod = get_obj(content, [vim.StoragePod], datastorecluster_name)
        podsel.storagePod = pod

        storagespec = vim.storageDrs.StoragePlacementSpec()
        storagespec.podSelectionSpec = podsel
        storagespec.type = 'create'
        storagespec.folder = destfolder
        storagespec.resourcePool = resource_pool
        storagespec.configSpec = vmconf

        try:
            rec = content.storageResourceManager.RecommendDatastores(
                storageSpec=storagespec)
            rec_action = rec.recommendations[0].action[0]
            real_datastore_name = rec_action.destination.name
        except:
            real_datastore_name = template.datastore[0].info.name

        datastore = get_obj(content, [vim.Datastore], real_datastore_name)

    # set relospec
    relospec = vim.vm.RelocateSpec()
    relospec.datastore = datastore
    relospec.pool = resource_pool

    clonespec = vim.vm.CloneSpec()
    clonespec.location = relospec
    clonespec.powerOn = power_on

    print("cloning VM...")
    task = template.Clone(folder=destfolder, name=vm_name, spec=clonespec)
    wait_for_task(task)

def clone_vm(window):
    content = window.si.RetrieveContent()
    template = window.template_entry.get()

    template = get_obj(content, [vim.VirtualMachine], template)

    if template:
        _clone_vm(
            content, template, window.vm_name_entry.get(), window.si,
            window.datacenter_name_entry.get(), window.folder_entry.get(),
            # args.datastore_name,
            None,
            # args.cluster_name,
            None,
            # args.resource_pool,
            None,
            # args.power_on,
            None,
            # args.datastorecluster_name
            None
            )
        # if window.opaque_network_entry.get():
        #     vm = get_obj(content, [vim.VirtualMachine], args.vm_name)
        #     add_nic(window.si, vm, args.opaque_network)
    else:
        messagebox.showinfo("Error", "Please enter in a valid template")

def render_clone_vm(window):
    # clear the screen of anything in it before
    for child in window.central_frame.winfo_children():
        child.destroy()

    # render scrollable frame
    window.update_idletasks()
    scroll_frame = scrollable_frame(window.central_frame, window)
    scroll_frame.pack(expand=tk.YES, fill=tk.BOTH, side=tk.LEFT)
    # render template
    frame1 = tk.Frame(scroll_frame.scrollFrame.viewPort, width=565,
                      height=80, bg="#f442e8")
    frame1.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES)
    frame1_1 = tk.Frame(frame1, width=200,
                        height=80, bg="#ffffff")
    frame1_1.pack(side=tk.LEFT, expand=tk.NO, fill=tk.Y)
    frame1_2 = tk.Frame(frame1, width=200,
                        height=80, bg="#000000")
    frame1_2.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    frame1_label = tk.Label(frame1_1, text="Enter template name:",
                            font=("Helvetica", 14), anchor="e", width=20)
    # add a resize event that increases font size
    frame1_label.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    window.template_entry = tk.Entry(frame1_2, font=("Helvetica", 14))
    window.template_entry.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    # render new VM name
    frame2 = tk.Frame(scroll_frame.scrollFrame.viewPort, width=565,
                      height=80, bg="#f442e8")
    frame2.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES)
    frame2_1 = tk.Frame(frame2, width=200,
                        height=80, bg="#ffffff")
    frame2_1.pack(side=tk.LEFT, expand=tk.NO, fill=tk.Y)
    frame2_2 = tk.Frame(frame2, width=200,
                        height=80, bg="#000000")
    frame2_2.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    frame2_label = tk.Label(frame2_1, text="Enter new VM name:",
                            font=("Helvetica", 14), anchor="e", width=20)
    # add a resize event that increases font size
    frame2_label.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    window.vm_name_entry = tk.Entry(frame2_2, font=("Helvetica", 14))
    window.vm_name_entry.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    # optional name of datacenter
    frame3 = tk.Frame(scroll_frame.scrollFrame.viewPort, width=565,
                      height=80, bg="#f442e8")
    frame3.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES)
    frame3_1 = tk.Frame(frame3, width=200,
                        height=80, bg="#ffffff")
    frame3_1.pack(side=tk.LEFT, expand=tk.NO, fill=tk.Y)
    frame3_2 = tk.Frame(frame3, width=200,
                        height=80, bg="#000000")
    frame3_2.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    frame3_label = tk.Label(frame3_1, text="Enter datacenter name:",
                            font=("Helvetica", 14), anchor="e", width=20)
    # add a resize event that increases font size
    frame3_label.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    window.datacenter_name_entry = tk.Entry(frame3_2, font=("Helvetica", 14))
    window.datacenter_name_entry.pack(side=tk.LEFT,
                                      expand=tk.YES, fill=tk.BOTH)
    # optional vm folder
    frame4 = tk.Frame(scroll_frame.scrollFrame.viewPort, width=565,
                      height=80, bg="#f442e8")
    frame4.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES)
    frame4_1 = tk.Frame(frame4, width=200,
                        height=80, bg="#ffffff")
    frame4_1.pack(side=tk.LEFT, expand=tk.NO, fill=tk.Y)
    frame4_2 = tk.Frame(frame4, width=200,
                        height=80, bg="#000000")
    frame4_2.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    frame4_label = tk.Label(frame4_1, text="Enter VM folder:",
                            font=("Helvetica", 14), anchor="e", width=20)
    # add a resize event that increases font size
    frame4_label.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    window.folder_entry = tk.Entry(frame4_2, font=("Helvetica", 14))
    window.folder_entry.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    # optional datastore
    # optional cluster name
    # optional resourcePool
    # power on tick box and send it button
    frame5 = tk.Frame(scroll_frame.scrollFrame.viewPort, width=565,
                      height=80, bg="#f442e8")
    frame5.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES)
    frame5_1 = tk.Frame(frame5, width=200,
                        height=80, bg="#ffffff")
    frame5_1.pack(side=tk.LEFT, expand=tk.NO, fill=tk.Y)
    frame5_2 = tk.Frame(frame5, width=200,
                        height=80, bg="#000000")
    frame5_2.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    # TODO add power on tick box
    # frame5_label = tk.Label(frame5_1, text="Enter VM folder:",
    #                         font=("Helvetica", 14), anchor="e", width=20)
    # frame5_label.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)
    tk.Button(frame5_2, font=("Helvetica", 14),
              text="Clone VM",
              command=lambda: clone_vm(window)).pack(
              side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)


from imports import *

def check_playlists(name, spotify, deezer):
	if (spotify):
		spotify_playlist = spotify.user_playlists(spotify.current_user()["id"])
		for i in range(0, int(spotify_playlist["total"])):
			if (spotify_playlist["items"][i]["name"] == name):
				return (spotify_playlist["items"][i])
	if (deezer):
		deezer_playlist = deezer.get_playlists()
		for i in range(0, int(deezer_playlist["total"]) - 1):
			if (deezer_playlist["data"][i]["title"] == name):
				return (deezer_playlist["data"][i])
	return (0)

def create_playlists(name, spotify, deezer):
	try:
		s_id = spotify.user_playlist_create(spotify.current_user()["id"], name)["id"]
		d_id = deezer.create_playlist(name)["id"]
		if (not(os.path.exists("data.json")) or os.stat("data.json").st_size == 0):
			with open("data.json", "w") as file:
				data = {"Deezer": {f"{name}": f"{d_id}"},"Spotify": {f"{name}": f"{s_id}"},"total": 1,"update_liked": 0}
				json.dump(data, file, indent=4)
		else:
			with open("data.json", "r") as file:
				data = json.load(file)
				data["total"] += 1
				data["Deezer"][name] = f"{d_id}"
				data["Spotify"][name] = f"{s_id}"
			with open("data.json", "w") as file:
				json.dump(data, file, indent=4)
	except:
		spotify_playlist = spotify.user_playlists(spotify.current_user()["id"])
		for i in range(0, int(spotify_playlist["total"])):
			if (spotify_playlist["items"][i]["name"] == new_playlist):
				spotify.current_user_unfollow_playlist(spotify_playlist["items"][i]["id"])
		deezer_playlist = deezer.get_playlists()
		for i in range(0, int(deezer_playlist["total"]) - 1):
			if (deezer_playlist["data"][i]["title"] == new_playlist):
				deezer.delete_playlist(deezer_playlist["data"][i]["id"])
		print("Failed to create playlist.")

def connect(secrets):
	spotify = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope, client_id=secrets[3], client_secret=secrets[4], redirect_uri=secrets[5]))
	if (not(os.path.exists(".env"))):
		d_oauth.main(secrets[0], secrets[1])
	with open(".env", "r") as file:
		deezer_tokens = ast.literal_eval(file.readline())
		deezer_token = deezer_tokens.get("access_token")
		deezer = Deezer(deezer_token)
	return (spotify, deezer)

def main():
	action = menu.menu()
	secrets = get_secrets()
	spotify, deezer = connect(secrets)
	if (action == 1):
		new_playlist = input("Enter the name of the new playlist : ")
		print("Creating new playlist...")
		create_playlists(new_playlist, spotify, deezer)
	elif (action == 2):
		print("Updating playlists...")
		updater.update_playlists(spotify, deezer)
	elif (action == 3):
		with open("data.json", "r") as file1:
			data = json.load(file1)
			if (data["update_liked"] == 0):
				data["update_liked"] = 1
			with open("data.json", "w") as file2:
				json.dump(data, file2, indent=4)
		print("Updating liked songs..")
		updater.update_liked(spotify)

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


import pygame
import sqlite3
import random

from main_menu_class import menu_player
from npc_class import npc
from projectiles_class import projectile
from player_class import player
from enemy_class import enemy
from menu_button_class import menu_button
from non_animated_images import menubg, wall, bg, bg2, bg3, bubble, bubble_2, fireball2, \
    fireball3  # icon, title, button
from collectibles import collectibles

connection = sqlite3.connect("sqlite.db")

sqlcommand = """CREATE TABLE if not exists players (
playerId int AUTO_INCREMENT,
playerName varchar(255),
PRIMARY KEY(playerId)
);"""

cursor = connection.cursor()

cursor.execute(sqlcommand)

npcs = [pygame.image.load("Images/man_npc.png"), pygame.image.load("Images/lady_npc.png"),
        pygame.image.load("Images/old_man_npc.png")]
npcs_spoken_to = 0

pygame.init()  # Initiate pygame
W, H = (1280, 720)
win = pygame.display.set_mode((W, H))
clock = pygame.time.Clock()

running = True  # Start the menu
run = False
run_l1 = False
run_l2 = False
run_l3 = False
main_run = False
collect_fireball = False

font1 = pygame.font.SysFont("comicsans", 60, True)  # Font
font2 = pygame.font.SysFont("comicsans", 25, True)  # NPC Font
font3 = pygame.font.SysFont("comicsans", 20, True)  # Lady npc Font
font_option = pygame.font.SysFont("comicsans", 30, True)  # Option Font

play_text = font1.render("PLAY", 1, (0, 80, 0))
quit_text = font1.render("QUIT", 1, (0, 80, 0))
message1 = font2.render("Welcome adventurer!", 1, (0, 0, 0))
message1_2 = font2.render("I hope you are liking it here...", 1, (0, 0, 0))
message1_3 = font2.render("There's been sightings of goblins", 1, (0, 0, 0))
message1_4 = font2.render("lurking around the corner and", 1, (0, 0, 0))
message1_5 = font2.render("we need you to get rid of some of", 1, (0, 0, 0))
message1_6 = font2.render("those creatures, are you up for it?", 1, (0, 0, 0))
option1 = font_option.render("Y - Yes I'm up for it", 1, (255, 255, 255))
option1_2 = font_option.render("N - I need a minute to think ", 1, (255, 255, 255))

message2 = font3.render("I see you found my friend Balgruuf,", 1, (0, 0, 0))
message2_2 = font3.render("you can see that this is not a game.", 1, (0, 0, 0))
message2_3 = font3.render("The situation is getting worse with every breath", 1, (0, 0, 0))
message2_4 = font3.render("we take so I won't take anymore of your time", 1, (0, 0, 0))
message2_5 = font3.render("If you want to make a difference I need", 1, (0, 0, 0))
message2_6 = font3.render("you to take care of something, if you succeed,", 1, (0, 0, 0))
message2_7 = font3.render("praise won't be the only thing you'll get.", 1, (0, 0, 0))

message3 = font3.render("I see you are competent adventurer.", 1, (0, 0, 0))
message3_2 = font3.render("Our village is looking up at you now", 1, (0, 0, 0))
message3_3 = font3.render("The last wave of enemies was seen nearby and", 1, (0, 0, 0))
message3_4 = font3.render("you're the man to do it. If you pull this off", 1, (0, 0, 0))
message3_5 = font3.render("we will forever be in your service. However", 1, (0, 0, 0))
message3_6 = font3.render("I warn you, those things are... well, ", 1, (0, 0, 0))
message3_7 = font3.render("something we haven't seen before. ", 1, (0, 0, 0))

button_play = menu_button((W / 2) - 200, (H / 2) - 250, 100, 200)
button_quit = menu_button((W / 2) - 200, (H / 2) + 50, 100, 200)

menubgX = 0
menubgX2 = menubg.get_width()  # Moving background

shoot_loop = 0
speed = 50
score = 0
levels_completed = 0

player1 = menu_player(100, 445, 64, 64)  # Menu
player2 = player(650, 600, 100, 100)  # Game
player3 = player(200, 510, 100, 100)  # All mini games

old_man_npc = npc(1130, 370, 46, 84)  # Old man NPC
old_man_npc_2 = npc(1130, 370, 46, 84)  # After level is finished

lady_npc = npc(190, 190, 46, 84)  # Lady NPC
lady_npc_2 = npc(190, 190, 46, 84)  # After level is finished

man_npc = npc(730, 530, 46, 84)  # Man NPC
man_npc_2 = npc(730, 530, 46, 84)  # After level is finished

enemy1 = enemy(1350, 545, 64, 64, 0, 2, 1, False)  # Game
enemy2 = enemy(1350, 545, 64, 64, 0, 6, 1, False)  # Game
enemy3 = enemy(1550, 545, 64, 64, 0, 6, 1, False)  # Game
boss_enemy1 = enemy(1400, 545, 65, 65, 0, 2, 1, False)
# enemy4 = enemy()

fireball1 = collectibles(1000, 545, 62, 71, False)

def redraw_menu_window():
    global click_play, click_quit
    click_play = pygame.draw.rect(win, (255, 0, 0), (button_play.x + 95, button_play.y + 55, 250, 85))
    click_quit = pygame.draw.rect(win, (255, 0, 0), (button_quit.x + 95, button_quit.y + 55, 250, 85))
    win.blit(menubg, (menubgX, 137))
    win.blit(menubg, (menubgX2, 137))
    win.blit(wall, (0, 0))
    win.blit(wall, (0, 583))
    player1.draw(win)
    button_play.draw(win)  # W = about 250px, H = about 80px
    button_quit.draw(win)
    win.blit(play_text, (600, 187))
    win.blit(quit_text, (600, 487))

    pygame.display.update()

def redraw_game_window():
    win.blit(bg, (0, 0))
    player2.draw(win)
    man_npc.draw1(win)
    man_npc_2.draw1(win)
    lady_npc_2.draw2(win)
    old_man_npc.draw3(win)
    old_man_npc_2.draw3(win)
    lady_npc.draw2(win)

    if man_npc.talking:
        win.blit(bubble, (man_npc.x - 310, man_npc.y - 360))
        win.blit(message1, (man_npc.x - 280, man_npc.y - 300))
        win.blit(message1_2, (man_npc.x - 280, man_npc.y - 270))
        win.blit(message1_3, (man_npc.x - 280, man_npc.y - 240))
        win.blit(message1_4, (man_npc.x - 280, man_npc.y - 210))
        win.blit(message1_5, (man_npc.x - 280, man_npc.y - 180))
        win.blit(message1_6, (man_npc.x - 280, man_npc.y - 150))

        win.blit(option1, (20, 660))
        win.blit(option1_2, (20, 690))

    if lady_npc.talking:
        win.blit(bubble_2, (lady_npc.x - 20, lady_npc.y + 60))
        win.blit(message2, (lady_npc.x + 10, lady_npc.y + 190))
        win.blit(message2_2, (lady_npc.x + 10, lady_npc.y + 220))
        win.blit(message2_3, (lady_npc.x + 10, lady_npc.y + 250))
        win.blit(message2_4, (lady_npc.x + 10, lady_npc.y + 280))
        win.blit(message2_5, (lady_npc.x + 10, lady_npc.y + 310))
        win.blit(message2_6, (lady_npc.x + 10, lady_npc.y + 340))
        win.blit(message2_7, (lady_npc.x + 10, lady_npc.y + 370))
    if old_man_npc.talking:
        win.blit(bubble, (old_man_npc.x - 310, old_man_npc.y - 360))
        win.blit(message3, (old_man_npc.x - 280, old_man_npc.y - 300))
        win.blit(message3_2, (old_man_npc.x - 280, old_man_npc.y - 270))
        win.blit(message3_3, (old_man_npc.x - 280, old_man_npc.y - 240))
        win.blit(message3_4, (old_man_npc.x - 280, old_man_npc.y - 210))
        win.blit(message3_5, (old_man_npc.x - 280, old_man_npc.y - 180))
        win.blit(message3_6, (old_man_npc.x - 280, old_man_npc.y - 150))

    pygame.display.update()

def redraw_game_2_window():
    win.blit(bg2, (0, 0))
    player3.draw(win)
    enemy1.draw(win)
    text = font1.render('Score: ' + str(score), 1, (0, 0, 0))
    win.blit(text, (350, 10))
    for bullet in bullets:
        bullet.draw(win)

    if not enemy1.visible:
        enemy2.draw(win)
        enemy3.draw(win)

    if not enemy1.visible and not enemy2.visible and not enemy3.visible:
        man_npc.visible = True
        man_npc.x = 1000
        man_npc.draw1(win)

    pygame.display.update()

def redraw_game_3_window():
    global collect_fireball
    fireball1.draw()
    win.blit(bg3, (0, 0))
    text2 = font1.render('Score: ' + str(score), 1, (0, 0, 0))
    win.blit(text2, (350, 10))
    player3.draw(win)
    enemy1.draw(win)
    fireball1.draw()

    if not enemy1.visible:
        enemy2.draw(win)
        enemy3.draw(win)
        if not enemy2.visible and not enemy3.visible:
            boss_enemy1.draw(win)
            if not boss_enemy1.visible:
                fireball1.visible = True
                enemy1.draw(win)
                enemy1.y = 1000

    if not fireball1.visible and not enemy2.visible and not enemy3.visible and not boss_enemy1.visible:
        lady_npc.visible = True
        lady_npc.x = 600
        lady_npc.y = 470
        lady_npc.draw2(win)

    for bullet in bullets:
        bullet.draw(win)

    for fireball in fireballs:
        fireball.draw2(win)

    pygame.display.update()

def redraw_game_4_window():
    win.blit(bg3, (0, 0))
    player3.draw(win)

    pygame.display.update()

bullets = []
fireballs = []

enemies = [enemy1, enemy2, enemy3, boss_enemy1]
npcs_l = [man_npc, lady_npc, old_man_npc]

while running:

    mouse_x, mouse_y = pygame.mouse.get_pos()
    mouse_x2, mouse_y2 = pygame.mouse.get_pos()

    player1.right = True
    clock.tick(speed)
    menubgX -= 1
    menubgX2 -= 1

    if menubgX < menubg.get_width() * -1:  # Moving background
        menubgX = menubg.get_width()
    if menubgX2 < menubg.get_width() * -1:
        menubgX2 = menubg.get_width()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            running = False
            quit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse_pos = pygame.mouse.get_pos()
            if click_play.collidepoint(mouse_pos):  # If play is clicked, run the program
                print("hit")
                running = False
                main_run = True
            if click_quit.collidepoint(mouse_pos):  # If quit is clicked, quit the program
                print("hit")
                running = False
                quit()
    print((mouse_x, mouse_y))

    redraw_menu_window()

while main_run:

    run = True

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            main_run = False
            pygame.quit()
            quit()

    while run:

        clock.tick(27)  # FPS
        keys = pygame.key.get_pressed()  # Key is held

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                main_run = False
                pygame.quit()
                quit()
        for npc in npcs_l:
            if npc.visible:
                if player2.hitbox[1] < npc.hitbox[1] + npc.hitbox[3] and player2.hitbox[1] + \
                        player2.hitbox[3] > npc.hitbox[1]:
                    if player2.hitbox[0] + player2.hitbox[2] > npc.hitbox[0] and player2.hitbox[0] < \
                            npc.hitbox[0] + npc.hitbox[2]:

                        if npcs_spoken_to == 0:
                            if npc == npcs_l[0]:
                                npcs_l[0].talking = True
                                if keys[pygame.K_y]:
                                    # npcs_spoken_to += 1
                                    man_npc.talking = False
                                    npc.visible = False
                                    run = False
                                    run_l1 = True

                                if keys[pygame.K_n]:
                                    player2.x = player2.x - 40
                                    man_npc.talking = False

                        if npcs_spoken_to == 0:
                            if npc == npcs_l[1]:
                                print("Test")
                                npcs_l[1].talking = True
                                if keys[pygame.K_y]:
                                    # npcs_spoken_to += 1
                                    lady_npc.visible = False
                                    lady_npc.talking = False
                                    enemy1.empowered = True

                                    run = False
                                    run_l2 = True

                                    player3.x = 600

                                if keys[pygame.K_n]:
                                    player2.x = player2.x - 40
                                    lady_npc.talking = False

                        if npcs_spoken_to == 0:
                            if npc == npcs_l[2]:
                                npcs_l[2].talking = True
                                if keys[pygame.K_y]:
                                    old_man_npc.talking = False
                                    npcs_l[2].visible = False

                                    run = False
                                    run_l3 = True

                                if keys[pygame.K_n]:
                                    player2.x = player2.x - 40
                                    old_man_npc.talking = False

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

        if old_man_npc.talking:
            print("old man talking")
        if man_npc.talking:
            print("man talking")
        if lady_npc.talking:
            print("lady talking")

        if not lady_npc.talking:
            if not old_man_npc.talking:
                if not man_npc.talking:

                    if keys[pygame.K_LEFT] and player2.x > player2.vel:
                        player2.x -= player2.vel
                        player2.left = True
                        player2.right = False
                        player2.standing = False
                        player2.down = False
                        player2.up = False

                    elif keys[pygame.K_RIGHT] and player2.x < W - (player2.width - 30):
                        player2.x += player2.vel
                        player2.left = False
                        player2.right = True
                        player2.standing = False
                        player2.down = False
                        player2.up = False

                    else:
                        player2.standing = True
                        player2.walk_count = 0

                    if keys[pygame.K_DOWN] and player2.y < H - player2.height - player2.vel:
                        player2.y += player2.vel
                        player2.is_jump = False
                        player2.down = True
                        player2.up = False
                        player2.standing = False
                        player2.right = False
                        player2.left = False

                    if keys[pygame.K_UP] and player2.y > player2.vel:
                        player2.y -= player2.vel
                        player2.right = False
                        player2.left = False
                        player2.is_jump = False
                        player2.down = False
                        player2.up = True
                        player2.standing = False

        redraw_game_window()

    while run_l1:
        clock.tick(27)
        keys = pygame.key.get_pressed()

        if enemies[2].visible:
            print("visible")
        for enemy in enemies:
            if enemy.visible:
                if player3.hitbox[1] < enemy.hitbox[1] + enemy.hitbox[3] and player3.hitbox[1] + player3.hitbox[3] > \
                        enemy.hitbox[1]:
                    if player3.hitbox[0] + player3.hitbox[2] > enemy.hitbox[0] and player3.hitbox[0] \
                            < enemy.hitbox[0] + enemy.hitbox[2]:
                        player3.hit()

                        score -= 5

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run_l1 = False
                run = True
                # player2.x = 650
                player2.x = man_npc_2.x - 80
                player2.y = man_npc_2.y

        for bullet in bullets:
            for enemy in enemies:

                if enemy.visible:
                    if bullet.y - bullet.radius < enemy.hitbox[1] + enemy.hitbox[3] and bullet.y + bullet.radius > \
                            enemy.hitbox[1]:
                        if bullet.x + bullet.radius > enemy.hitbox[0] and bullet.x - bullet.radius < enemy.hitbox[0] + \
                                enemy.hitbox[2]:
                            enemy.hit()
                            score += 1
                            bullets.pop(bullets.index(bullet))

            if 1280 > bullet.x > 0:
                bullet.x += bullet.vel
            else:
                bullets.pop(bullets.index(bullet))

        if shoot_loop > 0:
            shoot_loop += 1
        if shoot_loop > 3:
            shoot_loop = 0
        if keys[pygame.K_SPACE] and shoot_loop == 0:
            if player3.left:
                facing = -1
            else:
                facing = 1
            if len(bullets) < 40:  # Adds a bullet to the screen when SPACE is pressed.
                bullets.append(
                    projectile(round((player3.x + player3.width // 2) - 20), round(player3.y + player3.height // 2), 6,
                               (0, 0, 0),
                               facing))

                # Bullet appears a the centre of the player
            shoot_loop = 1
        if enemy1.empowered:
            print("empowered")
        if man_npc.visible:
            if player3.hitbox[1] < man_npc.hitbox[1] + man_npc.hitbox[3] and player3.hitbox[1] + \
                    player3.hitbox[3] > man_npc.hitbox[1]:
                if player3.hitbox[0] + player3.hitbox[2] > man_npc.hitbox[0] and player3.hitbox[0] < \
                        man_npc.hitbox[0] + man_npc.hitbox[2]:
                    player2.x = man_npc_2.x - 100
                    man_npc.visible = False
                    print("visible")
                    # enemy1.vel = 2

                    enemy1.health = 10
                    enemy2.health = 10
                    enemy3.health = 10

                    enemy1.x = 0
                    enemy1.end = 1280

                    enemy2.x = 0
                    enemy2.end = 1280

                    enemy3.x = 1280
                    enemy3.end = 0

                    bullets.clear()
                    enemy1.visible = True
                    enemy2.visible = True
                    enemy3.visible = True

                    run = True
                    run_l1 = False

        if keys[pygame.K_LEFT] and player3.x > player3.vel:
            player3.x -= player3.vel
            player3.left = True
            player3.right = False
            player3.standing = False
            player3.down = False
            player3.up = False

        elif keys[pygame.K_RIGHT] and player3.x < W - (player3.width - 30):
            player3.x += player2.vel
            player3.left = False
            player3.right = True
            player3.standing = False
            player3.down = False
            player3.up = False
        else:
            player3.standing = True

        if not player3.is_jump:
            if keys[pygame.K_UP]:
                player3.is_jump = True
                player3.right = False
                player3.left = False
                player3.down = False
                player3.up = False

        else:
            if player3.jump_count >= -10:  # Jumping quadratic equation
                neg = 1
                if player3.jump_count < 0:
                    neg = -1
                player3.y -= player3.jump_count ** 2 * 0.5 * neg
                player3.jump_count -= 1
            else:
                player3.is_jump = False
                player3.jump_count = 10

        redraw_game_2_window()

    while run_l2:
        clock.tick(27)
        keys = pygame.key.get_pressed()
        for enemy in enemies:

            if enemy1.visible:
                if player3.hitbox[1] < enemy1.hitbox[1] + enemy1.hitbox[3] and player3.hitbox[1] + player3.hitbox[3] > \
                        enemy1.hitbox[1]:
                    if player3.hitbox[0] + player3.hitbox[2] > enemy1.hitbox[0] and player3.hitbox[0] < enemy1.hitbox[
                        0] + \
                            enemy1.hitbox[2]:
                        player3.hit()
                        score -= 5

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run_l2 = False
                run = True
                player2.x = lady_npc_2.x + 80
                player2.y = lady_npc_2.y + 85
        for bullet in bullets:
            for enemy in enemies:
                if enemy.visible:
                    if bullet.y - bullet.radius < enemy.hitbox[1] + enemy.hitbox[3] and bullet.y + bullet.radius > \
                            enemy.hitbox[1]:
                        if bullet.x + bullet.radius > enemy.hitbox[0] and bullet.x - bullet.radius < enemy.hitbox[0] + \
                                enemy.hitbox[2]:
                            if enemy.width <= 64:
                                enemy.hit()
                                score += 1
                                bullets.pop(bullets.index(bullet))
                            else:
                                boss_enemy1.hit_boss()
                                score += 1
                                bullets.pop(bullets.index((bullet)))

            if 1280 > bullet.x > 0:
                bullet.x += bullet.vel
            else:
                bullets.pop(bullets.index(bullet))

        for fireball in fireballs:
            for enemy in enemies:

                if enemy.visible:
                    if fireball.y - fireball.radius < enemy.hitbox[1] + enemy.hitbox[
                        3] and fireball.y + fireball.radius > \
                            enemy.hitbox[1]:
                        if fireball.x + fireball.radius > enemy.hitbox[0] and fireball.x - fireball.radius < \
                                enemy.hitbox[0] + \
                                enemy.hitbox[2]:
                            if enemy.width <= 64:
                                enemy.hit()
                                score += 1
                                fireballs.pop(fireballs.index(fireball))
                            else:
                                boss_enemy1.hit_boss()
                                score += 1
                                fireballs.pop(fireballs.index((fireball)))
                print(fireball.x, fireball.y)

            if 1280 > fireball.x > 0:
                fireball.x += fireball.vel
            else:
                fireballs.pop(fireballs.index(fireball))

        if shoot_loop > 0:
            shoot_loop += 1
        if shoot_loop > 3:
            shoot_loop = 0
        if keys[pygame.K_SPACE] and shoot_loop == 0:
            if player3.left:
                facing = -1
            else:
                facing = 1
            if len(bullets) < 40:  # Adds a bullet to the screen when SPACE is pressed.
                bullets.append(
                    projectile(round((player3.x + player3.width // 2) - 20), round(player3.y + player3.height // 2), 6,
                               (0, 0, 0),
                               facing))
        if keys[pygame.K_f] and shoot_loop == 0:
            if player3.left:
                facing = -1
            else:
                facing = 1
            if len(fireballs) < 10:
                fireballs.append(
                    projectile(round((player3.x + player3.width // 2) - 20),
                               round(player3.y + player3.height // 2) - 18, 6,
                               (0, 0, 0),
                               facing))

                print("shot")

                # Bullet appears at the centre of the player
            shoot_loop = 1
        if lady_npc.visible:
            if player3.hitbox[1] < lady_npc.hitbox[1] + lady_npc.hitbox[3] and player3.hitbox[1] + \
                    player3.hitbox[3] > lady_npc.hitbox[1]:
                if player3.hitbox[0] + player3.hitbox[2] > lady_npc.hitbox[0] and player3.hitbox[0] < \
                        lady_npc.hitbox[0] + lady_npc.hitbox[2]:
                    bullets.clear()

                    enemy1.health = 10
                    enemy2.health = 10
                    enemy3.health = 10

                    enemy1.x = 0
                    enemy1.end = 1280

                    enemy2.x = 0
                    enemy2.end = 1280

                    enemy3.x = 1280
                    enemy3.end = 0

                    bullets.clear()

                    enemy1.empowered = True
                    enemy2.empowered = True
                    enemy3.empowered = True
                    enemy1.visible = True
                    enemy2.visible = True
                    enemy3.visible = True
                    lady_npc.visible = False
                    levels_completed += 1
                    run = True
                    run_l2 = False

        if fireball1.visible:
            if player3.hitbox[1] < fireball1.hitbox[1] + fireball1.hitbox[3] and player3.hitbox[1] + player3.hitbox[3] > \
                    fireball1.hitbox[1]:
                if player3.hitbox[0] + player3.hitbox[2] > fireball1.hitbox[0] and player3.hitbox[0] < fireball1.hitbox[
                    0] + \
                        enemy1.hitbox[2]:
                    collect_fireball = False
                    enemy1.health = 10
                    enemy1.visible = True
                    enemy1.y = 1000
                    print("touch")
                    fireball1.visible = False

        if keys[pygame.K_LEFT] and player3.x > player3.vel:
            player3.x -= player3.vel
            player3.left = True
            player3.right = False
            player3.standing = False
            player3.down = False
            player3.up = False

        elif keys[pygame.K_RIGHT] and player3.x < W - (player3.width - 30):
            player3.x += player2.vel
            player3.left = False
            player3.right = True
            player3.standing = False
            player3.down = False
            player3.up = False
        else:
            player3.standing = True

        if not player3.is_jump:
            if keys[pygame.K_UP]:
                player3.is_jump = True
                player3.right = False
                player3.left = False
                player3.down = False
                player3.up = False

        else:
            if player3.jump_count >= -10:  # Jumping quadratic equation
                neg = 1
                if player3.jump_count < 0:
                    neg = -1
                player3.y -= player3.jump_count ** 2 * 0.5 * neg
                player3.jump_count -= 1
            else:
                player3.is_jump = False
                player3.jump_count = 10

        redraw_game_3_window()

    while run_l3:
        clock.tick(27)
        keys = pygame.key.get_pressed()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run_l3 = False
                run = True
                player2.x = 650

        for bullet in bullets:
            if bullet.y - bullet.radius < enemy1.hitbox[1] + enemy1.hitbox[3] and bullet.y + bullet.radius > \
                    enemy1.hitbox[1]:
                if bullet.x + bullet.radius > enemy1.hitbox[0] and bullet.x - bullet.radius < enemy1.hitbox[0] + \
                        enemy1.hitbox[2]:
                    enemy1.hit()
                    num2 = 0
                    num2 += 1
                    print(num2)

                    score += 1
                    bullets.pop(bullets.index(bullet))

            if 1280 > bullet.x > 0:
                bullet.x += bullet.vel
            else:
                bullets.pop(bullets.index(bullet))

        if shoot_loop > 0:
            shoot_loop += 1
        if shoot_loop > 10:
            shoot_loop = 0
        if keys[pygame.K_SPACE] and shoot_loop == 0:
            if player3.left:
                facing = -1
            else:
                facing = 1
            if len(bullets) < 10:  # Adds a bullet to the screen when SPACE is pressed.
                bullets.append(
                    projectile(round((player3.x + player3.width // 2) - 20), round(player3.y + player3.height // 2), 6,
                               (0, 0, 0),
                               facing))

                # Bullet appears at the centre of the player
            shoot_loop = 1
        if keys[pygame.K_LEFT] and player3.x > player3.vel:
            player3.x -= player3.vel
            player3.left = True
            player3.right = False
            player3.standing = False
            player3.down = False
            player3.up = False

        elif keys[pygame.K_RIGHT] and player3.x < W - (player3.width - 30):
            player3.x += player2.vel
            player3.left = False
            player3.right = True
            player3.standing = False
            player3.down = False
            player3.up = False
        else:
            player3.standing = True

        if not player3.is_jump:
            if keys[pygame.K_UP]:
                player3.is_jump = True
                player3.right = False
                player3.left = False
                player3.down = False
                player3.up = False

        else:
            if player3.jump_count >= -10:  # Jumping quadratic equation
                neg = 1
                if player3.jump_count < 0:
                    neg = -1
                player3.y -= player3.jump_count ** 2 * 0.5 * neg
                player3.jump_count -= 1
            else:
                player3.is_jump = False
                player3.jump_count = 10

        # if event.type == pygame.KEYDOWN:
        # if event.key == pygame.K_SPACE:
        # run2 = False
        # run = True
        redraw_game_4_window()


#-*- coding: UTF-8 -*-
import unittest
import xlrd
import requests
import json
import Readini
from BeautifulReport import BeautifulReport
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# 解决verify= False报错
# 在Run中选择运行，防止pycharm使用单元测试框架运行脚本，导致数据错误

print_log= 'Y'
# 是否打印请求参数

class PatientInfoSave(Readini.Config):
    '''
    1.保存患者信息
    2.form_data_post返回请求结果
    '''
    def __init__(self):
        super(PatientInfoSave,self).__init__()

    @staticmethod
    def checks():
        if print_log== 'Y':
            return True
        elif print_log== 'N':
            return False
        else:
            return False

    def form_data_post(self,params):
        super().cfg_general()
        self.headers= {
            "Content-Type":"application/json",
            "Authorization":"",
            "clientType":"X",
            "firmId":"dev",
            "hosId":"",
            "subjectType":"",
            "version":""
        }
        self.result= requests.post(url= self.BaseUrl + "/changmugu-basic/patient/patientInfoSave",
                                    data= json.dumps(params),
                                    headers= self.headers,
                                    verify= False)
        if self.checks():
            print("请求参数:")
            print(params)
            print("请求地址:")
            print(self.BaseUrl + "/changmugu-basic/patient/patientInfoSave")
            print()
        return self.result

class BeginPISTest(Readini.ParametrizedTestCase,Readini.Config):
    '''使用unittest进行PatientInfoSave接口测试'''
    def setUp(self):
        super().cfg_general()
        self.t= PatientInfoSave()
        self.r= self.t.form_data_post(
            Readini.create_parameter_dict(
                docId= self.param[1],
                docPhone= self.param[2],
                idNo= self.param[3],
                openId= self.param[4],
                patientName= self.param[5],
                telNo= self.param[6],
            ))
        self.formR= json.loads(self.r.text)
        print("返回参数:")
        print(self.formR)
        print()

        if self.param[0]== '0':
            with open("Temporary/001.txt", "a+") as f:
                f.write(str(self.formR) + "\n")
        else:
            pass
        # 将返回参数写入文件，便于之后接口调用

    def testX(self):
        self.doc= self.param[-1]  # 重写了源文件get_testcase_property，来读取我用例文档的title列
        if self.param[0]== '0':
            self.assertEqual(self.formR["code"],20000)
        elif self.param[0]== '1':
            self.assertNotEqual(self.formR["code"],20000)
        else:
            raise Exception

def runners():
    '''
    读取测试用例文件，加载成list用于循环
    :return:
    '''
    suite= unittest.TestSuite()
    list_open= []
    file= "Cases_File/Case001_PatientInfoSave.xls"
    sheet1= xlrd.open_workbook(filename= file).sheet_by_index(0)
    for i in range(1,sheet1.nrows):
        rows= sheet1.row_values(i)
        list_open.append(rows)
    for i in list_open:
        suite.addTest(Readini.ParametrizedTestCase.parametrize(BeginPISTest, param= i))
    result= BeautifulReport(suite)
    result.report(filename= "接口测试报告_Case001_PatientInfoSave",
                  description= "PatientInfoSave接口测试报告",
                  report_dir= "report",
                  theme=  "theme_memories")

if __name__== '__main__':
    Readini.delete_temp("001.txt")
    runners()


import numpy as np
import math
from ROOT import *
from array import array

# ### makes canvases of POT error evolution for xsec dials (similar to fluxErrors.py but for xsec) ####

def getRelError(i, idials, year, fit_path, xsectype=""):

    '''Returns the relative error of dials[i] for a specified year'''
    #print(fit_path)
    file = TFile(fit_path)
    #print(file)
    if (xsectype == "CCQE_EB"):
        xsec = file.Get('FitterEngine/postFit/Hesse/errors/Cross-Section (binned) Systematics/valuesNorm/postFitErrors_TH1D')
    elif (xsectype == "FSI"):
        xsec = file.Get('FitterEngine/postFit/Hesse/errors/Cross-Section FSI Systematics/valuesNorm/postFitErrors_TH1D')
    else:
        xsec = file.Get('FitterEngine/postFit/Hesse/errors/Cross-Section Systematics/valuesNorm/postFitErrors_TH1D')

    err = xsec.GetBinError(idials[i])
    return err

def rel_error_evolution(i, idials, years, fit_paths, xsectype=""):
    '''returns an array of relative xsec errors for a dial i, with length = number of years'''
    err_evol = array('d')
    j = 0
    for y in years:
        err_evol.append(getRelError(i, idials, y, fit_paths[j], xsectype))
        j += 1
    return err_evol

def plot_xsec_errs(subsets, dials, idials, years, mini, maxi, fit_paths_ndup, fit_paths_fgd12, fit_paths_ndup_pmucthmu):
    '''plots the relative & absolute xsec errors of all dials, and saves the plots in two canvases'''
    if (len(idials) <= 4): gStyle.SetPalette(kBlueGreenYellow)
    else: gStyle.SetPalette(kRainBow)
    #gStyle.SetNdivisions(6)
    gStyle.SetLegendBorderSize(0)
    gStyle.SetLegendTextSize(0.05)

    c1 = TCanvas("c1", "c1", 600, 1000)
    c1.cd()
    xsectype = ""
    if ("FSI" in subsets): xsectype = "FSI"
    elif ("CCQE_EB" in subsets): xsectype = "CCQE_EB"
    else: xsectype = ""

    gPad.SetMargin(0.15, 0.1, 0.08, 0.5)
    relativeUncertainties1 = TMultiGraph()
    relativeUncertainties2 = TMultiGraph()
    relativeUncertainties3 = TMultiGraph()
    ayears = array('d', years)
    for i in range(len(dials)):
        gr_temp = TGraph(len(years), ayears, rel_error_evolution(i, idials, years, fit_paths_ndup, xsectype))
        gr_temp.SetTitle(dials[i])
        gr_temp.SetMarkerStyle(kFullCircle)
        gr_temp.SetLineWidth(2)
        relativeUncertainties1.Add(gr_temp)

        gr_temp2 = TGraph(len(years), ayears, rel_error_evolution(i, idials, years, fit_paths_fgd12, xsectype))
        #gr_temp2.SetTitle(dials[i])
        gr_temp2.SetMarkerStyle(kFullCircle)
        gr_temp2.SetLineWidth(2)
        gr_temp2.SetLineStyle(7)
        relativeUncertainties2.Add(gr_temp2)

        gr_temp3 = TGraph(len(years), ayears, rel_error_evolution(i, idials, years, fit_paths_ndup_pmucthmu, xsectype))
        #gr_temp2.SetTitle(dials[i])
        #gr_temp3.SetMarkerStyle(kFullCircle)
        gr_temp3.SetLineWidth(2)
        gr_temp3.SetLineStyle(3)
        relativeUncertainties3.Add(gr_temp3)

        #relativeUncertainties1.SetTitle("Rel. Xsec Syst. for "+subsets+ ";years;#sigma_{postfit}/#sigma_{prefit}")
    relativeUncertainties1.GetXaxis().SetTitle("x10^{21} POT")
    relativeUncertainties1.GetXaxis().SetTitleOffset(0.6)
    relativeUncertainties1.GetXaxis().SetTitleSize(0.045)
    relativeUncertainties1.GetXaxis().SetLabelSize(0.045)
    relativeUncertainties1.GetXaxis().SetLabelOffset(-0.01)
    relativeUncertainties1.GetYaxis().SetTitle("#sigma_{postfit}/#sigma_{prefit}")
    relativeUncertainties1.GetYaxis().SetTitleSize(0.045)
    relativeUncertainties1.GetYaxis().SetLabelSize(0.04505)
#     relativeUncertainties1.SetMinimum(mini)
#     relativeUncertainties1.SetMaximum(maxi)
    relativeUncertainties1.Draw("LAP PLC PMC")
    gPad.BuildLegend(0.05, 0.52, 0.95, 0.52+(0.99-0.52)*((len(idials))/7.0))

    leg = TLegend(0.1, 0.4, 0.9, 0.6)
    line = TH1D("h", "", 1, 0, 1)
    line.SetLineColor(kBlack)
    line.SetLineWidth(2)
    line2 = TH1D("hh", "", 1, 0, 1)
    line2.SetLineColor(kBlack)
    line2.SetLineWidth(2)
    line2.SetLineStyle(7)
    line3 = TH1D("hhh", "", 1, 0, 1)
    line3.SetLineColor(kBlack)
    line3.SetLineWidth(2)
    line3.SetLineStyle(3)
    leg.AddEntry(line2, "FGD1+2", "l")
    leg.AddEntry(line3, "SFGD+FGD1+2 #mu only", "l")
    leg.AddEntry(line, "SFGD+FGD1+2 #mu+N", "l")

    relativeUncertainties2.Draw("LP PLC PMC")
    relativeUncertainties3.Draw("LP PLC PMC")

    c1.Update()
    c1.SaveAs("5050_corr/{}.pdf".format(subsets))

idialsset = [
        [7, 8, 9, 10, 11], # Nucleon FSI, MAQE, Q2 norm 5, Q2 norm 6, Q2 norm 7,
        [12, 13, 14, 15, 16], # SF Carbon
        [17, 18, 19, 20, 21, 22, 23], # SF Oxygen
        [24, 25, 26, 27, 28, 29], # PB + OP
        [30, 31, 32], # 2p2h norm
        [37, 38, 39, 40, 41], # 2p2h shape
        [42, 43, 45], # CA5, MARES, BGSCL
        [46, 47, 48, 49], # RES Eb
        [50, 51, 52], # RS Delta, SPP pi0 norm
        [53, 54, 62, 65], # CC Coh C+O, CC Misc, NC other near
        [55, 56, 57, 58], # MPi TotXSec, MPi BY Vec, MPi BY Ax, MPi BY shape
        [59, 60, 61], # DIS
        [1, 2, 3, 4], # EB
        [1, 2, 3, 4, 5, 6] # FSI
]

dialsset = [
        ["Nucleon FSI", "M^{A}_{QE}", "CCQE Q^{2} Mod. 5", "CCQE Q^{2} Mod. 6", "CCQE Q^{2} Mod. 7"],
        ["P Shell MF Norm C", "S Shell MF Norm C", "SRC Norm C", "P Shell MF p_{miss} Shape C", "S Shell MF p_{miss} Shape C"], # SF Carbon
        ["P_{1/2} Shell MF Norm O", "P_{3/2} Shell MF Norm O", "S Shell MF Norm O", "SRC Norm O", "P_{1/2} Shell MF p_{miss} Shape O", "P_{3/2} Shell MF p_{miss} Shape O", "S Shell MF p_{miss} Shape O"], # SF Oxygen
        ["Pauli Blocking C #nu", "Pauli Blocking O #nu", "Pauli Blocking C #bar{#nu}", "Pauli Blocking O #bar{#nu}", "Optical Potential C", "Optical Potential O"], # PB + OP
        ["2p2h Norm #nu", "2p2h Norm #bar{#nu}", "2p2h Norm C to O"], # 2p2h norm
        ["PNNN Shape", "2p2h Shape C np", "2p2h Shape C NN", "2p2h Shape O np", "2p2h Shape O NN"], # 2p2h shape
        ["C^{A}_{5}", "M^{A}_{RES}", "I_{1/2} non RES Bkg."], # CA5, MARES, BGSCL
        ["Res. Eb C #nu_{#mu}", "Res. Eb O #nu_{#mu}", "Res. Eb C #bar{#nu}_{#mu}", "Res. Eb O #bar{#nu}_{#mu}"], # RES Eb
        ["RS Delta Decay", "SPP #pi^{0} Norm #nu_{#mu}", "SPP #pi^{0} Norm #bar{#nu}_{#mu}"], # RS Delta, SPP pi0 norm
        ["CC Coh C", "CC Coh O", "CC Misc.", "NC Other Near"], # CC Coh C+O, CC Misc, NC other near
        ["multi-#pi multiplicity total xsec", "multi-#pi Bodek-Yang Vector", "multi-#pi Bodek-Yang Axial", "multi-#pi multiplicity shape"], # MPi TotXSec, MPi BY Vec, MPi BY Ax, MPi BY shape
        ["CC Bodek-Yang DIS", "CC DIS multi-#pi Norm #nu", "CC DIS multi-#pi Norm #bar{#nu}"], # DIS
        ["E_{b} C #nu", "E_{b} C #bar{#nu}", "E_{b} O #nu", "E_{b} O #bar{#nu}"],
        ["FSI QE Scatter Low E", "FSI QE Scatter High E", "FSI Hadron Prod.", "FSI #pi Absorption", "FSI Charge Ex. Low E", "FSI Charge Ex. High E"]
]

subsets = [
        "CCQE", # Nucleon FSI, MAQE, Q2 norm 5, Q2 norm 6, Q2 norm 7,
        "SF_Carbon", # SF Carbon
        "SF_Oxygen", # SF Oxygen
        "PB_OP", # PB + OP
        "2p2h_norm", # 2p2h norm
        "2p2h_shape", # 2p2h shape
        "CCRES", # CA5, MARES, BGSCL
        "CCRES_EB", # RES Eb
        "SPP", # RS Delta, SPP pi0 norm
        "Other", # CC Coh C+O, CC Misc, NC other near
        "MPi", # MPi TotXSec, MPi BY Vec, MPi BY Ax, MPi BY shape
        "DIS", # DIS
        "CCQE_EB", # EB
        "Pi_FSI" # FSI
]
mini = [0.07, 0.00, 0.12, 0.02, 0.00, 0.00, 0.15, 0.12, 0.00, 0.12, 0.02, 0.00, 0.00, 0.15, 0.12]

maxi = [0.96, 0.97, 1.025, 0.43, 0.70, 0.82, 0.66, 0.56, 0.00, 0.12, 0.02, 0.00, 0.00, 0.15, 0.12]
# subsets = ["PBOP"]
# dialsset = [dials4]
# idialsset = [idials4]
#years = [2022, 2023, 2024, 2025, 2026, 2027]
years = [3.82, 4.90, 6.08, 7.40, 9.06, 10.8]

fit_paths_ndup = [
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_noSFGD_2022.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_withSFGD_evisdpt_2023.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_withSFGD_evisdpt_2024.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_withSFGD_evisdpt_2025.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_withSFGD_evisdpt_2026.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_withSFGD_evisdpt_2027.root"
]

fit_paths_fgd12 = [
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_noSFGD_2022.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_noSFGD_2023.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_noSFGD_2024.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_noSFGD_2025.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_noSFGD_2026.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_noSFGD_2027.root"
]

fit_paths_ndup_pmucthmu = [
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_noSFGD_2022.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_withSFGD_evisdpt_2023.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_withSFGD_evisdpt_2024.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_withSFGD_evisdpt_2025.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_withSFGD_evisdpt_2026.root",
    "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit21Nov_5050_COcorr95_withSFGD_evisdpt_2027.root"
]
# fit_paths_ndup = [
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_noSFGD_2022.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_withSFGD_evisdpt_2023.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_withSFGD_evisdpt_2024.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_withSFGD_evisdpt_2025.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_withSFGD_evisdpt_2026.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_withSFGD_evisdpt_2027.root"
# ]

# fit_paths_fgd12 = [
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_noSFGD_2022.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_noSFGD_2023.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_noSFGD_2024.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_noSFGD_2025.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_noSFGD_2026.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_noSFGD_2027.root"
# ]

# fit_paths_ndup_pmucthmu = [
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_noSFGD_2022.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_withSFGD_pmucthmu_2023.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_withSFGD_pmucthmu_2024.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_withSFGD_pmucthmu_2025.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_withSFGD_pmucthmu_2026.root",
#     "/sps/t2k/jchakran/gundam/inputconfig/OA2022/GundamInputOA2021withSFGD/outputs/fit10Nov_5050_withSFGD_pmucthmu_2027.root"
# ]

# the python macro assumes that 2022-2027 fits are in 'fit_path' and named: 0703_banffsfgd****_datacorrect_2M.root
# if this is no longer the case, change 'fit_path' or the names in getRelError() and getAbsError()

# ### if you want to call only one of the xsec subsets, either change lists above or function call below ####
# ### canvas.Save() names are automatically adjusted for the different subsets ####

gROOT.SetBatch(kFALSE)

print(len(subsets))
print(len(dialsset))
print(len(idialsset))
print(len(years))

for i in range(len(subsets)):
    print(i)
    plot_xsec_errs(subsets[i], dialsset[i], idialsset[i], years, mini[i], maxi[i], fit_paths_ndup, fit_paths_fgd12, fit_paths_ndup_pmucthmu)

print("Done")


#!/user/bin/env python
import hashlib, logging, urllib, datetime, sys, base64, os, string
from google.appengine.ext import db
from google.appengine.api import images
from google.appengine.api import memcache
import wsgiref.handlers
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.api import users
from google.appengine.ext.webapp.util import run_wsgi_app
from django.utils import simplejson
import models
from common import *
import cgi
import generalcounter

# auto retry for random timeout
from gae_retry import autoretry_datastore_timeouts
autoretry_datastore_timeouts()

# Add our custom Django template filters to the built in filters
template.register_template_library('templatetags.basetags')

class MainHandler(webapp.RequestHandler):
    def get(self):
        user = users.get_current_user()
        if user:
          appUser = models.get_or_create_appUser()
          self.response.out.write(respond_to_request(self.request, user, 'app_base.html'))
        else:
         self.response.out.write(respond_to_request(self.request, user, 'app_base.html'))

class CreateHandler(webapp.RequestHandler):
    def get(self):
        recaptcha_challenge = cgi.escape(self.request.get('recaptcha_challenge_field'))
        recaptcha_response = cgi.escape(self.request.get('recaptcha_response_field'))
        tags = cgi.escape(self.request.get('tags').lower()).split(',')
        tags = [tag.strip() for tag in tags]
        name = cgi.escape(self.request.get('name'))
        if recaptcha_challenge != '' and recaptcha_response != '' and name != '':
            recaptchaResponse = RecaptchaSubmit(recaptcha_challenge, recaptcha_response,
                                                 '6LeqlggAAAAAAFcYAzZ1fn6zwNKHlZRuoKLnBrPu', os.environ['REMOTE_ADDR'])

            if recaptchaResponse.is_valid or DEBUG:
                appUser = models.get_or_create_appUser()
                self.create(appUser, name, tags)
            else:
                self.failed()
        else:
            self.failed()

    def create(self, appUser, name, tags=None):
        generalcounter.increment(PAGE_CREATED_COUNTER)
        p = models.create_page(appUser, name, getNewPageTemplate(name), tags)
        #json = createPageJson(p)
        json = {}
        json['edit'] = 'http://' + os.environ['HTTP_HOST'] + '/a/edit/' + str( p.key() )
        self.response.out.write(simplejson.dumps(json))

    def failed(self):
        json = {}
        json['error'] = True
        json['message'] = 'Failed to create new page.'
        self.response.out.write(simplejson.dumps(json))

class EditHandler(webapp.RequestHandler):
    def get(self, page_key):
        p = models.Page.get(page_key)
        if p:
            #appUser = models.get_or_create_appUser()
            json = createPageJson(p, False)
            params = {}
            params['page'] = json
            self.response.out.write(respond_to_request(self.request, users.get_current_user(), 'app_edit.html', params))
        else:
            self.error(403)

class SaveHandler(webapp.RequestHandler):
    def post(self):
        page_key = cgi.escape(self.request.get('pk'))
        save_key = cgi.escape(self.request.get('spk'))
        sjson = self.request.get('__saveHidden')
        saved = False
        if sjson != '' and page_key and save_key:
            #json = simplejson.loads(sjson)
            if canSavePage(page_key, save_key):
                page = models.Page.get(page_key)
                if page:
                    if page.content.content != sjson:
                        page.content.content = sjson
                        memcache.delete(PAGE_MEMCACHE_HTML + str(page.key().id()))
                        #update updated property
                        db.put([page.content, page])
                    saved = True
                    self.response.out.write('save')
        if not saved:
            self.error(403)

class LoggerHandler(webapp.RequestHandler):
    def get(self):
        page_key = cgi.escape(self.request.get('pk'))
        save_key = cgi.escape(self.request.get('spk'))
        message = cgi.escape(self.request.get('message'))
        if message and canSavePage(page_key, save_key):
            logging.debug(message)
        self.response.out.write('save')

class JsonPageHandler(webapp.RequestHandler):
    def get(self, page_key):
        page_key = page_key.split('.')[0]
        p = models.Page.get(page_key)
        #appUser = models.get_or_create_appUser()
        if p:
            json = createPageJson(p)
            self.response.out.write('JSON_PAGE=' + simplejson.dumps(json))

class DebugHandler(webapp.RequestHandler):
    def get(self):
        if users.is_current_user_admin() or DEBUG:
            appUser = models.get_or_create_appUser()
            params = {}
            params['pages_set'] = models.get_all_pages_for_user(appUser)
            params['pages_none_user'] = models.get_pages_for_nonuser()
            params['PATH_INFO'] = os.environ['PATH_INFO']
            params['HTTP_HOST'] = os.environ['HTTP_HOST']
            params['pages_new_ordered'], next = models.get_pages_newest()
            self.response.out.write(respond_to_request(self.request, users.get_current_user(), 'debug_base.html', params))
        else:
            self.error(403)

class DeleteHandler(webapp.RequestHandler):
    def get(self):
        page_key = cgi.escape(self.request.get('pk'))
        save_key = cgi.escape(self.request.get('spk'))
        redirect = self.request.get('redirect')
        if page_key and save_key and canSavePage(page_key, save_key):
            appUser = models.get_or_create_appUser()
            models.del_page(page_key, appUser)
            if redirect:
                self.redirect(redirect)
            else:
                json = {}
                json['success'] = True
                self.response.out.write(simplejson.dumps(json))
        else:
            self.error(403)

class GetUserPagesHandler(webapp.RequestHandler):
    def get(self):
        pageIndex = int(self.request.get('p', '0'))
        appUser = models.get_or_create_appUser()
        if appUser:
          pages, next = models.get_pages_for_user(appUser, pageIndex, 20)
          if next:
           nexturi = 'http://' + os.environ['HTTP_HOST'] + '/a/get/?p=%d' % (pageIndex + 1)
          else:
           nexturi = None
          if pageIndex > 1:
           prevuri = 'http://' + os.environ['HTTP_HOST'] + '/a/get/?p=%d' % (pageIndex - 1)
          elif pageIndex == 1:
           prevuri = 'http://' + os.environ['HTTP_HOST'] + '/a/get/'
          else:
           prevuri = None

          params = {}
          jsonPages=[]
          for page in pages:
              json = {}
              json['edit'] = 'http://' + os.environ['HTTP_HOST'] + '/a/edit/' + str(page.key())
              json['name'] = page.name
              json['id'] = str(page.key().id())
              json['updated'] = page.updated
              jsonPages.append(json)
          if nexturi:
              params['nextIndex'] = str((pageIndex + 1))
          if prevuri:
              params['prevIndex'] = str((pageIndex - 1))
          params['pages'] = jsonPages
          self.response.out.write(respond_to_request(self.request, users.get_current_user(), 'open_page.html', params))
        else:
         self.error(403)

class ImageSharingUploadImage(webapp.RequestHandler):
  """Handler for uploading images."""
  def post(self):
    """Process the image upload form.
    """
    page_key = cgi.escape(self.request.get('pk'))
    save_key = cgi.escape(self.request.get('spk'))
    if canSavePage(page_key, save_key) == False:
      self.error(400)
      self.response.out.write('Access Denied')
    else:
        page = db.get(page_key)
        # Get the actual data for the picture
        img_data = self.request.POST.get('the_file').file.read()
        json = {}
        params = {}
        try:
          img = images.Image(img_data)
          # Basically, we just want to make sure it's a PNG
          # since we don't have a good way to determine image type
          # through the API, but the API throws an exception
          # if you don't do any transforms, so go ahead and use im_feeling_lucky.
          #img.im_feeling_lucky()
          #png_data = img.execute_transforms(images.PNG)

          #img.resize(60, 100)
          #thumbnail_data = img.execute_transforms(images.PNG)
          params['json'] = json
          if page.image_upload_count > 10:
            json['error'] = 'Sorry, we only allow 10 uploads per page. try using \'Add Image URL\' tab.'
          else:
            pic = models.create_image(models.get_or_create_appUser(), page, img_data)
            page.image_upload_count = page.image_upload_count + 1
            page.put()
            json['url'] = 'http://' + os.environ['HTTP_HOST'] + '/a/i/' + str( pic.key().id() )
        except images.BadImageError:
          json['error'] = 'Sorry, we had a problem processing the image provided. Try again later.'
        except images.NotImageError:
          json['error'] = 'Sorry, we don\'t recognize that image format. We can process JPEG, GIF, PNG, BMP, TIFF, and ICO files.'
        except images.LargeImageError:
         json['error'] = 'Sorry, the image provided was too large for us to process. 1 MEG is the size limit, try using \'Add Image URL\' tab or resizing your image and upload again.'
        except RequestTooLargeError:
          json['error'] = 'Sorry, the image provided was too large for us to process. 1 MEG is the size limit, try using \'Add Image URL\' tab or resizing your image and upload again.'
        finally:
          self.response.out.write(respond_to_request(self.request, None, 'common/iframeJsonResponse.html', params))

class ServeImage(webapp.RequestHandler):
    def get(self, image_id):
        if image_id:
            image_id = long(image_id)
            imageModel = models.Picture.get_by_id(image_id)
            if imageModel:
                self.response.out.write(imageModel.image.img_data)
            else:
                self.error(403)
        else:
            self.error(403)
class TestDataHandler(webapp.RequestHandler):
    def get(self):
        if users.is_current_user_admin() or DEBUG:
            appUser = models.get_or_create_appUser()
            for i in range(50):
                models.create_page(appUser, 'Test Data:' + str(i), '{}', 'Car,Porsche,vorun,jaydn,kreal'.split(','))
            self.response.out.write('done')
        else:
            self.error(403)

class RenameHandler(webapp.RequestHandler):
    def get(self):
        page_key = cgi.escape(self.request.get('pk'))
        save_key = cgi.escape(self.request.get('spk'))
        name = cgi.escape(self.request.get('name'))
        if name != '' and page_key and save_key and canSavePage(page_key, save_key):
            page = models.Page.get(page_key)
            if page:
                page.name = name
                page.put()
            json = {}
            json['success'] = True
            self.response.out.write(simplejson.dumps(json))
        else:
            self.error(403)

class ShortenUrlHandler(webapp.RequestHandler):
    def get(self):
        url = cgi.escape(self.request.get('url'))
        s = shortenUrl(url)
        json = {}
        json['shorten'] = s
        self.response.out.write(simplejson.dumps(json))

class PreviewImageHandler(webapp.RequestHandler):
    def get(self):
        url = cgi.escape(self.request.get('url'))
        self.response.out.write(respond_to_request(self.request, None, 'common/previewImage.html', {'imageurl':url}))

application = webapp.WSGIApplication([
    #these paths are relative to app.yaml
    ('/a/', MainHandler),
    ('/a/i/([-\w]+)', ServeImage),
    ('/a/edit/([-\w]+)', EditHandler),
    ('/a/delete/.*', DeleteHandler),
    ('/a/create/.*', CreateHandler),
    ('/a/save/.*', SaveHandler),
    ('/a/get/.*', GetUserPagesHandler),
    ('/a/jsonpage/(.*)', JsonPageHandler),
    ('/a/upload/.*', ImageSharingUploadImage),
    ('/a/debug/.*', DebugHandler),
    ('/a/rename/.*', RenameHandler),
    ('/a/logger/.*', LoggerHandler),
    ('/a/shortenurl/.*', ShortenUrlHandler),
    ('/a/previewimage/.*', PreviewImageHandler),
    ], debug=DEBUG)

def main():
    wsgiref.handlers.CGIHandler().run(application)

if __name__=='__main__':
     main()