from classes.menu import *
from classes.rangos import *
from classes.obtención import *
from classes.reporte import *
import sys
import matplotlib.pyplot as plt
import matplotlib.animation as animation

global pause
pause = False
global y_data
y_data = []

def onclick(event):
    global pause
    print("pausa")
    pause=True

fig, ax=plt.subplots()
fig.canvas.mpl_connect("button_press_event", onclick)

def update_data(i):
    if not pause:

        dato=int(puerto.readline().decode().strip())
        print(dato)
        y_data.append(dato)
        ax.clear()
        ax.plot(y_data)
        time.sleep(1)

def main():
    menu = Menu("Escuela de Ingeniería")
    op=menu.ver()

    if op == "1":
        menu2=Captura()
        op2=menu2.ver()
        if op2=="1":
            obtencion()
            main()
        elif op2=="2":
            ani= animation.FuncAnimation(fig,update_data)
            plt.show()
            save_dato(y_data)
            main()

    elif op =="2":
        eq=definir_rangos()
        eq.save_parametros()
        main()

    elif op=="3":
        menu2=Reportes()
        op2=menu2.ver()
        if op2==1:
            grafica()
            main()
        elif op2==2:
            valor_max()
            main()
        elif op2==3:
            valor_min()
            main()
        elif op2==4:
            prom_temp()
            main()

    elif op=="4":
        exit()
    else:
            print("Opción inválida")
            main()

if __name__=='__main__':
    main()


# This files contains your custom actions which can be used to run
# custom Python code.
#
# See this guide on how to implement these action:
# https://rasa.com/docs/rasa/custom-actions

from typing import Any, Text, Dict, List, Union

from rasa_sdk import Action, Tracker , FormValidationAction
from rasa_sdk.events import SlotSet, EventType,UserUtteranceReverted, ConversationPaused
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.types import DomainDict

from datetime import date,datetime,timedelta
import json

global recipient_email
recipient_email = "mata.khalili@nokia-bell-labs.com"

global user_name
user_name = "there"

global outlook_free_time
outlook_free_time = "4 pm"

global final_date
final_date = (date.today() + timedelta(days=10)) #assume that it's withtin 10 days to deliver the parcel

global locations
locations = {'chappe':[], 'curie':['E', 'D', 'B', 'C'],'shannon':[],
             'pascal':[], 'laplace':['East','West'],'torricelli':[],
             'ritchie':[], 'copernic':['G','H', 'EBC'], 'bourseul':[],
             'galilee':[], 'montgomerie':[], 'huygens':[], 'newton':['F','B'] }

class AppointmentInfoForm(Action):
    def name(self) -> Text:
        return "user_details_form"

    def run(
        self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict
    ) -> List[EventType]:

        required_slots = ["language","confirm_time","recipient","another_day","date", "time","location", "entrance"]

        for slot_name in required_slots:

            if tracker.slots.get(slot_name) is None:
                # The slot is not filled yet. Request the user to fill this slot next.
                return [SlotSet("requested_slot", slot_name)]

        # All slots are filled.
        return [SlotSet("requested_slot", None)]

class ActionSubmit(Action):
    def name(self) -> Text:
        return "action_submit"

    def run(
        self,
        dispatcher,
        tracker: Tracker,
        domain: "DomainDict",
    ) -> List[Dict[Text, Any]]:

        recipient=tracker.get_slot("recipient")
        date =tracker.get_slot("date")
        time=tracker.get_slot("time")
        building=tracker.get_slot("location")
        entrance= tracker.get_slot("entrance")

        dispatcher.utter_message(response="utter_details_thanks",
                                  Recipient=recipient,
                                  Date =date,
                                  Time=time,
                                  Location=building,
                                  Entrance= entrance)

        # try to add data to json file in the following format
        output=[]
        Appointment_data= {'Recipient':recipient,
                           'Date':date,
                           'Time':time,
                           'Building':building,
                           'Entrance':entrance}

        output.append(Appointment_data)
        json_output = json.dumps(output, indent = 6)

        # Writing to Output.json in a file
        with open("Appointment_details.json", "w") as outfile:
          outfile.write(json_output)

        return [ConversationPaused()]

