#! python3
# -*- coding: utf-8 -*-
"""Excel_Control: Core excel functionality

The meat of the program. This is very specific to the template.xlsx file and the
current (June 22, 2017) version of GEMS' output (our input) file.

"""
import os
import shutil
import math
import openpyxl
from glob import iglob
from datetime import datetime
import sys

import src
import src.config.index as excel_rows
import src.utils as utils

'''
Entry point to this file is below the Excel_Control class
'''

class Excel_Control(object):

    def __init__(self):
        """Constructor for the excel_control object

        NOTE: input automates to the newest created/modified .xls(x) file
        """

        # Catches an exception thrown from max() when it has no input
        try:
            self.input_path = max(iglob(os.path.join(src.args.input_dir, '*.xls*')),
                                  key=os.path.getctime)
        except:
            input('Failed to run: No files in input directory. <Press enter to exit>')
            sys.exit()

        self.output_path = os.path.join(src.args.output_dir,
                                        (src.args.output_name + '.xlsx'))
        self.template    = src.args.template
        self.input_file  = self.__get_input_file()
        self.output_file = self.__get_output_file()
        self.backup_dir  = src.args.backup_dir if src.args.backup else None
        self.index       = excel_rows.Index()

    def __get_input_file(self):
        """Private method: get_input_file
        """
        # if the input file is .xls, we convert it to .xlsx
        if self.input_path.endswith('s'):
            try:
                ret = utils.convert_xls(self.input_path)
                self.input_path += 'x'
                return ret
            except ValueError as err:
                sys.exit('Your input path is incorrectly formatted:', err)

        else:
            # returns an open excel workbook
            return openpyxl.load_workbook(self.input_path)

    def __get_output_file(self):
        """Private method: get_output_file
        """
        # Copies the template to the output path
        shutil.copy(self.template, self.output_path)
        #returns an open excel workbook
        return openpyxl.load_workbook(self.output_path)

    def __get_build_date(self, in_sheet):
        r = 2
        curr_date = in_sheet.cell(row=r, column=4).value
        while not curr_date:
            r += 1
            curr_date = in_sheet.cell(row=r, column=4).value

        start_day = (in_sheet.cell(row=r, column=4).value).day
        curr_day = (in_sheet.cell(row=r, column=4).value).day
        build_date = (in_sheet.cell(row=r, column=4).value)

        for i in range(r, 92):
            if not (in_sheet.cell(row=r, column=4).value):
                continue

            start_day = (in_sheet.cell(row=r, column=4).value).day

            if start_day == curr_day:
                continue

            if start_day < curr_day:
                break

            if start_day > curr_day:
                build_date = (in_sheet.cell(row=r, column=4).value)
                break

        return build_date

    def populate(self):
        """Populate: Populates the excel template with data

        This is VERY specific to the template bundled in with the program

        Changing templates will involve manipulating source code directly.
        """
        # We're really only working with the first ('active') excel sheet
        in_sheet = self.input_file.active
        out_sheet = self.output_file.active

        # Check that the input sheet is populated:
        if in_sheet.max_row == 1:
            input("ERROR: Input sheet is empty. <Press enter to exit>")
            sys.exit(1)

        build_date = self.__get_build_date(in_sheet)
        out_sheet.cell(row=5, column=1).value = build_date.strftime('%m/%d/%Y')

        # this runs for each row in the input file, except the first,
        # which is the column titles

        for i in range(2, in_sheet.max_row+1):
            # the country is column 2, and we're sanitizing it so all spaces and
            # periods are removed. This corresponds to an index in our dictionary
            # (./src/config/index.py)
            country = in_sheet.cell(row=i, column=2).value
            country = country.replace(' ', '_').replace('.', '')

            # same idea for the task
            task = in_sheet.cell(row=i, column=3).value
            task = task.replace(' ', '_').replace('-', '_')
            # we're storing the time to make the next few lines more readable
            tmp = in_sheet.cell(row=i, column=4).value
            # two possible cases for the time--a datetime object or nothing
            # if it's nothing, start_time will be an empty string
            start_time = tmp if type(tmp) is datetime else ''

            tmp = in_sheet.cell(row=i, column=5).value
            end_time = tmp if type(tmp) is datetime else ''

            # if we have both a start and end time,
            # calculate the difference in minutes. We could also grab that from
            # the input file, but it often seems to be inaccurate, so we'll just
            # do it ourselves. If there is an issue calculating the time, advise
            # the operator to check the start/end times.
            if end_time and not start_time:
                elapsed = 'VERIFY START TIME'

            elif start_time and not end_time:
                elapsed = 'VERIFY END TIME'

            elif start_time and end_time:
                elapsed = (end_time - start_time).total_seconds()
                elapsed = math.ceil(elapsed / 60)
                if (elapsed > 1400) or (elapsed < 0):
                    elapsed = 'CHECK START/END DATE'
            else:
                elapsed = ''

            # Now we'll convert our datetime objects to formatted strings
            start_time = start_time.strftime('%H:%M') \
                         if type(start_time) is datetime else ''

            end_time = end_time.strftime('%H:%M') \
                       if type(end_time) is datetime else ''

            # these next few lines may need reworking

            # this retrieves the appropriate dictionary of excel rows for the
            # specific task from our index object
            try:
                task_rows = getattr(self.index, task)
            except:
                continue

            # we then grab the row specific to the country we're working on
            r = task_rows[country]

            # now we know what row we need, and the columns never change, so
            # we can put our data in the right place in our output file:

            out_sheet.cell(row=r, column=3).value = start_time
            out_sheet.cell(row=r, column=4).value = end_time
            out_sheet.cell(row=r, column=5).value = elapsed

            # and then we repeat for the next row

    # and that's all the formatting that needs to be done!

    def backup(self):
        """Creates a backup of files in the specified backup directory. """
        # get the input directory from it's path
        input_dir = os.path.dirname(self.input_path)

        # grab all the files in ./Runtime/Input..
        files = os.listdir(input_dir)
        for item in files:
            # ..and then copy them to the backup directory
            item_path = os.path.join(input_dir, item)
            shutil.copy(item_path, self.backup_dir)

    def save(self):
        """Cleans and saves data"""

        input_dir = os.path.dirname(self.input_path)
        # get all files in the input directory
        files = os.listdir(input_dir)
        for item in files:
            item_path = os.path.join(input_dir, item)
            # and delete them
            os.unlink(item_path)

        self.output_file.save(self.output_path)

        # if we're running in quick mode, don't open the excel file at the end
        if (src.args.quick):
            return

        # We're all done--open the file
        cmd = "start excel.exe \"" + self.output_path+"\""
        os.system(cmd)

# entry point to this file
def start():
    control = Excel_Control()
    control.populate()
    if (src.args.backup):
        control.backup()
    control.save()


import asyncio
from unittest.mock import Mock

from ext.telegram.bot import TelegramBot, TelegramBotCommand

def test_create_bot_instance():
    bot = TelegramBot('token', 'test_bot')
    assert bot.api
    assert bot.logger
    assert bot.url == 'https://telegram.me/test_bot'
    assert bot.name == 'test_bot'
    assert not list(bot.commands)

def test_add_bot_command():

    class CmdFoo(TelegramBotCommand):
        name = 'foo'

    bot = TelegramBot('token', 'bot_name')
    bot.add_command(CmdFoo)
    commands = list(bot.commands)
    assert len(commands) == 1
    assert commands[0] == 'foo'

def test_execute_bot_command():
    mock = Mock()

    class TestHelpCommand(TelegramBotCommand):
        name = 'help'

        async def execute(self, message):
            mock()

    bot = TelegramBot('token', 'bot_name')
    bot.add_command(TestHelpCommand)
    update = {
        'message': {
            'text': '/help',
            'message_id': 2666,
            'date': 1465764948,
            'chat': {
                'id': 425606,
                'username': 'djudman',
                'last_name': 'Dorofeev',
                'type': 'private',
                'first_name': 'Dmitry'
            },
            'entities': [
                {
                    'offset': 0,
                    'length': 5,
                    'type': 'bot_command'
                }
            ],
            'from': {
                'id': 425606,
                'username': 'djudman',
                'last_name': 'Dorofeev',
                'first_name': 'Dmitry'
            }
        },
        'update_id': 84506398
    }
    loop = asyncio.get_event_loop()
    loop.run_until_complete(bot.handle_update(update))
    mock.assert_called_once_with()

def test_on_text_callback():
    mock = Mock()

    class MyBot(TelegramBot):
        async def on_text(self, message):
            mock()

    bot = MyBot('token', 'test_bot')
    update = {
        'message': {
            'chat': {
                'id': 425606,
                'username': 'djudman',
                'last_name': 'Dorofeev',
                'type': 'private',
                'first_name': 'Dmitry'
            },
            'text': 'test text',
            'from': {
                'id': 425606,
                'username': 'djudman',
                'last_name': 'Dorofeev',
                'first_name': 'Dmitry'
            },
            'date': 1465821925,
            'message_id': 2668
        },
        'update_id': 84506399
    }
    loop = asyncio.get_event_loop()
    loop.run_until_complete(bot.handle_update(update))
    mock.assert_called_once_with()


from app.utils import helper
from app.mac import mac
from app.utils import helper
import dateparser
from modules.kalender import dbCore
import datetime, time

commands = ["!termin", "!notiz", "!hilfe", "!settings", "!show"]
termine = []
notizen = []
text = ""
dateNow = datetime.datetime.now()
global db
db = dbCore.db()
class Kalender(object):
    pass

def handle_command(message):
    try:
        command, text = message.text.split(" ", 1)
        command = command.lower()
    except:
        command = message.text.lower()
        text = ""
    if command in commands:
        command = int(commands.index(command)) + 1
        if command == 1: #termine
            handle_termin(message, text)
        elif command == 2: #notizen
            handle_notiz(message, text)
        elif command == 3: #help
            handle_help(message, text)
        elif command == 4:
            handle_settings(message, text)
        elif command == 5:
            handle_show(message, text)
        else:
            handle_help(message, text)

