from dateutil.parser import parse as datetime_parser
import asyncio
import csv
import datetime
import io
import numpy as np
import re
import requests
import shlex

from ..Client import Client
from ..CommandProcessor import DiscordArgumentParser, ValidUserAction
from ..CommandProcessor.exceptions import NoValidCommands, HelpNeeded
from ..Log import Log
from ..SQL import SQL
from .Grapher import Grapher

class Dragons:

    def __init__(self):
        self.client = Client()
        self.log = Log()
        self.ready = False
        self.sql = SQL()

    async def on_message(self, message):
        if not self.ready:
            self.log.warning(f"Saw message before we were ready: {message.content}")
            return

        self.log.debug(f"Saw message: {message.content}")

        match_obj = re.match("^>dragon(s)?", message.content, re.IGNORECASE)
        if match_obj:
            # await self.log_command(message)
            self.log.info("Saw a command, handle it!")
            await self.command_proc(message)

    async def on_ready(self):
        self.log.info("Dragons, ready to recieve commands!")
        self.ready = True

    async def command_proc(self, message):
        """Handle specific commands, or pass to the session_manager
        """
        parser = DiscordArgumentParser(
            description="Manage information about a dragon",
            prog=">dragon")
        parser.set_defaults(message=message)
        sp = parser.add_subparsers()

        sub_parser = sp.add_parser('csv',
                                   description='Upload csv data on your dragon')
        sub_parser.add_argument(
            "--template",
            action='store_true',
            help="Log to previous date",
            )
        sub_parser.set_defaults(cmd=self._cmd_csv)

        sub_parser = sp.add_parser('edit',
                                   description='Edit details about your dragon')
        sub_parser.add_argument(
            "id",
            help="ID of the dragon, or name",
            metavar="DRAGON-ID"
            )
        sub_parser.set_defaults(cmd=self._cmd_edit)

        sub_parser = sp.add_parser('graph',
                                   description='Graph stats from a dragon')
        sub_parser.add_argument(
            "id",
            help="ID of the dragon",
            metavar="DRAGON-ID"
            )
        group = sub_parser.add_argument_group(title="Values to Graph")
        group.add_argument("--mass", "--weight", action='store_true')
        group.add_argument("--length", action='store_true')
        group.add_argument("--bowel-movement", action='store_true')
        group.add_argument("--brumation", action='store_true')
        group.add_argument("--shedding", action='store_true')
        group.add_argument("--fecal-check", action='store_true')
        group.add_argument("--new-uv-tube", action='store_true')
        group.add_argument("--vet-visit", action='store_true')
        group.add_argument("--crickets", action='store_true')
        group.add_argument("--bsfl", action='store_true')
        group.add_argument("--dubia", action='store_true')
        group.add_argument("--horn-worms", action='store_true')
        group.add_argument("--meal-worms", action='store_true')
        group.add_argument("--pinkie-mouse", action='store_true')
        group.add_argument("--silk-worms", action='store_true')
        group.add_argument("--super-worms", action='store_true')
        sub_parser.set_defaults(cmd=self._cmd_graph)

        sub_parser = sp.add_parser('list',
                                   description='Log stats for your dragon')
        sub_parser.add_argument("--global",
            action='store_true',
            help='List all dragons, not just USERS (Not working)')
        sub_parser.add_argument(
            "user_id",
            action=ValidUserAction,
            default=f"<@{message.author.id}>",
            help="Mention of the user in question",
            metavar="@user",
            nargs="?",
            )
        sub_parser.set_defaults(cmd=self._cmd_list)

        sub_parser = sp.add_parser('log',
                                   description='Log stats for your dragon(s)')
        sub_parser.add_argument(
            "id",
            help="ID of the dragon",
            metavar="DRAGON-ID"
            )
        sub_parser.add_argument(
            "--date",
            default=datetime.datetime.now(),
            help="Log to previous date",
            type=lambda d: datetime.datetime.strptime(d, '%Y-%m-%d'),
            )

        group = sub_parser.add_argument_group(title="Basic Stats")
        group.add_argument(
            "--length",
            help="Length of dragon (units assumed to be centimeters unless given)",
            metavar="LENGTH",
            nargs="+",
            )
        group.add_argument(
            "--mass", "--weight",
            help="Mass of dragon (units assumed to be grams unless given)",
            metavar="MASS",
            nargs="+",
            )

        group = sub_parser.add_argument_group(title="Behaviors")
        group.add_argument(
            "--bowel-movement",
            action='store_true',
            default=None,
            help="Dragon had a bowel movement.",
            )
        group.add_argument(
            "--brumation",
            action='store_true',
            default=None,
            help="Dragon is brumating",
            )
        group.add_argument(
            "--shedding",
            action='store_true',
            default=None,
            help="Dragon is shedding",
            )

        group = sub_parser.add_argument_group(title="Care")
        group.add_argument(
            "--fecal-check",
            action='store_true',
            default=None,
            help="Checked fecal mater for parasites",
            )
        group.add_argument(
            "--new-uv-tube",
            action='store_true',
            default=None,
            help="Replaced the UV tube",
            )
        group.add_argument(
            "--vet-visit",
            action='store_true',
            default=None,
            help="Had a vet visit",
            )

        group = sub_parser.add_argument_group(title="Feeding")
        group.add_argument(
            "--crickets",
            const=1,
            default=None,
            help="Ate Crickets",
            nargs="?",
            type=int,
            )
        group.add_argument(
            "--bsfl",
            const=1,
            default=None,
            help="Ate Black Soldier Fly Larva",
            nargs="?",
            type=int,
            )
        group.add_argument(
            "--dubia",
            const=1,
            default=None,
            help="Ate Dubia Roaches",
            nargs="?",
            type=int,
            )
        group.add_argument(
            "--horn-worms",
            const=1,
            default=None,
            help="Ate Horn Worms",
            nargs="?",
            type=int,
            )
        group.add_argument(
            "--meal-worms",
            const=1,
            default=None,
            help="Ate Meal Worms",
            nargs="?",
            type=int,
            )
        group.add_argument(
            "--pinkie-mouse",
            const=1,
            default=None,
            help="Ate Pinkie Mince",
            nargs="?",
            type=int,
            )
        group.add_argument(
            "--silk-worms",
            const=1,
            default=None,
            help="Ate Silk Worm",
            nargs="?",
            type=int,
            )
        group.add_argument(
            "--super-worms",
            const=1,
            default=None,
            help="Ate Super Worm",
            nargs="?",
            type=int,
            )

        sub_parser.add_argument(
            "--note",
            help="Text note to affix",
            metavar="NOTE",
            nargs="+",
            )

        sub_parser.set_defaults(cmd=self._cmd_log)

        sub_parser = sp.add_parser('register',
                                   description='Register a new dragon dragon')
        sub_parser.set_defaults(cmd=self._cmd_register)

        try:
            self.log.info("Parse Arguments")
            results = parser.parse_args(shlex.split(message.content)[1:])
            self.log.info(results)
            if type(results) == str:
                self.log.info("Got normal return, printing and returning")
                self.log.info(type(results))
                await self.client.send_message(message.channel, results)
                return
            elif hasattr(results, 'cmd'):
                await results.cmd(results)
                return
            else:
                msg = parser.format_help()
                await self.client.send_message(message.channel, msg)
                return
        except NoValidCommands as e:
            # We didn't get a subcommand, let someone else deal with this mess!
            self.log.error("???")
            pass
        except HelpNeeded as e:
            self.log.info("TypeError Return")
            self.log.info(e)
            msg = f"{e}. You can add `-h` or `--help` to any command to get help!"
            await self.client.send_message(message.channel, msg)
            return
            pass

        return

    async def _cmd_csv(self, args):
        message = args.message
        cur = self.sql.cur

        self.log.info("Start _cmd_csv command")
        self.log.info(args)

        if args.message.attachments:
            for attachment in args.message.attachments:
                response = requests.get(attachment['url'])

                data = list(csv.DictReader(io.StringIO(response.text)))
                ids = set()
                try:
                    for row in data:
                        ids.add(str(int(row['ID'])))
                        row['Date'] = datetime_parser(row['Date']).timestamp()
                        row['Weight (g)'] = float(row['Weight (g)']) if row['Weight (g)'] != '' else None
                        row['Length (cm)'] = float(row['Length (cm)']) if row['Length (cm)'] != '' else None
                        row['Notes'] = row['Notes'] if row['Notes'] != '' else None
                except Exception as e:
                    msg = f"Couldn't handle csv because: {e}"
                    await self.client.send_message(message.channel, msg)
                    continue

                # Get dragons for this user
                cur = self.sql.cur
                user_id = args.message.author.id
                dragon_ids = ",".join(ids)
                cmd = f"""
                    SELECT *
                    FROM dragons
                    WHERE
                        user_id=:user_id
                        AND dragon_id IN ({dragon_ids})
                """
                dragons = cur.execute(cmd,locals()).fetchall()
                if dragons == None or len(dragons) != len(ids):
                    msg = f"Woops! I can't save that CSV file. I couldn't match up you, your dragon IDs and my database. Are you sure the ID column is correct, and you own all these dragons?"
                    await self.client.send_message(message.channel, msg)
                    continue

                dragon_names = ", ".join([x['name'] for x in dragons])

                question = f"About to store {len(data)} rows for {dragon_names}. Are you sure?"
                try:
                    choice = await self.client.confirm_prompt(args.message.channel, question, user=args.message.author, timeout=60)
                except TimeoutError:
                    continue

                if choice is not True:
                    continue

                for row in data:
                    dragon_id = row['ID']
                    log_date = row['Date']
                    mass = row['Weight (g)']
                    length = row['Length (cm)']
                    note = row['Notes']

                    cmd = """
                        INSERT
                        INTO dragon_stat_logs
                        (
                            dragon_id,
                            log_date,
                            mass,
                            length,
                            note
                        ) VALUES (
                            :dragon_id,
                            :log_date,
                            :mass,
                            :length,
                            :note
                        )
                    """
                    cur.execute(cmd, locals())
                await self.sql.commit(now=True)

        elif args.template:
            fields = ["ID", "Date", "Weight (g)", "Length (cm)", "Notes"]
            csv_file = io.StringIO()

            writer = csv.DictWriter(csv_file, fieldnames=fields)
            writer.writeheader()

            csv_file.seek(0)

            await self.client.send_file(message.channel, csv_file, filename=f"data_template.csv")

            csv_file.close()

        else:
            msg = "You can upload a file with the comment `>dragon csv <ID>`, or call `>dragon csv --template` to get a template file!"
            await self.client.send_message(message.channel, msg)

        self.log.info("Finished _cmd_csv command")
        return

    async def _cmd_edit(self, args):
        message = args.message
        cur = self.sql.cur
        self.log.info("Start _cmd_edit command")
        self.log.info(args)

        await self.client.start_private_message(message.author)
        for channel in self.client.private_channels:
            if channel.user == message.author:
                break
            else:
                raise RuntimeError("Couldn't find our pirvate channel, woops!")

        msg = "Sorry, this command is a WIP. Come back later!"
        await self.client.send_message(channel, msg)

        self.log.info("Finished _cmd_edit command")
        return

    async def _cmd_graph(self, args):
        message = args.message
        cur = self.sql.cur

        self.log.info("Start _cmd_graph command")
        self.log.info(args)

        g = Grapher(args)
        await g.run()

        self.log.info("Finished _cmd_graph command")
        return

    async def _cmd_list(self, args):
        message = args.message
        user_id = args.user_id
        self.log.info("Start _cmd_list command")
        self.log.info(args)
        cur = self.sql.cur
        cmd = """
            SELECT *
            FROM dragons
            WHERE
                user_id=:user_id
        """
        dragons = cur.execute(cmd,locals())

        msg = "Dragons:"
        msg += "\n```"
        msg += f"\n  ID Name"
        for dragon in dragons:
            msg += f"\n{dragon['dragon_id']:4d} {dragon['name']}"
        msg += "\n```"

        await self.client.send_message(message.channel, msg)

        self.log.info("Finished _cmd_list command")
        return

    async def _cmd_log(self, args):
        message = args.message
        cur = self.sql.cur

        self.log.info("Start _cmd_log command")
        self.log.info(args)

        mass = None
        length = None
        note = None
        dragon_id = args.id
        user_id = args.message.author.id
        bowel_movement = args.bowel_movement
        brumation = args.brumation
        shedding = args.shedding
        fecal_check = args.fecal_check
        new_uv_tube = args.new_uv_tube
        vet_visit = args.vet_visit
        crickets = args.crickets
        bsfl = args.bsfl
        dubia = args.dubia
        horn_worms = args.horn_worms
        meal_worms = args.meal_worms
        pinkie_mouse = args.pinkie_mouse
        silk_worms = args.silk_worms
        super_worms = args.super_worms

        if args.mass:
            mass = " ".join(args.mass)
            mass_match_obj = re.match(
                r"(?P<num>[+-]?((\d+\.?\d*)|(\.\d+))) ?(?P<unit>g|grams?|kg|lbs?)?",
                mass)

            mass = float(mass_match_obj.group('num'))
            unit = mass_match_obj.group('unit')
            if unit in ['lb', 'lbs']:
                mass = mass * 453.592
            elif unit in ['kg']:
                mass = mass * 1000

            self.log.info(f"Mass is: {mass}g")

        if args.length:
            length = " ".join(args.length)
            length_match_obj = re.match(
                r"(?P<num>[+-]?((\d+\.?\d*)|(\.\d+))) ?(?P<unit>cm|m|in|ft|\"|\'|smoots?)?",
                length)

            length = float(length_match_obj.group('num'))
            unit = length_match_obj.group('unit')
            if unit in ['in', '\"']:
                length = length * 2.54
            elif unit in ['ft', '\'']:
                length = length * 30.48
            elif unit in ['m']:
                length = length * 100
            elif unit in ['smoot', 'smoots']:
                length = length * 170.18

            self.log.info(f"Length is: {length}cm")

        if args.note:
            note = " ".join(args.note)
            self.log.info(f"Note is: {note}")

        log_date = args.date
        self.log.info(f"Date is: {log_date}")

        # Lookup name of dragon given
        cmd = """
            SELECT *
            FROM dragons
            WHERE dragon_id=:dragon_id
                AND user_id=:user_id
        """
        dragon_dict = cur.execute(cmd, locals()).fetchone()

        if dragon_dict is None:
            await self.client.send_message(
                message.channel,
                f"I couldn't find a draong with id {dragon_id}, owned by you!")
            return

        msg = "Would you like to log this?"
        msg += "\n```"
        msg += f"\n  Name: {dragon_dict['name']}"
        msg += f"\n  Date: {log_date}"

        if mass is not None:
            msg += f"\n          Mass: {mass}"
        if length is not None:
            msg += f"\n        Length: {length}"

        if bowel_movement is not None:
            msg += f"\nBowel Movement: {bowel_movement}"
        if brumation is not None:
            msg += f"\n     Brumation: {brumation}"
        if shedding is not None:
            msg += f"\n      Shedding: {shedding}"

        if fecal_check is not None:
            msg += f"\n   Fecal Check: {fecal_check}"
        if new_uv_tube is not None:
            msg += f"\n   New UV Tube: {new_uv_tube}"
        if vet_visit is not None:
            msg += f"\n     Vet Visit: {vet_visit}"

        if crickets is not None:
            msg += f"\n      Crickets: {crickets}"
        if bsfl is not None:
            msg += f"\n          BSFL: {bsfl}"
        if dubia is not None:
            msg += f"\n  Dubia Roachs: {dubia}"
        if horn_worms is not None:
            msg += f"\n    Horn Worms: {horn_worms}"
        if meal_worms is not None:
            msg += f"\n    Meal Worms: {meal_worms}"
        if pinkie_mouse is not None:
            msg += f"\n  Pinkie Mouse: {pinkie_mouse}"
        if silk_worms is not None:
            msg += f"\n    Silk Worms: {silk_worms}"
        if super_worms is not None:
            msg += f"\n   Super Worms: {super_worms}"

        if note is not None:
            msg += f"\n          Note: {note}"
        msg += "\n```"
        answer = await self.client.confirm_prompt(
            message.channel,
            msg,
            user=message.author)

        if answer is not True:
            self.log.info("Finished _cmd_log command")
            return

        log_date = log_date.timestamp()
        # Save to SQL
        cmd = """
            INSERT
            INTO dragon_stat_logs
            (
                dragon_id,
                log_date,
                length,
                mass,
                bowel_movement,
                brumation,
                fecal_check,
                shedding,
                new_uv_tube,
                vet_visit,
                crickets,
                bsfl,
                dubia,
                horn_worms,
                meal_worms,
                pinkie_mouse,
                silk_worms,
                super_worms,
                note
            ) VALUES (
                :dragon_id,
                :log_date,
                :length,
                :mass,
                :bowel_movement,
                :brumation,
                :fecal_check,
                :shedding,
                :new_uv_tube,
                :vet_visit,
                :crickets,
                :bsfl,
                :dubia,
                :horn_worms,
                :meal_worms,
                :pinkie_mouse,
                :silk_worms,
                :super_worms,
                :note
            )
        """
        cur.execute(cmd, locals())
        await self.sql.commit(now=True)

        self.log.info("Finished _cmd_log command")
        return

    async def _cmd_register(self, args):
        message = args.message
        user = message.author
        cur = self.sql.cur

        self.log.info("Start _cmd_register command")
        self.log.info(args)

        await self.client.start_private_message(user)
        for channel in self.client.private_channels:
            if channel.user == user:
                break
            else:
                raise RuntimeError("Couldn't find our pirvate channel, woops!")

        msg = "Do you wish to register a new dragon?"
        choice = await self.client.confirm_prompt(channel, msg)
        if choice is not True:
            return

        await asyncio.sleep(1)
        msg = "Okay!"
        await self.client.send_message(channel, msg)
        await asyncio.sleep(1)

        while True:
            msg = "What is your dragons name? (Your next message should be their full name, with no extra characters)"
            name = await self.client.text_prompt(channel, msg, user=message.author, timeout=120)
            await asyncio.sleep(1)

            msg = f"Your dragons name is '{name}', is that correct?"
            choice = await self.client.confirm_prompt(channel, msg)

            if choice is True:
                break
            elif choice is False:
                continue
            elif choice is None:
                return

        while True:
            msg = "When was your dragon hatched? If you don't know exactly, guess as close as you can!"\
                  " (Format is YYYY-MM-DD, so you can answer `2018-03-25`)\n. You can say STOP to exit."
            hatch_date = await self.client.text_prompt(channel, msg, user=message.author, timeout=300)

            if hatch_date is None:
                self.log.info("STOP encountered?")
                return

            self.log.info(f"Got user response of: {hatch_date}")
            hatch_match = re.search(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})", hatch_date)
            if hatch_match is None:
                continue

            hatch_date = datetime.datetime(
                int(hatch_match.group('year')),
                int(hatch_match.group('month')),
                int(hatch_match.group('day')),
                )

            await asyncio.sleep(1)

            now = datetime.datetime.utcnow().replace(microsecond=0, second=0, minute=0, hour=0)
            age = (now-hatch_date).total_seconds()/60/60/24

            if age < 30:
                age = f"{age:.0f} days"
            elif age < 365/12*18:
                age = f"{age/30:.1f} months"
            else:
                age = f"{age/365:.1f} years"

            msg = f"Your dragons hatch date was '{hatch_date}' (about {age} ago!), is that correct?"
            choice = await self.client.confirm_prompt(channel, msg)

            if choice is True:
                break
            elif choice is False:
                continue
            elif choice is None:
                return

        created_at = datetime.datetime.utcnow().timestamp()
        hatched_on = hatch_date.timestamp()
        last_updated = datetime.datetime.utcnow().timestamp()
        user_id = user.id
        cmd = """
            INSERT INTO dragons
            (
                name,
                created_at,
                hatched_on,
                last_updated,
                user_id
            ) VALUES (
                :name,
                :created_at,
                :hatched_on,
                :last_updated,
                :user_id
            )
        """
        cur.execute(cmd,locals())
        await self.sql.commit()

        msg = f"{name} was registered to the DB! You can try `>dragon list` to see them!"
        await self.client.send_message(channel, msg)

        self.log.info("Finished _cmd_register command")
        return