class ActionGreet(Action):

    def name(self) -> Text:
        return "action_greet"

    def run(self, dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
        dispatcher.utter_message(response="utter_greet",
                                 name=user_name)

        return []

class ValidateNameForm(FormValidationAction):
    def name(self) -> Text:
        return "validate_user_details_form"

    async def validate_language(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> Dict[Text, Any]:
        allowed_languages=['english','french','anglais','francais','en','fr']
        language = value.lower()
        if language in allowed_languages:
            if language == "english" or language == "anglais" or language == "en":
                return {"language":"en"}
            else:
                return {"language":"fr"}
        else:
            dispatcher.utter_message(text="Supported languages are English and French only")
            return {"language":None }

    async def validate_confirm_time(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> Dict[Text, Any]:
        if value:
            Date = date.today().strftime('%Y-%m-%d')
            return {"recipient":recipient_email,"date":Date,"time": "4 pm","confirm_time": True,"another_day": False}
        else:
            return {"recipient":recipient_email,"another_day": False,"confirm_time": False }

    async def validate_date(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> Dict[Text, Any]:
        Format = '%Y-%m-%d'
        if value=="Today":
            Date = date.today().strftime(Format)
            return {"date":Date}
        elif value == "Tomorrow":
            Date = (date.today() + timedelta(days=1)).strftime(Format)
            return {"date":Date}
        elif value == "Another day":
            return {"another_day": True,"date":None}
        elif value == "Another Person":
            return {"time": "Not specified yet","date": "Not specified yet",
                    "location": "Not specified yet", "entrance":"Not specified yet","recipient":None}
        else:
            # return {"date":value}
            # if tracker.get_slot("another_day"):
              try:
                Date = datetime.strptime(value, Format).date()
                Today=date.today()
                if Date >= Today and Date <= final_date: # to make sure that the date is within the allowed period
                    return {"date":value}
                else:
                    if tracker.get_slot("language") == "en":
                       dispatcher.utter_message(text="Please enter a valid date ,date should be between "+Today.strftime('%Y-%m-%d')+" and "+final_date.strftime('%Y-%m-%d'))
                    else:
                       dispatcher.utter_message(text="Veuillez entrer une date valide, la date doit être comprise entre "+Today.strftime('%Y-%m-%d')+" et "+final_date.strftime('%Y-%m-%d'))
                    return {"date":None}
              except:
                try:
                    Format = '%d-%m-%Y'
                    Date = datetime.strptime(value, Format).date()
                    Today=date.today()
                    if Date >= Today and Date <= final_date: # to make sure that the date is within the allowed period
                      return {"date":value}
                    else:
                      if tracker.get_slot("language") == "en":
                        dispatcher.utter_message(text="Please enter a valid date ,date should be between "+Today.strftime('%Y-%m-%d')+" and "+final_date.strftime('%Y-%m-%d'))
                      else:
                        dispatcher.utter_message(text="Veuillez entrer une date valide, la date doit être comprise entre "+Today.strftime('%Y-%m-%d')+" et "+final_date.strftime('%Y-%m-%d'))
                      return {"date":None}
                except:
                  try:
                    Format = '%d/%m/%Y'
                    Date = datetime.strptime(value, Format).date()
                    Today=date.today()
                    if Date >= Today and Date <= final_date: # to make sure that the date is within the allowed period
                      return {"date":value}
                    else:
                      if tracker.get_slot("language") == "en":
                        dispatcher.utter_message(text="Please enter a valid date ,date should be between "+Today.strftime('%Y-%m-%d')+" and "+final_date.strftime('%Y-%m-%d'))
                      else:
                        dispatcher.utter_message(text="Veuillez entrer une date valide, la date doit être comprise entre "+Today.strftime('%Y-%m-%d')+" et "+final_date.strftime('%Y-%m-%d'))
                      return {"date":None}
                  except:
                    if tracker.get_slot("language") == "en":
                      dispatcher.utter_message(text="Please enter a valid date in the following format: "+Format)
                    else:
                      dispatcher.utter_message(text="Veuillez saisir la date au format suivant: "+ Format)
                    return {"date":None}

    def validate_time(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> Dict[Text, Any]:
        if tracker.get_slot("language") == "en":
         try:
          time = datetime.strptime(value, "%I:%M %p")
          final_time= datetime.strftime(time, "%H:%M")
          return{"time":final_time}
         except:
            try:
               time = datetime.strptime(value, "%I:%M%p")
               final_time= datetime.strftime(time, "%H:%M")
               return{"time":final_time}
            except:
                try:
                   time = datetime.strptime(value, "%I %p")
                   final_time= datetime.strftime(time, "%H:%M")
                   return{"time":final_time}
                except:
                     try:
                       time = datetime.strptime(value, "%I%p")
                       final_time= datetime.strftime(time, "%H:%M")
                       return{"time":final_time}
                     except:
                        try:
                            time = datetime.strptime(value, "%I:%M")
                            final_time= datetime.strftime(time, "%H:%M")
                            return{"time":final_time}
                        except:
                            if tracker.get_slot("language") == "en":
                               dispatcher.utter_message(text="Please enter a valid time (e.g 3:00 PM)")
                            else:
                               dispatcher.utter_message(text="Veuillez entrer une heure valide (e.g 3:00 PM)")
                            return{"time":None}
        else:
            try:
              x = value.index('h')
              if x==len(value)-1:
                time= value[0:x]+':'+'00'
              else:
                time = value[0:x]+ ':' + value[x+1:len(value)]
              return({"time":time})
            except:
              return({"time":value})

    async def validate_location(
        self,
        slot_value: Any,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> Dict[Text, Any]:
        """Validate `location` value."""

        # If the building isn't exist
        print(f"location given = {slot_value}")

        building = slot_value.lower()

        if building in locations:

            if len(locations.get(building))>0:
               return{"location": slot_value}
            else:
              if tracker.get_slot("language") == "en":
                return {"entrance":"main","location": slot_value}
              else:
                return {"entrance":"principale","location": slot_value}
        else:
            buildings= ','.join([str(elem) for elem in locations])
            if tracker.get_slot("language") == "en":
                 dispatcher.utter_message(text="That's not valid Building. \nYou should choose one of the following: \n"+buildings)
            else:
                 dispatcher.utter_message(text="Ce n'est pas un bâtiment valide. \nVous devez choisir l'une des options suivantes: \n"+buildings)
            return {"location": None}

    def validate_entrance(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> Dict[Text, Any]:
        try:
         Entrances= locations.get(tracker.get_slot("location").lower())
         entrances = ','.join([str(elem) for elem in Entrances])
         if value in Entrances:
             return {"entrance": value}
         else:
            if tracker.get_slot("language") == "en":
                dispatcher.utter_message(text="That's not valid Entrance. \nYou should choose one of the following: \n"+entrances)
            else:
                dispatcher.utter_message(text="Ce n'est pas une entrée valide. \n Vous devez choisir l'un des éléments suivants : \n"+entrances)
            return {"entrance": None}
        except:
            return {"entrance": None}

class ActionCustomFallback(Action):

    def name(self) -> Text:
        return "action_custom_fallback"

    def run(self, dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:

        dispatcher.utter_message(template="utter_custom")

        return[UserUtteranceReverted()]  # to consider it a fallback action


import pandas as pd
import matplotlib.pyplot as plt

aurora = pd.read_csv("tmp/rl_test/rl_test_log0.csv")
cubic = pd.read_csv("tmp_cubic/cubic_test_log0.csv")

fig, axes = plt.subplots(2, 2, figsize=(12, 8))

axes[0, 0].plot(aurora['timestamp'],
                aurora['throughput'] * 1500 * 8 / 1000000, c='C0',
                label='{} recv rate, avg {:.3f}mbps'.format(
                    "aurora", aurora['throughput'].mean() * 1500 * 8 / 1000000))
axes[0, 0].plot(aurora['timestamp'],
                aurora['send_throughput'] * 1500 * 8 / 1000000, ls='--',
                c='C0', label='{} send rate, avg {:.3f}mbps'.format(
                    "aurora", aurora['send_throughput'].mean() * 1500 * 8 / 1000000))

axes[0, 0].plot(cubic['timestamp'],
                cubic['throughput'] * 1500 * 8 / 1000000, c='C1',
                label='{} recv rate, avg {:.3f}mbps'.format(
                    "cubic", cubic['throughput'].mean() * 1500 * 8 / 1000000))
axes[0, 0].plot(cubic['timestamp'],
                cubic['send_throughput'] * 1500 * 8 / 1000000, ls='--',
                c='C1',
                label='{} send rate, avg {:.3f}mbps'.format(
                    "cubic", cubic['send_throughput'].mean() * 1500 * 8 / 1000000))
axes[0, 0].plot(cubic['timestamp'], cubic['link0_bw'] * 1500 * 8 / 1000000,
                c='C2', label='bw, avg {}mbps'.format(cubic['link0_bw'].mean() * 1500 * 8 / 1000000))
axes[0, 0].set_title("Simulator, Rate")
axes[0, 0].set_xlabel("Time(s)")
axes[0, 0].set_ylabel("mbps")
axes[0, 0].legend()

axes[0, 1].scatter(aurora['timestamp'], aurora['latency'] * 100, c='C0',
        label='Aurora, RTT, avg {:.2f}ms'.format(aurora['latency'].mean() * 1000))
axes[0, 1].scatter(cubic['timestamp'], cubic['latency'] * 100, c='C1',
        label='Cubic, RTT, avg {:.2f}ms'.format(cubic['latency'].mean() * 1000))
axes[0, 1].set_title("Simulator(Link RTT=100ms), RTT")
axes[0, 1].set_xlabel("Time(s)")
axes[0, 1].set_ylabel("ms")
axes[0, 1].legend()

plt.tight_layout()
plt.show()


from __future__ import unicode_literals
from pn532 import PN532_SPI
import vlc
import random
import re
import unicodedata

import RPi.GPIO as GPIO

GPIO.setwarnings(False)

class Reader:

    TIMEOUT = 1  # seconds
    DEFAULT = "downloads/default/endline.wav"

    def __init__(self, player, playlist_map) -> None:
        self.player = player
        self.playlist_map = playlist_map
        self.playing = False
        self.reading = True
        self.last_tag = None

    def start(self) -> None:
        try:
            pn532 = PN532_SPI(debug=False, reset=20, cs=4)
            ic, ver, rev, support = pn532.get_firmware_version()
            print("Found PN532: {0}.{1}".format(ver, rev))
            pn532.SAM_configuration()
            print("Starting reader...")
            while self.reading:
                tag = pn532.read_passive_target(timeout=self.TIMEOUT)
                if tag is None:
                    self.player.stop()
                    self.playing = False
                    continue
                self.last_tag = str(tag.hex())
                if not self.playing:
                    print(f"looking for match: {self.last_tag}")
                    try:
                        joycon = self.playlist_map[self.last_tag]
                        print(f"Found: {joycon['name']}")
                        playlist = joycon["playlist"]
                        if joycon["shuffle"]:
                            random.shuffle(playlist)
                        self.player.set_media_list(vlc.MediaList(playlist))
                        if joycon["repeat"]:
                            self.player.set_playback_mode(vlc.PlaybackMode.loop)
                        else:
                            self.player.set_playback_mode(vlc.PlaybackMode.default)
                        self.player.play()
                        self.playing = True
                    except Exception as x:
                        self.player.set_media_list(vlc.MediaList([self.DEFAULT]))
                        self.player.play()
                        self.playing = True

        except Exception as e:
            print(e)


from __future__ import unicode_literals
#TODO Send try_dl of music after getting number of track if not automatic
#TODO aioify blocking calls
#TODO irs music dler
#TODO torrent
#TODO aria2 dler
#TODO Go through WG-TE and add the spotify songs based on today's date: 8 Jun 2018
#TODO repeat n-times module
#TODO self_only eval
#TODO Tumblr? :D
#TODO Google?
#TODO adapt other modules
#TODO borg injection into util

from aioify import aioify
import eyed3
import re

import asyncio
import pexpect
from telethon import TelegramClient, events
from telethon.tl.functions.users import GetFullUserRequest
import logging
from uniborg import util
from requests import get  # to make GET request
import wget
import os
import sys
import traceback
import youtube_dl
import uuid
import types

is_interactive = True

pexpect_ai = aioify(pexpect)
os_aio = aioify(os)
eyed3_aio = aioify(eyed3)

######################
async def get_music(name='Halsey Control', cwd="./dls/BAD/", tg_event=None):
    #Be sure to set cwd again. It is only set once.
    #TODO Raise exception if cwd is not set. Non-optional named variable?

    # print(name + " cwd0: \n" + cwd)
    await pexpect_ai.run('mkdir -p ' + cwd)
    child = await pexpect_ai.spawn('instantmusic', cwd=cwd)
    child.logfile = open('/tmp/mylog', 'wb')
    child.expect('Enter*')
    child.sendline(name)
    child.expect(re.compile(b'Found.*Pick one', re.S))
    if tg_event is None:
        child.sendline('0')
    else:
        choose_msg = await tg_event.reply(child.match.group().decode('utf-8') +
                                          ".")
        choose_reply_msg = await await_reply(tg_event.chat, choose_msg)
        choice_text = choose_reply_msg.raw_text
        if choice_text.isnumeric():
            child.sendline(choice_text)
        else:
            child.sendline('0')
    child.expect(['Download*', '\(y/n\)*'])
    child.sendline('y')
    # print(name + " cwd1: \n" + cwd)
    await (aioify(child.expect)(
        ['Fixed*', 'couldnt get album art*'], timeout=3000))
    # print(name + " cwd2: \n" + cwd)
    mp3_file_add = cwd + str(
        await pexpect_ai.run('bash -c "exa -a --color=never"', cwd=cwd),
        'utf-8').strip() # exa --all doesn't include . and ..
    mp3_file = await eyed3_aio.load(mp3_file_add)
    mp3_file.tag.title = str(await os_aio.path.basename(mp3_file_add))[:-4]
    await (aioify(mp3_file.tag.save))()
    return mp3_file_add

######################
async def await_reply(chat, message):
    async def reply_filter(new_msg_event):
        return (new_msg_event.message.reply_to_msg_id == message.id)

    fut = borg.await_event(events.NewMessage(chats=chat), reply_filter)
    return await fut

######################
@borg.on(events.NewMessage())
async def _(event):
    first_line = "l"
    try:
        first_line = event.raw_text.lower().splitlines().pop(0)
    except:
        pass
    quiet = any(s in first_line for s in ('quiet','ساکت','آروم','اروم'))
    if ('ژاله' in first_line or 'زاله' in first_line or 'julia' in first_line):
        # print("Julia")
        global my_event
        my_event = event
        if event.sender is not None and (
            (event.sender).is_self or
            (event.sender).username == "Orphicality"):
            if any(s in first_line for s in ('laugh', 'بخند')):
                await event.reply('😆')
            if any(s in first_line for s in ('you okay', 'خوبی')):
                await event.reply('I know of no light. :p')

            if any(
                    s in first_line for s in ('nice work', 'thanks', 'merci',
                                              'good job', 'مرسی')):
                await event.reply("You're welcome. ❤")
        # else:
        # else:

        if any(s in first_line for s in ('debug', 'دیباگ')):
            db_msg = await event.reply('DEBUG')
            db_reply = await await_reply(event.chat, db_msg)
            print("YDebug: " + db_reply.raw_text)

        if any(
                s in first_line for s in ('hi', 'hello', 'hey', 'yo',
                                          'greetings', 'سلام', 'هی', 'یو!')):
            sender_name = "Unknown"
            if event.sender is not None:
                sender_name = (event.sender).first_name
            await event.reply("Julia is operational.\nGreetings,  " +
                              sender_name + "!")

        if any(s in first_line for s in ('upload', 'اپلود', 'آپلود')):
            urls = event.raw_text.splitlines()
            urls.pop(0)
            for url in urls:
                try:
                    if url == '':
                        continue
                    url_name = wget.detect_filename(url)
                    trying_to_dl_msg = await util.discreet_send(event, "Julia is trying to download \"" + url_name + "\" from \"" + url + "\".\nPlease wait ...", event.message, quiet)
                    d1 = wget.download(url, out="dls/", bar=None)
                    try:
                        trying_to_upload_msg = await util.discreet_send(
                            event, "Julia is trying to upload \"" +
                            url_name + "\".\nPlease wait ...",
                            trying_to_dl_msg, quiet)
                        await borg.send_file(
                            event.chat,
                            d1,
                            reply_to=trying_to_upload_msg,
                            caption=(url_name))
                    except:
                        await event.reply(
                            "Julia encountered an exception. :(\n" +
                            traceback.format_exc())
                    finally:
                        await util.remove_potential_file(d1)

                except:
                    await event.reply("Julia encountered an exception. :(\n" +
                                      traceback.format_exc())

        if any(s in first_line for s in ('yt', 'youtube', 'یوتیوب')):
            urls = event.raw_text.splitlines()
            urls.pop(0)
            for url in urls:
                if url == '':
                    continue
                file_name_with_ext = ""
                try:
                    trying_to_dl = await util.discreet_send(event,
                                                 "Julia is trying to download \"" + url +
                                                 "\".\nPlease wait ...", event.message, quiet)
                    file_name = 'dls/' + str(uuid.uuid4()) + '/'
                    ydl_opts = {
                        'quiet': True,
                        'outtmpl':
                        file_name +'%(playlist_title)s_%(title)s_%(format)s.%(ext)s'  # 'dls/%(playlist_title)s_%(title)s_%(format)s_%(autonumber)s.%(ext)s'
                    }
                    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
                        extract_info_aio = aioify(ydl.extract_info)
                        d2 = await extract_info_aio(url)
                        file_name_with_ext = file_name + (await os_aio.listdir(file_name))[0]
                        trying_to_upload_msg = await util.discreet_send(
                            event,
                            "Julia is trying to upload \"" + d2['title'] +
                            "\".\nPlease wait ...",
                            trying_to_dl,
                            quiet)
                        sent_video = await borg.send_file(
                            event.chat,
                            file_name_with_ext,
                            reply_to=trying_to_upload_msg,
                            caption=str(d2['title']))
                        try:
                            full_caption = "Title: " + str(
                                d2['title']
                            ) + "\nFormat: " + str(
                                d2['format']
                            ) + "\nWidth: " + str(d2['width']) + "\nHeight: " + str(
                                d2['height']
                            ) + "\nFPS: " + str(d2['fps']) + "\nPlaylist: " + str(
                                d2['playlist']) + "\nLikes: " + str(
                                    d2['like_count']) + "\nDislikes: " + str(
                                        d2['dislike_count']
                                    ) + "\nView Count: " + str(
                                        d2['view_count']) + "\nUploader: " + str(
                                            d2['uploader'] + "\nWebpage Url: " +
                                            str(d2['webpage_url']) +
                                            "\nDescription:\n" +
                                            str(d2['description']))
                            await borg.send_message(
                                event.chat,
                                full_caption,
                                sent_video,
                                link_preview=False)
                        except:
                            pass
                except:
                    await event.reply("Julia encountered an exception. :(\n" +
                                      traceback.format_exc())
                finally:
                    await util.remove_potential_file(file_name_with_ext)
        if any(s in first_line for s in ('music', 'موسیقی', 'اهنگ', 'آهنگ')):
            # print(first_line)
            urls = event.raw_text.splitlines()
            urls.pop(0)
            for url in urls:
                # print(url)
                if url == '':
                    continue
                file_name_with_ext = ''
                trying_to_dl = await util.discreet_send(event, "Julia is trying to download \"" + url + "\".\nPlease wait ...",
                                                   event.message, quiet)
                try:
                    if any(s in first_line for s in ('automatic', 'اتوماتیک')):
                        file_name_with_ext = await get_music(
                            url, cwd="./dls/" + str(uuid.uuid4()) + "/")
                    else:
                        file_name_with_ext = await get_music(
                            url,
                            tg_event=event,
                            cwd="./dls/" + str(uuid.uuid4()) + "/")
                    base_name = str(await os_aio.path.basename(file_name_with_ext))
                    trying_to_upload_msg = await util.discreet_send(
                        event,
                        "Julia is trying to upload \"" + base_name +
                        "\".\nPlease wait ...",
                        trying_to_dl,
                        quiet)
                    sent_music = await borg.send_file(
                        event.chat,
                        file_name_with_ext,
                        reply_to=trying_to_upload_msg,
                        caption=base_name)
                except:
                    await event.reply("Julia encountered an exception. :(\n" +
                                      traceback.format_exc())
                finally:
                    await util.remove_potential_file(file_name_with_ext, event)
    p = re.compile(r'^Added to (.*) on Spotify: "(.*)" by (.*) https:.*$')
    m = p.match(event.raw_text)
    if m is not None:
        file_name_with_ext = ''
        try:
            # print(m.group(3)+" "+m.group(2)) #DBG
            file_name_with_ext = await get_music(
                m.group(3)+" "+m.group(2),
                cwd="./dls/" + str(uuid.uuid4()) + "/")
            base_name = str(await os_aio.path.basename(file_name_with_ext))
            sent_music = await borg.send_file(
                event.chat,
                file_name_with_ext,
                reply_to=event.message,
                caption=base_name)
        except:
            await event.reply("Julia encountered an exception. :(\n" +
                              traceback.format_exc())
        finally:
            await util.remove_potential_file(file_name_with_ext, event)


#fourier transform in numpy
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img = cv.imread('Resources/messi5.jpg',0)
# img = np.ones((3,3))
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
fshift_magnitude = np.abs(fshift)
magnitude_spectrum = 20*np.log(np.abs(fshift))
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()

#low frequency filter
# rows, cols = img.shape
# crow,ccol = rows//2 , cols//2
# fshift[crow-30:crow+31, ccol-30:ccol+31] = 0
# f_ishift = np.fft.ifftshift(fshift)
# img_back = np.fft.ifft2(f_ishift)
# img_back = np.real(img_back)
# plt.subplot(222),plt.imshow(img, cmap = 'gray')
# plt.title('Input Image'), plt.xticks([]), plt.yticks([])
# plt.subplot(223),plt.imshow(img_back, cmap = 'gray')
# plt.title('Image after HPF'), plt.xticks([]), plt.yticks([])
# plt.subplot(224),plt.imshow(img_back)
# plt.title('Result in JET'), plt.xticks([]), plt.yticks([])
# plt.show()

#fourier transform in opencv
# It returns the same result as previous, but with two channels. First channel will have the real part of the result and second channel will have the imaginary part of the result. The input image should be converted to np.float32 first.
# dft = cv.dft(np.float32(img),flags = cv.DFT_COMPLEX_OUTPUT)
# dft_shift = np.fft.fftshift(dft)
# magnitude_spectrum = 20*np.log(cv.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
# plt.subplot(121),plt.imshow(img, cmap = 'gray')
# plt.title('Input Image'), plt.xticks([]), plt.yticks([])
# plt.subplot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')
# plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
# plt.show()

#low pass filter
# rows, cols = img.shape
# crow,ccol = rows//2 , cols//2
# # create a mask first, center square is 1, remaining all zeros
# mask = np.zeros((rows,cols,2),np.uint8)
# mask[crow-30:crow+30, ccol-30:ccol+30] = 1
# # apply mask and inverse DFT
# fshift = dft_shift*mask
# f_ishift = np.fft.ifftshift(fshift)
# img_back = cv.idft(f_ishift)
# img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])
# plt.subplot(121),plt.imshow(img, cmap = 'gray')
# plt.title('Input Image'), plt.xticks([]), plt.yticks([])
# plt.subplot(122),plt.imshow(img_back, cmap = 'gray')
# plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
# plt.show()

#performance optimization of dft
rows,cols = img.shape
print("{} {}".format(rows,cols))

nrows = cv.getOptimalDFTSize(rows)
ncols = cv.getOptimalDFTSize(cols)
print("{} {}".format(nrows,ncols))

nimg = np.zeros((nrows,ncols))
nimg[:rows,:cols] = img

# laplacian high pass filter
# simple averaging filter without scaling parameter
# mean_filter = np.ones((100,100))
# # creating a gaussian filter
# x = cv.getGaussianKernel(20,10)
# gaussian = x*x.T
# # different edge detecting filters
# # scharr in x-direction
# scharr = np.array([[-3, 0, 3],
#                    [-10,0,10],
#                    [-3, 0, 3]])
# # sobel in x direction
# sobel_x= np.array([[-1, 0, 1],
#                    [-2, 0, 2],
#                    [-1, 0, 1]])
# # sobel in y direction
# sobel_y= np.array([[-1,-2,-1],
#                    [0, 0, 0],
#                    [1, 2, 1]])
# # laplacian
# laplacian=np.array([[0, 1, 0],
#                     [1,-4, 1],
#                     [0, 1, 0]])
# filters = [mean_filter, gaussian, laplacian, sobel_x, sobel_y, scharr]
# filter_name = ['mean_filter', 'gaussian','laplacian', 'sobel_x', \
#                 'sobel_y', 'scharr_x']
# fft_filters = [np.fft.fft2(x) for x in filters]
# fft_shift = [np.fft.fftshift(y) for y in fft_filters]
# mag_spectrum = [np.log(np.abs(z)+1) for z in fft_shift]
# for i in range(6):
#     plt.subplot(2,3,i+1),plt.imshow(mag_spectrum[i],cmap = 'gray')
#     plt.title(filter_name[i]), plt.xticks([]), plt.yticks([])
# plt.show()


import sys, os, pathlib, subprocess

sys.path.append(os.path.join(pathlib.Path(__file__).resolve().parents[1], 'src'))

import physion

if os.path.isfile(sys.argv[-1]) and ('.nwb' in sys.argv[-1]):
    cmd, cwd = physion.assembling.build_NWB.build_cmd(sys.argv[-1])
    p = subprocess.Popen(cmd,
                         cwd=cwd,
                         shell=True)
else:
    print(' build test data ' )


import os
import AtmelCom
import time
import numpy as np
import utils
from datetime import datetime

th = 900 # threshold de corriente de pulsacion, default 700
tm = 1 # tiempo entre cada ciclo
m = AtmelCom.Atmel()

freq = [262, 294, 330, 349, 392]
dbi = [20, 40, 60]

mc = 0
cb = 0
cf = -1
cdbi = -1

duracionplay = 3

psi = False
pno = False
repr = False

f = -1
i = -1

# freq, intensidad
results = []

print("Mantenga presionado dos unidades de tiempo el boton del asistente para cambiar de modo!")

print("Ciclo principal iniciado...")
while True:
    lc = m.analogRead([0, 1, 2])

    if np.max(lc) >= th:
        btn = np.argmax(lc)
        print(btn)

        ffm = f"la frecuencia {freq[cf]} Hz, intensidad de {dbi[cdbi]} dB, duracion de {duracionplay}"

        if len(results) >= 5:
            ffm = f"la frecuencia {f} Hz, intensidad de {i} dB, duracion de {duracionplay}"

        if btn == 0:
            cb += 1
            print("."*cb)
        elif btn == 1:
            if repr:
                print(f"Si ha escuchado {ffm}")
                repr = False

                if len(results) < 5:
                    utils.insert(freq[cf], duracionplay, dbi[cdbi], 1)
                    results.append([freq[cf], dbi[cdbi], 1])
                else:
                    utils.insert(f, duracionplay, i, 1)
                    results.append([f, i, 1])
        elif btn == 2:
            if repr:
                print(f"No ha escuchado {ffm}")
                repr = False

                if len(results) < 5:
                    utils.insert(freq[cf], duracionplay, dbi[cdbi], 0)
                    results.append([freq[cf], dbi[cdbi], 0])
                else:
                    utils.insert(f, duracionplay, i, 0)
                    results.append([f, i, 0])

        if len(results) >= 5:
            s = input("Finalizar audiometria? (s/n): ").strip().lower() == 's'

            if s:
                print("Guardando resultados...")
                jklm = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                utils.generar_pdf_audiometria([c[:2] for c in results if c[2] == 1], f'escuchadas-{jklm}')
                utils.generar_pdf_audiometria([c[:2] for c in results if c[2] != 1], f'no-escuchadas-{jklm}')
                print("Audiometria finalizada...")
                exit()

            f = float(input("Ingrese la frecuencia (Hz): "))
            i = float(input("Ingrese la intensidad (dB): "))
            print("Reproduciendo...")
            utils.play_frequency(f, duracionplay, i)
            repr = True
    else:
        if cb == 1:
            if mc == 0:
                cf += 1
                if cf >= len(freq): cf = 0
                print(f"La frecuencia elegida es: {freq[cf]}")
            elif mc == 1:
                cdbi += 1
                if cdbi >= len(dbi): cdbi = 0
                print(f"Decibeles elegidos: {dbi[cdbi]}")
        elif cb >= 2:
            if mc == 0:
                print("Modo de eleccion de decibeles activado!")
                mc = 1
            elif mc == 1:
                print("Reproduccion iniciada!")
                utils.play_frequency(freq[cf], duracionplay, dbi[cdbi])
                repr = True
                mc = 0
        cb = 0

    time.sleep(tm)


'''
Neural Style Transfer   -   Drawing images in the style of another image
'''

import IPython.display as display
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import PIL.Image
import time
import os
from datetime import datetime

import tensorflow as tf

global start_process, epochs, steps_per_epoch, image_to_use, style_to_use, generated_dir, photos_dir, paintings_dir, photos_dict, paintings_dict

# Defines the content and style variables, the functions that are used and the training procedure
def initialize():
    global start_process, epochs, steps_per_epoch, image_to_use, style_to_use, generated_dir, photos_dir, paintings_dir, photos_dict, paintings_dict
    start_process = datetime.now()
    mpl.rcParams['figure.figsize'] = (10, 10)
    mpl.rcParams['axes.grid'] = False
    epochs = 5      # Final output quality increases with epoch count (up to max ~20)
    steps_per_epoch = 50

    root_dir = os.path.dirname(os.path.abspath(__file__))  # os.getcwd()
    photos_dir = root_dir + "/images/content/"
    paintings_dir = root_dir + "/images/styles/"
    generated_dir = root_dir + "/images/generated/"
    image_extension = ".jpg"

    # Setting up Images and Styles
    photos_dict = {}
    paintings_dict = {}
    for filename in os.listdir(photos_dir):
        if filename.endswith(image_extension):
            photos_dict[filename[:-4]] = photos_dir + filename

    for filename in os.listdir(paintings_dir):
        if filename.endswith(image_extension):
            paintings_dict[filename[:-4]] = paintings_dir + filename

    print(photos_dict)
    print(paintings_dict)

'''
Functions to visualise the input
'''

# Converts Tensor Object to Image
def tensor_to_image(tensor):
    tensor = tensor * 255
    tensor = np.array(tensor, dtype=np.uint8)
    if np.ndim(tensor) > 3:
        assert tensor.shape[0] == 1
        tensor = tensor[0]
    return PIL.Image.fromarray(tensor)

# Loads the Image
def load_img(path_to_img):
    max_dim = 512
    img = tf.io.read_file(path_to_img)
    img = tf.image.decode_image(img, channels=3)
    img = tf.image.convert_image_dtype(img, tf.float32)
    shape = tf.cast(tf.shape(img)[:-1], tf.float32)
    long_dim = max(shape)
    scale = max_dim / long_dim
    new_shape = tf.cast(shape * scale, tf.int32)
    img = tf.image.resize(img, new_shape)
    img = img[tf.newaxis, :]
    return img

# Displays the Image
def show_image(image, title=None):
    if len(image.shape) > 3:
        image = tf.squeeze(image, axis=0)

    plt.imshow(image)
    if title:
        plt.title(title)

'''
Runs The ML Program Start To Finish
'''

def training(content, style):
    print("From NST", '{}-{}.jpg'.format(content, style))
    print("Training...")

    # Configuring Modules
    print("Creating TF image objects...")
    content_path = photos_dict[content]
    style_path = paintings_dict[style]
    content_image = load_img(content_path)
    style_image = load_img(style_path)

    # Define Content and Style Representations
    print("Defining photo and painting input representations for the model...")
    x = tf.keras.applications.vgg19.preprocess_input(content_image*255)
    x = tf.image.resize(x, (224, 224))
    vgg = tf.keras.applications.VGG19(include_top=True, weights='imagenet')
    prediction_probabilities = vgg(x)

    content_layers = ['block5_conv2']
    style_layers = ['block1_conv1',
                    'block2_conv1',
                    'block3_conv1',
                    'block4_conv1',
                    'block5_conv1']
    num_content_layers = len(content_layers)
    num_style_layers = len(style_layers)

    extractor = StyleContentModel(style_layers, content_layers)

    # Run Gradient Descent
    style_targets = extractor(style_image)['style']
    content_targets = extractor(content_image)['content']
    image = tf.Variable(content_image)      # This is the image object that gets passed to numerous functions

    opt = tf.optimizers.Adam(learning_rate=0.02, beta_1=0.99, epsilon=1e-1)

    style_weight = 1e-2
    content_weight = 1e4
    total_variation_weight = 30

    input_values = [style_targets, style_weight, num_style_layers,
                    content_targets, content_weight, num_content_layers,
                    extractor, opt]

    '''
    Perform a Long Optimisation
    '''
    print("Performing Long Optimisation...")
    start = time.time()
    step = 0
    for n in range(epochs):
        for m in range(steps_per_epoch):
            step += 1
            train_step(image, input_values, total_variation_weight)
            print(".", end='')
        display.clear_output(wait=True)
        # display.display(tensor_to_image(image))
        print("Train step: {}".format(step))
    end = time.time()
    print("Total time: {:.1f}".format(end - start))
    print("Finished Optimisation!")

    # Total Variational Loss
    tf.image.total_variation(image).numpy()

    '''
    Rerun Optimisation
    '''
    print("Rerunning Optimisation With New Variational Loss Calculated...")
    image = tf.Variable(content_image)     # This is the redefined image object
    start = time.time()
    step = 0
    for n in range(epochs):
        for m in range(steps_per_epoch):
            step += 1
            train_step(image, input_values, total_variation_weight)
            print(".", end='')
        display.clear_output(wait=True)
        # display.display(tensor_to_image(image))
        print("Train step: {}".format(step))
    end = time.time()
    print("Total time: {:.1f}".format(end - start))
    print("Finished rerunning optimisation!")
    save_results(image, content, style)
    gen_path = generated_dir + '/detail/' + '{}-{}.jpg'.format(content, style)
    return gen_path, image

'''
Extracting Model Features Functions
'''

def vgg_layers(layer_names):
    vgg = tf.keras.applications.VGG19(include_top=False, weights='imagenet')
    vgg.trainable = False

    outputs = [vgg.get_layer(name).output for name in layer_names]

    model = tf.keras.Model([vgg.input], outputs)
    return model

# Calculate Style and Extracting Style and Content
def gram_matrix(input_tensor):
    result = tf.linalg.einsum('bijc,bijd->bcd', input_tensor, input_tensor)
    input_shape = tf.shape(input_tensor)
    num_locations = tf.cast(input_shape[1]*input_shape[2], tf.float32)
    return result/num_locations

def clip_0_1(image):
    return tf.clip_by_value(image, clip_value_min=0.0, clip_value_max=1.0)

def style_content_loss(outputs, input_values):
    style_targets, style_weight, num_style_layers, content_targets, content_weight, num_content_layers, extractor, opt = input_values
    style_outputs = outputs['style']
    content_outputs = outputs['content']
    style_loss = tf.add_n([tf.reduce_mean((style_outputs[name] - style_targets[name]) ** 2)
                           for name in style_outputs.keys()])
    style_loss *= style_weight / num_style_layers

    content_loss = tf.add_n([tf.reduce_mean((content_outputs[name] - content_targets[name]) ** 2)
                             for name in content_outputs.keys()])
    content_loss *= content_weight / num_content_layers
    loss = style_loss + content_loss
    return loss

'''
Training Function
'''

def train_step(image, input_values, total_variation_weight):
    extractor, opt = input_values[-2], input_values[-1]
    with tf.GradientTape() as tape:
        outputs = extractor(image)
        loss = style_content_loss(outputs, input_values)
        loss += total_variation_weight*tf.image.total_variation(image)

    grad = tape.gradient(loss, image)
    opt.apply_gradients([(grad, image)])
    image.assign(clip_0_1(image))

'''
Total Variation Loss Functions
'''

def high_pass_x_y(image):
    x_var = image[:, :, 1:, :] - image[:, :, :-1, :]
    y_var = image[:, 1:, :, :] - image[:, :-1, :, :]
    return x_var, y_var

def total_variation_loss(image):
    x_deltas, y_deltas = high_pass_x_y(image)
    return tf.reduce_sum(tf.abs(x_deltas)) + tf.reduce_sum(tf.abs(y_deltas))

'''
Saving Results Function
'''

def save_results(image, content, style):
    print("Saving Results...")
    file_name = '{}-{}.jpg'.format(content, style)
    print("Saving {}...".format(file_name))
    tensor_to_image(image).save(generated_dir + file_name)
    print("Finished Saving Stylised File")
    print("Finished ML Process In ", datetime.now() - start_process)

# Builds a model that returns the style and content tensors
class StyleContentModel(tf.keras.models.Model):
    def __init__(self, style_layers, content_layers):
        super(StyleContentModel, self).__init__()
        self.vgg = vgg_layers(style_layers + content_layers)
        self.style_layers = style_layers
        self.content_layers = content_layers
        self.num_style_layers = len(style_layers)
        self.vgg.trainable = False

    def call(self, inputs):
        # Expects float input in [0,1]
        inputs = inputs*255.0
        preprocessed_input = tf.keras.applications.vgg19.preprocess_input(inputs)
        outputs = self.vgg(preprocessed_input)
        style_outputs, content_outputs = (outputs[:self.num_style_layers],
                                          outputs[self.num_style_layers:])

        style_outputs = [gram_matrix(style_output)
                         for style_output in style_outputs]

        content_dict = {content_name: value
                        for content_name, value
                        in zip(self.content_layers, content_outputs)}

        style_dict = {style_name: value
                      for style_name, value
                      in zip(self.style_layers, style_outputs)}

        return {'content': content_dict, 'style': style_dict}

'''
Simple Command To Run The Whole Thing
'''

def run(content, style):
    initialize()
    gen_path, image = training(content, style)
    return gen_path, image

def run_all():
    initialize()
    for style in paintings_dict.keys():
        for content in photos_dict.keys():
            if not check_exists(content, style):
                training(content, style)
            else:
                print(content + '-' + style + '.jpg' + ' already has been generated!')

def check_exists(content, style):
    filename = content + '-' + style + '.jpg'
    for generated in os.listdir(generated_dir):
        if filename == generated:
            return True        # Has already been generated
    return False    #  Has not already been generated


import sys

sys.path.append("./")

from time import sleep

# import data.dbase.djconn
from data.dbase.db_tables import (
    Tracking,
    TrackingBP,
    SessionCondition,
    Surgery,
)
import pandas as pd

dest_fld = "/Users/federicoclaudi/Desktop/mysql-server-locomotion/whole_session_tracking"

# check if the folder exists
import os

if not os.path.exists(dest_fld):
    os.makedirs(dest_fld)

entries = (
    Tracking * TrackingBP * SessionCondition * Surgery
    & "bpname='body'"
    & "target='CUN/GRN'"
)

count = 0
for entry in entries:
    count += 1
    # if count < 60:
    #     continue
    name, target, condition = (
        entry["name"],
        entry["target"],
        entry["condition"],
    )
    target = target.replace("/", "-")

    dest_fl = os.path.join(dest_fld, f"{name}_{target}_{condition}.csv")
    if os.path.exists(dest_fl):
        print(f"Skipping {name} {target} {condition}")
        sleep(0.25)
        continue

    print(count, name)

    df = pd.DataFrame(
        dict(
            x=entry["x"],
            y=entry["y"],
            u=entry["u"],
            udot=entry["udot"],
            speed=entry["speed"],
            acceleration=entry["acceleration"],
            theta=entry["theta"],
            thetadot=entry["thetadot"],
            thetadotdot=entry["thetadotdot"],
        )
    )

    df.to_csv(dest_fl)


import bs4, requests, random

class arrestorg():
    def __init__(self):
        self.state = ""
        self.arrestsession = requests.session()
        self.page = self.arrestsession.get("https://arrests.org/", headers = {'User-Agent': self.RandomAgent()})

    def RandomAgent(self):
        agents_list = []
        with open("useragents.txt", "r") as f:
            for l in f:
                l = l.strip()
                if l:
                    agents_list.append(l)
        return agents_list[random.randint(0, len(agents_list))]

    def GetArrest(self, profilelink):
        arrestpage = self.arrestsession.get(profilelink, headers = {'User-Agent': self.RandomAgent()})
        #get the page in sessions
        arrestsoup = bs4.BeautifulSoup(arrestpage.content, "lxml")
        info = arrestsoup.find("div", { "class" : "info" })
        firstsec = info.find("div", {"class" : "section-content"})
        secondsec = info.find("div", {"class" : "section-content personal-information"})
        chargessec = arrestsoup.find("div", {"class" : "section-content charges"})
        arrestinfo = {}
        arrestinfo["arrest_url"] = profilelink
        arrestinfo["charges"] = []
        charges = []
        descriptions = []

        for i in firstsec.find_all("div"):
            i = i.text.replace("\n", " ").replace(": ", ":").split(":")
            if(i[0] == "Time"):
                k = i
                i = []
                i.append("Time")
                i.append(k[1] + ":" + k[2])
            arrestinfo[i[0]] = i[1]

        for i in secondsec.find_all("div"):
            i = i.text.replace("\n", " ").replace(": ", ":").split(":")
            arrestinfo[i[0]] = i[1]

        for charge in chargessec.find_all("div"):
            if(charge.attrs == {'class': ['charge-title']}):
                charges.append(charge.text)
            elif(charge.attrs == {'class': ['charge-description']}):
                descriptions.append(charge.text)

        inc = -1
        for charge in charges:
            inc += 1
            chargedict = {}
            chargedict["charge"] = charge
            chargedict["description"] = descriptions[inc]
            arrestinfo["charges"].append(chargedict)
        return arrestinfo

    def GetListOfArrests(self):
        #TODO:make this get arrest info from the results page
        pagesoup = bs4.BeautifulSoup(self.page.content, "lxml")
        searchresultsoup = bs4.BeautifulSoup(str(pagesoup.find("div", { "class" : "search-results" })), "lxml")
        failedsearchtest = pagesoup.find("h2", { "class" : "search-failed" })
        faileddatatest = pagesoup.text
        if(failedsearchtest is not None or faileddatatest == 'database error' or faileddatatest == ""):
            if(failedsearchtest is not None):
                raise Exception("No results")
            if(faileddatatest == 'database error' or faileddatatest == ""):
                raise Exception("server returned nothing")
        arrests = []
        for arrest in searchresultsoup.find_all("div", { "class" : "profile-card" }, "lxml"):
            thissoup = bs4.BeautifulSoup(str(arrest), "lxml")
            profilelink = self.state + thissoup.find("a")["data-src"]
            arrests.append(profilelink)
        return arrests

    def SearchState(self, fname=None, lname=None, page=None, resultsperpage=None, partialmatch=True):
        ua = {'User-Agent': self.RandomAgent()}
        params = {}
        if(fname is None):
            pass
        elif(not(isinstance(fname, str))):
            raise TypeError("first name must be str")
        else:
            params["fname"] = fname
        if(lname is None):
            pass
        elif(not(isinstance(lname, str))):
            raise TypeError("last name must be str")
        else:
            params["lname"] = lname
        if(page is None):
            params["page"] = "1"
        elif(not(isinstance(page, int))):
            raise TypeError("page must be int")
        else:
            params["page"] = str(page)
        if(resultsperpage is None):
            params["results"] = "18"
        elif(not(isinstance(resultsperpage, int))):
            raise TypeError("resultsperpage must be int")
        else:
            params["results"] = str(resultsperpage)
        if(not(isinstance(partialmatch, bool))):
            raise TypeError("partial match must be bool")
        else:
            params["partialmatch"] = str(partialmatch)

        self.page = self.arrestsession.get(self.state+"search.php/", headers = ua, params = params)
        return self.GetListOfArrests()

    def statesf(self):
        return ['alabama', 'alaska', 'arizona', 'arkansas', 'california', 'colorado', 'connecticut', 'delaware', 'district of columbia', 'florida', 'georgia', 'hawaii', 'idaho', 'illinois', 'indiana', 'iowa', 'kansas', 'kentucky', 'louisiana', 'maine', 'maryland', 'massachusetts', 'michigan', 'minnesota', 'mississippi', 'missouri', 'montana', 'nebraska', 'nevada', 'new hampshire', 'new jersey', 'new mexico', 'new york', 'north carolina', 'north dakota', 'ohio', 'oklahoma', 'oregon', 'pennsylvania', 'rhode island', 'south carolina', 'south dakota', 'tennessee', 'texas', 'utah', 'vermont', 'virginia', 'washington', 'west virginia', 'wisconsin', 'wyoming']
    def statess(self):
        return ['ak', 'al', 'ar', 'az', 'ca', 'co', 'ct', 'dc', 'de', 'fl', 'ga', 'hi', 'ia', 'id', 'il', 'in', 'ks', 'ky', 'la', 'ma', 'md', 'me', 'mi', 'mn', 'mo', 'ms', 'mt', 'nc', 'nd', 'ne', 'nh', 'nj', 'nm', 'nv', 'ny', 'oh', 'ok', 'or', 'pa', 'ri', 'sc', 'sd', 'tn', 'tx', 'ut', 'va', 'vt', 'wa', 'wi', 'wv', 'wy']

    def SetState(self, state):
        self.pagenumber=1
        if(state.lower() in self.statesf() or state.lower() in self.statess()):
            try:
                link = 'https://'+ state.replace(" ", "") +'.arrests.org/'
                headers = {'User-Agent': self.RandomAgent()}
                self.page = self.arrestsession.get(link, headers=headers)
                self.state = link
            except:
                raise ConnectionError(state + ' isnt compatible, check https://arrests.org for compatible states')
        else:
            raise ValueError(state + " isnt a state")
        return self.GetListOfArrests()

    def SaveFullStateSearch(self, headers, storelocation):
        page = None
        resultsperpage = 56
        statess = self.statess()
        #self.SearchState(headers)


import torch
from torch import nn, optim
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision import transforms

BATCH_SIZE = 128
LEARNING_RATE = 1e-3
EPOCHS = 5
NUM_CLASSES = 10
CHANNELS = 3

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)

train_dataset = datasets.CIFAR10(
    root='./data',
    train=True,
    transform=transforms.ToTensor(),
    download=True)
test_dataset = datasets.CIFAR10(
    root='./data',
    train=False,
    transform=transforms.ToTensor())
train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False)

class Cnn(nn.Module):
    def __init__(self, in_channels, n_class):
        super(Cnn, self).__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(in_channels, 16, 3, stride=1, padding=1),  # input:3*32*32
            nn.ReLU(True), # output:16*32*32
            nn.MaxPool2d(2), # output:16*16*16
            nn.Conv2d(16, 32, 5, stride=1, padding=0),  # input:16*16*16
            nn.ReLU(True), # output:32*12*12
            nn.MaxPool2d(2))  # output:32*6*6

        self.fc = nn.Sequential(
            nn.Linear(1152, 128),  # 1152=32*6*6
            nn.ReLU(True),
            nn.Linear(128, 64),
            nn.ReLU(True),
            nn.Linear(64, n_class))

    def forward(self, x):
        out = self.conv(x)
        out = out.view(out.size(0), -1)
        out = self.fc(out)
        return out

model = Cnn(CHANNELS, NUM_CLASSES).to(device)
print(model)

criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)

for epoch in range(EPOCHS):
    print('epoch {}'.format(epoch + 1))
    print('*' * 10)
    running_loss = 0.0
    running_acc = 0.0
    for i, data in enumerate(train_loader, 1):
        img, label = data
        '''
        Since PyTorch 0.4.0, Tensors and Variables have merged.
        Variable wrapping continues to work as before but returns an object of type torch.Tensor.
        img = Variable(img).to(device)
        label = Variable(label).to(device)
        '''
        img = img.to(device)
        label = label.to(device)
        # zero the parameter gradients
        optimizer.zero_grad()
        # forward + backward + optimize
        out = model(img)
        loss = criterion(out, label)
        loss.backward()
        optimizer.step()
        # loss.data.item():average of batches
        # total loss = loss.data.item()*batch_size
        running_loss += loss.item() * label.size(0)
        #prediction and accuracy
        _, pred = torch.max(out.data, 1)
        num_correct = (pred == label).sum()
        running_acc += num_correct.item()
    # print statistics every epoch
    print('Train Finish {} epoch, Loss: {:.6f}, Acc: {:.6f}'.format(
        epoch + 1,
        running_loss / (len(train_dataset)),
        running_acc / (len(train_dataset))))

# eval mode (batchnorm uses moving mean/variance instead of mini-batch mean/variance)
model.eval()
eval_loss = 0
eval_acc = 0
# torch.no_grad() impacts the autograd engine and deactivate it.
# It will reduce memory usage and speed up computations but you won’t be able to backprop (which you don’t want in an eval script).
with torch.no_grad():
    for data in test_loader:
        img, label = data
        '''
        Volatile is recommended for purely inference mode, when you’re sure you won’t be even calling .backward().
        It will use the absolute minimal amount of memory to evaluate the model.
        Since PyTorch 0.4.0, Volatile flag have been deprecated.
        This has now been replaced by a set of more flexible context managers including torch.no_grad(), torch.set_grad_enabled(grad_mode), and others.
        img = Variable(img, volatile=True).to(device)
        label = Variable(label, volatile=True).to(device)
        '''
        img = img.to(device)
        label = label.to(device)
        out = model(img)
        loss = criterion(out, label)
        eval_loss += loss.item() * label.size(0)
        _, pred = torch.max(out.data, 1)
        num_correct = (pred == label).sum()
        eval_acc += num_correct.item()

print('Test Loss: {:.6f}, Acc: {:.6f}'.format(eval_loss / (len(
    test_dataset)), eval_acc * 1.0 / (len(test_dataset))))

torch.save(model.state_dict(), './cnn.pth')


#! python3
# collections: Counter, namedtuple, OrderedDictionary, defaultdict, dequeue

from collections import deque

d = deque()

d.append(1)
d.append(2)

d.appendleft(3)

print(d)

d.pop()
print(d)

d.extendleft([4, 5, 6])
print(d)

d.rotate(1)
print(d)


import xlwt
import json
import time
import requests
import queue as Queue
import threading

# 本脚本主要通过用户身份证号，已经回溯时间获取用户历史借贷特征

# 设置队列长度
workQueue = Queue.Queue(40000)

class myThread(threading.Thread):
    def __init__(self, name, q,wf):
        threading.Thread.__init__(self)
        self.name = name
        self.q = q
        self.wf = wf

    def run(self):
        print("Starting " + self.name)
        while True:
            try:
                crawler(self.name, self.q,self.wf)
            except:
                break
        print("Exiting " + self.name)

# 创建5个线程名
threadList = ["Thread-1", "Thread-2"]
# 线程池
threads = []

def crawler(threadName, q,wf):
    # 从队列里获取url
    idNum_Date = q.get(timeout=2)
    idNum=idNum_Date[0]
    curr_date=idNum_Date[1]
    try:
        all_list = get_response(idNum,curr_date)
        if all_list:
            print('获取到特征值，开始写入到文本')
            wf.write(str(all_list)+'\n')
            wf.flush()
        # 打印：队列长度，线程名，响应吗，正在访问的url
        print(q.qsize(), threadName, idNum)
    except Exception as e:
        print(q.qsize(), threadName, "Error: ", e)

# 获取test.txt中所有身份证的107条规则并写入文本
def get_value(file):
    file_idNum=open('huaxiatest.txt',encoding='utf-8').readlines()
    for i in file_idNum:
        # 去掉结尾空格
        i=i.rstrip()
        # 取出身份证号码
        # order_id = i.split(',')[0]
        idNum=i.split(',')[0]
        curr_date = i.split(',')[1]
        if not idNum:
            break
        workQueue.put([idNum,curr_date])
    # 创建新线程
    with open(file,'w') as wf:
        for tName in threadList:
            thread = myThread(tName, workQueue,wf)
            thread.start()
            threads.append(thread)

        # 等待所有线程完成
        for t in threads:
            t.join()

        # all_list=get_response(idNum)
        # if all_list:
        #     print('获取到%s特征值，开始写入到文本'%idNum)
        #     file3.write(str(all_list)+'\n')
        #     file3.flush()
    print('写入完成')
    time.sleep(2)

# 根据身份证号码获取107条特征，并转换成list输出
def get_response(idNum,currDate):
    all_dic={}
    url='http://127.0.0.1:5000/getJinpanLoanFeatures?identityNo=%s'
    res=requests.get(url % (idNum,currDate))
    if res.status_code==200:
        all_list=[]
        res=res.json()
        result=res.get('result')
        all_dic['identity_no']=result.get('identity_no')
        features=result.get('features')
        if features:
            all_dic.update(features)
        for key in all_dic:
            all_list.append(all_dic[key])
        return all_list
    else:
        return None

# 将结果写入表格
def wirte_excle():
    file = 'value.txt'
    get_value(file)
    print("准备写表格")
    f = xlwt.Workbook()
    sheet1 = f.add_sheet(u'sheet1', cell_overwrite_ok=True)
    # #将列名写入第0行
    file_dict = {'idNum': '', "apply_pdl_7": 0, "apply_int_7": 0, "apply_sum_7": 0, "reject_pdl_7": 0,
                 "reject_int_7": 0, "reject_sum_7": 0, "approve_pdl_7": 0, "approve_int_7": 0, "approve_sum_7": 0,
                 "overdue_pdl_7": 0, "overdue_int_7": 0, "overdue_sum_7": 0, "loanamount_pdl_7": 0.0,
                 "loanamount_int_7": 0.0, "loanamount_sum_7": 0.0, "maxOverdue_pdl_7": -99999,
                 "maxOverdue_int_7": -99999, "maxOverdue_sum_7": -99999, "apply_pdl_14": 0, "apply_int_14": 0,
                 "apply_sum_14": 0, "reject_pdl_14": 0, "reject_int_14": 0, "reject_sum_14": 0, "approve_pdl_14": 0,
                 "approve_int_14": 0, "approve_sum_14": 0, "overdue_pdl_14": 0, "overdue_int_14": 0,
                 "overdue_sum_14": 0, "loanamount_pdl_14": 0.0, "loanamount_int_14": 0.0, "loanamount_sum_14": 0.0,
                 "maxOverdue_pdl_14": -99999, "maxOverdue_int_14": -99999, "maxOverdue_sum_14": -99999,
                 "apply_pdl_30": 0, "apply_int_30": 0, "apply_sum_30": 0, "reject_pdl_30": 0, "reject_int_30": 0,
                 "reject_sum_30": 0, "approve_pdl_30": 0, "approve_int_30": 0, "approve_sum_30": 0, "overdue_pdl_30": 0,
                 "overdue_int_30": 0, "overdue_sum_30": 0, "loanamount_pdl_30": 0.0, "loanamount_int_30": 0.0,
                 "loanamount_sum_30": 0.0, "maxOverdue_pdl_30": -99999, "maxOverdue_int_30": -99999,
                 "maxOverdue_sum_30": -99999, "apply_pdl_60": 0, "apply_int_60": 0, "apply_sum_60": 0,
                 "reject_pdl_60": 0, "reject_int_60": 0, "reject_sum_60": 0, "approve_pdl_60": 0, "approve_int_60": 0,
                 "approve_sum_60": 0, "overdue_pdl_60": 0, "overdue_int_60": 0, "overdue_sum_60": 0,
                 "loanamount_pdl_60": 0.0, "loanamount_int_60": 0.0, "loanamount_sum_60": 0.0,
                 "maxOverdue_pdl_60": -99999, "maxOverdue_int_60": -99999, "maxOverdue_sum_60": -99999,
                 "apply_pdl_90": 0, "apply_int_90": 0, "apply_sum_90": 0, "reject_pdl_90": 0, "reject_int_90": 0,
                 "reject_sum_90": 0, "approve_pdl_90": 0, "approve_int_90": 0, "approve_sum_90": 0, "overdue_pdl_90": 1,
                 "overdue_int_90": 0, "overdue_sum_90": 0, "loanamount_pdl_90": 0.0, "loanamount_int_90": 0.0,
                 "loanamount_sum_90": 0.0, "maxOverdue_pdl_90": 0, "maxOverdue_int_90": -99999,
                 "maxOverdue_sum_90": 0, "apply_pdl_180": 0, "apply_int_180": 0, "apply_sum_180": 0,
                 "reject_pdl_180": 0, "reject_int_180": 0, "reject_sum_180": 0, "approve_pdl_180": 0,
                 "approve_int_180": 0, "approve_sum_180": 0, "overdue_pdl_180": 0, "overdue_int_180": 0,
                 "overdue_sum_180": 0, "loanamount_pdl_180": 0.0, "loanamount_int_180": 0.0,
                 "loanamount_sum_180": 0.0, "maxOverdue_pdl_180": 0, "maxOverdue_int_180": -99999,
                 "maxOverdue_sum_180": 0, "apply_pdl_all": 0, "apply_int_all": 0, "apply_sum_all": 0,
                 "reject_pdl_all": 0, "reject_int_all": 0, "reject_sum_all": 0, "approve_pdl_all": 0,
                 "approve_int_all": 0, "approve_sum_all": 0, "overdue_pdl_all": 0, "overdue_int_all": 0,
                 "overdue_sum_all": 0, "loanamount_pdl_all": 0.0, "loanamount_int_all": 0.0,
                 "loanamount_sum_all": 0.0, "maxOverdue_pdl_all": 0, "maxOverdue_int_all": -99999,"maxOverdue_sum_all": 0,
                 "apply_pdl_label": 0, "apply_int_label": 0, "apply_sum_label": 0,
                 "reject_pdl_label": 0, "reject_int_label": 0, "reject_sum_label": 0, "approve_pdl_label": 0,
                 "approve_int_label": 0, "approve_sum_label": 0, "overdue_pdl_label": 0, "overdue_int_label": 0,
                 "overdue_sum_label": 0, "loanamount_pdl_label": 0.0, "loanamount_int_label": 0.0,
                 "loanamount_sum_label": 0.0, "maxOverdue_pdl_label": 0, "maxOverdue_int_label": -99999,
                 "maxOverdue_sum_label": 0
                 }

    s=0
    for key in file_dict:
        sheet1.write(0, s, key)
        s+=1
    print("表头设置完成")

    #然后将数据写入第 i 行，第 j 列
    i = 1
    file=open(file,encoding='utf-8').readlines()
    for data in file:
        data=eval(data)
        for j in range(len(data)):
            sheet1.write(i, j, data[j])
        i = i + 1
        print("正在写入第%s行"%i)
    print("内容写入完成")
    f.save('a_new.xls')  # 保存文件

if __name__ == '__main__':
    time1 = time.time()
    wirte_excle()
    # wirte_excle1()
    time2 = time.time()
    print(time2-time1)


from flask.ext.wtf import Form
from wtforms import StringField, BooleanField, TextAreaField
from wtforms.validators import DataRequired, Length, Email
from app.models import User

class LoginForm(Form):
    openid = StringField('openid', validators=[DataRequired()])
    remember_me = BooleanField('remember_me', default=False)

class SearchForm(Form):
    search = StringField('search', validators=[DataRequired()])

class EditProfileForm(Form):
    nickname = StringField('nickname', validators=[DataRequired()])
    about_me = TextAreaField('about_me', validators=[Length(min=0, max=140)])

    def __init__(self, original_nickname, *args, **kwargs):
        Form.__init__(self, *args, **kwargs)
        self.original_nickname = original_nickname

    def validate(self):
        if not Form.validate(self):
            return False
        if self.nickname.data == self.original_nickname:
            return True
        user = User.query.filter_by(nickname=self.nickname.data).first()
        if user != None:
            self.nickname.errors.append('This nickname is already in use. Please choose another one.')
            return False
        return True

class ContactForm(Form):
    mail_from = StringField('from', validators=[DataRequired('Please enter your email address.'),
                                                Email('This field requires a valid email address')])
    message = TextAreaField('message', validators=[DataRequired('Please enter message.'),
                                                   Length(min=0, max=800)])

class BookmarksEditForm(Form):
    name = StringField('name', validators=[DataRequired('Please enter bookmark name.')])
    url = StringField('url', validators=[DataRequired('Please enter bookmark url.')])
    tags = StringField('tags')

class PostsEditForm(Form):
    title = StringField('title', validators=[DataRequired('Please enter title.')])
    body = TextAreaField('body', validators=[DataRequired('Please enter body.')])
    delete = BooleanField('delete')
    tags = StringField('tags')


from google.appengine.ext import db

import logging

class AdminController(object):

    def delete_all_entities(self, kind, where_clause=''):
        logging.info('deleting entities of kind %s' % kind)
        q = db.GqlQuery("SELECT __key__ FROM " + kind + where_clause)
        while q.count():
            results = q.fetch(100)
            db.delete(results)
            q = db.GqlQuery("SELECT __key__ FROM " + kind + where_clause)


import pygame
pygame.init()

TILE_SIZE = 50

save = 0
WIDTH = 650
HEIGHT = 500
screen = pygame.display.set_mode((WIDTH,HEIGHT))

rem = pygame.sprite.Group.empty

NUM_TILES_WIDTH = WIDTH / TILE_SIZE
NUM_TILES_HEIGHT = HEIGHT / TILE_SIZE

hero = pygame.sprite.Sprite()

hero_group = pygame.sprite.GroupSingle(hero)

walls = pygame.sprite.OrderedUpdates()

doors = pygame.sprite.OrderedUpdates()

keys = pygame.sprite.OrderedUpdates()

hero.image = pygame.image.load('grams/hero.png')
hero.rect = hero.image.get_rect()

def ne_wall(v_pos,pos):
    if v_pos > 0:
        pos = pos - 13 * v_pos
    ne_wall = pygame.sprite.Sprite()
    ne_wall.image = pygame.image.load('grams/l0_wall_2.png')
    ne_wall.rect = ne_wall.image.get_rect()
    ne_wall.rect.left = int(pos) *     TILE_SIZE
    ne_wall.rect.top = int(v_pos) * TILE_SIZE
    walls.add(ne_wall)

def se_wall(v_pos,pos):
    if v_pos > 0:
        pos = pos - 13 * v_pos
    se_wall = pygame.sprite.Sprite()
    se_wall.image = pygame.image.load('grams/l0_wall_3.png')
    se_wall.rect = se_wall.image.get_rect()
    se_wall.rect.left = int(pos) *     TILE_SIZE
    se_wall.rect.top = int(v_pos) * TILE_SIZE
    walls.add(se_wall)

def sw_wall(v_pos,pos):
    if v_pos > 0:
        pos = pos - 13 * v_pos
    sw_wall = pygame.sprite.Sprite()
    sw_wall.image = pygame.image.load('grams/l0_wall_4.png')
    sw_wall.rect = sw_wall.image.get_rect()
    sw_wall.rect.left = int(pos) *     TILE_SIZE
    sw_wall.rect.top = int(v_pos) * TILE_SIZE
    walls.add(sw_wall)

def nw_wall(v_pos,pos):
    if v_pos > 0:
        pos = pos - 13 * v_pos
    nw_wall = pygame.sprite.Sprite()
    nw_wall.image = pygame.image.load('grams/l0_wall_1.png')
    nw_wall.rect = nw_wall.image.get_rect()
    nw_wall.rect.left = int(pos) *     TILE_SIZE
    nw_wall.rect.top = int(v_pos) * TILE_SIZE
    walls.add(nw_wall)

def v_wall(v_pos,pos):
    if v_pos > 0:
        pos = pos = pos - 13 * v_pos
    v_wall = pygame.sprite.Sprite()
    v_wall.image = pygame.image.load('grams/l0_wall_5.png')
    v_wall.rect = v_wall.image.get_rect()
    v_wall.rect.left = int(pos) *     TILE_SIZE
    v_wall.rect.top = int(v_pos) * TILE_SIZE
    walls.add(v_wall)
    #print(pos)

def h_wall(v_pos,pos):
    if v_pos > 0:
        pos = pos - 13 * v_pos
    h_wall = pygame.sprite.Sprite()
    h_wall.image = pygame.image.load('grams/l0_wall_6.png')
    h_wall.rect = h_wall.image.get_rect()
    h_wall.rect.left = int(pos) *     TILE_SIZE
    h_wall.rect.top = int(v_pos) * TILE_SIZE
    walls.add(h_wall)
    print(pos)

def door(v_pos,pos):
    if v_pos > 0:
        pos = pos - 13 * v_pos
    door = pygame.sprite.Sprite()
    door.image = pygame.image.load('grams/door-1.png.png')
    door.rect = door.image.get_rect()
    door.rect.left = int(pos) *     TILE_SIZE
    door.rect.top = int(v_pos) * TILE_SIZE
    doors.add(door)

def key(v_pos,pos):
    if v_pos > 0:
        pos = pos - 13 * v_pos
    key = pygame.sprite.Sprite()
    key.image = pygame.image.load('grams/key-1.png.png')
    key.rect = key.image.get_rect()
    key.rect.left = int(pos) *     TILE_SIZE
    key.rect.top = int(v_pos) * TILE_SIZE
    keys.add(key)

pos = 0
v_pos = 0
level1_vwall = [1,4,6,19,21,28,32,34,44,45,52,58,62,71,80,82,84,86,92,93,99,101,108,112,114,123,125,127]
level1_hwall = [23,24,25,42,48,66,74,96]
level1_newall = [14,41,47,57,65,105]
level1_sewall = [73,95]
level1_swwall = [15,39,49,67]
level1_nwwall = [75,97,106]
level1_door = [126]
level1_keys = [2,79,12]

def level_1(v_pos,pos):
    while pos <= 128:
        if pos == 13 or pos == 26 or pos == 39 or pos == 52 or pos == 65 or pos == 78 or pos == 91 or pos == 104 or pos == 117 :
             v_pos = v_pos + 1
        if pos in level1_vwall: # up wall
            v_wall(v_pos,pos)
        elif pos in level1_hwall: # flat wall
            h_wall(v_pos,pos)
        elif pos in level1_newall : # ne wall
            ne_wall(v_pos,pos)
        elif pos in level1_sewall: # se wall
            se_wall(v_pos,pos)
        elif pos in level1_swwall: # sw wall
            sw_wall(v_pos,pos)
        elif pos in level1_nwwall : # nw wall
            nw_wall(v_pos,pos)
        elif pos in level1_door:
            door(v_pos,pos)
        elif pos in level1_keys:
            key(v_pos,pos)
        pos += 1
        #print(pos)

level2_vwall =[1,5,10,12,14,16,18,23,25,27,29 ,31,33,40,44,46,48,50,53,55,57,59,68,70,72 ,75,88,92,94,105]
level2_hwall = [21,78,82,100,103,108,110,111,112,113,114]
level2_newall = [61,85,99,107]
level2_sewall =[20,81,102]
level2_swwall = [62,86,79]
level2_nwwall = [63,76,83,101,115]
level2_door = [116]
level2_keys = [69,87,89]

def level_2(v_pos,pos):
    while pos <= 128:
        # checks vertical position so walls arent placed off screen
        if pos == 13 or pos == 26 or pos == 38 or pos == 51 or pos == 64 or pos == 77 or pos == 90 or pos == 104 or pos == 117 :
             v_pos = v_pos + 1

        if pos in level2_vwall: # up wall
            v_wall(v_pos,pos)
        elif pos in level2_hwall: # flat wall
            h_wall(v_pos,pos)
        elif pos in level2_newall: # ne wall
            ne_wall(v_pos,pos)
        elif pos in level2_sewall: # se wall
            se_wall(v_pos,pos)
        elif pos in level2_swwall: # sw wall
            sw_wall(v_pos,pos)
        elif pos in level2_nwwall: # nw wall
            nw_wall(v_pos,pos)
        elif pos in level2_door:
            door(v_pos,pos)
        elif pos in level2_keys:
            key(v_pos,pos)
        pos += 1

def v_cords():
    if cur_v == 0:
         v_can = [0,1,2,3,4,5,6,7,8,9,10,11,12]

#def enemy():

finish = False
win = False
level = 1
level_com = 1
while not finish:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            finish = True
        if level == 1 and level_com == 1:
            level_1(v_pos,pos)
            level_com = 2
        elif level == 2 and level_com == 2:
            pos = 0
            v_pos = 0
            level_2(v_pos,pos)
            level_com = 3

        hero_pos_t = hero.rect.top
        hero_pos_r = hero.rect.right

        if event.type == pygame.KEYDOWN:
            screen.fill((0, 0, 0))
        # Move the hero around the screen
            if event.key == pygame.K_UP:
                hero.rect.top -= TILE_SIZE
                if pygame.sprite.spritecollideany(hero,walls):
                    hero.rect.top = hero_pos_t
            elif event.key == pygame.K_DOWN:
                hero.rect.top += TILE_SIZE
                if pygame.sprite.spritecollideany(hero,walls):
                    hero.rect.top = hero_pos_t
            elif event.key == pygame.K_RIGHT:
                hero.rect.right += TILE_SIZE
                if pygame.sprite.spritecollideany(hero,walls):
                    hero.rect.right = hero_pos_r
            elif event.key == pygame.K_LEFT:
                hero.rect.right -= TILE_SIZE
                if pygame.sprite.spritecollideany(hero,walls):
                    hero.rect.right = hero_pos_r

        pygame.sprite.groupcollide(hero_group, keys, False, True)

        if pygame.sprite.spritecollideany(hero,doors):
            if len(keys) == 0:
                win = True
            else:
                hero.rect.top = hero_pos_t
                hero.rect.right = hero_pos_r

        if win == True:
            font = pygame.font.Font(None, 36)
            text_image = font.render("Level Complete", True, (255, 255, 255))
            text_rect = text_image.get_rect(centerx=WIDTH/2, centery=100)
            screen.blit(text_image, text_rect)

            rem(walls)
            rem(doors)

            hero.rect.top = 0
            hero.rect.right = 50
            level += 1
            win = False
        hero_group.draw(screen)
    walls.draw(screen)
    doors.draw(screen)
    keys.draw(screen)
    pygame.display.update()
pygame.quit()


###############################################
################### Imports ###################
###############################################

import os
import sys
import json
import subprocess
from datetime import date
from datetime import datetime

###############################################
################# Functions ###################
###############################################

def get_data_from_json_file(filename):
    with open(filename, "r", encoding="utf-8") as out:
        data = json.load(out)
    return data

def run_checks():
    check1 = ""
    check2 = ""
    check3 = ""
    check4 = ""

    try:
        get_data_from_json_file("msgstruct.json")
    except FileNotFoundError:
        check1 = "(X) Couldn't found 'msgstruct.json'."
    except json.JSONDecodeError:
        check1 = "(X) File 'msgstruct.json' has errors."
    except Exception:
        check1 = "(X) Unknown error occurred [SOURCE: msgstruct.json]."
    check1 = "(i) Successful."

    try:
        get_data_from_json_file("config.json")
    except FileNotFoundError:
        check2 = "(X) Couldn't found 'config.json'."
    except json.JSONDecodeError:
        check2 = "(X) File 'config.json' has errors."
    except Exception:
        check2 = "(X) Unknown error occurred [SOURCE: config.json]."

    data = get_data_from_json_file("config.json")
    path_to_project = data["cwd"]

    if os.path.isdir(path_to_project) == True:
        os.chdir(path_to_project)
        check2 = "(i) Successful."
    else:
        check2 = "(X) File 'config.json' contains wrong path."

    try:
        returnStr = subprocess.run("git status", capture_output=True, text=True,check=True,shell=True)
        returnStr.check_returncode()
    except subprocess.CalledProcessError:
        check3 =  "(X) Couldn't detect git."
    except Exception:
        check3 = "(X) Unknown error occured [SOURCE: Git]."
    check3 = "(i) Successful."

    try:
        returnStr = subprocess.run("git status", capture_output=True, text=True,check=True,shell=True)
        returnStr.check_returncode()
    except subprocess.CalledProcessError:
        check4 = "(X) Checking for unstaged files failed."

    if returnStr.stdout.find("Changes not staged") != -1:
        check4 = "(X) Found unstaged files."
    else:
        check4 = "(i) Successful."

    print("[CHECK]: ", check1)
    print("[CHECK]: ", check2)
    print("[CHECK]: ", check3)
    print("[CHECK]: ", check4)
    print("[CWD]:   ", os.getcwd())

def get_current_date():
    dateNow = date.today()
    return dateNow.strftime("%B %d, %Y")

def get_current_time():
    timeNow = datetime.now()
    return timeNow.strftime("%H:%M:%S")

def get_modifications():
    returnStr = subprocess.run("git diff --staged --stat", capture_output=True, text=True,shell=True)
    return returnStr.stdout

def assemble_commit_message():
    data = get_data_from_json_file("./msgstruct.json")
    msg = ""
    for i in data:
        if i == "name":
            continue
        elif i.startswith('blank'):
            msg += "\n"
        elif data[i] == "input":
            msg += input("[{}]: ".format(i))
        elif i.startswith('Seperator'):
            msg += data[i]
        elif i == "date":
            msg += get_current_date()
        elif i == "time":
            msg += get_current_time()
        elif i == "mods":
            msg += get_modifications()
            print(get_modifications())
        else:
            print("[{}]: ".format(i))
            line = 0
            for j in data[i]:
                print("  ..{}:{}".format(line,j))
                line += 1
            selected = input("[SELECT]: ")
            while int(selected) < 0 or int(selected) >= len(data[i]):
                selected = input("[SELECT]: ")
            msg += data[i][int(selected)]
    return msg

def save_to_file(msg):
    with open("commit-msg.txt", "w", encoding="utf-8") as outputFile:
        outputFile.write(msg)
    print("[LOG]: Saved to file 'commit-msg.txt'.")

def check_for_unstaged_files():
    try:
        returnStr = subprocess.run("git status", capture_output=True, text=True,check=True,shell=True)
        returnStr.check_returncode()
    except subprocess.CalledProcessError:
        print("(X) Checking for unstaged files failed.")

    if(returnStr.stdout.find("Changes not staged") != -1):
        print("(i) Found unstaged files.")
    else:
        print("(i) Everything Clean.")

def commit_to_branch(msg):
    print("(i) Trying to commit.")
    secParam = "git commit -m \"" + msg + "\""

    if sys.platform.startswith('win32'):
        try:
            retCode = subprocess.run(secParam, check=True) # windows
        except subprocess.CalledProcessError:
            print("(X) Failed to commit.")
    elif sys.platform.startswith('linux'):
        try:
            retCode = subprocess.run(secParam,shell=True,check=True) # linux
        except subprocess.CalledProcessError:
            print("(X) Failed to commit.")
    elif sys.platform.startswith('darwin'):
        try:
            retCode = subprocess.run(secParam,shell=True,check=True)
        except subprocess.CalledProcessError:
            print("(X): Failed to commit.")

    try:
        retCode.check_returncode()
    except subprocess.CalledProcessError:
        print("(X): Failed to commit.")
    print("(i) Successfully committed.")

###############################################
############# Main Functionality ##############
###############################################

def exit_script():
    print("[LOG]: Stopping...")
    print("ðŸ”¥FireCommit Exited")
    sys.exit()

def main():

    ### Start
    print("ðŸ”¥FireCommit - V.6.2")

    ### Checks
    run_checks()

    ### Actions
    print("[OPTION]: 0:start | 1:abort")
    input_option = input("[0|1]: ")
    while input_option != "0" and input_option != "1":
        input_option = input("[0|1]: ")

    ### Exit
    if input_option == "1":
        exit_script()

    ### Assemble commit-message
    msg = assemble_commit_message()
    print("[OPTION]: 0:show | 1:save | 2:commit | 3:abort.")
    input_option3 = input("[0|1|2|3]: ")

    if input_option3 == "0":
        print()
        print(msg)
        print()
        input_option3 = input("[1|2|3]: ")
    if input_option3 == "3":
        exit_script()

    while input_option3 != "1" and input_option3 != "2":
        input_option3 = input("[1|2|3]: ")
        if input_option3 == "3":
            exit_script()

    if input_option3 == "0":
        print(msg)
    elif input_option3 == "1":
        save_to_file(msg)
    else:
        check_for_unstaged_files()
        print("[OPTION]: 0:commit | 1:abort.")
        input_option4 = "-1"
        while input_option4 != "0" and input_option4 != "1":
            input_option4 = input("[0|1]: ")

        if input_option4 == "1":
            exit_script()
        elif input_option4 == "0":
            commit_to_branch(msg)
    print()
    main()

###############################################
############### Start Script ##################
###############################################

main()


#!/usr/bin/env python3
# coding=utf-8
# date 2022-12-14 10:56:05
# author calllivecn <c-all@qq.com>

import time
import asyncio
import threading
from datetime import datetime

def my_func():
    for i in range(3):
        print("sleep(1)")
        time.sleep(1)
    return datetime.now()

async def fetch_async(func, *args, **kwargs):
    print("begin")
    #loop = asyncio.get_event_loop()
    loop = asyncio.get_running_loop()

    # 这个方法是在后台起了一个线程实现的。
    future = loop.run_in_executor(None, func, *args, **kwargs)
    result = await future
    return result

tasks = [
    fetch_async(my_func),
    fetch_async(my_func),
]

tasks2 = [
    fetch_async(my_func),
    fetch_async(my_func),
    fetch_async(my_func),
]

tasks3 = [
    fetch_async(my_func),
    fetch_async(my_func),
    fetch_async(my_func),
]

tasks4 = [
    fetch_async(my_func)
]

async def main():
    result_list = await asyncio.gather(*tasks)
    th_list = threading.enumerate()
    print("运行完后：len(threads):", len(th_list))

    result_list = await asyncio.gather(*tasks2)
    th_list = threading.enumerate()
    print("运行完后：len(threads):", len(th_list))

    result_list = await asyncio.gather(*tasks3)
    th_list = threading.enumerate()
    print("运行完后：len(threads):", len(th_list))

    result_list = await asyncio.gather(*tasks4)
    th_list = threading.enumerate()
    print("运行完后：len(threads):", len(th_list))

    return result_list

"""
# 新版 不这样了。
loop = asyncio.get_event_loop()
results = loop.run_until_complete(asyncio.gather(*tasks))
print(results)
loop.close()
"""

th_list = threading.enumerate()
print("运行前：len(threads):", len(th_list))

results = asyncio.run(main())
print(results)