def handle_termin(message, text):
    #try:
    answer = handle_date(text)
    mac.send_message(answer, message.conversation)
    termine.append(text + "\n")
    nachricht = getNachricht(text)
    date, nachricht = text.split(";", 1)
    finalDate = dateparser.parse(date, settings={'PREFER_DATES_FROM': 'future', 'PREFER_DAY_OF_MONTH': 'first', 'DATE_ORDER': 'DMY'}, locales=["de"])

    if finalDate.hour == 0 and finalDate.minute == 0:
        try:
            standardTime = db.getStandardTime(str(message.conversation))
            print("Found a StandardTime!")
        except:
            #db.createSettings(str(message.conversation))
            standardTime = db.getStandardTimeDefault()
            print("Used Default StandardTime!")
        hour, minute = standardTime.split(":", 1)
        finalDate = finalDate.replace(hour=int(hour), minute=int(minute))

    db.addEntry(date=finalDate, text=nachricht, message=str(message.conversation))
    print(db.printAllDirectly())
    #searchRemind()
    #except:
    #   answer = "Fehler: Bitte geben sie ihre Anfrage in diesem Format an: !termin dd-mm-yyyy [mm:hh];*name*"
    #   mac.send_message(answer, message.conversation)
def dbArrToStr(dbArray):
    outputStr = ""
    for i in range(len(dbArray)):
        outputStr = outputStr + "Erinnerung: " + str(dbArray[i][3]) + " " + str(dbArray[i][4])+ " ID: " + str(dbArray[i][6])
        if not i == (len(dbArray) - 1):
            outputStr += "\n"
    return outputStr

def handle_notiz(message, text):
    if "showall" in text.lower():
        answer = ''.join(notizen)
        mac.send_message(answer, message.conversation)
    else:
        notizen.append(text + "\n")

def handle_date(text):
    date, nachricht = text.split(";", 1)
    finalDate = dateparser.parse(date, settings={'PREFER_DATES_FROM': 'future', 'PREFER_DAY_OF_MONTH': 'first', 'DATE_ORDER': 'DMY'}, locales=["de"])
    return "Datum: " + str(finalDate.day) + "-" + str(finalDate.month) + "-" + str(finalDate.year)

def getDate(text):
    date, nachricht = text.split(";", 1)
    return date

def getNachricht(text):
    date, nachricht = text.split(";", 1)
    return nachricht

def searchRemind():
    output = db.getAllRoot()
    now = datetime.datetime.now()
    for i in range(len(output)):
        dateObj = datetime.datetime.strptime(output[i][3], '%d-%m-%Y %H:%M')
        if dateObj <= now:
            print(str(dateObj))
            print(str(now))
            id = output[i][6]
            remindTermin(id)
            db.deleteEntry(id)

def searchRemindThread():
    db2 = dbCore.db()
    output = db2.getAllRoot()
    now = datetime.datetime.now()
    for i in range(len(output)):
        dateObj = datetime.datetime.strptime(output[i][3], '%d-%m-%Y %H:%M')
        if dateObj <= now:
            print(str(dateObj))
            print(str(now))
            id = output[i][6]
            remindTerminThread(id, db2)
            db2.deleteEntry(id)
def remindTerminThread(id, db2):
    reqObj = db2.getTermin(id)
    answer = "Erinnerung Termin: " + reqObj.dateAndTime + " " + reqObj.message
    mac.send_message(answer, reqObj.author)
    print("Reminder verschickt!")

def remindTermin(id):
    reqObj = db.getTermin(id)
    answer = "Erinnerung Termin: " + reqObj.dateAndTime + " " + reqObj.message
    mac.send_message(answer, reqObj.author)
    print("Reminder verschickt!")

def searchAlarmThread():
    db2 = dbCore.db()
    now = datetime.datetime.today()
    alarmArr = db2.getAllAlarmSettings()
    for i in range(len(alarmArr)):
        print (str(alarmArr[i]))
        alarmTest = datetime.datetime.strptime(alarmArr[i][0], "%H:%M")
        timeNow = int(str(now.hour)) * 60 * 60 + int(str(now.minute)) * 60
        timeCompare = int(str(alarmTest.hour)) * 60 * 60 + int(str(alarmTest.minute)) * 60
        print(alarmTest)
        timeDifference = timeNow - timeCompare
        if alarmTest.time() == now.time() or (timeDifference <= 600 and timeDifference > 0):
            db2.getLastAlarm()
            testTime = db2.getAlarmTime(alarmArr[i][1])
            print(testTime)
            db2Array = db2.getAllByDay(alarmArr[i][1], timeToIntegerNow())
            answer = dbArrToStr(db2Array)
            if answer:
                pass
            else:
                answer = "Heute gibt es keine Termine!"
            mac.send_message(answer, alarmArr[i][1])

def handle_help(message, text):
    help_text = """Momentane Aktionen möglich:
                    !termin dd-mm-yyyy [mm:hh];*name*
                    !show heute;morgen;woche;monat
                    !settings
                    !help"""
    mac.send_message(help_text, message.conversation)

def timeToIntegerNow():
    return int(str(dateNow.year) + str(dateNow.month) + str(dateNow.day))

def timeToInteger(dateReq):
    return int(str(dateReq.year) + str(dateReq.month) + str(dateReq.day))

def handle_show(message, text):
    if "showall" in text.lower():
        dbArray = db.getAllUser(str(message.conversation))
        answer = dbArrToStr(dbArray)

    elif "heute" in text.lower():
        dbArray = db.getAllByDay(str(message.conversation), timeToIntegerNow())
        answer = dbArrToStr(dbArray)

    elif "morgen" in text.lower():
        dateReq = datetime.date.today() + datetime.timedelta(days=1)
        dbArray = db.getAllByDay(str(message.conversation), timeToInteger(dateReq))
        answer = dbArrToStr(dbArray)

    elif "woche" in text.lower():
        dateReq1 = datetime.datetime.now()
        dateReq2 = datetime.date.today() + datetime.timedelta(days=7)
        dbArray = db.getAllByDays(str(message.conversation), timeToInteger(dateReq1), timeToInteger(dateReq2))
        answer = dbArrToStr(dbArray)

    elif "monat" in text.lower():
        dateReq1 = datetime.datetime.now()
        dateReq2 = datetime.date.today() + datetime.timedelta(days=30)
        dbArray = db.getAllByDays(str(message.conversation), timeToInteger(dateReq1), timeToInteger(dateReq2))
        answer = dbArrToStr(dbArray)
    else:
        answer = """Befehl nicht gefunden!
                    !show heute;morgen;woche;monat"""
    if answer:
        mac.send_message(answer, message.conversation)
    else:
        answer = "Keine Termine für diese Zeit."
        mac.send_message(answer, message.conversation)

def handle_settings(message, text):
    userSettings = db.getUserSettings()


from settings import cms_detect_api

import requests

def cms_detect(domain, port):
    if not cms_detect_api:
        print("[-]Нет ключа `cms_detect_api` (в settings.py)!")
        return
    payload = {'key': cms_detect_api, 'url': domain}
    cms_url = "https://whatcms.org/APIEndpoint/Detect"
    response = requests.get(cms_url, params=payload)
    cms_data = response.json()
    cms_info = cms_data['result']
    if cms_info['code'] == 200:
        print(f'Detected CMS     : {cms_info["name"]}')
        print(f'Detected Version : {cms_info["version"]}')
        print(f'Confidence       : {cms_info["confidence"]}')
    else:
        print(cms_info['msg'])
        print(f'Detected CMS : {cms_info["name"]}')
        print(f'Detected Version : {cms_info["version"]}')


# -*- mode: python; coding: utf-8 -*-
# Copyright 2020 the AAS WorldWide Telescope project
# Licensed under the MIT License.

"""
Support for loading images from a Djangoplicity database.
"""

__all__ = """
DjangoplicityImageSource
DjangoplicityCandidateInput
""".split()

import codecs
from contextlib import contextmanager
from datetime import datetime, timezone
import functools
import html
import json
import numpy as np
import os.path
import requests
import shutil
from urllib.parse import urljoin, quote as urlquote
import yaml

from ..image import ImageLoader
from . import CandidateInput, ImageSource, NotActionableError

class DjangoplicityImageSource(ImageSource):
    """
    An ImageSource that obtains its inputs from a query to a Djangoplicity website.
    """

    _base_url = None
    _channel_name = None
    _search_page_name = None
    _force_insecure_tls = True  # TODO: migrate to False

    @classmethod
    def get_config_key(cls):
        return "djangoplicity"

    @classmethod
    def deserialize(cls, data):
        inst = cls()
        inst._base_url = data["base_url"]
        inst._channel_name = data["channel_name"]
        inst._search_page_name = data.get("search_page_name", "page")
        inst._force_insecure_tls = data.get(
            "force_insecure_tls", True
        )  # TODO: migrate to false
        return inst

    @contextmanager
    def make_request(self, url, stream=False, none404=False):
        """force_insecure_tls is for noirlab.edu"""

        with requests.get(
            url, stream=stream, verify=not self._force_insecure_tls
        ) as resp:
            if none404 and resp.status_code == 404:
                yield None
                return

            if not resp.ok:
                raise Exception(f"error fetching url `{url}`: {resp.status_code}")

            if stream:
                # By default, `resp.raw` does not perform content decoding.
                # eso.org gives us gzipped content. The following bit is
                # apparently the preferred workaround. Cf:
                # https://github.com/psf/requests/issues/2155
                #
                # A side effect of the content decoding, however, is that the
                # first read of the stream can return a zero-length string,
                # which causes `readlines` iteration to exit. Callers must be
                # prepared to handle this.
                resp.raw.decode_content = True

            yield resp

    def query_candidates(self):
        page_num = 1

        while True:
            url = (
                self._base_url
                + f"archive/search/{self._search_page_name}/{page_num}/?type=Observation"
            )
            print(f"requesting {url} ...")

            with self.make_request(url, stream=True, none404=True) as resp:
                if resp is None:
                    break  # got a 404 -- all done

                text_stream = codecs.getreader("utf8")(resp.raw)
                json_lines = []

                # Cf. stream=True in make_request -- skip the zero-length result
                # to prevent readlines iteration from exiting early. This is
                # definitely OK since our `var images` line won't be the first
                # line.
                text_stream.readline()

                for line in text_stream:
                    if not len(json_lines):
                        if "var images = [" in line:
                            json_lines.append("[")
                    elif "];" in line:
                        json_lines.append("]")
                        break
                    else:
                        json_lines.append(line)

            if not len(json_lines):
                raise Exception(
                    f'error processing url {url}: no "var images" data found'
                )

            # This is really a JS literal, but YAML is compatible enough.
            # JSON does *not* work because the dict keys here aren't quoted.
            data = yaml.safe_load("".join(json_lines))

            for item in data:
                yield DjangoplicityCandidateInput(item)

            page_num += 1

    def fetch_candidate(self, unique_id, cand_data_stream, cachedir):
        url = self._base_url + urlquote(unique_id) + "/api/json/"

        with self.make_request(url) as resp:
            info = json.loads(resp.content)

        # Find the "fullsize original" image URL

        fullsize_url = None

        for resource in info["Resources"]:
            if resource.get("ResourceType") == "Original":
                fullsize_url = resource["URL"]
                break

        if fullsize_url is None:
            raise Exception(
                f'error processing {unique_id}: can\'t identify "fullsize original" image URL'
            )

        ext = fullsize_url.rsplit(".", 1)[-1].lower()
        info["toasty_image_extension"] = ext

        # Validate that there's actually WCS we can use

        if not isinstance(info.get("Spatial.CoordsystemProjection", None), str):
            raise NotActionableError("image does not have full WCS")

        # Download it

        with self.make_request(fullsize_url, stream=True) as resp:
            with open(os.path.join(cachedir, "image." + ext), "wb") as f:
                shutil.copyfileobj(resp.raw, f)

        with open(os.path.join(cachedir, "metadata.json"), "wt", encoding="utf8") as f:
            json.dump(info, f, ensure_ascii=False, indent=2)

    def process(self, unique_id, cand_data_stream, cachedir, builder):
        # Set up the metadata.

        with open(os.path.join(cachedir, "metadata.json"), "rt", encoding="utf8") as f:
            info = json.load(f)

        img_path = os.path.join(cachedir, "image." + info["toasty_image_extension"])
        md = DjangoplicityMetadata(info)

        # Load up the image.

        img = ImageLoader().load_path(img_path)

        # Do the processing.

        builder.tile_base_as_study(img)
        builder.make_thumbnail_from_other(img)

        builder.imgset.set_position_from_wcs(
            md.as_wcs_headers(img.width, img.height),
            img.width,
            img.height,
            place=builder.place,
        )

        builder.set_name(info["Title"])
        builder.imgset.credits_url = info["ReferenceURL"]
        builder.imgset.credits = html.escape(info["Credit"])
        builder.place.description = html.escape(info["Description"])

        # Annotation metadata

        pub_dt = datetime.fromisoformat(info["Date"])
        if pub_dt.tzinfo is None:
            pub_dt = pub_dt.replace(tzinfo=timezone.utc)

        amd = {
            "channel": self._channel_name,
            "itemid": unique_id,
            "publishedUTCISO8601": pub_dt.isoformat(),
        }
        builder.place.annotation = json.dumps(amd)

        # Finally, crunch the rest of the pyramid.

        builder.cascade()