from __future__ import print_function

import argparse
import sys
from nlp.reviews.utils import *
from mlflow import mlflow

spark = get_spark()
logger = get_logger()

try:
    mlflow_tracking_uri = sys.argv[1]  # "databricks://adb-field-eng"
    data_file_location = sys.argv[2]  # "/databricks-datasets/amazon/data20K"
    scoring_data_file_location = sys.argv[3]  # "/databricks-datasets/amazon/test4K"
except:
    # parser.print_help()
    logger.warn("the following arguments are required: mlflow_tracking_uri, data_file_location, scoring_data_file_location")
    logger.warn("received no args at runtime, using defaults")
    logger.warn("\n")
    mlflow_tracking_uri = "databricks://adb-field-eng"
    data_file_location = "/databricks-datasets/amazon/data20K"
    scoring_data_file_location = "/databricks-datasets/amazon/test4K"

'''
- Tests connectivity to hosted mlflow server using a databricks cli profile configured on your local system
    - check_mlflow_connectivity("databricks://adb-field-eng")
- Checks if datasets used are available
    - check_datasets_availability("/databricks-datasets/amazon/data20K","/databricks-datasets/amazon/test4K")
- Checks if mlflow lib (PyPi) is installed on the cluster
    - check_if_libs_installed()
'''

def check_if_libs_installed():
    print("\n *********** checking if mlflow is installed ***************")
    if(len(mlflow.version.VERSION) > 0):
        print("\nMLflow Version installed on databricks cluster:", mlflow.version.VERSION)
    else:
        logger.error("mlflow lib not found on databricks cluster, please install mlflow lib")
        assert False

def check_datasets_availability(data_file_location,scoring_data_file_location):
    print("\n *********** checking if datasets exists ***************")
    raw_data = spark.read.parquet(data_file_location).select("rating","review")
    if(raw_data.count() > 0):
        print(data_file_location + " exists and contains " + str(raw_data.count()) + " records")
    else:
        logger.error("couldn't locate " + data_file_location )
        assert False

    scoring_data = spark.read.parquet(scoring_data_file_location).select("review")
    if (scoring_data.count() > 0):
        print(scoring_data_file_location + " exists and contains " + str(scoring_data.count()) + " records")
    else:
        logger.error("couldn't locate " + scoring_data_file_location)
        assert False

def check_mlflow_connectivity(mlflow_tracking_uri):
    print("\n *********** checking mlflow connectivity ***************")
    mlflow_tracking_uri = mlflow_tracking_uri
    mlflow.set_tracking_uri(mlflow_tracking_uri)
    client = mlflow.tracking.MlflowClient()
    print("There are in total " + str(len(client.list_experiments())) + " experiments on your mlflow tracking server")
    print("You are connected to databricks hosted tracking server using ******" + mlflow_tracking_uri)

# check_if_libs_installed()
# check_mlflow_connectivity("databricks://adb-field-eng")

def validate_env_setup(data_file_location, scoring_data_file_location,mlflow_tracking_uri):
    print("***************** running environment setup tests ********************")
    check_datasets_availability(data_file_location, scoring_data_file_location)
    check_if_libs_installed()
    check_mlflow_connectivity(mlflow_tracking_uri)

#validate setup

if __name__ == "__main__":
    validate_env_setup(data_file_location, scoring_data_file_location, mlflow_tracking_uri)


#!/usr/bin/python3

from random import randint
from datetime import datetime as dt
import datetime
from os import system, name

def clear():

    # for windows
    if name == 'nt':
        _ = system('cls')

    # for linux and mac
    else:
        _ = system('clear')

def decToBin(x):
    maxNum = 2 ** x - 1
    maxDec = len(str(maxNum))
    random_number = randint(0, maxNum)
    print(f'{"-" * maxDec} (10)')
    print(f"{random_number:{maxDec}d}")
    print(f'{"-" * x} (2)')
    timeStart = dt.now()

    answer = int(input(), 2)

    timeStop = dt.now()
    timeLeft = (timeStop - timeStart).total_seconds()

    if answer == random_number:
        return (1, timeLeft)
    else:
        print(f"Error: {answer:{maxDec}d}")
        return (0, timeLeft)

def binToDec(x):
    maxNum = 2 ** x - 1
    maxDec = len(str(maxNum))
    random_number = randint(0, maxNum)
    print(f'{"-" * x} (2)')
    print(f"{random_number:0{x}b}")
    print(f'{"-" * maxDec} (10)')
    timeStart = dt.now()

    answer = int(input())

    timeStop = dt.now()
    timeLeft = (timeStop - timeStart).total_seconds()

    if answer == random_number:
        return (1, timeLeft)
    else:
        print(f"Error: {answer:{maxDec}d}")
        return (0, timeLeft)

def scoreChange(x, y):
    """
    x: 0 for incorrect answer, 1 for correct
    y: seconds spent on previous solution
    """
    if x:
        score = round(1000 / y)
    else:
        score = -(round(y * 10))
    return score

def scoreTable(x, score, gameTime):
    """
    x - 0 for incorrect answer, 1 for correct
    """
    sign = ("-", "+")

    print("=" * 43)
    print(f" {sign[x]} | Score: {score: 8d} | Time: {datetime.timedelta(seconds=gameTime, microseconds=0)}")
    print("=" * 43)


# coding: utf-8
# Copyright 2013 The Font Bakery Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# See AUTHORS.txt for the list of Authors and LICENSE.txt for the License.
from __future__ import print_function

from datetime import datetime
import os
import glob
import io
from flask import current_app
import itsdangerous
from collections import OrderedDict

ROOT = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))
DATA_ROOT = os.path.join(ROOT, 'data')

import sys
if sys.version < '3':
    import codecs

    def u(x):
        return codecs.unicode_escape_decode(x)[0]
else:
    def u(x):
        return x

def get_current_time():
    return datetime.utcnow()

def pretty_date(dt, default=None):
    """
    Returns string representing "time since" e.g.
    3 days ago, 5 hours ago etc.
    Ref: https://bitbucket.org/danjac/newsmeme/src/a281babb9ca3/newsmeme/
    """

    if default is None:
        default = 'just now'

    now = datetime.utcnow()
    diff = now - dt

    periods = (
        (diff.days / 365, 'year', 'years'),
        (diff.days / 30, 'month', 'months'),
        (diff.days / 7, 'week', 'weeks'),
        (diff.days, 'day', 'days'),
        (diff.seconds / 3600, 'hour', 'hours'),
        (diff.seconds / 60, 'minute', 'minutes'),
        (diff.seconds, 'second', 'seconds'),
    )

    for period, singular, plural in periods:

        if not period:
            continue

        if period == 1:
            return u'%d %s ago' % (period, singular)
        else:
            return u'%d %s ago' % (period, plural)

    return default

def signify(text):
    signer = itsdangerous.Signer(current_app.secret_key)
    return signer.sign(text)

class RedisFd(object):
    """Redis File Descriptor class, publish writen data to redis channel in parallel to file"""
    def __init__(self, name, mode='a'):
        self.fd = open(name, mode)
        self.fd.write("Start: Start of log\n")  # end of log

    def write(self, data, prefix=''):
        self.fd.write("%s%s" % (prefix, data))
        self.fd.flush()

    def close(self):
        self.fd.write("End: End of log\n")  # end of log
        self.fd.close()

def project_fontaine(project, build):
    from fontaine.font import Font

    param = {'login': project.login, 'id': project.id,
        'revision': build.revision, 'build': build.id}

    _out = os.path.join(DATA_ROOT, '%(login)s/%(id)s.out/%(build)s.%(revision)s/' % param)

    # Its very likely that _out exists, but just in case:
    if os.path.exists(_out):
        os.chdir(_out)
    else:
        # This is very unlikely, but should it happen, just return
        return

    # Run pyFontaine on all the TTF fonts
    fonts = {}
    for filename in glob.glob("*.ttf"):
        fontaine = Font(filename)
        fonts[filename] = fontaine

    # Make a plain dictionary, unlike the fancy data structures used by pyFontaine :)
    family = {}
    for fontfilename, fontaine in fonts.iteritems():
        # Use the font file name as a key to a dictionary of char sets
        family[fontfilename] = {}
        for charset, coverage, percentcomplete, missingchars in fontaine.get_orthographies():
            # Use each char set name as a key to a dictionary of this font's coverage details
            charsetname = charset.common_name
            family[fontfilename][charsetname] = {}
            family[fontfilename][charsetname]['coverage'] = coverage  # unsupport, fragmentary, partial, full
            family[fontfilename][charsetname]['percentcomplete'] = percentcomplete  # int
            family[fontfilename][charsetname]['missingchars'] = missingchars  # list of ord numbers
            # Use the char set name as a key to a list of the family's average coverage
            if not charsetname in family:
                family[charsetname] = []
            # Append the char set percentage of each font file to the list
            family[charsetname].append(percentcomplete)  # [10, 32, 40, 40] etc
            # And finally, if the list now has all the font files, make it the mean average percentage
            if len(family[charsetname]) == len(fonts.items()):
                family[charsetname] = sum(family[charsetname]) / len(fonts.items())
    # Make a plain dictionary with just the bits we want on the dashboard
    totals = {}
    totals['gwf'] = family.get('GWF latin', None)
    totals['al3'] = family.get('Adobe Latin 3', None)
    # Store it in the $(id).state.yaml file
    project.config['local']['charsets'] = totals
    project.save_state()

    # fonts.itervalues() emits <fontaine.font.Font instance at 0x106123c68> objects that we return for the rfiles.html template
    return fonts.itervalues()

def sortFont(fonts):
    sortedfonts = []
    for font in fonts:
        fontMetadata = OrderedDict()
        fontMetadata["name"] = font["name"]
        fontMetadata["style"] = font["style"]
        fontMetadata["weight"] = font["weight"]
        fontMetadata["filename"] = font["filename"]
        fontMetadata["postScriptName"] = font["postScriptName"]
        fontMetadata["fullName"] = font["fullName"]
        fontMetadata["copyright"] = font["copyright"]
        sortedfonts.append(fontMetadata)
    return sortedfonts

def sortMetadata(old):
    ordered = OrderedDict()
    ordered["name"] = old["name"]
    ordered["designer"] = old["designer"]
    ordered["license"] = old["license"]
    ordered["visibility"] = old["visibility"]
    ordered["category"] = old["category"]
    ordered["size"] = old["size"]
    ordered["fonts"] = sortFont(old["fonts"])
    ordered["subsets"] = sorted(old["subsets"])
    ordered["dateAdded"] = old["dateAdded"]
    return ordered

def striplines(jsontext):
    lines = jsontext.split("\n")
    newlines = []
    for line in lines:
        newlines.append("%s\n" % (line.rstrip()))
    return "".join(newlines)

def saveMetadata(metadata, path):
    # flask json serializer doesn't support OrderedDict
    import json
    data = json.loads(u(metadata))
    ready_data = sortMetadata(data)
    dump = json.dumps(ready_data, indent=2, ensure_ascii=True)
    strip_dump = striplines(dump)
    with io.open(path, 'w', encoding='utf-8') as f:
        f.write(u(strip_dump))


import numpy as np
from scipy import ndimage
import matplotlib.pyplot as plt

import skimage
from skimage import io, filters, feature, morphology, color
from skimage.morphology import disk

from PIL import Image
import warnings
import time
import os.path
import glob
import re

# find all the training images with a filename
# of which matches the pattern train*.jpg, where
# the '*' symbols could represent any character
im_list = glob.glob('../images/train*.jpg')

# sort the filenames which matched the specified path
# this is used for saving the center of ojbects.mat files
im_list.sort(key=lambda f: int(re.findall('([0-9]+)', os.path.basename(f))[0]))

# Read each image file and store them in a list
train_imgs = [io.imread(fpath) for fpath in im_list]

# use the skimage.color.rgb2gray() function to
# convert the multichannel color images to
# single channel grayscale image
train_grey = [color.rgb2gray(im) for im in train_imgs]

# imgray = train_grey[-1]

# Empty list for center coordinates
train_centers = []

# start a timer
start = time.time()

for imgray in train_grey:
    # smooth the image using a rank median filter
    denoised = filters.rank.median(imgray, disk(2))

    # detect contrast differences using Canny edge filtering
    edges = feature.canny(denoised, sigma=1)

    # binary-dilation algorithm to fill groups
    segmented = ndimage.binary_fill_holes(edges)

    label_objects, nb_labels = ndimage.label(segmented)

    # threshold size, then perform essentially an
    sizes = np.bincount(label_objects.ravel())
    mask_sizes = sizes > 40
    mask_sizes[0] = 0

    # logically AND operation with the surviving labels
    cleaned = mask_sizes[label_objects]
    labels, _ = ndimage.label(cleaned)
    labels.min(), labels.max()
    centers = ndimage.measurements.center_of_mass(denoised,labels=labels, index=np.arange(labels.min(),labels.max()))
    train_centers.append(centers)

end = time.time()

# imrgb = train_imgs[-1]
# imrgb[np.logical_not(cleaned),0] = 0
# imrgb[np.logical_not(cleaned),1] = 0
# imrgb[np.logical_not(cleaned),2] = 0
# io.imshow(imrgb)

print('Took {} seconds'.format(end -start))
(end-start)/len(centers)

for fpath, img, centers in zip(im_list, train_imgs, train_centers):

    # split the directory path from the file name
    dirname, fname = os.path.split(fpath)

    # split the file name from the file extention
    fname, _ = os.path.splitext(fname)

    # make a directiory to store the centers
    if not os.path.exists(dirname+'/centers'):
        os.mkdir(dirname+'/centers')
    else:
        print('Over-writing images in centers directory!')

    newf = '{}/centers/{}_centers.jpg'.format(dirname,fname)
    print('Saving "{}"'.format(newf))

    fig = plt.figure()
    plt.imshow(img)
    for c in centers:
        y,x = c
        plt.plot(x,y, 'r.', markersize=14)
    fig.savefig(newf)


from __future__ import print_function
import os, sys
from IPython.core.display import display, HTML
import shutil
import requests
import threading
import glob
import math
import matplotlib.pyplot as plt
from matplotlib.dates import date2num, AutoDateFormatter, AutoDateLocator

from utilities import hydroshare

is_py2 = sys.version[0] == '2'
if not is_py2:
    msg = 'The ts_utils function currently only works with Python 2.X'
    raise Exception(msg)
else:
    # set this for future python3 compatibility
    input = raw_input

    from odm2api.ODMconnection import dbconnection
    from odm2api.ODM2.services.readService import *
    from odm2api.ODM2.services.createService import *