class DjangoplicityCandidateInput(CandidateInput):
    """
    A CandidateInput obtained from an AstroPix query.
    """

    def __init__(self, info):
        self._info = info

    def get_unique_id(self):
        return self._info["id"]

    def save(self, stream):
        with codecs.getwriter("utf8")(stream) as text_stream:
            json.dump(self._info, text_stream, ensure_ascii=False, indent=2)

class DjangoplicityMetadata(object):
    metadata = None

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

    def as_wcs_headers(self, width, height):
        """
        The metadata here are essentially AVM headers. As described in
        `Builder.apply_avm_info()`, the data that we've seen in the wild are a
        bit wonky with regards to parity: the metadata essentially correspond to
        FITS-like parity, and we need to flip them to JPEG-like parity. See also
        very similar code in `astropix.py`.
        """
        headers = {}

        # headers['RADECSYS'] = self.wcs_coordinate_frame  # causes Astropy warnings
        headers["CTYPE1"] = "RA---" + self.metadata["Spatial.CoordsystemProjection"]
        headers["CTYPE2"] = "DEC--" + self.metadata["Spatial.CoordsystemProjection"]
        headers["CRVAL1"] = float(self.metadata["Spatial.ReferenceValue"][0])
        headers["CRVAL2"] = float(self.metadata["Spatial.ReferenceValue"][1])

        # See Calabretta & Greisen (2002; DOI:10.1051/0004-6361:20021327), eqn 186
        crot = np.cos(float(self.metadata["Spatial.Rotation"]) * np.pi / 180)
        srot = np.sin(float(self.metadata["Spatial.Rotation"]) * np.pi / 180)
        scale0 = float(self.metadata["Spatial.Scale"][0])

        # Seen in noao-02274; guessing how to handle this
        if not self.metadata["Spatial.Scale"][1]:
            scale1 = np.abs(scale0)
        else:
            scale1 = float(self.metadata["Spatial.Scale"][1])

        lam = scale1 / scale0

        pc1_1 = crot
        pc1_2 = -lam * srot
        pc2_1 = srot / lam
        pc2_2 = crot

        # If we couldn't get the original image, the pixel density used for
        # the WCS parameters may not match the image resolution that we have
        # available. In such cases, we need to remap the pixel-related
        # headers. From the available examples, `wcs_reference_pixel` seems to
        # be 1-based in the same way that `CRPIXn` are. Since in FITS, integer
        # pixel values correspond to the center of each pixel box, a CRPIXn of
        # [0.5, 0.5] (the lower-left corner) should not vary with the image
        # resolution. A CRPIXn of [W + 0.5, H + 0.5] (the upper-right corner)
        # should map to [W' + 0.5, H' + 0.5] (where the primed quantities are
        # the new width and height).

        factor0 = width / float(self.metadata["Spatial.ReferenceDimension"][0])
        factor1 = height / float(self.metadata["Spatial.ReferenceDimension"][1])

        headers["CRPIX1"] = (
            float(self.metadata["Spatial.ReferencePixel"][0]) - 0.5
        ) * factor0 + 0.5
        headers["CRPIX2"] = (
            float(self.metadata["Spatial.ReferencePixel"][1]) - 0.5
        ) * factor1 + 0.5

        # Now finalize and apply the parity flip.

        cdelt1 = scale0 / factor0
        cdelt2 = scale1 / factor1
        headers["CD1_1"] = cdelt1 * pc1_1
        headers["CD1_2"] = -cdelt1 * pc1_2
        headers["CD2_1"] = cdelt2 * pc2_1
        headers["CD2_2"] = -cdelt2 * pc2_2
        headers["CRPIX2"] = height + 1 - headers["CRPIX2"]

        return headers


import pygame
import random
import os
import socket
import _pickle as pickle

#================================================= The connection part ================================================#

class Network:
    def __init__(self):
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.host = "192.168.56.1"
        self.port = 50007
        self.addr = (self.host, self.port)

    def connect(self, name):
        self.client.connect(self.addr)
        self.client.send(str.encode(name))
        val = self.client.recv(1024)
        return print(val)

    def send(self, data, pick=False):
        try:
            if pick:
                self.client.send(pickle.dumps(data))
            else:
                self.client.send(str.encode(data))
            reply = self.client.recv(2048*4)
            try:
                reply = pickle.loads(reply)
            except Exception as e:
                print(e)
            return reply
        except socket.error as e:
            print(e)

#===================================================== The classes ====================================================#

class Players:
    def __init__(self, x, y , health, image, width, height):
        self.imgP1 = pygame.image.load(image).convert_alpha()
        self.x = x
        self.y = y
        self.health = health
        self.image = image
        self.width = width
        self.height = height
        self.missiles = []
        self.score = 0
        self.lives = 3

    def add_Missile(self, MissleObj):
        self.missiles.append(MissleObj)

    def position(self):
        return (self.x, self.y)

    def Increase_Score(self):
        self.score += 100

class Enemy:
    def __init__(self, init_x = 0, init_y = 0):
        self.imgProj = pygame.image.load(r'assets\enemies\enemy1better.png')
        self.x = init_x
        self.y = init_y
        self.speed = random.randint(5,10)
        self.id = id

    def remove_life(self, playerObj):
        playerObj.lives -= 1
        return playerObj.lives

    def SendCoordinates(self):
        return [self.x, self.y]

class Missile:
    def __init__(self, player1Obj, mainwindow):
        self.imgMissile1 = pygame.image.load(r'assets\laser.png').convert_alpha()
        self.shoot_speed = 15
        self.playerObj = player1Obj
        self.y = 700
        self.window = mainwindow
        self.imgMissile2 = pygame.transform.scale(self.imgMissile1, (40, 80))
        self.state = 'ready'
        self.currentx = []

    def ChangeState(self):
        self.state = 'shot'

    def onFire(self, CurrentX):
        self.currentx.append(CurrentX)

    def shoot(self):
        if len(self.currentx) > 1:
            self.currentx.remove(self.currentx[0])

        self.window.blit(self.imgMissile2, (self.currentx[-1] - 15, self.y))
        self.y -= self.shoot_speed

        if self.y < 0:
            self.y = 700
            self.state = 'ready'

    def getCoords(self):
        if self.currentx == []:
            pass
        else:
            return [self.currentx[0], self.y]

#=================================================== The game method ==================================================#

# Move speed of the bullet
move_speed = 15

# =============================================== The pygame innit #===================================================#

def lan_game():

    # Moving the player2 object on the screen
    def move_Player2(data):
        if int(data) == 1000:
            pass
        else:
            Player2Obj.x = int(data)

# ============================================== Establishing connection #=============================================#

    Server = Network()
    Server.connect('Player2')

# =============================================== The pygame innit #===================================================#

    pygame.init()
    os.environ['SDL_VIDEO_CENTERED'] = '1'
    main_window = pygame.display.set_mode((900, 900))

    clock = pygame.time.Clock()
    move_rate = 15
    pygame.mouse.set_visible(False)

    backgroundIMG = pygame.image.load(r'assets\main background.png')

# ===================================================# ALL OBJECTS #===================================================#

    # Players

    Player1Obj = Players(400, 750, 100, r'assets\player 1\player1.png', 58, 61)
    Player2Obj = Players(600, 750, 100, r'assets\player 1\player1.png', 58, 61)

    # Enemies

    Bob = Enemy()
    Martin = Enemy()

    # Missiles

    for i in range (0,2):
        missile = Missile(Player1Obj, main_window)
        Player1Obj.missiles.append(missile)

# =================================================# Sound and Music #=================================================#

    pygame.mixer.music.set_volume(pygame.mixer.music.get_volume() - 0.90)
    music_li = random.randint(1, 4)
    if music_li == 1:
        pygame.mixer.music.load(r'assets\music\all star.mp3')
    elif music_li == 2:
        pygame.mixer.music.load(r'assets\music\what is love 8 bit.mp3')
    elif music_li == 3:
        pygame.mixer.music.load(r'assets\music\feel good.mp3')
    else:
        pygame.mixer.music.load(r'assets\music\remove.mp3')

    pygame.mixer.music.play(0)

    # the hit variable - used when the player 1 hits an enemy of the other player
    global hit

# ================================================ The main game loop #================================================#

    while open:

        # KEY LISTENERS

        key_listener = pygame.key.get_pressed()
        if (key_listener[pygame.K_LEFT] or key_listener[pygame.K_a]) and Player1Obj.x > 30:
            Player1Obj.x -= move_rate

        elif (key_listener[pygame.K_RIGHT] or key_listener[pygame.K_d]) and Player1Obj.x < 855:
            Player1Obj.x += move_rate

        # Blitting main images, background, players
        main_window.blit(backgroundIMG, (0, 0))
        main_window.blit(Player1Obj.imgP1, (Player1Obj.x - 20, Player1Obj.y))
        main_window.blit(Player2Obj.imgP1, (Player2Obj.x - 20, Player2Obj.y))

        # Looping over the missiles
        for missile in Player1Obj.missiles:
            if missile.state == 'shot':
                missile.shoot()

        # Setting hit to default 0
        hit = 0

        # Looping over missile and collision
        for missile in Player1Obj.missiles:
            a = missile.getCoords()
            if a == None:
                pass
            if a == None:
                pass
            else:
                if missile.state == 'ready':
                    break
                if Martin.y - 20 <= a[1] <= Martin.y + 20 and Martin.x - 30 < a[0] <= Martin.x + 80:
                    print('Martin')
                    missile.state = 'ready'
                    missile.y = 700
                    Martin.x = 0
                    Martin.y = 0
                elif Bob.y - 20 <= a[1] <= Bob.y + 20 and Bob.x - 30 < a[0] <= Bob.x + 80:
                    print('Bob')
                    missile.state = 'ready'
                    missile.y = 700
                    hit = 1

# ================================================# Server connection #================================================#

        response = Server.send([[Player1Obj.x], Martin.SendCoordinates(), hit], pick=True)
        print(response)

        Bob.x = response[1][0]
        Bob.y = response[1][1]
        Martin.x = response[2][0]
        Martin.y = response[2][1]

        main_window.blit(Bob.imgProj, (Bob.x, Bob.y))
        main_window.blit(Martin.imgProj, (Martin.x, Martin.y))

        # calling move_Player2 with the response we got from the server
        move_Player2(response[0][0])

        pygame.display.update()

        # KEY LISTENERS PART 2
        clock.tick(30)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
            if event.type == pygame.KEYUP:
                if key_listener[pygame.K_SPACE]:
                    Current_Missile_X = Player1Obj.x
                    for missile in Player1Obj.missiles:
                        if missile.state == 'ready':
                            missile.ChangeState()
                            missile.onFire(Current_Missile_X)
                            break

# ========================================================# END #======================================================#

lan_game()


import sklearn.datasets
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.naive_bayes import MultinomialNB
import numpy as np
from sklearn.linear_model import SGDClassifier
from sklearn.metrics import classification_report as clsr
from modules.RankRetrieval.PreP import NLTKPreprocessor
from sklearn.metrics.pairwise import cosine_similarity
import pickle
import os
from pathlib import Path
from nltk.corpus import wordnet

'''variables'''

business = 510
entertainment = 386
politics = 417
sport = 511
tech = 401
path = 'Dataset\\bbc'

'''utility functions'''

def readFile(className,docNo):
    count = 0
    for file in os.listdir(path+'\\'+className):
        count+=1
        if count==docNo:
            fin = open(path+'\\'+className+'\\'+file,'r')
            content = fin.read()
            fin.close()
            #return (className,file,content)
            return (className,file)
    return None

def calcSim(query,exp):
    qWords = query.split()
    eWords = exp.split()
    sim = 0
    for i in range(len(qWords)):
        a = wordnet.synsets(qWords[i])
        if len(a)==0:
            sim+=1
            continue
        b = wordnet.synsets(eWords[i])
        if a[0].wup_similarity(b[0]) is not None:
            sim+= (a[0].wup_similarity(b[0]))
    return sim

def search_main(keyword):

   proData = []
   query = [keyword]
   allSim =[]

   '''reading dataset'''

   for dir in os.listdir(path):
        #className = dir
    #    print(className+'\n\n')
        filePath = path+'\\'+dir
        for file in os.listdir(filePath):
            fileName = file
            fPath = filePath+'\\'+file
            fp = open(fPath,'r')
            #converting to lower case and toeknizing
            fileContent = fp.read()
            fp.close()
            proData.append(fileContent)

   picFile = Path('pickles\\bbc\\preProData.pik')

   if picFile.exists():
        fin = open('pickles\\bbc\\preProData.pik','rb')
        proData = pickle.load(fin)
        fin.close()
   else:
        prePro = NLTKPreprocessor()
        proData = prePro.transform(proData)
        fout = open('pickles\\bbc\\preProData.pik','wb')
        pickle.dump(proData,fout)
        fout.close()

   fin = open('pickles\\bbc\\invertedInd.pik','rb')
   invertedIndex = pickle.load(fin)
   fin.close()

   '''query expansion'''

   preProc = NLTKPreprocessor()
   query = preProc.transform(query)
   qWords = query[0].split()
   dct={}
   for word in qWords:
       value=[word]
       dct[word] = value
       for syn in wordnet.synsets(word):
           for l in syn.lemmas():
               if l.name() not in value:
                   value.append(l.name())

       dct[word]=value

   allQuery = []

   def all_comb(currPos,total,newQuery):
#    print('In rec')
    if(currPos>=total):
        if list(newQuery) not in allQuery:
            allQuery.append(' '.join(list(newQuery)))
        return
    for syn in dct[qWords[currPos]]:
        newQuery.append(syn)
        all_comb(currPos+1,total,newQuery)
        newQuery.pop()

   all_comb(0,len(qWords),[])

   qSim = []

   for exp in allQuery:
       qSim.append(calcSim(query[0],exp))

   docQInv = {}
   i = -1
   for query in allQuery:
       i+=1
       qWords = query.split()
       docList = []
       for word in qWords:
           if word in invertedIndex:
               for doc in invertedIndex[word]:
                   if doc not in docList:
                       docList.append(doc)
       proDataFiltered = []
       for index in docList:
           proDataFiltered.append(proData[index])
       if len(proDataFiltered)==0:
           continue

       count_vect = CountVectorizer()
       cVector = count_vect.fit_transform(proDataFiltered)
       tfidf_transformer = TfidfTransformer()
       tVector = tfidf_transformer.fit_transform(cVector)
       cQuery = count_vect.transform([query])
       tQuery = tfidf_transformer.transform(cQuery)

       sim = cosine_similarity(tQuery, tVector)

       simScore = []
       docCount = 0
       for score in list(sim[0]):
           scoreList = []
           docCount+=1
           scoreList.append(score)
           scoreList.append(docList[docCount-1])
           simScore.append(scoreList)
           simScore.sort(key=lambda x: x[0],reverse=True)
       allSim.append(simScore[0:9])
       resultList = []

       for item in simScore[0:9]:
           docNo = item[1]+1
           if docNo not in docQInv:
               docQInv[docNo] = [[i,item[0]]]
           else:
               docQInv[docNo].append([i,item[0]])

   docScore = []
   for doc in docQInv.keys():
       tScore = 0
       for elem in docQInv[doc]:
           qNo = elem[0]
           dScore = elem[1]
           qScore = qSim[qNo]
           tScore+= dScore*qScore
       docScore.append([tScore,doc])

   docScore.sort(key=lambda x: x[0],reverse=True)
   #print(docScore)

   for item in docScore[0:9]:
    docNo = item[1]
    if docNo>business:
        docNo=docNo-business
    else:
        resultList.append(readFile('business',docNo))
        continue
    if docNo>entertainment:
        docNo=docNo-entertainment
    else:
        resultList.append(readFile('entertainment',docNo))
        continue
    if docNo>politics:
        docNo=docNo-politics
    else:
        resultList.append(readFile('politics',docNo))
        continue
    if docNo>sport:
        docNo=docNo-sport
    else:
        resultList.append(readFile('sport',docNo))
        continue
    resultList.append(readFile('tech',docNo))

   return resultList


#!/usr/bin/python3