class timeseries():
    def __init__(self):
        self.hydroshare = hydroshare.hydroshare()
        self.odm2db = None
        self._session = None
        self.read = None
        self.write = None
        self.tsresults = {}
        self.tsvalues = {}

    def content(self):
        return self.hydroshare.content

    def loadDatabase(self):
        if self.odm2db is None:
            display(HTML('Failed to load the database. Please make sure that the content for this resource contains a *.sqlite file.'))

        # load odm2 database
        self._session = dbconnection.createConnection('sqlite', self.odm2db)
        self.read = ReadODM2(self._session)
        self.write = CreateODM2(self._session)

    def readResults(self):
        res = self.read.getResults()
        self.tsresults = {r.ResultID:r for r in res}
        return self.tsresults

    def readTsValues(self, ids = []):

        if len(self.tsresults.keys()) == 0:
            self.readResults()

        # assemble a list if ids to download data for
        resids = self.tsresults.keys() if len(ids) == 0 else ids

        # download values for each result
        for resid in resids:
            res = self.tsresults[resid]
            print('Processing -> ' + ': '.join([res.VariableObj.VariableNameCV,
                                             res.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName]))
            self.tsvalues[resid] = self.read.getResultValues(resid)

    def previewTs(self, ids=[], rows=5):

        if len(self.tsresults.keys()) == 0:
            self.readResults()

        # assemble a list if ids to download data for
        resids = self.tsresults.keys() if len(ids) == 0 else ids

        get_ids = [tsid for tsid in resids if tsid not in self.tsvalues.keys()]
        if len(get_ids) > 0:
            print('Need to prepare the data for one or more of these result ids')
            self.readTsValues(get_ids)
        if len(get_ids) > 0 :print('\n')

        for tsid in resids:
            dv = self.tsvalues[tsid]['DataValue']
            dt = self.tsvalues[tsid]['ValueDateTime']
            res = self.tsresults[tsid]
            title = ' %s ' % (': '.join([res.VariableObj.VariableNameCV,
                                         res.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName]))
            restext = ' ResultID: %s' % tsid
            headtext ='DataValue \t ValueDateTime'

            # print timeseries header
            line_len = len(title)+4
            sepline = '-'* line_len
            print('-%s-' % sepline)
            print('%s%s' % (restext,' '*(line_len-len(restext))))
            print('%s%s' % (title,' '*(line_len-len(title))))
            print('-%s-' % sepline)

            # print timeseries values
            sys.stdout.write("%-25s %-25s \n" % ('DataValue','ValueDateTime'))
            for i in range(5):
                sys.stdout.write("%-25s %-25s \n" % (dt[i], dv[i]))
            print('\n')

    def subplotTimeSeries(self, ids=[], cols=1):
        # assemble a list if ids to download data for
        resids = self.tsresults.keys() if len(ids) == 0 else ids

        get_ids = [tsid for tsid in resids if tsid not in self.tsvalues.keys()]
        if len(get_ids) > 0:
            print('Need to prepare the data for one or more of these result ids')
            self.readTsValues(get_ids)
        if len(get_ids) > 0 :print('\n')

        # create the figure
        rows = math.ceil(float(len(resids)) / float(cols))
        fig = plt.figure(figsize=(15,rows*5))
        fig.subplots_adjust(hspace=.5)

        # plot the results, each in its own subplot
        for i in range(1, len(resids)+1):
            ax = fig.add_subplot(rows, cols, i)
            res = self.tsresults[resids[i-1]]
            tsval = self.tsvalues[resids[i-1]]

            x = list(self.tsvalues[resids[i-1]]['ValueDateTime'])
            y = list(self.tsvalues[resids[i-1]]['DataValue'])
            title = res.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName
            col_width=80/cols - 4
            subtitle = title[:col_width]+' ...' if len(title) > col_width else title
            ax.set_title(subtitle, fontsize=14)

            ax.plot_date(x,y,'-')
            ax.set_ylabel(res.VariableObj.VariableNameCV + " (" + res.UnitsObj.UnitsAbbreviation + ")")

            locator = AutoDateLocator()
            ax.xaxis.set_major_locator(locator)
            ax.xaxis.set_major_formatter(AutoDateFormatter(locator))
            labels = ax.get_xticklabels()
            plt.setp(labels, rotation=30, fontsize=10)

            ax.grid(True)

    def plotTimeSeries(self, ids=[]):
        # assemble a list if ids to download data for
        resids = self.tsresults.keys() if len(ids) == 0 else ids

        get_ids = [tsid for tsid in resids if tsid not in self.tsvalues.keys()]
        if len(get_ids) > 0:
            print('Need to prepare the data for one or more of these result ids')
            self.readTsValues(get_ids)
        if len(get_ids) > 0 :print('\n')

        # create the figure
        fig = plt.figure(figsize=(15,5))
        ax = fig.add_subplot(1,1,1)

        # plot the results
        for i in range(1, len(resids)+1):
            x = list(self.tsvalues[resids[i-1]]['ValueDateTime'])
            y = list(self.tsvalues[resids[i-1]]['DataValue'])
            res = self.tsresults[resids[i-1]]
            l = res.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName
            ax.plot(x,y, label=l[:30])

        ax.set_ylabel(res.VariableObj.VariableNameCV + " (" + res.UnitsObj.UnitsAbbreviation + ")")
        locator = AutoDateLocator()
        ax.xaxis.set_major_locator(locator)
        ax.xaxis.set_major_formatter(AutoDateFormatter(locator))
        labels = ax.get_xticklabels()
        plt.setp(labels, rotation=30, fontsize=10)

        ax.grid(True)

        # add a legend
        plt.legend()
        box = ax.get_position()
        ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
        ax.legend(loc='center left', bbox_to_anchor=(1, 0.9))

    def getTimeSeriesResource(self, resourceid=None, destination='.'):
        """
        Downloads the content of HydroShare resource to the JupyterHub userspace

        Args:
            resourceid: id of the HydroShare resource to query
            destination: path relative to /user/[username]/notebooks/data

        """
        try:
            res_meta = self.hydroshare.hs.getSystemMetadata(resourceid)

            if res_meta['resource_type'].lower() != 'timeseriesresource':
                display(HTML('Attempting to download resource of type %s.
 The'
                                 '`getTimeSeriesResource` function can only be used to download resources'
                                 'of type TimeSeriesResource.
Please specify a TimeSeries resource to download'
                                 % res_meta['resource_type']))
                return  None
        except Exception as e:
            display(HTML('Failed to retrieve resource content from HydroShare: %s' % e))
            return None

        # set the download path
        default_dl_path = os.environ['DATA']
        dst = os.path.abspath(os.path.join(default_dl_path, destination))
        download = True

        # get the hydroshare resource.  This puts the result into hs.content
        self.hydroshare.getResourceFromHydroShare(resourceid, destination)

        # load the odm2db into memory
        try:
            # get the sqlite file associated with the resource
            odm2dbName = next(k for k in self.content().keys() if k[-6:] == 'sqlite')
            self.odm2db = self.content()[odm2dbName]
            self.loadDatabase()
        except:
            print(self.content())
            display(HTML('Failed to find a database associated with this resource.  Please make sure that the content for this resource contains a *.sqlite file.'))
            return None


from sklearn.preprocessing import StandardScaler
import pandas as pd
import numpy as np
import tensorflow as tf
import random as rnd

#Import Data Set
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = pd.read_csv('prima-indians-diabetes.txt', names=names)
dataset = dataframe.as_matrix()

#Create Scaled Input Layer Data
x_data = dataset[:,0:7]
Y = dataset[:,8]
scalerS = StandardScaler().fit(x_data)
x_data = scalerS.transform(x_data)

#Define Model Variables
X = tf.Variable(x_data,tf.float64)
iterations = 1000
layers = {'0':63,'1':84,'output':2}
features = 7
alpha = .05

biases = {
      '0':tf.cast(tf.Variable(tf.ones([layers['0']])),tf.float64),
      '1':tf.cast(tf.Variable(tf.ones(layers['1'])),tf.float64),
      '2':tf.cast(tf.Variable(tf.ones([layers['output']])),tf.float64)
      }

weights = {
           '0':tf.cast(tf.Variable(tf.random_normal([features,layers['0']])),tf.float64),
           '1':tf.cast(tf.Variable(tf.random_normal([layers['0'],layers['1']])),tf.float64),
           '2':tf.cast(tf.Variable(tf.random_normal([layers['1'],layers['output']])),tf.float64),
           }

def feedforward(X):
    z1 = (tf.matmul(X,weights['0'])+biases['0'])
    z2 = (tf.matmul(z1,weights['1'])+biases['1'])
    z3 = (tf.matmul(z2,weights['2'])+biases['2'])
    #Final Hypothesis
    ht = z3
    return ht