import cgi
import subprocess
print("Content-Type: text/html\n")
form = cgi.FieldStorage(environ={'REQUEST_METHOD':'POST'})
fname = form.getvalue("fname")
lname = form.getvalue("lname")
email = form.getvalue("email")
subject = form.getvalue("subject")
message = form.getvalue("message")
mail = [ 'mail', '-s', subject, '-r', email, '--', 'joebert@kenchlightyear.com']
body = [ 'printf', 'Message from: ' + fname + ' ' + lname + '\n\n' + message ]
bodyproc = subprocess.Popen(body, stdout=subprocess.PIPE)
mailproc = subprocess.Popen(mail, stdin=bodyproc.stdout)
confirmation = "Thank you for contacting us. We have received your message. We will get back to you soon."
signature = "Regards,\nJoebert Jacaba\nCEO, Kench Lightyear\n+63 919 999 2056"
mail = [ 'mail', '-s', "Confirmation", '-r', 'joebert@kenchlightyear.com', '--', email ]
body = [ 'printf', 'Hello ' + fname + ',\n\n' + confirmation + '\n\n' + signature]
bodyproc = subprocess.Popen(body, stdout=subprocess.PIPE)
mailproc = subprocess.Popen(mail, stdin=bodyproc.stdout)
print(confirmation)
print('
Close
')


#!/usr/bin/env python

# ENCODE DCC Cutadapt wrapper
# Author: Frankie James (fjames003)

import sys
import os
import re
import argparse
import multiprocessing
from encode_common_genomic import *

def parse_arguments():
    parser = argparse.ArgumentParser(prog='ENCODE DCC Cutadapt adapter trimmer.',
                                        description='')
    parser.add_argument('fastqs', nargs='+', type=str,
                        help='List of FASTQs (R1 and R2). \
                            FASTQs must be compressed with gzip (with .gz).')
    parser.add_argument('--paired-end', action="store_true",
                        help='Paired-end FASTQs.')
    parser.add_argument('--nth', type=int, default=1,
                        help='Number of threads to parallelize.')
    parser.add_argument('--out-dir', default='', type=str,
                            help='Output directory.')
    parser.add_argument('--log-level', default='INFO',
                        choices=['NOTSET','DEBUG','INFO',
                            'WARNING','CRITICAL','ERROR','CRITICAL'],
                        help='Log level')
    args = parser.parse_args()

    # check if fastqs have correct dimension
    if args.paired_end and len(args.fastqs)!=2:
        raise argparse.ArgumentTypeError('Need 2 fastqs for paired end.')
    if not args.paired_end and len(args.fastqs)!=1:
        raise argparse.ArgumentTypeError('Need 1 fastq for single end.')

    log.setLevel(args.log_level)
    log.info(sys.argv)
    return args

def cutadapt_se(fastq, nth, out_dir):
    basename = os.path.basename(strip_ext_fastq(fastq))
    prefix = os.path.join(out_dir, basename)
    fastq_out = "{}.trimmed.fastq.gz".format(prefix)

    cmd =  'cutadapt -j {} '
    cmd += '--length 36 --minimum-length 35 '
    cmd += '--trim-n -e 0.1 -q 30 '
    cmd += '-a GATCGGAAGAGCACACGTCTGAACTCCAGTCAC -A GATCGGAAGAGCGTCGTGTAGGGAAAGAGTGTAGATCTCGGTGGTCGCCGTATCATT '
    cmd += '-o {} '
    cmd += '{}'
    cmd = cmd.format(nth, fastq_out, fastq1)

    run_shell_cmd(cmd)

    return fastq_out

def cutadapt_pe(fastq1, fastq2, nth, out_dir):
    basename1 = os.path.basename(strip_ext_fastq(fastq1))
    prefix1 = os.path.join(out_dir, basename1)
    fastq_out1 = "{}.trimmed.fastq.gz".format(prefix1)

    basename2 = os.path.basename(strip_ext_fastq(fastq2))
    prefix2 = os.path.join(out_dir, basename2)
    fastq_out2 = "{}.trimmed.fastq.gz".format(prefix2)

    cmd =  'cutadapt -j {} '
    cmd += '--length 36 --minimum-length 35 '
    cmd += '--trim-n -e 0.1 -q 30 '
    cmd += '-a GATCGGAAGAGCACACGTCTGAACTCCAGTCAC -A GATCGGAAGAGCGTCGTGTAGGGAAAGAGTGTAGATCTCGGTGGTCGCCGTATCATT '
    cmd += '-o {} -p {} '
    cmd += '{} '
    cmd += '{}'
    cmd = cmd.format(nth, fastq_out1, fastq_out2, fastq1, fastq2)

    run_shell_cmd(cmd)

    return fastq_out1, fastq_out2

def main():
    # read params
    args = parse_arguments()

    log.info('Initializing and making output directory...')
    mkdir_p(args.out_dir)

    # declare temp arrays
    temp_files = [] # files to deleted later at the end

    # STAR
    log.info('Running Cutadapt...')
    if args.paired_end:
        fastq_out1, fastq_out2 = cutadapt_pe(args.fastqs[0], args.fastqs[1], args.nth, args.out_dir)
    else:
        fastq_out1 = cutadapt_se(args.fastqs[0], args.nth, args.out_dir)

    log.info('Removing temporary files...')
    rm_f(temp_files)

    log.info('List all files in output directory...')
    ls_l(args.out_dir)

    log.info('All done.')

if __name__=='__main__':
    main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Oct 18 16:20:25 2018

@author: liyuan
"""

'''
Data_char is prepared by converting each word into a list of characters e.g. explanation[0] contains 200 words, this is converted to 270 (max length of explanation) lists of length 19 (max char in word) integer sequence
the result is a 1663x270x19 array
'''

from Data import Data

from keras.preprocessing.sequence import pad_sequences
import nltk
import numpy as np
import codecs
import keras.backend as K
import time
import datetime
#import config
import re
from Struct import Struct

#%% define class
class Data_char(Data):
    explanations_path = './data/explanations2.txt'
    questions_path = './data/questions2.txt'
    word_embeddings_path = './embeddings/binaries/glove.840B.300d'
#    word_embeddings_path = './embeddings/binaries/glove.6B.50d'
    cache = Struct()
    lengths = Struct()
    indices = []
    questions_intseq = None
    exp_intseq = None
    answers_intseq = None
    answers_intseq2_val = None
    dummy_labels_train = None
    dummy_labels_val = None
    raw_questions = None
    char_vocab = None
    char2index = None

    def __init__(self):
        pass

    def __str__(self):
        """
        print attributes
        """
        attr_list = []
        for attribute in dir(self):
            if attribute != '__weakref__':
                if not hasattr(getattr(self,attribute),'__call__') and not '__' in attribute :
                    attribute_value = getattr(self,attribute)
                    if isinstance(attribute_value, (np.ndarray, np.generic)):
                        attribute_value = 'array with shape {}'.format(str(attribute_value.shape))
                    elif isinstance(attribute_value, Struct):
                        attribute_value = 'Struct with {} attributes'.format(len(attribute_value))
                    elif isinstance(attribute_value, list):
                        attribute_value = 'list with {} elements'.format(len(attribute_value))
                    if (attribute_value is not None) and len(attribute_value) > 100:
                        # print in red then revert to white
#                        attribute_value = '\033[33m'+'too long to display...'+'\033[0m'
                        attribute_value = '[{}]'.format(len(attribute_value))
                    line = '{:>30s} : {:<10s}'.format(attribute,str(attribute_value))
                    attr_list.append(line)
        return '\n'.join(attr_list)

    def preprocess_data(self):
        """
        reads questions2.txt and explanations2.txt and returns questions and explanations in fully processed form, i.e. questions as sequences of numbers, one number for each word, and similarly for explanations
        """
        self.load_raw()
        self.get_vocab()
        self.preprocess_exp()
        self.preprocess_questions()

        num_train = 1363
        num_val = 150
        num_test = 150
        train_indices,val_indices,test_indices = self.get_shuffled_indices(num_examples = 1663, proportions = [num_train,num_val,num_test])
        self.indices = [train_indices,val_indices,test_indices]
        self.dummy_labels_train = np.array([None]*num_train).reshape(num_train,1)
        self.dummy_labels_val = np.array([None]*num_val).reshape(num_val,1)
        self.answers_intseq2_val = self.sample_wrong_answers()

        self.exp_intseq = np.array(self.exp_intseq)
        self.questions_intseq = np.array(self.questions_intseq)
        self.answers_intseq = np.array(self.answers_intseq)
        self.get_lengths()

    def load_raw(self):
        file = open('./data/questions2.txt',encoding = 'utf-8')
        raw_question = file.readlines()
        raw_question = [self.replacer(text.strip()) for text in raw_question]

        file = open('./data/explanations2.txt','r')
        raw_exp = file.readlines()
        raw_exp = [self.replacer(text.strip()) for text in raw_exp]

        self.raw_question = raw_question
        self.raw_exp = raw_exp

    def get_vocab(self):
        raw_question = self.raw_question
        raw_exp = self.raw_exp

        char_vocab = set()
        for text in raw_exp:
            char_vocab = char_vocab | set(text)

        for text in raw_question:
            char_vocab = char_vocab | set(text)

        char_vocab = sorted(char_vocab)
        char2index = {char:i+1 for i,char in enumerate(char_vocab)}

        raw = raw_question+raw_exp
        raw = [nltk.tokenize.word_tokenize(sentence) for sentence in raw]
        max_char_in_word = max([max([len(list(word)) for word in sentence]) for sentence in raw])

        self.char_vocab = char_vocab
        self.char2index = char2index
        self.lengths.max_char_in_word = max_char_in_word

    def replacer(self,raw_sentence):
        raw_sentence = re.sub('[âÂ]','',raw_sentence,flags = re.I)
        raw_sentence = raw_sentence.replace('\x93','')
        raw_sentence = raw_sentence.replace('\x9d','')
        return raw_sentence

    def preprocess_exp(self):
        """
        make vocab dictionary for all explanations, convert explanations to integer sequence
        """
        raw_exp = self.raw_exp
        raw_exp = [self.replace_text_in_braces(line) for line in raw_exp]
        exp_tokenized = [nltk.word_tokenize(paragraph) for paragraph in raw_exp]
        exp_intseq = self.all_examples_to_intseq(self.pad(exp_tokenized))

        self.cache.raw_exp = raw_exp
        self.cache.exp_tokenized = exp_tokenized
        self.exp_intseq = exp_intseq

    def preprocess_questions(self):
        filepath = self.questions_path

        raw_question = self.raw_question
        blank_index = 0

        # remove newline characters and double quotes
        raw_question = [text.rstrip().strip('"') for text in raw_question]

        # turn question into list of separate words, make separate lists for questions and answers
        questions = []
        answers = []
        answer_options_all_questions_with_questions= []
        answer_indices = []
        for text in raw_question:
            raw_question,ans_letter = text.split(' : ')

            # correct_answer_string contains two parts, the letter answer and the answer string
            #'A' and 'sound in a loud classroom' for example.
            split_question = self.split_question_and_answers(raw_question)
            question_part = split_question[0]
            answer_part = split_question[1:]
            answer_options_all_questions_for_one_question = [self.process_sentence(sentence) for sentence in answer_part]
            answer_index = self.convert_to_int(ans_letter)
            answer_indices.append(answer_index)
            correct_ans_string = answer_options_all_questions_for_one_question[answer_index]
            ans = [ans_letter,correct_ans_string]

            # separate question into a list of words and punctuation
            tokenized_question = self.process_sentence(raw_question)
            questions.append(tokenized_question)
            answers.append(ans)
            answer_options_all_questions_with_questions.append([tokenized_question] + answer_options_all_questions_for_one_question)
            answer_options_all_questions = [part[1:] for part in answer_options_all_questions_with_questions]

        # calculate some lengths
        maxlen_question = max([len(sent) for sent in questions])
        maxlen_answer = max([max([len(sentence) for sentence in part]) for part in answer_options_all_questions])

        # make each question into a sequence of integers, use unk if word not in list
        cutoff_length = 150
        questions_intseq = self.all_examples_to_intseq(self.pad(questions, cutoff_length = cutoff_length))
        # note: didn't do padding here

        # answers_words is a list of each answer, expressed as a tokenized list of that answer sentence
        #convert every word in answers_words to its index (e.g. 'teacher' to 1456)
        answers_words = [sent for option,sent in answers]
        answers_intseq = self.all_examples_to_intseq(self.pad(answers_words,maxlen_answer))
        # note: didn't do padding here

        '''
        answer_options_all_questions is a list of tokenized answers e.g. [['large','leaves'],['shallow','roots'],...]
        all_answer_options_intseq is the same list padded and converted to integer representations
        e.g. [[0,0,0,...,]]
        '''

        padded_answer_options = [self.pad(x,maxlen_answer) for x in answer_options_all_questions]
        all_answer_options_intseq = [self.all_examples_to_intseq(answer_options) for answer_options in padded_answer_options]

        wrong_answers = [np.delete(part,index,axis = 0) for part,index in zip(all_answer_options_intseq,answer_indices)]

        self.questions_intseq = questions_intseq
        self.answers_intseq = answers_intseq

        self.raw_question = raw_question
        self.cache.questions = questions
        self.cache.answers = answers
        self.cache.answer_options_all_questions = answer_options_all_questions
        self.cache.all_answer_options_intseq = all_answer_options_intseq
        self.cache.answer_options_all_questions_with_questions = answer_options_all_questions_with_questions
        self.cache.wrong_answers = wrong_answers

    def to_intseq(self,word):
        char2index = self.char2index
        char2index['`'] = 0
        intseq = [char2index[char] for char in list(word)]

        raise_message = 0
        if raise_message and '`' in word:
            print('` detected...' ,end = '')
            print(word)
        return intseq

    def all_examples_to_intseq(self,all_examples):
        '''expects explanations or questions in tokenized form i.e. each explanation paragraph is tokenized into words
        '''
        max_char_in_word = self.lengths.max_char_in_word

        intseq = []
        for words in all_examples:
            intseq_words = [self.to_intseq(word) for word in words]
            intseq_words = pad_sequences(intseq_words,max_char_in_word)
            intseq.append(intseq_words)
        return intseq

    def get_lengths(self):
        '''because must include padding character'''
        self.lengths.maxlen_question = max([len(sent) for sent in self.questions_intseq])
        self.lengths.maxlen_raw_question = max([len(sent) for sent in self.cache.questions])
        self.lengths.maxlen_exp = max([len(sent) for sent in self.exp_intseq])
        self.lengths.num_examples = len(self.cache.questions)
        self.lengths.char2index_length = len(self.char2index) + 1
        self.lengths.maxlen_answer = self.answers_intseq.shape[1]

    def pad(self,tokenized,maxlen = None,cutoff_length = None):
        '''
        pads all examples with '' to same length to facilitate processing
        inputs are tokenized sentences/paragraphs of varying lengths
        '''
        if maxlen == None:
            maxlen = max([len(x) for x in tokenized])
        if cutoff_length == None:
            cutoff_length = maxlen
        padded = [['']*(maxlen - len(sentence)) + sentence for sentence in tokenized]
        padded = [sentence[maxlen-cutoff_length:] for sentence in padded]
        return padded

    def sample_wrong_answers(self):
        answers_intseq2 = [part[np.random.randint(len(part))] for part in self.cache.wrong_answers]
        answers_intseq2 = np.array(answers_intseq2)
        return answers_intseq2

#    def foo(self):
#        exp_tokenized = self.cache.exp_tokenized
#        question_tokenized = self.cache.questions
#
#        vocab = set()
#        for paragraph in exp_tokenized

#            exp_vocab = set()
#            for paragraph in raw_exp:
#                tokenized_paragraph = nltk.word_tokenize(paragraph)
#                exp_vocab = exp_vocab | set(tokenized_paragraph)
#            exp_vocab = sorted(exp_vocab)
#            exp_vocab_dict = {word:ind+1 for ind,word in enumerate(exp_vocab)}

#%% example

if __name__ == '__main__':
    temp = Data_char()
    temp.preprocess_data()
    print(temp)


# Copyright 2018 Benjamin Bueno (bbueno5000) 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.
"""
Plot the data gathered from StarCraft II experiments.
"""
from collections import defaultdict
from dill import load as dill_load
from matplotlib import pyplot
from numpy import add as np_add
from numpy import array as np_array
from numpy import cumsum as np_cumsum
from numpy import digitize as np_digitize
from numpy import float32 as np_float32    # pylint: disable=E0611
from numpy import linspace as np_linspace
from numpy import where as np_where
from numpy import zeros as np_zeros
from pandas import DataFrame as pd_DataFrame
from pandas import Series as pd_Series
from seaborn import tsplot

MAX_TSTEPS = int(2e3)
NSAMPLES = 100

def main():
    with open("pysc2/data/results.pkl", 'rb') as file:
        results = dill_load(file)
    experiment_labels = {'starcraft-a': "Double Q Learning",
                         'starcraft-duel-a': "Dueling Double Q Learning",
                         'starcraft-prior-a': "Double Q Learning with Prioritized Replay",
                         'starcraft-prior-duel-a': "Dueling Double Q Learning with Prioritized Replay"}
    experiments = experiment_labels.keys()
    agent_data = defaultdict(lambda: defaultdict(lambda: []))
    for experiment in experiments:
        for name, data in results.items():
            if name.startswith(experiment):
                agent = data['agent_id']
                times = np_cumsum(data['episode_data']['episode_lengths'])
                rewards = np_array(data['episode_data']['episode_rewards'])
                rewards = rewards[times < MAX_TSTEPS]
                times = times[times < MAX_TSTEPS]
                agent_data[agent][experiment].append((times, rewards))
    experiments_to_plot = ['starcraft-a']
    plot_experiments(experiment_labels, experiments_to_plot, agent_data)

def plot_experiments(experiment_name, experiments_to_plot, agent_data, ncols=4):
    """
    Given a set of experiments, plot them in a line graph.
    experiments_to_plot: Chosen experiments to plot.
    """
    colors = ['red', 'green', 'blue', 'yellow', 'magenta', 'cyan']
    assert len(colors) >= len(experiments_to_plot)
    color_legend = dict(zip(experiments_to_plot, colors))
    # Print the legend
    for experiment, color in color_legend.items():
        print(color, ":", experiment_name[experiment])
    # Select relevant games for those experiments
    all_games = list(agent_data.keys())
    relevant_agents = [g for g in all_games if any(e in agent_data[g] for e in experiments_to_plot)]
    # Create the figure
    # TODO: fix figures columns and rows
    # ncols = min(ncols, len(relevant_agents))
    # nrows = (len(relevant_agents) + ncols - 1) // ncols
    ncols = 2
    nrows = 2
    _, axes = pyplot.subplots(nrows, ncols, figsize=(5 * ncols, 5 * nrows))
    if nrows == 1:
        axes = [axes]
    # Plot the data
    for index, agent in enumerate(sorted(relevant_agents)):
        ax = axes[index // ncols][index % ncols]
        ax.set_title(agent)
        for experiment_label, experiment_data in agent_data[agent].items():
            if experiment_label in experiments_to_plot:
                tsplot(ax=ax,
                       ci=[68, 95],
                       color=color_legend[experiment_label],
                       data=translate_episode_data(experiment_data),
                       time="Frame",
                       unit="run_id",
                       value="Average Episode Reward")
    pyplot.show()

def sample(bins, time, value):
    """
    Given value[i] was observed at time[i],
    group them into bins i.e.,
    *(bins[j], bins[j+1], ...)*

    Values for bin j are equal to the
    average of all value[k] and,
    bin[j] <= time[k] < bin[j+1].

    __Arguments__
    bins: _np.array_
        Endpoints of the bins.
        For n bins it shall be of length n + 1.
    t: _np.array_
        Times at which the values are observed.
    vt: _np.array_
        Values for those times.

    __Returns__
    x: _np.array_
        Endspoints of all the bins.
    y: _np.array_
        Average values in all bins.
    """
    bin_idx = np_digitize(time, bins) - 1
    value_sums = np_zeros(shape=len(bins) - 1, dtype=np_float32)
    value_cnts = np_zeros(shape=len(bins) - 1, dtype=np_float32)
    np_add.at(value_sums, bin_idx, value)
    np_add.at(value_cnts, bin_idx, 1)
    # ensure graph has no holes
    zeros = np_where(value_cnts == 0)
    assert value_cnts[0] > 0
    for z in zeros:
        value_sums[z] = value_sums[z - 1]
        value_cnts[z] = value_cnts[z - 1]
    return bins[1:], value_sums / value_cnts

def translate_episode_data(episode_data):
    """
    Convert episode data into data that
    can be used in a graph.

    Given data from multiple episodes make
    it such that it can be plotted by tsplot,
    i.e. the mean plus the confidence bounds.
    """
    times, units, values = [], [], []
    for index, (ep_len, ep_rew) in enumerate(episode_data):
        # Smooth out the data
        ep_rew = pd_Series(ep_rew).ewm(span=1000).mean()
        # sample for faster plotting
        x, y = sample(bins=np_linspace(0, MAX_TSTEPS, NSAMPLES + 1),
                      time=ep_len,
                      value=ep_rew)
        # Convert to tsplot format
        times.extend(x)
        values.extend(y)
        units.extend([index] * len(x))
    return pd_DataFrame({'Frame': times, 'run_id': units, 'Average Episode Reward': values})

if __name__ == "__main__":
    main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Jun 15 16:17:58 2018

@author: jimmyhomefolder
"""

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv("data/student_data.csv")
df_pred = df

label = 'Sauna' #要預測的 label
staying = 'Staying'
features = list(set(df.columns) - {label,
                 'Name',
                 'Address',
                 'Working',
                 'Age of Parent',
                 'Consuming Power',
                 'Beauty',
                 'Purchased',
                 'Massage',
                 'Resource',
                 'Birth Date',
                 'Register Date'
                 })

#%%
# Encoding categorical data (we have string in our data type)
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
X_0 = LabelEncoder()
df['County'] = X_0.fit_transform(df['County'])
df['District'] = X_0.fit_transform(df['District'])
df['Road'] = X_0.fit_transform(df['Road'])
df['Sex'] = X_0.fit_transform(df['Sex'])
#X['Consuming Power'] = X_0.fit_transform(X['Consuming Power'])
#X['Resource '] = X_0.fit_transform(X['Resource '])
#X['Sentimental'] = X_0.fit_transform(X['Sentimental'])

#%%
#df['Birth Date'] = pd.to_datetime(df['Birth Date'])
#df['Register Date'] = pd.to_datetime(df['Register Date'])
df = df.loc[df[staying].notnull()] # 我覺得staying 是個很強的特徵，先用它有值的資料來做預測 看看效果
df_staying_notnull = df
df = df.loc[df[label].notnull() ] # 要預測的 label
X = df[features] #metrics of features
y = df[label].values # independent variable vector(outcome) #Label Column

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

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

#%%
# Fitting Logistic Regression to the Training set

import keras
from keras.models import Sequential #used to initialize our neural network
from keras.layers import Dense # used to create layers in our neural network
from keras.layers import Dropout

from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB

"""
input_dim = len(X.columns)
classifier = Sequential() # classifier is the future ann we r going to build
classifier.add(Dense(units = 6, kernel_initializer = 'uniform', activation = 'relu', input_dim = input_dim))
#classifier.add(Dense(units = 6, kernel_initializer = 'uniform', activation = 'relu'))
classifier.add(Dense(units = 1, kernel_initializer = 'uniform', activation = 'sigmoid'))
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
classifier.fit(X_train, y_train, batch_size = 1, epochs = 25)

classifier = GaussianNB()
classifier = DecisionTreeClassifier(criterion = 'entropy', random_state = 0)
classifier = RandomForestClassifier(n_estimators = 10, criterion = 'entropy', random_state = 0)
classifier = SVC(kernel = 'rbf', random_state = 0)
classifier = KNeighborsClassifier(n_neighbors = 5, metric = 'minkowski', p = 2)
classifier = LogisticRegression(random_state = 0)
"""

classifier = LogisticRegression(random_state = 0)

classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)