def model(X,Y,layers,iterations,features,alpha):

    sess = tf.Session()
    ht = feedforward(X)

    y_matrix = np.zeros((768,2))

    for i,h in enumerate(Y):
        if Y[i]==1:
            y_matrix[i,1]=1
        else:
            y_matrix[i,0]=1

    Y = tf.constant(y_matrix,tf.float64)
    Y = tf.cast(Y,tf.float64)

    #Create Cost Function & Train
    #cross_entropy = tf.reduce_mean(-tf.reduce_sum(Y - tf.log(ht),reduction_indices=[1]))
    cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=Y,logits=ht))
    train_step = tf.train.GradientDescentOptimizer(alpha).minimize(cross_entropy)

    init = tf.global_variables_initializer()
    sess.run(init)

    for _ in range(iterations):
        sess.run(train_step)

    ans = []
    correct_prediction = tf.equal(tf.argmax(ht,1),tf.argmax(Y,1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
    ans = sess.run(correct_prediction)
    #Print Accuracy
    model_accuracy = sess.run(accuracy)

    return model_accuracy

def test_hyperparams(X,Y,iterations,features):
    best_config = {'accuracy':.001, 'config':{}}
    for i in range(100):
        l1n = rnd.randint(3, 100) #layer one nueron count
        l2n = rnd.randint(3, 100)   #layer two nueron count
        alpha = .05
        layers = {'0':l1n,'1':l2n, 'output':2}
        ans = (model(X,Y,layers,iterations,features,alpha))
        if ans > best_config['accuracy']:
            best_config['accuracy'] = ans
            best_config['config'] = layers
        print(best_config)
    return best_config

#final_config= print(test_hyperparams(X,Y,iterations,features))
#print('Best Configuration Identified:')
#print(final_config)

#print(model(X,Y,layers,iterations,features,alpha))
print(dataset[1,:])
print(x_data[1,:])

test_x = dataset[1,:]
print(test_x)
scalerT = StandardScaler().fit(test_x)
test_x = scalerT.transform(scalerT)
print(test_x)
test_x = tf.Variable(test_x,tf.float64)
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
print(sess.run([test_x]))

#print(sess.run([X[1,:]]))
#print(X[1,:])

#dataset = np.concatenate((ans,dataset))
#print(ans)
#print(ans.size)
#print(dataset.shape)
#print(y_matrix.size)
#print(sess.run(ht[766]))
#print(sess.run(Y[766]))
#print(dataset[766,:])
#print(ans[766])

#Forward Prop
#Try building this as a function
#def forward_prop(b,w):
#    layer_count = len(weights.keys())
#    layers = {}
#    print(w)
#    for li in range(layer_count):
#        layers[li] = tf.matmul(w[i],w[i])
#
#        #print(li)
#        if li==0:
#            #print(0)
#            #print(w)
#            #layers[li] = (tf.matmul(X,w[i]),+b[i])
#        #else:
#            #layers[li] = (tf.matmul(layers[i],w[i]),+b[i]])
#            print(layers)
#
#
#        #layers = {}
#        #index,val
##    for i,v in enumerate(biases):
##        z = 0;
##        weight = w.values()[i]
##        print(weight)
##        if i == 1:
##            print(1)
##        layers['l'+str(i)] = v
#
#    #print(layers)
#    return 'done'


from django.shortcuts import render, render_to_response
from django.views.decorators.csrf import csrf_exempt,csrf_protect,ensure_csrf_cookie
from .models import Domain
# Create your views here.

def logout(request):
    return render_to_response('logout.html')

@ensure_csrf_cookie
@csrf_exempt
def ansviews(request, template_name='mypage.html'):
    if request.method == "POST":  # checking POST request
        name = request.POST.get('name', '')  # get the input from front end text box
        favcolor = request.POST.get('favcolor', '')
        pet = request.POST.get('pet', '')
        print(name, favcolor, pet)
        Domain.objects.create(name=name, favcolor=favcolor, pet=pet)
        context = {
            'name': name,
            'favcolor': favcolor,
            'pet': pet
        }
        return render(request, template_name, context)
    else:
        print("GET Type")
        return render(request, template_name)


from flask import Flask
from flask_ask import Ask, statement, question, session
import json
import requests
import bs4

app = Flask(__name__)
ask = Ask(app, "/techcrunch_reader")

def get_headlines():
    res = requests.get('https://techcrunch.com/')
    res.raise_for_status()
    techcrunch_site = bs4.BeautifulSoup(res.text)
    elements = techcrunch_site.select('.block-title')
    elements2 = techcrunch_site.select('.plain-title')

    headlines = ''
    for i in range (0, len(elements)):
        headlines += elements[i].getText()

    for i in range (0, len(elements2)):
        headlines += elements2[i].getText()

    return headlines

@app.route('/')
def homepage():
    homepage_message = "Welcome"
    return homepage_message

@ask.launch
def start_skill():
    welcome_message = "Hi, would you like to know the current Techcrunch headlines?"
    return question(welcome_message)

@ask.intent("YesIntent")
def share_headlines():
    techcrunch_headlines = get_headlines()
    techcrunch_headines_msg = "Great! The current news are " + techcrunch_headlines
    return statement(techcrunch_headines_msg)

@ask.intent("NoIntent")
def no_intent():
    closing_message = "Well, guess I will talk to you late"
    return statement(closing_message)

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


import unittest

from egnyte import EgnyteTasks

class TestEgnyteTasks(unittest.TestCase):
    def setUp(self):
        self.tasks = EgnyteTasks()

    def test_difference_calculation(self):
        self.assertEqual(self.tasks._EgnyteTasks__difference(10, 6), 4,
                         'difference should be substraction'
        )
        self.assertEqual(self.tasks._EgnyteTasks__difference(6, 10), 4,
                         'difference should be absolute substraction'
        )
        self.assertEqual(self.tasks._EgnyteTasks__difference('10', '6'), 4,
                         'difference should work with strings'
        )
        self.assertEqual(self.tasks._EgnyteTasks__difference(1, 1), 0,
                         'difference should be 0 for equal arguments'
        )
        self.assertEqual(self.tasks._EgnyteTasks__difference(-3, -1), 2,
                         'difference should work with negative numbers'
        )
        self.assertEqual(self.tasks._EgnyteTasks__difference(-3, 1), 4,
                         'difference should work with various signs numbers'
        )

    def test_new_min(self):
        self.assertEqual(self.tasks._EgnyteTasks__new_min(None, 1), True,
                         'new_min should be True when old is None'
        )
        self.assertEqual(self.tasks._EgnyteTasks__new_min(6, 10), False,
                         'new_min should be False for larger new number'
        )
        self.assertEqual(self.tasks._EgnyteTasks__new_min(10, 6), True,
                         'new_min should be True for smaller new number'
        )

    def test_weather_matching(self):
        self.assertIsNone(self.tasks._EgnyteTasks__weather_match(''),
                         'weather_match should be None for empty string'
        )
        legend_line = ('  Dy MxT   MnT   AvT   HDDay  AvDP 1HrP TPcpn WxType '
                       + 'PDir AvSp Dir MxS SkyC MxR MnR AvSLP'
        )
        self.assertIsNone(self.tasks._EgnyteTasks__weather_match(legend_line),
                         'weather_match should be None for legend line'
        )
        valid_line = ('   1  88    59    74          53.8       0.00 F'
                      + '       280  9.6 270  17  1.6  93 23 1004.5'
        )
        self.assertIsNotNone(
            self.tasks._EgnyteTasks__weather_match(valid_line),
            'weather_match should not be None for valid line'
        )
        short_line = '   1  88    59    74 '
        self.assertIsNotNone(
            self.tasks._EgnyteTasks__weather_match(short_line),
            'weather_match should not be None for short line'
        )
        line_with_stars = '   1  88*   59*   74 '
        self.assertIsNotNone(
            self.tasks._EgnyteTasks__weather_match(line_with_stars),
            'weather_match should not be None for line with stars'
        )

    def test_team_matching(self):
        self.assertIsNone(self.tasks._EgnyteTasks__team_match(''),
                         'team_match should be None for empty string'
        )
        legend_line = ('       Team            P     W    L   D    '
                       +'F      A     Pts'
        )
        self.assertIsNone(self.tasks._EgnyteTasks__team_match(legend_line),
                         'team_match should be None for legend line'
        )
        valid_line = ('    1. Arsenal         38    26   9   3    '
                      +'79  -  36    87'
        )
        self.assertIsNotNone(
            self.tasks._EgnyteTasks__team_match(valid_line),
            'team_match should not be None for valid line'
        )
        short_line = '    1. Arsenal   79  -  36 '
        self.assertIsNotNone(
            self.tasks._EgnyteTasks__team_match(short_line),
            'team_match should not be None for short line'
        )

    def test_default_weather_file(self):
        self.assertEqual(self.tasks.smallest_temperature_spread(), 14,
                        'wrong day from default file'
        )

    def test_default_football_file(self):
        self.assertEqual(self.tasks.smallest_goals_difference(),
                         'Aston_Villa', 'wrong team from default file'
        )

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


#Author : Chitrasen
#Date : 11/1/2013
# Basic benchmark code LogisticRegression with sampling agents

import pandas as pd
import re
from sklearn import cross_validation,metrics
from sklearn.feature_extraction.text import CountVectorizer
from sklearn import linear_model as lm
from sklearn.metrics import mean_squared_error
from sklearn.decomposition import TruncatedSVD
from sklearn.tree import DecisionTreeClassifier

#import PorterStemmer

def clean(s):
    s = s.lower()
    s = re.sub('n\'t',' not',s)
    s = re.sub('{link}',' ',s)
    s = re.sub('#\w+',' ',s)
    s = re.sub('@\w+',' ',s)
    s = re.sub('[\W]',' ',s)
    s = re.sub('\s+',' ',s)
    s = removeStopWords(s)
    return s

def removeStopWords(s):
    stopWordsStr = 'a about above after again against all am an and any are as at be because been before being below between both but by cannot could did do does doing down during each few for from further had has have having he he\'d he\'ll he\'s her here here\'s hers herself him himself his how how\'s i i\'d i\'ll i\'m i\'ve if in into is it it\'s its itself let\'s me more most my myself no nor not of off on once only or other ought our ours  ourselves out over own rt same she she\'d she\'ll she\'s should so some such than that that\'s the their theirs them themselves then there there\'s these they they\'d they\'ll they\'re they\'ve this those through to too under until up very was we we\'d we\'ll we\'re we\'ve were what what\'s when when\'s where where\'s which while who who\'s whom why why\'s with would you you\'d you\'ll you\'re you\'ve your yours yourself yourselves'
    stopWords = re.split('\s+',stopWordsStr)
    cleanwords = [w for w in re.split('\W+',s) if w not in stopWords]

    p = PorterStemmer()

    s = ''
    for word in cleanwords:
        s += " " +p.stem(word,0,len(word)-1)
    return s

def normalize_prob(a):
    row_sums = a.sum(axis =1)
    return a/row_sums[:,np.newaxis]

def isItRetweet(df):
    return [len(re.findall('^rt', tweet)) > 0 for tweet in df.tweet]

def hashTagsCount(df):
    return [len(re.findall('\#.',tweet)) for tweet in df.tweet]

def mentionCount(df):
    return [len(re.findall('\@.',tweet)) for tweet in df.tweet]

def numericContains(df):
    return [len(re.findall('[0-9]+[:.]*[0-9]*.',tweet)) for tweet in df.tweet]

def containsAMPM(df):
    return [len(re.findall('[0-9]+\s*am|pm',tweet)) for tweet in df.tweet]

def linksCount(df):
    return [len(re.findall('{link}',tweet)) for tweet in df.tweet]

def containsHashWeather(df):
    return [len(re.findall('\#weather',tweet)) for tweet in df.tweet]

def tweetLength(df):
    return [len(tweet) for tweet in df.tweet]

def getHighFeqWords(df,col,percent = 0.85, stop_words = 'english',max_features = 50):
    df1 = df['tweet'][df[col] > percent]
    countVect = CountVectorizer(strip_accents = 'ascii',analyzer='word',stop_words = stop_words,
                                max_features = max_features,binary = True)

    countVect.fit(df1.values)
    maxFeatures = countVect.fit(df['tweet'][df[col] > percent]).get_feature_names()
    print(maxFeatures)
    countVect = CountVectorizer(vocabulary=maxFeatures)
    return countVect.fit_transform(df.tweet).toarray()

def getFeatureVecture(df,function_list = None,col_category=None):

    returnVals = None

    if(function_list == None):
        function_chain = [isItRetweet,hashTagsCount,mentionCount,numericContains,containsAMPM,linksCount,
                      containsHashWeather,tweetLength]
        returnVals = np.hstack([np.matrix(func(df)).T for func in function_chain])

    return returnVals

def main():
    print('Reading datasets...')
    train = pd.read_csv('/home/trupti/data_local/kaggle/partly_sunny/train.csv',header = 0)
    test = pd.read_csv('/home/trupti/data_local/kaggle/partly_sunny/test.csv', header = 0)

    pred = pd.DataFrame(np.zeros((test.shape[0], train.shape[1]- test.shape[1])), columns = train.columns[4:])
    pred.index = test['id']

    tweets_train = train['tweet']
    tweets_test = test['tweet']
    #X_all = list(tweets_train)+list(tweets_test)

    X_all_a = list(tweets_train)+list(tweets_test)
    X_all = [clean(s) for s in X_all_a]

    tfidf = CountVectorizer(X_all,min_df=5,  max_features=None, strip_accents='unicode',
        analyzer='word',token_pattern=r'\w{1,}',ngram_range=(1,1),stop_words = 'english')

    lr = lm.LogisticRegression(penalty='l2', dual=True, tol=0.0001,
                           C=1, fit_intercept=True, intercept_scaling=1.0,
                           class_weight=None, random_state=None)

    clf = DecisionTreeClassifier()

    print('fitting TfIDF...')
    trainLen = tweets_train.shape[0]

    tfidf.fit(X_all)
    X_all = tfidf.transform(X_all)
    lsa = TruncatedSVD(n_components = 100)

    print('Fitting in LSA')
    X_all = lsa.fit_transform(X_all)

    X_train = X_all[:trainLen]
    X_test = X_all[trainLen:]

    X_train = np.hstack((X_train,getFeatureVecture(train)))

    # sampling from the data and fitting indivisual samples linear model and average the results

    final_cv_error = 0
    sampling_count = 10

    kf = cross_validation.KFold(X_train.shape[0],n_folds = 10)
    cols = {'s':['s1','s2','s3','s4','s5'],
        'w':['w1','w2','w3','w4'],
        'k':['k1','k2','k3','k4','k5','k6','k7','k8','k9','k10','k11','k12','k13','k14','k15']}

    col_keys = ['s','w','k']
    final_error = []
    j = 0

    for train_idx,cv_idx in kf:
        j +=1
        print('prcessing CV :',j)
        X_train_kf = X_train[train_idx,:]
        X_cv_kf = X_train[cv_idx,:]

        y_train_kf = train.ix[train_idx,4:]
        y_cv_kf = train.ix[cv_idx,4:]
        #creating a place holder of cv predictions
        pred_cv = pd.DataFrame(np.zeros(y_cv_kf.shape), columns = train.columns[4:])

        error_pred = 100

        for y_col in col_keys:
            #do this for 100s simulation

            print('    Normalizing prediction values')
            y_train_kf_norm = normalize_prob(y_train_kf[cols[y_col]].values)

            pred_sampling = np.zeros((len(cv_idx),sampling_count))

            #print 'sampling for ',y_col,sampling
            sim_data = [np.random.choice(np.arange(len(cols[y_col])),
                                     sampling_count,replace = True,
                                     p = y_train_kf_norm[i,:]) for i in np.arange(len(train_idx))]
            sim_data = np.array(sim_data)
            print('    sim_data shape', sim_data.shape)
            #print sim_data[:10]
            for sampling in range(sampling_count):
                #print 'sim_data', sim_data[sampling]
                clf.fit(X_train_kf,sim_data[:,sampling])
                pred_sampling[:,sampling] = clf.predict(X_cv_kf)
            pred_sampling = pd.DataFrame(pred_sampling)

            print('    processed all the samplings')

            col_index = 0
            for col in cols[y_col]:
                col_val = pred_sampling == col_index
                pred_cv[col] = np.array(col_val.sum(axis = 1), dtype = float)/sampling_count
                col_index +=1
        print('Score CV',j, sqrt(mean_squared_error(y_cv_kf,pred_cv)))

if __name__ == '__main__':
    main()


import re

import time
from distutils.command import register

from django.contrib.auth.decorators import login_required

from django.shortcuts import render, redirect
from django.contrib import auth

from account.forms import SlidesForm
from account.models import Presentation, PresentationCopy
from google_api.drive import files_export_media
from project_teta import settings
import hashlib
from django.core.files import File
from django.template.defaulttags import register
import urllib
import json

@register.filter
def get_item0(dictionary, key):
    val = dictionary.get(key)
    if val:
        return int(val[0])
    return 0
@register.filter
def get_item1(dictionary, key):
    val = dictionary.get(key)
    if val:
        return int(val[1])
    return 0
#

# Create your views here.

@login_required
def account_info(request):
    presentations = Presentation.objects.filter(user=auth.get_user(request))
    return render(request, 'account.html', locals())

@login_required
def presentation_info(request, id=0):
    id = int(id)
    link = ""
    if id <= 0:
        return redirect('/account/presentations/')
    presentation = Presentation.objects.get(id=id)

    status = ""
    if presentation.is_active:
        status = "Close"
    else:
        status = "Open"

    if presentation is None:
        return redirect('/account/presentations/')

    if request.POST.get('status'):
        presentation.is_active = not presentation.is_active
        presentation.save()
        if presentation.is_active:
            status = "Close"
        else:
            status = "Open"
    link = ""

    if request.POST.get('add_link'):
        pcopy = PresentationCopy()
        pcopy.origin = presentation
        pcopy.name = request.POST['name']
        magic = pcopy.name + str(time.time())
        pcopy.hash = hashlib.md5(magic.encode()).hexdigest()
        pcopy.save()

    if request.POST.get('delete'):
        idc = request.POST['copy_id']
        obj = PresentationCopy.objects.get(id=idc)
        PresentationCopy.delete(obj)

    api_url = 'https://api-metrika.yandex.ru/stat/v1/data?'
    counter_id = "id=47725444"
    metrics = '&metrics=ym:pv:pageviews,ym:pv:users'
    dimensions = '&dimensions=ym:pv:URLPath'
    auth_token = '&oauth_token=AQAAAAAOGSvpAATQtPCjgBAfGU1wobj5hSPXApg'
    filter_url = '&filters=ym:pv:URLPath=~%27/show/' + str(presentation.id) + '/[0-9]%2B/*%27'
    request_url = api_url + counter_id + metrics + dimensions + filter_url + auth_token
    print(request_url)
    f = urllib.request.urlopen(request_url)
    ans = f.read()
    json_ans = json.loads(ans)
    data = json_ans['data']

    view_stat = {}

    for item in data:
        path = item['dimensions'][0]['name'].strip().split('/')
        view_stat[int(path[3])] = item['metrics']

    print(view_stat)

    copys = PresentationCopy.objects.filter(origin=presentation)
    return render(request, 'presentation.html', locals())

@login_required
def add_presentation(request):
    form = SlidesForm(request.GET)
    if request.POST:
        newslidesform = SlidesForm(request.POST, request.FILES)
        if newslidesform.is_valid():
            presentation = Presentation()
            presentation.name = newslidesform["name"].value()
            presentation.description = newslidesform["description"].value()
            presentation.url = newslidesform["url"].value()
            presentation.user = auth.get_user(request)
            file_url = presentation.url
            start = file_url.find("/d/") + 3
            end = file_url.find("/edit")
            presentation.presentationId = file_url[start:end]
            pdf_s = newslidesform['pdf'].value()
            f = None
            if pdf_s is None:
                fh = files_export_media(presentation.presentationId, 'application/pdf')
                f = open(settings.MEDIA_URL + "user_files/" + presentation.presentationId + ".pdf", 'wb')
                f.write(fh.getvalue())
                f.close()
                f = open(settings.MEDIA_URL + "user_files/" + presentation.presentationId + ".pdf", 'rb')
                pdf_s = File(f)

            # Assumes the default UTF-8
            hash = hashlib.md5(presentation.name.encode()).hexdigest()
            presentation.hash = hash
            presentation.pdf.save(presentation.presentationId + ".pdf", pdf_s)
            # Presentation.objects.create(name=presentation.name, description=presentation.description,
            #                             url=presentation.url,
            #                             presentationId=presentation.presentationId, pdf=pdf_s, user=presentation.user,
            #                             hash=hash)
            if f is not None:
                f.close()
            return redirect('/account/')
        else:
            form = SlidesForm(request.POST)

    return render(request, 'upload_presentation.html', locals())


import click

from .utils import do_my_super_path_stuff

@click.command()
@click.option('--graph-path', required=True, type=click.Path(dir_okay=False, file_okay=True), help='Path to networkx pickle file')
@click.option('--df-path', required=True, help='Path to TSV file')
@click.option('--output-path', required=True, help='Where to stick output TSV file')
@click.option('--dgxp-threshold', default=2.0, show_default=True, type=float, help='What makes a gene differentially expressed?')
def cli(graph_path: str, df_path: str, output_path: str, dgxp_threshold):
    print('Doing my super path stuff')
    print(graph_path)
    print(df_path)
    print(output_path)
    print(dgxp_threshold)
    do_my_super_path_stuff(graph_path, df_path, output_path)

if __name__ == '__main__':
    cli()


from django.urls import path
from django.urls.resolvers import URLPattern
from firstapp import views
from django.contrib.auth import views as v
from django.conf.urls.static import static
urlpatterns = [
    path('',views.home,name="hm"),
    path('about/',views.about,name="ab"),
    path('cnct/',views.contact,name="ct"),
    path('rg/',views.usrreg,name="reg"),
    path('order/',views.order,name="order"),
    path('oc/',views.orderaccept,name="accept"),
    path('od/<int:m>',views.od,name="od"),
    path('login/',v.LoginView.as_view(template_name="app/login.html"),name="lg"),
    path('logout',v.LogoutView.as_view(template_name="app/logout.html"),name="lgo"),
    path('roletype/',views.rolereq,name="rlrq"),
    path('gvper/',views.gveperm,name="gvpm"),
    path('gvup/<int:t>/',views.gvupd,name="gvup"),
    path('gvdel/<int:m>/',views.gvdel,name="gvdel"),
    path('pfle/',views.pfle,name="pf"),
    path('pfupd/',views.pfupd,name="pfupd"),
    path('fbd',views.feedback,name="fd"),
    path('chge/',views.changepwd,name="chpd"),
]


from flask import render_template
from flask_login import login_required
from app import app

from app.MSSql.SqlGet import SQLGet
from app.routes.Spravochniki.sql.get_commands import *

@app.route('/admin/spravochniki/torgovietochki/kateg_torg_tochek')
@login_required
def spravochniki_finance_kateg_torg_tochek():
        sqlcmd = """
               Select CategoryTTNo, CategoryTTName, Active from D_CategoryTT
            """

        context = {
            'title': 'Категории Торг Точек',
            'username': 'admin',
            'table_fields': ['Номер', 'Наименование категории ТТ', 'Активен'],
            'table_data': list(SQLGet(sqlcmd).get_sql_from_db()),
        }
        return render_template('admin/pages/table_view.html', context=context)

@app.route('/admin/spravochniki/torgovietochki/rajoni')
@login_required
def spravochniki_torgovietochki_rajoni():
    sqlcmd = """
        select RegionNo,RegionName, Visible
        from Regions

        order by RegionName
    """

    context = {
        'title': 'Районы',
        'username': 'admin',
        'table_fields': ['Номер', 'Наименование', 'Спрятать'],
        'table_data': list(SQLGet(sqlcmd).get_sql_from_db()),
    }
    return render_template('admin/pages/table_view.html', context=context)

@app.route('/admin/spravochniki/torgovietochki/territorii')
@login_required
def spravochniki_torgovietochki_territorii():
    sqlcmd = """
        select * from KOATUUOfPepsico
    """
    context = {
        'title': 'территории',
        'username': 'admin',
        'table_fields': ['KOATUU_ID_CODE', 'KOATUU_L1_NAME_RUS', 'KOATUU_L2_NAME_RUS'],
        'table_data': list(SQLGet(sqlcmd).get_sql_from_db()),
    }
    return render_template('admin/pages/table_view.html', context=context)

@app.route('/admin/spravochniki/torgovietochki/ABCDZ_klassificator')
@login_required
def spravochniki_torgovietochki_ABCDZ_klassificator():
    sqlcmd = """
                   Select * from ClassifierABCDZ
                """

    context = {
        'title': 'ABCDZ Классивикатор',
        'username': 'admin',
        'table_fields': ['Номер', 'Наименование', 'Активен'],
        'table_data': list(SQLGet(sqlcmd).get_sql_from_db()),
    }
    return render_template('admin/pages/table_view.html', context=context)

@app.route('/admin/spravochniki/torgovietochki/torgovie_seti')
@login_required
def spravochniki_torgovietochki_torgovie_seti():
    sqlcmd = """
        select *
        from OurCommercialNetwork ocn
          where (ocn.NameCommercialNetwork is not null or ocn.NameCommercialNetwork <> ' ')  and Visible = 1 and Trash = 0
        order by ocn.NameCommercialNetwork
    """
    context = {
        'title': 'Торговые сети',
        'username': 'admin',
        'table_fields': ['Код', 'Наименование сети', 'V', 'D'],
        'table_data': list(SQLGet(sqlcmd).get_sql_from_db()),
    }
    return render_template('admin/pages/table_view.html', context=context)

@app.route('/admin/spravochniki/torgovietochki/logicZones')
@login_required
def spravochniki_torgovietochki_logic_zones():
    sqlcmd = """
        select *
         from LogisticZone lz
          where (lz.NameLogisticZone is not null or lz.NameLogisticZone <> ' ')  and Visible = 1 and Trash = 0
        order by lz.NameLogisticZone
    """
    context = {
        'title': 'Лоические зоны',
        'username': 'admin',
        'table_fields': ['Код', 'Наименование зоны', 'V', 'D'],
        'table_data': list(SQLGet(sqlcmd).get_sql_from_db()),
    }
    return render_template('admin/pages/table_view.html', context=context)


from django.db import models
from django.core.cache import cache
from django.dispatch import receiver
from django.db.models.signals import post_save

class ModuleManager(models.Manager):
    def installed(self, module):
        """
        By default, all modules considered installed
        """
        installed_cache = cache.get('material.modules.installed')
        if not installed_cache:
            installed_cache = [mod.label for mod in self.get_queryset().filter(installed=True)]
            cache.set('material.modules.installed', installed_cache, 60*60*24)
        return module in installed_cache

class Module(models.Model):
    label = models.SlugField()
    installed = models.BooleanField(default=True)

    objects = ModuleManager()

    def __str__(self):
        return self.label

@receiver(post_save, sender=Module)
def clean_installed_cache(sender, **kwargs):
    cache.delete('material.modules.installed')


# Copyright 2015 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Common utilities for the gcloud dataproc tool."""

import time
import uuid

from apitools.base.py import encoding
from apitools.base.py import exceptions as apitools_exceptions

from googlecloudsdk.api_lib.dataproc import exceptions
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.core import log
from googlecloudsdk.core.console import progress_tracker

def FormatRpcError(error):
  """Returns a printable representation of a failed Google API's status.proto.

  Args:
    error: the failed Status to print.

  Returns:
    A ready-to-print string representation of the error.
  """
  log.debug('Error:\n' + encoding.MessageToJson(error))
  formatted_error = error.message
  # Only display details if the log level is INFO or finer.
  if error.details and log.GetVerbosity() <= log.info:
    formatted_error += (
        '\nDetails:\n' + encoding.MessageToJson(error.details))
  return formatted_error

def WaitForResourceDeletion(
    request_method,
    resource_ref,
    message,
    timeout_s=60,
    poll_period_s=5):
  """Poll Dataproc resource until it no longer exists."""
  with progress_tracker.ProgressTracker(message, autotick=True):
    start_time = time.time()
    while timeout_s > (time.time() - start_time):
      try:
        request_method(resource_ref)
      except apitools_exceptions.HttpError as error:
        if error.status_code == 404:
          # Object deleted
          return
        log.debug('Get request for [{0}] failed:\n{1}', resource_ref, error)

        # Do not retry on 4xx errors
        if IsClientHttpException(error):
          raise
      time.sleep(poll_period_s)
  raise exceptions.OperationTimeoutError(
      'Deleting resource [{0}] timed out.'.format(resource_ref))

def GetJobId(job_id=None):
  if job_id:
    return job_id
  return str(uuid.uuid4())

class Bunch(object):
  """Class that converts a dictionary to javascript like object.

  For example:
      Bunch({'a': {'b': {'c': 0}}}).a.b.c == 0
  """

  def __init__(self, dictionary):
    for key, value in dictionary.iteritems():
      if isinstance(value, dict):
        value = Bunch(value)
      self.__dict__[key] = value

def AddJvmDriverFlags(parser):
  parser.add_argument(
      '--jar',
      dest='main_jar',
      help='The HCFS URI of jar file containing the driver jar.')
  parser.add_argument(
      '--class',
      dest='main_class',
      help=('The class containing the main method of the driver. Must be in a'
            ' provided jar or jar that is already on the classpath'))

def AddTimeoutFlag(parser, default='10m'):
  """Add hidden client side timeout flag to parser."""
  # This may be made visible or passed to the server in future.
  parser.add_argument(
      '--timeout',
      type=arg_parsers.Duration(),
      default=default,
      hidden=True)

def IsClientHttpException(http_exception):
  """Returns true if the http exception given is an HTTP 4xx error."""
  return http_exception.status_code >= 400 and http_exception.status_code < 500


# -*- coding: utf-8 -*-
"""
Created on Mon Dec 14 10:40:13 2020

@author: Voilet Pince
"""

import pandas as pd
import flask
from flask import Flask
import joblib
import numpy as np
from flask_cors import CORS
import warnings
import mysql.connector as connection

try:
    mydb = connection.connect(host='localhost', database = 'review',user='root', passwd='',use_pure=True)#creating the connection to the database review
    query = "Select * from review;"#selecting the table review from the database review
    ds= pd.read_sql(query,mydb)#storing the review table in a Pandas dataframe
    mydb.close() #close the connection
#exception to catch errors and print the errors
except Exception as e:
        mydb.close()
        print(str(e))

warnings.filterwarnings('ignore')

app = Flask(__name__)
CORS(app)
@app.route('/sentiment/', methods=['GET'])

def make_prediction():
    if flask.request.method == 'GET':
        X2 = ds['Comment'].values
        X_new = cv.transform(X2)# building up feature vector of our input
        prediction = clf.predict(X_new) #making predictions
        zeros = int(np.sum(prediction == 0))#counting the number of zeros in the analysis
        ones = int(np.sum(prediction == 1))#counting the number of ones in the analysis
        return flask.jsonify(zeros,ones)#returning the zeros and ones

if __name__ == '__main__':
    clf = joblib.load("NBmodel.pkl")#loading the already trained model
    cv = joblib.load("vector.pkl")#loading the count vectorizer that will be used to vectorize the new inputs
    app.run(debug=True, use_reloader=False,threaded=False)


import os
import json
import cv2
import argparse
import numpy as np
from matplotlib import pyplot as plt

from PIL import ImageDraw
from PIL import Image

meter2pixel = 20
border_pad = 20*3
ALLOWED_ROOM_TYPES = {'indoor':3, 'kitchen':4, 'dining_room':5, 'living_room':6,
                      'bathroom':7, 'bedroom':8, 'office':9, 'hallway':10}
beds_meter = [[2.0,2.0],[1.8, 2.0], [1.5, 2.0], [1.2 ,2.0]]
beds_pixels = [[int(bed_meter[0]*meter2pixel), int(bed_meter[1]*meter2pixel)] for bed_meter in beds_meter]

barriers_meter = [[0.5, 0.5],[0.4, 0.4],[0.3 ,0.3],[0.5, 0.4],[0.5,0.3],[0.4,0.3]]
# barriers_meter = [[0.3, 0.3],[0.2, 0.2],[0.1 ,0.1],[0.3, 0.2],[0.3,0.1],[0.2,0.1]]
barriers_pixels = [[int(barrier_meter[0]*meter2pixel), int(barrier_meter[1]*meter2pixel)] for barrier_meter in barriers_meter]

height, width = 512, 512

bx1 = int(0.95*width)
by1 = int(0.95*height)
bx0 = int(0.05*width)
by0 = int(0.05*height)

def get_cloest_pt(x,y):
    pt0 = np.array((x,y))
    pts = [np.array((x, by0)), np.array((x, by1)), np.array((bx0, y)), np.array((bx1, y))]
    dis = [np.linalg.norm(pt0-pt) for pt in pts]
#     print(np.amin(dis))
    return pts[np.argmin(dis)]

def check_closest_pt(x, y, bx, by, ref_image):
    cnt = 0
    if x == bx:
        for _y in range(min(y, by), max(y,by)):
            if ref_image[x, _y] != 0:
                cnt += 1;
    elif y == by:
        for _x in range(min(x, bx), max(x,bx)):
            if ref_image[_x, y] != 0:
                cnt += 1;
    if cnt > 5:
        return False
    return True

def darw_poly(draw, height, width, fil_col, ref_image, coinf=50, draw_pts=True):
    x_array, y_array=np.where(ref_image==2)
    px0,py0 = 0,0
    cpx, cpy = 511, 511
    while ref_image[px0,py0] != 1 or check_closest_pt(px0, py0, cpx, cpy, ref_image):
        idx = np.random.randint(x_array.shape[0])
        px0 = x_array[idx]
        py0 = y_array[idx]
        px0 = px0+np.random.randint(20)-10
        py0 = py0+np.random.randint(20)-10

        cpx, cpy = get_cloest_pt(px0, py0)

    rand_num = np.random.rand()
    px1, py1 = int(coinf*(np.random.rand()-0.5) + cpx), int(-coinf*(np.random.rand()-0.5) + cpy)
    px2, py2 = int(coinf*(np.random.rand()-0.5) + cpx), int(-coinf*(np.random.rand()-0.5) + cpy)

    for i in range(np.random.randint(1,40)):
        rand_x = np.random.rand()
        rand_y = np.random.rand()
        x, y = rand_x*px1+(1-rand_x)*px2, rand_y*py1+(1-rand_y)*py2
        draw.line((px0, py0, x, y), fil_col)

        if draw_pts:
            draw.point([(x, y)], 2)
            dot_enhance_num = np.random.randint(2,15)
            for _ in range(dot_enhance_num):
                add_x, add_y = np.random.rand(2)-0.5
                if rand_num < 0.5:
                    add_x, add_y = int(add_x*2), int(add_y*3)
                else:
                    add_x, add_y = int(add_x*3), int(add_y*2)
                draw.point([(x+add_x, y+add_y)], 2)
    return px0, py0, px1, py1, px2, py2

def _get_room_tp_id(room):
    room = room.lower()
    if room == 'toilet':
        room = 'bathroom'
    # elif room == 'guest_room':
    #     room = 'bedroom'
    if room not in ALLOWED_ROOM_TYPES:
        return ALLOWED_ROOM_TYPES['indoor']
    return ALLOWED_ROOM_TYPES[room]

def draw_map(file_name, json_path, save_path):
    print("Processing ", file_name)

    with open(json_path + '/' + file_name + '.json') as json_file:
        json_data = json.load(json_file)

    # Draw the contour
    verts = (np.array(json_data['verts']) * meter2pixel).astype(np.int)
    x_max, x_min, y_max, y_min = np.max(verts[:, 0]), np.min(verts[:, 0]), np.max(verts[:, 1]), np.min(verts[:, 1])

    if not os.path.exists(save_path):
        os.mkdir(save_path)
    ######################################
    raw_vis_map = np.ones((y_max - y_min + border_pad * 2,
                        x_max - x_min + border_pad * 2))*127
    if raw_vis_map.shape[0]>512 or raw_vis_map.shape[1]>512:
        return

    verts[:, 0] = verts[:, 0] - x_min + border_pad
    verts[:, 1] = verts[:, 1] - y_min + border_pad
    cv2.drawContours(raw_vis_map, [verts], -1, 255, -1)
    cv2.drawContours(raw_vis_map, [verts], -1, 0, 1)
    # Save map
    if not os.path.exists(save_path + "/raw_vis"):
        os.mkdir(save_path + "/raw_vis")
    cv2.imwrite(save_path + "/raw_vis/" + file_name + '.png', raw_vis_map)
    ######################################
    raw_map = np.zeros((y_max - y_min + border_pad * 2,
                        x_max - x_min + border_pad * 2))
    cv2.drawContours(raw_map, [verts], -1, 1, -1)
    cv2.drawContours(raw_map, [verts], -1, 2, 1)
    # Save map
    if not os.path.exists(save_path + "/raw"):
        os.mkdir(save_path + "/raw")
    cv2.imwrite(save_path + "/raw/" + file_name + '.png', raw_map)
    ######################################
    seg_map = np.zeros((y_max - y_min + border_pad * 2,
                        x_max - x_min + border_pad * 2))

    cv2.drawContours(seg_map, [verts], -1, 1, -1)
    cv2.drawContours(seg_map, [verts], -1, 2, 1)

    for room_cate in json_data['room_category']:
        room_id = _get_room_tp_id(room_cate)
        for box in json_data['room_category'][room_cate]:
            x0 = int(box[0]*meter2pixel)+border_pad-x_min
            y0 = int(box[1]*meter2pixel)+border_pad-y_min
            x1 = int(box[2]*meter2pixel)+border_pad-x_min
            y1 = int(box[3]*meter2pixel)+border_pad-y_min
            tmp_map = np.zeros(seg_map.shape)
            tmp_map[y0:y1, x0:x1] = 1
            seg_map[np.where((seg_map!=0)*(seg_map!=2)*(tmp_map==1))] = room_id

    # Save map
    if not os.path.exists(save_path + "/seg"):
        os.mkdir(save_path + "/seg")
    cv2.imwrite(save_path + "/seg/" + file_name + '.png', seg_map)
    ######################################
    inp_map = np.zeros((y_max - y_min + border_pad * 2,
                        x_max - x_min + border_pad * 2)).astype(np.uint8)

    cv2.drawContours(inp_map, [verts], -1, 1, -1)
    cv2.drawContours(inp_map, [verts], -1, 2, 1)

    # for room_cate in json_data['room_category']:
    #     room_id = _get_room_tp_id(room_cate)
    #     if room_id not in [4,5,6,9,8]:
    #         for box in json_data['room_category'][room_cate]:
    #             x0 = int(box[0]*meter2pixel)+border_pad-x_min
    #             y0 = int(box[1]*meter2pixel)+border_pad-y_min
    #             x1 = int(box[2]*meter2pixel)+border_pad-x_min
    #             y1 = int(box[3]*meter2pixel)+border_pad-y_min
    #             tmp_map = np.zeros(inp_map.shape)
    #             tmp_map[y0:y1, x0:x1] = 1
    #             inp_map[np.where((inp_map!=0)*(inp_map!=2)*(tmp_map==1))] = room_id

    for room_cate in json_data['room_category']:
        room_id = _get_room_tp_id(room_cate)
        # if room_id in [4,5,6,9,8]:
            # add
        # if room_id == 8:
        #     idx = np.random.randint(len(beds_pixels))
        #     scale_pixels = beds_pixels
        # else:
        idx = np.random.randint(len(barriers_pixels))
        scale_pixels = barriers_pixels
        for box in json_data['room_category'][room_cate]:
            x0 = int(box[0]*meter2pixel)+border_pad-x_min
            y0 = int(box[1]*meter2pixel)+border_pad-y_min
            x1 = int(box[2]*meter2pixel)+border_pad-x_min
            y1 = int(box[3]*meter2pixel)+border_pad-y_min
            try:
                tmp_map = np.zeros(inp_map.shape)
                tmp_map[y0:y1, x0:x1] = 1
                y_array, x_array = np.where((inp_map!=0)*(tmp_map==1))
                x00_lim = x_array.min()
                x11_lim = x_array.max()
                y00_lim = y_array.min()
                y11_lim = y_array.max()

                if np.random.randn()<0:
                    # bed ver
                    bed_w = scale_pixels[idx][0]
                    bed_h = scale_pixels[idx][1]
                else:
                    # bed hor
                    bed_w = scale_pixels[idx][1]
                    bed_h = scale_pixels[idx][0]
                # case = np.random.randint(4)
                add_bed_flag = False
                if not add_bed_flag:
                    x00 = x00_lim+np.random.randint(x11_lim-x00_lim-bed_h)
                    y00 = y00_lim
                    x11 = x00+bed_h
                    y11 = y00+bed_w
                    if (inp_map[y00:y11, x00:x11] != 0).all():
                        inp_map[y00-1:y11+1, x00-1:x11+1] = 19
                        add_bed_flag = True
                if not add_bed_flag:
                    x00 = x00_lim
                    y00 = y00_lim+np.random.randint(y11_lim-y00_lim-bed_w)
                    x11 = x00+bed_h
                    y11 = y00+bed_w
                    if ((inp_map[y00:y11, x00:x11] != 0) * \
                    (inp_map[y00:y11, x00:x11] != 2)).all():
                        inp_map[y00-1:y11+1, x00-1:x11+1] = 19
                        add_bed_flag = True
                if not add_bed_flag:
                    x11 = x11_lim-np.random.randint(x11_lim-x00_lim-bed_h)
                    y11 = y11_lim
                    x00 = x11-bed_h
                    y00 = y11-bed_w
                    if (inp_map[y00:y11, x00:x11] != 0).all():
                        inp_map[y00-1:y11+1, x00-1:x11+1] = 19
                        add_bed_flag = True
                if not add_bed_flag:
                    x11 = x11_lim
                    y11 = y11_lim-np.random.randint(y11_lim-y00_lim-bed_w)
                    x00 = x11-bed_h
                    y00 = y11-bed_w
                    if (inp_map[y00:y11, x00:x11] != 0).all():
                        inp_map[y00-1:y11+1, x00-1:x11+1] = 19
                        add_bed_flag = True

                if add_bed_flag:
                    # if room_id == 8:
                        # print("=============== add bed: {}".format(file_name))
                    # else:
                    print("=============== add barry: {}".format(file_name))
                    # print(x00, y00, x11, y11)
                    # print(case)
                    # print(bed_h, bed_w)
                    # print(x0, y0, x1, y1)
            except:
                pass

            tmp_map = np.zeros(inp_map.shape)
            tmp_map[y0:y1, x0:x1] = 1
            inp_map[np.where((inp_map!=19)*(inp_map!=0)*(inp_map!=2)*(tmp_map==1))] = room_id
            inp_map[np.where(inp_map==19)] = 0

    inp_map = (inp_map != 0).astype(np.uint8)
    contours, hierarchy = cv2.findContours(inp_map, 2, 1)
    cv2.drawContours(inp_map, contours, -1, 2)
    x_boundary, y_boundary = np.where(inp_map == 2)
    abandoned_boundary_idx = np.random.random(x_boundary.shape)<0.1
    x_boundary = x_boundary[abandoned_boundary_idx]
    y_boundary = y_boundary[abandoned_boundary_idx]
    inp_map[(x_boundary,y_boundary)] = 0
    x_boundary, y_boundary = np.where(inp_map == 2)
    abandoned_boundary_idx = np.random.random(x_boundary.shape)<0.1
    x_boundary = x_boundary[abandoned_boundary_idx]
    y_boundary = y_boundary[abandoned_boundary_idx]
    inp_map[(x_boundary,y_boundary)] = 1

    inp = np.zeros((height, width)).astype(np.uint8)
    inp[(height-inp_map.shape[0])//2:(height-inp_map.shape[0])//2+inp_map.shape[0],\
         (width-inp_map.shape[1])//2:(width-inp_map.shape[1])//2+inp_map.shape[1]] = inp_map

    tar = np.zeros((height, width)).astype(np.uint8)
    tar[(height-raw_map.shape[0])//2:(height-raw_map.shape[0])//2+raw_map.shape[0],\
         (width-raw_map.shape[1])//2:(width-raw_map.shape[1])//2+raw_map.shape[1]] = raw_map

    # freespace enhance
    dot_num = 100
    cnt = 0
    cnt2 = 0

    bx1 = int(0.95*width)
    by1 = int(0.95*height)
    bx0 = int(0.05*width)
    by0 = int(0.05*height)

    for _ in range(2500):
        randcoinf = np.random.random()
        if randcoinf<0.01:
            x,y = np.random.rand(2)
            x = int(x*height)
            y = int(y*width)
            w = np.random.randint(2,10)
            h = np.random.randint(2,10)
            x = max(min(x, bx1), bx0)
            y = max(min(y, by1), by0)
            # if np.unique(inp[x-h//2:x+h//2, y-h//2:y+h//2]).shape[0]>1:
            if inp[x,y] in [1,2]:
                inp[x-w//2:x+w//2,y-h//2:y+h//2] = np.zeros((w//2*2,h//2*2))
        elif randcoinf<0.1:
            x,y = np.random.rand(2)
            x = int(x*height)
            y = int(y*width)
            w = np.random.randint(2,5)
            h = np.random.randint(2,5)
            x = max(min(x, bx1), bx0)
            y = max(min(y, by1), by0)
            # if np.unique(inp[x-h//2:x+h//2, y-h//2:y+h//2]).shape[0]>1:
            if inp[x,y] in [1,2]:
                inp[x-w//2:x+w//2,y-h//2:y+h//2] = np.ones((w//2*2,h//2*2))*2
        else:
            x,y = np.random.rand(2)
            x = int(x*height)
            y = int(y*width)
            w = np.random.randint(2,5)
            h = np.random.randint(2,5)
            x = max(min(x, bx1), bx0)
            y = max(min(y, by1), by0)
            if np.unique(inp[x-h//2:x+h//2, y-h//2:y+h//2]).shape[0]>1:
            # if inp[x,y] in [1,2]:
                inp[x-w//2:x+w//2,y-h//2:y+h//2] = np.ones((w//2*2,h//2*2))*2

    for _ in range(dot_num):
        x,y = np.random.rand(2)
        x = int(x*height)
        y = int(y*width)
        if inp[x,y] == 2:
            w = np.random.randint(2,5)
            h = np.random.randint(2,5)
            random_num = np.random.rand()
            if random_num<0.8:
                inp[x-w//2:x+w//2,y-h//2:y+h//2] = np.ones((width,height))[x-w//2:x+w//2,y-h//2:y+h//2]*2
            elif random_num<0.9:
                inp[x-w*2:x+w*2,y-h*2:y+h*2] = np.ones((width,height))[x-w*2:x+w*2,y-h*2:y+h*2]*1
            else:
                inp[x-w*2:x+w*2,y-h*2:y+h*2] = np.zeros((width,height))[x-w*2:x+w*2,y-h*2:y+h*2]

        if inp[x,y] == 1:
            if cnt <20:
                if cnt2 < 10:
                    cnt2 += 1
                    w = np.random.randint(1,5)
                    h = np.random.randint(1,5)
                    inp[x-w//2:x+w//2,y-h//2:y+h//2] = np.zeros((width,height))[x-w//2:x+w//2,y-h//2:y+h//2]
                else:
                    cnt += 1
                    w = np.random.randint(1,3)
                    h = np.random.randint(1,3)
                    inp[x-w//2:x+w//2,y-h//2:y+h//2] = np.ones((width,height))[x-w//2:x+w//2,y-h//2:y+h//2]*2
    #             else:
    #                 inp[x,y] = 0
    image =  Image.fromarray(inp.copy())
    draw = ImageDraw.Draw(image)

    #     绘制飞线
    rect_num = 10
    for i in range(rect_num):
        darw_poly(draw, height, width, 1, inp, 50)
    inp = np.array(image)

    inp_map = np.concatenate([tar, inp], 1)

    inp_map[np.where(inp_map==0)] = 127
    inp_map[np.where(inp_map==1)] = 255
    inp_map[np.where(inp_map==2)] = 0

    # Save map
    if not os.path.exists(save_path + "/inp"):
        os.mkdir(save_path + "/inp")
    cv2.imwrite(save_path + "/inp/" + file_name + '.png', inp_map)
    #####################################

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Visualize the subset of maps in .png.")
    parser.add_argument("map_id_set_file", help="map id set (.txt)")
    parser.add_argument("--json_path", type=str, default="./HouseExpo/json/", help="json file path")
    parser.add_argument("--save_path", type=str, default='./png')
    result = parser.parse_args()

    json_path = os.path.abspath(os.path.join(os.getcwd(), result.json_path))
    map_file = os.path.abspath(os.path.join(os.getcwd(), result.map_id_set_file))
    save_path = os.path.abspath(os.path.join(os.getcwd(), result.save_path))
    print("---------------------------------------------------------------------")
    print("|map id set file path        |{}".format(map_file))
    print("---------------------------------------------------------------------")
    print("|json file path              |{}".format(json_path))
    print("---------------------------------------------------------------------")
    print("|Save path                   | {}".format(save_path))
    print("---------------------------------------------------------------------")

    map_ids = np.loadtxt(map_file, str)

    for map_id in map_ids:
        draw_map(map_id, json_path, save_path)

    print("Successfully draw the maps into {}.".format(save_path))


import os
import requests

def run_query(query, variables):
    body = {
        'query': query,
        'variables': variables
    }
    response = _make_post_call(body)
    if response.get('data') is not None:
        return response.get('data')
    raise RuntimeError('query failed: ' + str(response))

def _make_post_call(body):
    url = os.environ['HASURA_GRAPHQL_ENDPOINT']
    headers = {
        'Content-type': 'application/json',
        'x-hasura-admin-secret': os.environ['HASURA_ADMIN_SECRET']
    }
    print("HASURA_CLIENT_POST_CALL")
    print("URL : " + url)
    print("BODY : " + str(body))
    response = requests.post(url, json=body, headers=headers, timeout=10)
    print("RESPONSE : " + str(response.json()))
    return response.json()