#%%
# Making the Confusion Matrix(it is a function)
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred.round())

#%%
### Predicting...
df_pred = df_pred.loc[df_pred[staying].notnull()] # 我覺得staying 是個很強的特徵，先用它有值的資料來做預測 看看效果
X_pred = df_pred[features] #metrics of features
X_pred_df = X_pred

#%%
X_pred = X_pred.values #change pandas into numpy

Sauna_prediction = []
for i in X_pred[0:]:
    new_prediction = classifier.predict(sc.transform(np.array([list(i)])))
    new_prediction = (new_prediction > 0.5)
    Sauna_prediction.append(new_prediction)

#%%
df_pred['Sauna_prediction'] = Sauna_prediction
df_pred.to_excel('Sauna_prediction.xlsx')


# https://github.com/yt-dlp/yt-dlp
# python3 ./yt-dlp.py
# If target_leaf (see code) does not exist, it will be created.
#
# In wsl/linux, to create a symlink to the usual place...
# 1. ln_target='/mnt/e/Zoolz/C/Videos/YouTube/Others'
# 2. sudo ln -s $ln_target /wintemp
# So... ls -l /wintemp
# lrwxrwxrwx 1 root root 36 Dec 29 16:36 /wintemp -> /mnt/e/Zoolz/C/Videos/YouTube/Others

import datetime
from sys import platform
import os

def download_yt_video():
    ytexe = "./yt-dlp"
    yt_prefix = "https://www.youtube.com/watch?v="

    if (platform == 'linux'):
        SAVE_PATH = "/wintemp"
    else: # assume win32
        raise ValueError

    if not os.path.exists(ytexe):
        # non-checked-in static copy: D:\software\VideoSoftware\YoutubeDownloader\yt-dlp
        raise FileNotFoundError("no file found: [{}]. Exiting...".format(ytexe))

    link = input("Paste the YouTube URL (only the part aafter 'v='): ")
    target_leaf = input(f"What is the folder under {SAVE_PATH} to save the video? (return = none): ")
    output_template = f"{SAVE_PATH}/{target_leaf}/%(title)s-%(id)s"
    command_line = f"{ytexe} -v {yt_prefix}{link} -o '{output_template}'.mp4"
    print(f"[cmd line]: {command_line}")

    os.system(command_line)

    print("Completed download at {}".format(datetime.datetime.now()))
    print("See '[download] Destination' above for output folder and video name")

download_yt_video()


#!/usr/bin/env python3
# -*- coding:utf-8 -*-
'''
画图
1.坐标轴设置
2.改变坐标轴的方式

'''

__author__ = 'Jackie Qiang'

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-1, 1, 50)
y1 = 2*x +1
y2 = x**2

plt.figure()
plt.plot(x, y2)
plt.plot(x, y1, color='red', linewidth=1.0, linestyle='--')

plt.xlim((-1, 2))    #x轴的取值范围
plt.ylim((-2,3))    #y轴的取值范围
plt.xlabel('a\sdf')
plt.ylabel('i am y')

new_ticks = np.linspace(-1, 2, 5)
print(new_ticks)
plt.xticks(new_ticks)   #修改角标，范围从-1到2.共有5个点
plt.yticks([-2, -1.8, -1, 1.22, 3,],
    [r'$really\ bad$', r'$bad\ \alpha$', 'normal', 'good', 'really good']) #修改y轴的角标

#gca = 'get current axis'
ax =plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
ax.spines['bottom'].set_position(('data', 0)) # outward, axis
ax.spines['left'].set_position(('data', 0))

plt.show()


# https://github.com/agdelma/IntroCompPhysics/blob/master/Notebooks/26_Quadrature.ipynb

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from scipy.constants import pi as π

colors = ["#2078B5", "#FF7F0F", "#2CA12C", "#D72827", "#9467BE", "#8C574B",
          "#E478C2", "#808080", "#BCBE20", "#17BED0", "#AEC8E9", "#FFBC79",
          "#98E08B", "#FF9896", "#C6B1D6", "#C59D94", "#F8B7D3", "#C8C8C8",
          "#DCDC8E", "#9EDAE6"]

def dBx(t,x,y,z,ω):
    '''x-component of the B field (in units of μ0I)'''
    r = (x-np.cos(ω*t))**2+(y-t)**2+(z-np.sin(ω*t))**2
    return (1/(4.0*π))*(z - np.sin(ω*t) - ω*np.cos(ω*t)*(y-t))/r**3/2

def dBy(t,x,y,z,ω):
    '''y-component of the B field (in units of μ0I)'''
    r = (x-np.cos(ω*t))**2+(y-t)**2+(z-np.sin(ω*t))**2
    return (1/(4.0*π))*(ω*np.sin(ω*t)*(z-np.sin(ω*t))+ω*np.cos(ω*t)*(x-np.cos(ω*t)))/r**3/2

def dBz(t,x,y,z,ω):
    '''z-component of the B field (in units of μ0I)'''
    r = (x-np.cos(ω*t))**2+(y-t)**2+(z-np.sin(ω*t))**2
    return (1/(4.0*π))*(-ω*np.sin(ω*t)*(y-t)-x+np.cos(ω*t))/r**3/2

def trapezoidal_rule(f,x,*params):
    '''The trapezoidal rule for numerical integration of f(x) over x.'''

    a,b = x[0],x[-1]
    Δx = x[1] - x[0]
    np.delete(x, 0)
    np.delete(x, -1)

    ###
    I = (Δx/2) * (f(a, *params) + f(b, *params)) + np.sum(f(x, *params) * Δx)
    ###

    return I

N = 500
t = np.linspace(-4*π,4*π,N)

ω = 15

# along the axis
y = np.linspace(-20,20,N)
x,z = 0,0

Bx = np.zeros_like(y)
By = np.zeros_like(y)
Bz = np.zeros_like(y)

for i in range(N):
    Bx[i] = trapezoidal_rule(dBx,t,x,y[i],z,ω)
    By[i] = trapezoidal_rule(dBy,t,x,y[i],z,ω)
    Bz[i] = trapezoidal_rule(dBz,t,x,y[i],z,ω)

plt.plot(y,Bx,label=r'$B_x(0,y,0)$')
plt.plot(y,By, label=r'$B_y(0,y,0)$')
plt.plot(y,Bz, label=r'$B_z(0,y,0)$')

plt.legend(frameon=True, loc='lower right')
plt.xlabel('y')
plt.ylabel(r'$B/\mu_0 I$')

plt.show()


# -*- coding: utf-8 -*-
from django.shortcuts import render
from django.http import HttpResponse
from .models import Fphoto
from .forms import FphotoForm

def index(request):
    photos = Fphoto.objects.all()
    form = FphotoForm()
    context = {
        'photos': photos,
        'form': form
    }
    return render(request, 'finger/index.html', context)

def add_finger(request):
    form = FphotoForm()
    if request.method == 'POST':
        form = FphotoForm(request.POST, request.FILES)
        if form.is_valid():
            if 'photo' in request.FILES:
                form.photo = request.FILES['photo']
            form.save(commit=True)
            arr_photos = Fphoto.objects.all().order_by('-id')[0]
            print(arr_photos.img_1.path)
            print(arr_photos.img_2.path)
            result = checkFinger(arr_photos.img_1.path, arr_photos.img_2.path)
            print(result)

            arr_photos.num_evd = result
            arr_photos.save()
            if result > 80:
                context = {
                    'photos': arr_photos,
                    'num': result
                }
                return render(request, 'finger/result.html', context)
            else:
                return HttpResponse("Не прошел")
        else:
            print(form.errors)
        return render(request, 'finger/index.html', {'form': form})
    else:
        return HttpResponse('no')

from tkinter import *
from PIL import Image
import finger.lib.templateSkeletize2 as sk

def binary(img):
    bImg = []
    for i in range(img.size[0]):
        tmp = []
        for j in range(img.size[1]):
            t = img.getpixel((i, j))
            p = t[0] * 0.3 + t[1] * 0.59 + t[2] * 0.11
            if p > 128:
                p = 1
            else:
                p = 0
            tmp.append(p)
        bImg.append(tmp)
    return bImg

def __removeDouble(x, y):
    z = []
    for i in x:
        c = True
        for j in y:
            if i == j:
                c = False
        if c:
            z.append(i)
    for i in y:
        c = True
        for j in x:
            if i == j:
                c = False
        if c:
            z.append(i)
    return z

def delNoisePoint(r):
    tmp = []
    tmp2 = []
    for i in r[1]:
        x = range(i[0] - 5, i[0] + 5)
        y = range(i[1] - 5, i[1] + 5)
        for j in r[0]:
            if j[0] in x and j[1] in y:
                tmp.append(i)
                tmp2.append(j)
    return (__removeDouble(r[0], tmp2), __removeDouble(r[1], tmp))

def matchingPoint(r, v):
    all = 0
    match = 0
    for i in v[0]:
        x = range(i[0] - 15, i[0] + 15)
        y = range(i[1] - 15, i[1] + 15)
        all += 1
        for j in r[0]:
            if j[0] in x and j[1] in y:
                match += 1
                break
    for i in v[1]:
        x = range(i[0] - 15, i[0] + 15)
        y = range(i[1] - 15, i[1] + 15)
        all += 1
        for j in r[1]:
            if j[0] in x and j[1] in y:
                match += 1
                break

    return (match, all)

def checkThisPoint(img, x, y):
    c = 0
    for i in range(x - 1, x + 2):
        for j in range(y - 1, y + 2):
            if img[i][j] == 0:
                c += 1
    return c - 1

def findCheckPoint(img):
    x = len(img)
    y = len(img[0])
    branchPoint = []
    endPoint = []
    for i in range(x):
        for j in range(y):
            if img[i][j] == 0:
                t = checkThisPoint(img, i, j)
                if t == 1:
                    endPoint.append((i, j))
                if t == 3:
                    branchPoint.append((i, j))
    return (branchPoint, endPoint)

def checkFinger(r, v):
    reference = Image.open(r)

    ref = binary(reference)

    sk.tmpDelete(ref)
    rp = findCheckPoint(ref)
    rp = delNoisePoint(rp)

    verf = Image.open(v)

    ver = binary(verf)

    sk.tmpDelete(ver)
    vp = findCheckPoint(ver)
    vp = delNoisePoint(vp)

    res = matchingPoint(rp, vp)
    r = (res[0] / (res[1] * 1.)) * 100

    # root = Tk()
    # w = len(ver)
    # h = len(ver[0])
    # C = Canvas(root, width=w * 2, height=h)
    #
    # for i in range(w):
    #     for j in range(h):
    #         if ref[i][j] == 0:
    #             C.create_line([(i, j), (i + 1, j + 1)])
    #         if ver[i][j] == 0:
    #             C.create_line([(i + w + 1, j + 1), (i + w, j)])
    # for i in rp[0]:
    #     C.create_oval([(i[0] - 3, i[1] - 3), (i[0] + 3, i[1] + 3)], outline="#ff0000")
    # for i in rp[1]:
    #     C.create_rectangle([(i[0] - 3, i[1] - 3), (i[0] + 3, i[1] + 3)], outline="#0000ff")
    # for i in vp[0]:
    #     C.create_oval([(i[0] - 3 + w, i[1] - 3), (i[0] + 3 + w, i[1] + 3)], outline="#ff0000")
    # for i in vp[1]:
    #     C.create_rectangle([(i[0] - 3 + w, i[1] - 3), (i[0] + 3 + w, i[1] + 3)], outline="#0000ff")
    #
    # C.create_text((w, h * 0.95), fill="#009900", text=str(r) + "%", font='Arial,72')
    #
    # C.pack()
    # root.mainloop()
    return r


class Trie:
    def __init__(self,words):
        self.root={}
        for word in words:
            temp=self.root
            for c in word:
                if c not in temp:
                    temp[c]={}
                temp=temp[c]
            temp["leaf"]=word

    def search(self,s):
        ans=[]
        temp=self.root
        for c in s:
            if c in temp:
                temp=temp[c]
            else:
                break
            if "leaf" in temp:
                ans.append(temp["leaf"])

        return ans

from collections import defaultdict

class Solution:
    def multiSearch(self,big,smalls):
        trie=Trie(smalls)
        bigdict=defaultdict(list)

        for i in range(len(big)):
            res=trie.search(big[i:])
            for item in res:
                bigdict[item].append(i)

        res=[]
        for item in smalls:
            res.append(bigdict[item])

        return res


from django.conf.urls import include, url

from . import views
# from api.views import user_list

urlpatterns = [
    url(
        r'^basic_profile/$',
        views.BasicProfileUpdateView.as_view(),
        name='profile_update'
    ),
    url(
        r'^users/$',
        views.UserList.as_view(),
        name="user_list"
    ),
    # url(
    #     r'^users/(?P<token>[0-9a-z]+)$',
    #     views.UserList.as_view(),
    #     name="user_profile"
    # ),
    url(
        r'^user/profile/(?P<token>[0-9a-z]+)?$',
        views.UserProfile.as_view(),
        name="user_profile"
    )
]


import networkx as nx
import numpy as np
import os
import math
import matplotlib.pyplot as plt
import getEdgePair
from lxml import etree
from scipy import optimize
from getNet import get_nx, divide_name, get_mat
from getEdgeTime import get_all_edge_time
from finePlot import plot
from getFeatureJudge import get_k_shell_dict
from __Configuration import *

def show_info_with_net(_net_name):
    """
    展示网络的边数，节点数，聚类系数，直径
    :param _net_name:
    :return:
    """
    with open(".\\net_data\\meta_info.txt", 'a') as net_data_info:
        net = get_nx(_net_name)
        node_num = net.number_of_nodes()
        edge_num = net.number_of_edges()
        print("NET:", _net_name, " Num of edges:", edge_num, " Num of nodes:", node_num)
        net_data_info.write("NET:" + _net_name + " Num of edges:" + str(edge_num) + " Num of nodes:" +
                            str(node_num) + '\n')

        # cluster_coefficient = nx.average_clustering(net)
        # print("Cluster Coefficient:", cluster_coefficient)
        # net_data_info.write("Cluster Coefficient:" + str(cluster_coefficient) + '\n')
        #
        # max_diameter = 0
        # for sub_net in nx.connected_component_subgraphs(net):
        #     diameter = nx.diameter(sub_net)
        #     if diameter > max_diameter:
        #         max_diameter = diameter
        # print("Diameter:", max_diameter)
        # net_data_info.write("Diameter:" + str(max_diameter) + '\n')
        # 获取网络能区分新旧的边对数
        edges_num_with_day = show_edge_nums_with_time(_net_name)
        day_num = len(edges_num_with_day)
        ep_num = 0
        for i in range(day_num):
            for j in range(i, day_num):
                if i != j:
                    ep_num += edges_num_with_day[i] * edges_num_with_day[j]
        # ep_num = 0
        # for edge_pair, new in getEdgePair.get_all_edge_pairs(_net_name):
        #     ep_num += 1
        print("different time edge_pair num: ", ep_num)
        net_data_info.write("different time edge_pair num: " + str(ep_num) + '\n')
        print("-----------------slice line-----------------")
        net_data_info.write("-----------------slice line-----------------" + '\n')

def show_edge_nums_with_time(_net_name):
    """
    展示网络不同时间边的数量
    :param _net_name:
    :return:
    """
    edge_days = get_all_edge_time(_net_name)
    days = sorted(set(edge_days.values()))
    edges_num_with_day = [0] * len(days)
    for edge in edge_days.keys():
        edges_num_with_day[days.index(edge_days[edge])] += 1
    plt.figure(figsize=(10, 5))
    plot(range(len(days)), edges_num_with_day, 'day', 'edges', _net_name + ' Edges in days', None)
    plt.savefig(".\\net_data\\" + str(divide_name(_net_name)[0]) + "\\edge_num_with_time.png", dpi=600)
    plt.show()
    return edges_num_with_day

def line(x, a, b):
    return a * x + b

def show_degree_dis_with_net(_net_name):
    """
    展示网络的度分布，使用双对数坐标系
    :param _net_name:
    :return:
    """
    net = get_nx(_net_name)
    degree_dis = nx.degree_histogram(net)
    x = []
    y = []
    for degree in range(1, len(degree_dis)):  # 排除孤立节点
        if degree_dis[degree] != 0:
            x.append(math.log2(degree))
            y.append(math.log2(degree_dis[degree] / float(sum(degree_dis))))
    # 拟合
    a, b = optimize.curve_fit(line, x, y)[0]
    x1 = np.arange(0, max(x), 0.01)
    y1 = a * x1 + b

    plt.figure(figsize=(10, 5))
    plt.title(_net_name + ' Degree distribution, k is ' + str(round(a, 3)), fontsize=25, fontweight='bold')
    plt.xlabel('log(degree)', fontsize=15, fontweight='bold')
    plt.ylabel('log(degree dis)', fontsize=15, fontweight='bold')
    plt.scatter(x, y, color='blue', linewidth=2)

    plt.plot(x1, y1, "r")
    plt.savefig(".\\net_data\\" + str(divide_name(_net_name)[0]) + "\\last_graph_degree_dis.png", dpi=600)
    plt.show()

def show_k_shell_dis_with_net(_net_name):
    """
    展示网络的边的k_shell分布
    :param _net_name:
    :return:
    """
    k_shell_dict = get_k_shell_dict(get_mat(_net_name), _net_name)
    max_k_shell = int(max(k_shell_dict.values()))
    x = list(range(1, max_k_shell+1))
    dis = np.zeros(max_k_shell)
    for edge in k_shell_dict:
        dis[int(k_shell_dict[edge]) - 1] += 1
    plt.figure(figsize=(10, 5))
    plt.title(_net_name + ' k_shell distribution', fontsize=25, fontweight='bold')
    plt.xlabel('k_shell', fontsize=15, fontweight='bold')
    plt.ylabel('p', fontsize=15, fontweight='bold')
    plt.bar(x, dis, color='blue', linewidth=2)
    plt.show()

def write_to_gephi(_net_name):
    """
    将网络转换维gexf文件，方便gephi使用
    :param _net_name:
    :return:
    """
    net_type, net_time = divide_name(_net_name)
    net = get_nx(_net_name)
    if os.path.exists(".\\net_data\\" + net_type + "\\gephi\\") is False:
        os.mkdir(".\\net_data\\" + net_type + "\\gephi\\")
    if net_time != "":
        file_name = ".\\net_data\\" + net_type + "\\gephi\\" + str(net_time) + ".gexf"
    else:
        file_name = ".\\net_data\\" + net_type + "\\gephi\\" + str(net_type) + ".gexf"
    nx.write_gexf(net, file_name)

def plot_graph(_net_name):
    net_type, net_time = divide_name(_net_name)
    path = ".\\net_data\\" + net_type + "\\gephi\\" + net_type + '_' + str(net_time) + "_dynamic.gexf"
    edge_days = get_all_edge_time(_net_name)
    days = sorted(set(edge_days.values()))
    start_day = days[0]
    end_day = days[-1]
    # xml 编写
    nsmap = {'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
    gexf = etree.Element('gexf', nsmap=nsmap)
    gexf.set('xmlns', 'http://www.gexf.net/1.1draft')
    gexf.set('version', '1.1')

    graph = etree.SubElement(gexf, 'graph', attrib={'mode': 'dynamic', 'defaultedgetype': 'undirected'})
    nodes = etree.SubElement(graph, 'nodes')
    edges = etree.SubElement(graph, 'edges')
    node_list = []
    for edge_day in edge_days.keys():
        if edge_day[0] not in node_list:
            node_list.append(edge_day[0])
            xml_node = etree.Element('node', attrib={'id': str(edge_day[0]), 'label': str(edge_day[0]),
                                                     'start': str(start_day), 'end': str(end_day)})
            nodes.append(xml_node)
        if edge_day[1] not in node_list:
            node_list.append(edge_day[1])
            xml_node = etree.Element('node', attrib={'id': str(edge_day[1]), 'label': str(edge_day[1]),
                                                     'start': str(start_day), 'end': str(end_day)})
            nodes.append(xml_node)
        xml_edge = etree.Element('edge', attrib={'source': str(edge_day[0]), 'target': str(edge_day[1]),
                                                 'start': str(edge_days[edge_day])})
        edges.append(xml_edge)
    gexf_tree = etree.ElementTree(gexf)
    gexf_tree.write(path, pretty_print=True, xml_declaration=True, encoding='utf-8')

if __name__ == '__main__':
    net_names = protein_net_names  # social_net_names[2:]  # protein_net_names + ["sci_net_contacts%51"]
    for net_name in net_names:
        show_degree_dis_with_net(net_name)
        # show_edge_nums_with_time(net_name)
        # write_to_gephi(net_name)
        # plot_graph(net_name)
        # show_k_shell_dis_with_net(net_name)
        # show_info_with_net(net_name)
        pass