import json
import time

import requests
import re
from bs4 import BeautifulSoup

import Firm
import Person
from saveLog import saveLog

import warnings
warnings.filterwarnings("ignore")

def crawleOneFilm(IMDBID : str):
    import Film

    url = "https://www.imdb.com/title/" + IMDBID  # 拼接得到URL
    header = {
        "accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
        "user-agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36",
        "sec-ch-us" : '" Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"'
    }
    try:
        resp = requests.get(url = url , headers = header)
    except requests.exceptions.ConnectionError as e:
        time.sleep(10)
        resp = requests.get(url=url, headers=header)
    resp.raise_for_status()

    soup = BeautifulSoup(resp.text , "html.parser")

    try:
        filmName = soup.find("h1" , attrs={"data-testid":"hero-title-block__title"}).text
    except AttributeError as e:
        saveLog("IMDB ID: " + IMDBID + "找不到电影名字")
        return None
    print(" 电影名字: " + filmName)

    film = Film.Film(filmName , IMDBID)

    # release date
    date = findReleaseDate(soup)
    film.setReleaseDate(date)

    # duration
    duration = findDuration(soup)
    film.setDuration(duration)

    # type(genres)
    genres = findGenres(soup)
    film.setFilmType(genres)

    # boxoffice
    boxoffice = findBoxoffice(soup , IMDBID)
    film.setGrossBoxoffice(boxoffice)

    # actor director writer producer productionFirm distributeFirm
    fullCredit = getFullCredits(IMDBID)
    film.actorList = fullCredit['actor']
    film.directList = fullCredit['director']

    # 人员的票房
    _act_box = 0.0
    for i in film.actorList:
        _act_box += i.totalActorFilmBox
    film.totalActorBox = _act_box

    _dir_box = 0
    for i in film.directList:
        _dir_box += i.totalDirectFilmBox
    film.totalDirectBox = _dir_box

    # 公司的票房
    fullComp = getFullComp(IMDBID)
    film.productionFirm = fullComp['production']

    # 公司的票房
    _prod_firm_box = 0
    for i in film.productionFirm:
        _prod_firm_box += i.totalFilmBox
    film.totalProducFirmBox = _prod_firm_box

    return film

def findReleaseDate(soup) -> str:
    try:
        return soup.find("section" , attrs={"data-testid":"Details"}).find("li" , attrs = {"data-testid":"title-details-releasedate"}).find("div").text.replace("," , " ")
    except AttributeError as e:
        saveLog(e.args[0])
        return ""

def findDuration(soup) -> int:
    try:
        raw_dura = soup.find("section" , attrs = {"data-testid":"TechSpecs"}).find("li" , attrs = {"data-testid":"title-techspec_runtime"}).find("div").text
        return procRawDuartion(raw_dura)
    except AttributeError as e:
        saveLog(e.args)
        return -1

def procRawDuartion(string) -> int:
    '''

    :param string:
    :return: -1 表示有错误
    '''
    try:
        li = re.split(r"hours|hour" , string.replace(" " , "").replace("minutes" , "").replace("minutes" , ""))
        if li[1] == "":
            li[1] = "0"
        return eval(li[0]) * 60 + eval(li[1])
    except IndexError as e:
        saveLog(e.args)
        return -1

def findGenres(soup) -> list:
    try:
        result = []
        for i in soup.find("div", attrs={"data-testid": "genres"}).find_all("a"):
            result.append(i.text)
        return result
    except AttributeError as e:
        saveLog(e.args)
        return [""]

def findBoxoffice(soup , IMDBID) -> float:
    try:
        raw_box = soup.find("section" , attrs = {"data-testid":"BoxOffice"}).find("li" , attrs = {"data-testid":"title-boxoffice-cumulativeworldwidegross"}).find("ul").text
        return procBox(raw_box , IMDBID)
    except AttributeError as e:
        saveLog(e.args[0])
        return 0.0

def procBox(string , IMDBID) -> float:
    # moneyType = 1 if string[0] == '$' else -1
    if string[0] != "$":
        saveLog(IMDBID + "不是美元")
    return float(string[1:].replace("," , ""))

def getFullCredits(IMDBID) -> dict:
    with open("./ing_data/person.json") as f:
        person_json = json.load(f)

    fullList = {
        'actor': [],
        'director': []
    }
    url = "https://www.imdb.com/title/"+IMDBID+"/fullcredits"
    header = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36",
    }
    try:
        resp = requests.get(url=url, headers=header)
    except requests.exceptions.ConnectionError as e:
        time.sleep(10)
        resp = requests.get(url=url, headers=header)
    resp.raise_for_status()

    soup = BeautifulSoup(resp.text)
    try:
        title_l = soup.find("div", attrs={'id': 'fullcredits_content'}).find_all("h4")
        table_l = soup.find("div", attrs={'id': 'fullcredits_content'}).find_all("table")
    except AttributeError as e:
        saveLog(" IMDBID : " + IMDBID + " , Error : " + e.args[0])
        return fullList

    if len(title_l) != len(table_l):
        saveLog(" IMDBID: " + IMDBID + ", 在获取fullcredit时发生两个list长度不相等的问题\n")
        return fullList

    actor_list = []
    directer_list = []

    for i , u in enumerate(title_l):
        text = u.attrs.get("id")
        if text == "cast":
            c_list = table_l[i].find_all("tr" , class_ = ["odd","even"])
            for j,v in enumerate(c_list):
                if j >=5: # 只获取前五个演员的票房
                    break
                try:
                    name = v.find_all("td")[1].text.strip()
                    ID = re.findall('nm\d+' , v.find_all("a")[1].attrs.get("href"))[0]
                    print("  演员 名字 : " + name)
                    if ID not in person_json.keys():
                        person = Person.Person(name, ID , True) # 传参为True，表示这个人没有记录，需要爬取
                        temp = {
                            "actor": person.totalActorFilmBox,
                            "director": person.totalDirectFilmBox
                        }
                        person_json[ID] = temp
                        with open("./ing_data/person.json" , "w") as f:
                            json.dump(person_json , f)
                    else:
                        person = Person.Person(name , ID , False)
                        person.totalActorFilmBox = person_json[ID]["actor"]
                        person.totalDirectFilmBox = person_json[ID]["director"]
                    actor_list.append(person)
                except AttributeError as e:
                    saveLog(" IMDBID : " + IMDBID + " , Error : " + e.args[0])
                    continue
                except ConnectionError as e:
                    saveLog(" IMDBID : " + IMDBID + " , Error : " + e.args[0])
                    continue

        elif text == "director":
            d_tr_list = table_l[i].find_all("tr")
            for j, v in enumerate(d_tr_list):
                try:
                    name = v.find("a").text.strip()
                    ID = re.findall(r"nm\d+", v.find("a").attrs.get("href"))[0]
                    print("  导演 名字 : " + name)
                    if ID not in person_json.keys():
                        person = Person.Person(name, ID)
                        temp = {
                            "actor": person.totalActorFilmBox,
                            "director" : person.totalDirectFilmBox
                        }
                        person_json[ID] = temp
                        with open("./ing_data/person.json", "w") as f:
                            json.dump(person_json, f)
                    else:
                        person = Person.Person(name, ID, False)
                        person.totalActorFilmBox = person_json[ID]["actor"]
                        person.totalDirectFilmBox = person_json[ID]["director"]
                    directer_list.append(person)
                except AttributeError as e:
                    saveLog(" IMDBID : " + IMDBID + " , Error : " + e.args[0])
                    continue
                except ConnectionError as e:
                    saveLog(" IMDBID : " + IMDBID + " , Error : " + e.args[0])
                    continue

    fullList['actor'] = actor_list
    fullList['director'] = directer_list

    return fullList

def getFullComp(IMDBID) -> dict:
    with open("./ing_data/firm.json") as f:
        current_firm = json.load(f)

    url = "https://www.imdb.com/title/"+IMDBID+"/companycredits"
    header = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36",
    }
    try:
        resp = requests.get(url=url, headers=header)
    except requests.exceptions.ConnectionError as e:
        time.sleep(10)
        resp = requests.get(url=url, headers=header)

    resp.raise_for_status()

    soup = BeautifulSoup(resp.text)

    try:
        soup_content = soup.find("div" , attrs = {"id":"company_credits_content"})
    except AttributeError as e:
        saveLog(" IMDBID : " + IMDBID + " 时找不到company_credits_content, Error : " + e.args[0])
        return {'production': []}

    soup_h4 = soup_content.find_all("h4" , recursive= False)
    soup_ul = soup_content.find_all("ul" , recursive= False)

    prod_comp = []

    for i , v in enumerate(soup_h4):
        if v.attrs.get("id") == "production":
            a_s = soup_ul[i].find_all("a")
            for j in a_s:
                firm_name = j.text
                firm_id = re.findall(r"/company/co[0-9]+" , j.attrs.get("href"))[0]
                firm_id = firm_id.replace("/company/" , "")
                print("  公司 名字 : " + firm_name)
                if firm_id in current_firm.keys():
                    firm_temp = Firm.Firm(firm_name , firm_id , False)
                    firm_temp.totalFilmBox = current_firm[firm_id]
                else:
                    firm_temp = Firm.Firm(firm_name, firm_id)
                    current_firm[firm_id] = firm_temp.totalFilmBox
                    with open('./ing_data/firm.json', 'w') as file:
                        json.dump(current_firm, file)
                prod_comp.append(firm_temp)

    fullComp = {
        'production': prod_comp
    }
    return fullComp

# info =  crawleOneFilm("tt7362036")
# print(info)
# i = 1


from django import forms
from .models import Expense, Category, UserProfile, RecurringExpense
from django.forms import ModelForm
from django.core.validators import RegexValidator

CHART_CHOICES = [
    ('donut', 'Donut Chart'),
    ('line', 'Line Chart'),
    ('polar', 'Polar Area Chart'),
]

class YourReportForm(forms.Form):
    custom_title = forms.CharField(max_length=100, required=False, label="Report Title (optional)")
    start_date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}))
    end_date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}))
    category = forms.ModelMultipleChoiceField(
        queryset=Category.objects.order_by('name').distinct(),
        widget=forms.CheckboxSelectMultiple(attrs={'class': 'horizontal-select'}),
        required=True
    )

    chart_type = forms.ChoiceField(choices=CHART_CHOICES, required=False, label='Chart Type')

class ExpenseForm(forms.ModelForm):
    category = forms.ModelChoiceField(
        queryset=Category.objects.all(),
        widget=forms.Select(),  # You can choose a different widget if you prefer
        required=True
    )

    class Meta:
        model = Expense
        fields = ['title', 'amount', 'date', 'category']
        widgets = {
            'date': forms.DateInput(attrs={'type': 'date'})
        }

    def __init__(self, *args, **kwargs):
        super(ExpenseForm, self).__init__(*args, **kwargs)

class UserProfileForm(forms.ModelForm):
    # Regular expression for validating phone numbers
    phone_regex = RegexValidator(
        regex=r'^\+?1?\d{9,15}$',
        message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed."
    )

    # Adding the validator to the phone_number field
    phone_number = forms.CharField(validators=[phone_regex], max_length=17)

    class Meta:
        model = UserProfile
        fields = ['bio', 'phone_number', 'birth_date', 'profile_picture']
        widgets = {
            'birth_date': forms.DateInput(attrs={'type': 'date'}),  # Add this line
            # Other widgets if needed
        }


import Live
from APC import APC
from _Framework.ControlSurface import ControlSurface
from _Framework.InputControlElement import *
from _Framework.SliderElement import SliderElement
from _Framework.ButtonElement import ButtonElement
from _Framework.EncoderElement import EncoderElement
from _Framework.ButtonMatrixElement import ButtonMatrixElement
from _Framework.MixerComponent import MixerComponent
from _Framework.ClipSlotComponent import ClipSlotComponent
from _Framework.ChannelStripComponent import ChannelStripComponent
from _Framework.SceneComponent import SceneComponent
from _Framework.SessionZoomingComponent import SessionZoomingComponent
from _Framework.ChannelTranslationSelector import ChannelTranslationSelector
from _Framework.ModeSelectorComponent import ModeSelectorComponent
from _Framework.TransportComponent import TransportComponent
from _Framework.DeviceComponent import DeviceComponent

#from APC40.EncModeSelectorComponent import EncModeSelectorComponent
#from APC40.DetailViewCntrlComponent import DetailViewCntrlComponent
#from APC40.ShiftableDeviceComponent import ShiftableDeviceComponent
#from APC40.ShiftableTransportComponent import ShiftableTransportComponent
#from APC40.ShiftTranslatorComponent import ShiftTranslatorComponent
#from APC40.PedaledSessionComponent import PedaledSessionComponent
#from APC40.SpecialMixerComponent import SpecialMixerComponent

from APC40.APCSessionComponent import APCSessionComponent
from APC40.SpecialMixerComponent import SpecialMixerComponent
from APC20.ShiftableZoomingComponent import ShiftableZoomingComponent
from APC20.ShiftableSelectorComponent import ShiftableSelectorComponent
from APC20.SliderModesComponent import SliderModesComponent
from APC20.consts import *

from _Mono_Framework.MonoBridgeElement import MonoBridgeElement
from _Mono_Framework.MonoButtonElement import MonoButtonElement
from _Mono_Framework.MonoEncoderElement import MonoEncoderElement
from _Mono_Framework.MonomodComponent import MonomodComponent

#from MonoRingedEncoderElement import RingedEncoderElement, MonoRingedEncoderElement

#from Map import *

class AumPC20ShiftableSelectorComponent(ShiftableSelectorComponent):

	def __init__(self, select_buttons, master_button, arm_buttons, matrix, session, zooming, mixer, transport, slider_modes, mode_callback, script):
		self._script = script
		super(AumPC20ShiftableSelectorComponent, self).__init__(select_buttons, master_button, arm_buttons, matrix, session, zooming, mixer, transport, slider_modes, mode_callback)

	def _toggle_value(self, value):
		super(AumPC20ShiftableSelectorComponent, self)._toggle_value(value)
		if(self._mode_index > 0):
			self._script._monomod_mode.set_mode_toggle(self._master_button)
		else:
			self._script._monomod_mode.set_mode_toggle(None)

class AumPC20MonomodComponent(MonomodComponent):

	def _update_nav_buttons(self):
		if self._nav_buttons != None:
			if(self._y > 0):
				self._nav_buttons[0].turn_on()
			else:
				self._nav_buttons[0].turn_off()
			if(self._y < 8):
				self._nav_buttons[1].turn_on()
			else:
				self._nav_buttons[1].turn_off()

	def _set_nav_buttons(self, buttons):
		if self._nav_buttons != None:
			self._nav_buttons[0].remove_value_listener(self._nav_up_value)
			self._nav_buttons[1].remove_value_listener(self._nav_down_value)
		self._nav_buttons = buttons
		if buttons != None:
			assert len(buttons) == 2
			for button in buttons:
				assert isinstance(button, AumPCMonoButtonElement)
			self._nav_buttons[0].set_on_off_values(8, 2)
			self._nav_buttons[0].add_value_listener(self._nav_up_value)
			self._nav_buttons[1].set_on_off_values(8, 2)
			self._nav_buttons[1].add_value_listener(self._nav_down_value)

class AumPCMonoButtonElement(MonoButtonElement):

	def __init__(self, *a, **k):
		super(AumPCMonoButtonElement, self).__init__(*a, **k)
		self.set_color_map(tuple([1, 1, 1, 1, 1, 1, 1]))

	def send_value(self, value, force_send = False):
		if self._script.flash_status:
			super(AumPCMonoButtonElement, self).send_value(value, force_send)
		else:
			InputControlElement.send_value(self, value, force_send)

class MonomodModeComponent(ModeSelectorComponent):

	def __init__(self, callback, script, *a, **k):
		super(MonomodModeComponent, self).__init__(*a, **k)
		self._script = script
		self.update = callback
		self._set_protected_mode_index(0)

	def number_of_modes(self):
		return 2

	def set_mode_toggle(self, button):
		assert (button == None or isinstance(button, ButtonElement))
		if self._mode_toggle != None:
			self._mode_toggle.remove_value_listener(self._toggle_value)
		self._mode_toggle = button
		if self._mode_toggle != None:
			self._mode_toggle.add_value_listener(self._toggle_value)

class AumPC20(APC):
	""" Monomodular script for Akai's APC20 Controller """

	def __init__(self, c_instance, *a, **k):
		self._shift_modes = None
		super(AumPC20, self).__init__(c_instance, *a, **k)

	def disconnect(self):
		self._shift_modes = None
		super(AumPC20, self).disconnect()

	def _activate_combination_mode(self, track_offset, support_devices):
		super(AumPC20, self)._activate_combination_mode(track_offset, support_devices)
		if support_devices:
			self._shift_modes.invert_assignment()

	def _setup_session_control(self):
		is_momentary = True
		self._shift_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81, 'Shift_Button', self)
		self._session = APCSessionComponent(8, 5)
		self._session.name = 'Session_Control'
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Button_Matrix'
		scene_launch_buttons = [ AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (index + 82), 'Scene_' + str(index) + '_Launch_Button', self) for index in range(5) ]
		self._scene_launch_buttons = scene_launch_buttons
		track_stop_buttons = [ AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52, 'Track_' + str(index) + '_Stop_Button', self) for index in range(8) ]
		self._track_stop_buttons = track_stop_buttons
		for index in range(len(scene_launch_buttons)):
			scene_launch_buttons[index].name = 'Scene_' + str(index) + '_Launch_Button'

		for index in range(len(track_stop_buttons)):
			track_stop_buttons[index].name = 'Track_' + str(index) + '_Stop_Button'

		self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		self._session.set_stop_track_clip_value(2)
		for scene_index in range(5):
			scene = self._session.scene(scene_index)
			scene.name = 'Scene_' + str(scene_index)
			button_row = []
			scene.set_launch_button(scene_launch_buttons[scene_index])
			scene.set_triggered_value(2)
			for track_index in range(8):
				button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, track_index, (scene_index + 53), '_Clip_' + str(scene_index) + '_Button', self)
				button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
				button_row.append(button)
				clip_slot = scene.clip_slot(track_index)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				clip_slot.set_triggered_to_play_value(2)
				clip_slot.set_triggered_to_record_value(4)
				clip_slot.set_stopped_value(5)
				clip_slot.set_started_value(1)
				clip_slot.set_recording_value(3)
				clip_slot.set_launch_button(button)

			self._matrix.add_row(tuple(button_row))

		self._session.selected_scene().name = 'Selected_Scene'
		self._session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
		self._session_zoom = ShiftableZoomingComponent(self._session, tuple(track_stop_buttons))
		self._session_zoom.name = 'Session_Overview'
		self._session_zoom.set_button_matrix(self._matrix)
		self._session_zoom.set_zoom_button(self._shift_button)
		self._session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
		self._session_zoom.set_stopped_value(3)
		self._session_zoom.set_selected_value(5)

	def _setup_mixer_control(self):
		is_momentary = True
		self._mixer = SpecialMixerComponent(8)
		self._mixer.name = 'Mixer'
		self._mixer.master_strip().name = 'Master_Channel_Strip'
		self._mixer.selected_strip().name = 'Selected_Channel_Strip'
		self._solo_buttons = []
		for track in range(8):
			strip = self._mixer.channel_strip(track)
			strip.name = 'Channel_Strip_' + str(track)
			solo_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49, str(track) + '_Solo_Button', self)
			self._solo_buttons.append(solo_button)
			mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50)
			solo_button.name = str(track) + '_Solo_Button'
			mute_button.name = str(track) + '_Mute_Button'
			strip.set_solo_button(solo_button)
			strip.set_mute_button(mute_button)
			strip.set_shift_button(self._shift_button)
			strip.set_invert_mute_feedback(True)

		master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
		prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
		master_volume_control.name = 'Master_Volume_Control'
		prehear_control.name = 'Prehear_Volume_Control'
		self._mixer.set_prehear_volume_control(prehear_control)
		self._mixer.master_strip().set_volume_control(master_volume_control)

	def _setup_custom_components(self):
		is_momentary = True
		master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80)
		master_select_button.name = 'Master_Select_Button'
		self._master_select_button = master_select_button
		select_buttons = []
		arm_buttons = []
		sliders = []
		for track in range(8):
			select_buttons.append(AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51, str(track) + '_Select_Button', self))
			arm_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48))
			sliders.append(MonoEncoderElement(MIDI_CC_TYPE, track, 7, Live.MidiMap.MapMode.absolute, 'Slider_' + str(track), track, self))
			select_buttons[-1].name = str(track) + '_Select_Button'
			arm_buttons[-1].name = str(track) + '_Arm_Button'
			#sliders[-1].name = str(track) + '_Volume_Control'
		self._select_buttons = select_buttons

		transport = TransportComponent()
		transport.name = 'Transport'
		slider_modes = SliderModesComponent(self._mixer, tuple(sliders))
		slider_modes.name = 'Slider_Modes'
		self._shift_modes = AumPC20ShiftableSelectorComponent(tuple(select_buttons), master_select_button, tuple(arm_buttons), self._matrix, self._session, self._session_zoom, self._mixer, transport, slider_modes, self._send_introduction_message, self)
		self._shift_modes.name = 'Shift_Modes'
		self._shift_modes.set_mode_toggle(self._shift_button)
		self._device = DeviceComponent()

	def _product_model_id_byte(self):
		return 123

	def _setup_monobridge(self):
		self._monobridge = MonoBridgeElement(self)
		self._monobridge.name = 'MonoBridge'

	def _setup_monomod(self):
		self._host = AumPC20MonomodComponent(self)
		self._host.name = 'Monomod_Host'
		self._host._navbox_selected = 16
		self._host._navbox_unselected = 1
		self.hosts = [self._host]
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		for row in range(5):
			button_row = []
			for column in range(8):
				button_row.append(self._matrix.get_button(column, row))
			self._monomod.add_row(tuple(button_row))
		self._monomod.add_row(tuple(self._track_stop_buttons))
		self._monomod.add_row(tuple(self._select_buttons))
		self._monomod.add_row(tuple(self._solo_buttons))
		self._monomod_mode = MonomodModeComponent(self._monomod_mode_update, self)
		self._monomod_mode.name = "Monomod_Mode_Component"
		#self._shift_button.add_value_listener(self._shift_value)

	def _shift_value(self, value):
		if value > 0:
			self._mixer.master_strip().set_select_button(None)
			self._monomod_mode.set_mode_toggle(self._master_select_button)
		else:
			self._mixer.master_strip().set_select_button(self._master_select_button)
			self._monomod_mode.set_mode_toggle(None)

	def _monomod_mode_update(self):
		self.log_message('mode update: ' + str(self._monomod_mode._mode_index))
		if(self._monomod_mode._mode_index == 0) or (self._host._active_client == None):
			self.flash_status = 0
			self._host.set_enabled(False)
			self._host._set_button_matrix(None)
			#self._host._set_nav_buttons(None)
			self._host._set_lock_button(None)
			self._host._set_alt_button(None)
			self._host._set_shift_button(None)
			self._host._set_nav_buttons(None)
			self._scene_launch_buttons[2].set_on_off_values(127, 0)
			self._scene_launch_buttons[3].set_on_off_values(127, 0)
			self._monomod.reset()
			self._shift_modes.set_enabled(True)
			#self._session.set_track_bank_buttons(self._right_button, self._left_button)
			#self._session.set_scene_bank_buttons(self._down_button, self._up_button)
			for track in range(8):
				self._mixer.channel_strip(track).set_select_button(self._select_buttons[track])
				self._mixer.channel_strip(track).set_solo_button(self._solo_buttons[track])
			#self._transport.set_nudge_buttons(self._nudge_up_button, self._nudge_down_button)
			self._session.set_enabled(True)
			self._session_zoom._is_zoomed_out = False
			self._session_zoom.set_enabled(True)
			self.request_rebuild_midi_map()
			self._master_select_button.turn_off()

		elif(self._monomod_mode._mode_index == 1):
			if self._shift_modes._note_mode_active is True:
				self._shift_modes._mode_callback(ABLETON_MODE)
				self._shift_modes._note_mode_active = False
				self._session_zoom.set_ignore_buttons(False)
				self._shift_modes._transport.update()
				self._shift_modes._on_note_mode_changed()
			#self._transport.set_nudge_buttons(None, None)
			self._shift_modes.set_enabled(False)
			for track in range(8):
				self._mixer.channel_strip(track).set_select_button(None)
				self._mixer.channel_strip(track).set_solo_button(None)
			for scene in range(5):
				self._scene_launch_buttons[scene].turn_off()
			self._session.set_enabled(False)
			self._session_zoom.set_enabled(False)
			#self._session.set_track_bank_buttons(None, None)
			#self._session.set_scene_bank_buttons(None, None)
			self.flash_status = 1
			self._monomod.reset()
			self._host._set_button_matrix(self._monomod)
			#self._host._set_nav_buttons([self._up_button, self._down_button, self._left_button, self._right_button])
			self._host._set_shift_button(self._shift_button)
			self._host._set_lock_button(self._scene_launch_buttons[0])
			self._host._set_alt_button(self._scene_launch_buttons[1])
			self._host._set_nav_buttons([self._scene_launch_buttons[2], self._scene_launch_buttons[3]])
			self._host.set_enabled(True)
			self.request_rebuild_midi_map()
			self._master_select_button.turn_on()
			#self.log_message('mod mode')

	"""m4l bridge"""
	def generate_strip_string(self, display_string):
		#self.log_message(display_string)
		NUM_CHARS_PER_DISPLAY_STRIP = 12
		if (not display_string):
			return (' ' * NUM_CHARS_PER_DISPLAY_STRIP)
		if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.endswith('dB') and (display_string.find('.') != -1))):
			display_string = display_string[:-2]
		if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)):
			for um in [' ',
			 'i',
			 'o',
			 'u',
			 'e',
			 'a']:
				while ((len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.rfind(um, 1) != -1)):
					um_pos = display_string.rfind(um, 1)
					display_string = (display_string[:um_pos] + display_string[(um_pos + 1):])
		else:
			display_string = display_string.center((NUM_CHARS_PER_DISPLAY_STRIP - 1))
		ret = u''
		for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)):
			if ((ord(display_string[i]) > 127) or (ord(display_string[i]) < 0)):
				ret += ' '
			else:
				ret += display_string[i]

		ret += ' '
		assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
		return ret

	def notification_to_bridge(self, name, value, sender):
		if isinstance(sender, MonoEncoderElement):
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))

	def touched(self):
		if self._touched is 0:
			self._monobridge._send('touch', 'on')
			self.schedule_message(2, self.check_touch)
		self._touched +=1

	def check_touch(self):
		if self._touched > 5:
			self._touched = 5
		elif self._touched > 0:
			self._touched -= 1
		if self._touched is 0:
			self._monobridge._send('touch', 'off')
		else:
			self.schedule_message(2, self.check_touch)

	def get_clip_names(self):
		clip_names = []
		for scene in self._session._scenes:
			for clip_slot in scene._clip_slots:
				if clip_slot.has_clip() is True:
					clip_names.append(clip_slot._clip_slot)##.clip.name)
					return clip_slot._clip_slot
					##self.log_message(str(clip_slot._clip_slot.clip.name))
		return clip_names

	def update_display(self):
		super(AumPC20, self).update_display()
		self._timer = (self._timer + 1) % 256
		self.flash()

	def flash(self):
		if self.flash_status:
			for control in self.controls:
				if isinstance(control, MonoButtonElement):
					control.flash(self._timer)

	def set_appointed_device(self, *a, **k):
		pass


#! /usr/bin/env python
import os
import argparse
import datetime
import torch
import torchtext.data as data
import torchtext.datasets as datasets
import model
import train
import mydatasets
import numpy as np
np.random.seed(3)
torch.manual_seed(3) # Keeping it fixed

parser = argparse.ArgumentParser(description='classification_model text classificer')
# learning
parser.add_argument('--lr', type=float, default=0.001, help='initial learning rate [default: 0.001]')
parser.add_argument('--epochs', type=int, default=256, help='number of epochs for train [default: 256]')
parser.add_argument('--batch-size', type=int, default=64, help='batch size for training [default: 64]')
parser.add_argument('--log-interval',  type=int, default=1,   help='how many steps to wait before logging training status [default: 1]')
parser.add_argument('--test-interval', type=int, default=100, help='how many steps to wait before testing [default: 100]')
parser.add_argument('--save-interval', type=int, default=500, help='how many steps to wait before saving [default:500]')
parser.add_argument('--save-dir', type=str, default='snapshot', help='where to save the snapshot')
parser.add_argument('--early-stop', type=int, default=1000, help='iteration numbers to stop without performance increasing')
parser.add_argument('--save-best', type=bool, default=True, help='whether to save when get best performance')
# data
parser.add_argument('--shuffle', action='store_true', default=False, help='shuffle the data every epoch')
parser.add_argument('--dataset-dir', default='data', help = 'dataset directory path which contains negetive/positive/neutral files')
parser.add_argument('--max-length', type=int, default=600, help='The maximum number of characters in sequence.')
parser.add_argument('--min-freq', type=int, default=20, help='The minimum frequency of a character to be a vocab member')
# model
parser.add_argument('--dropout', type=float, default=0.5, help='the probability for dropout [default: 0.5]')
parser.add_argument('--max-norm', type=float, default=3.0, help='l2 constraint of parameters [default: 3.0]')
parser.add_argument('--embed-dim', type=int, default=128, help='number of embedding dimension [default: 128]')
parser.add_argument('--kernel-num', type=int, default=100, help='number of each kind of kernel')
parser.add_argument('--kernel-sizes', type=str, default='3,4,5', help='comma-separated kernel size to use for convolution')
parser.add_argument('--static', action='store_true', default=False, help='fix the embedding')
#rnn model
parser.add_argument('--rnn', action = 'store_true', default = False, help = 'activate char rnn')
parser.add_argument('--hidden_dim', type = int, default = 100, help = 'Hidden Dimensions of the RNN.')
parser.add_argument('--rnn-layers', type = int, default = 1, help = "Number of stacked RNN layers")
# device
parser.add_argument('--device', type=int, default=-1, help='device to use for iterate data, -1 mean cpu [default: -1]')
parser.add_argument('--no-cuda', action='store_true', default=False, help='disable the gpu')
# option
parser.add_argument('--snapshot', type=str, default=None, help='filename of model snapshot [default: None]')
parser.add_argument('--predict', type=str, default=None, help='predict the sentence given')
parser.add_argument('--test', action='store_true', default=False, help='train or test')

args = parser.parse_args()

tokenizer = lambda sent: list(sent[::-1])

# load data
print("\nLoading data...")
text_field = data.Field(lower=True, include_lengths = True, batch_first = True,
                        tokenize = tokenizer, fix_length = args.max_length)
label_field = data.Field(sequential=False, batch_first = True)
train_iter, dev_iter = mydatasets.load_twitter_dataset_vocab(text_field, label_field,
                                                             args.dataset_dir, args.min_freq,
                                                             args.batch_size, args.rnn)

args.embed_num = len(text_field.vocab)
print("Size of Vocab :", args.embed_num)
args.class_num = len(label_field.vocab) - 1
args.cuda = (not args.no_cuda) and torch.cuda.is_available(); del args.no_cuda
args.kernel_sizes = [int(k) for k in args.kernel_sizes.split(',')]
args.save_dir = os.path.join(args.save_dir, datetime.datetime.now()
                                                    .strftime('%Y-%m-%d_%H-%M-%S'))

print("\nParameters:")
for attr, value in sorted(args.__dict__.items()):
    print("\t{}={}".format(attr.upper(), value))

# model

if args.snapshot is not None:
    print('\nLoading model from {}...'.format(args.snapshot))
    classification_model = torch.load(args.snapshot)
elif args.rnn:
    classification_model = model.RNNClassifier(args.embed_num, args.embed_num,
                                               args.hidden_dim, args.rnn_layers,
                                               args.class_num)
else:
    classification_model = model.CharCNN(args.embed_num, args.embed_dim,
                                         args.class_num, args.kernel_num,
                                         args.kernel_sizes, args.dropout)

if args.cuda:
    torch.cuda.set_device(args.device)
    classification_model = classification_model.cuda()

# train or predict
if args.predict is not None:
    label = predict.predict(args.predict, classification_model, text_field, label_field, args.cuda)
    print('\n[Text]  {}\n[Label] {}\n'.format(args.predict, label))
elif args.test:
    train.eval(dev_iter, classification_model, args)
    #Print index of labels
    for i in range(args.class_num):
        print(str(i) +" --> " + label_field.vocab.itos[i+1])
else:
    print()
    try:
        train.train(train_iter, dev_iter, classification_model, args)
    except KeyboardInterrupt:
        print('\n' + '-' * 89)
        print('Exiting from training early')


#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Xiaobai Lei
import os
import sys
from core import accounts
from core import transaction
from core import logger
from core import auth
from conf import setting
from core.auth import login_require
# 所有的交易日志
transaction_logger = logger.logger("transaction")

def account_info(user_data):
    """
    列出个人信息
    :param user_data:
    :return:
    """
    user_info = u'''
           ------ %s info --------
           \033[32;1m
           卡号:  %s
           余额:  %s
           注册时间: %s
           过期时间: %s
           \033[0m''' % (user_data['account_data']['username'], user_data['account_id'],user_data['account_data']['credit_balance'], user_data['account_data']['register_date'], user_data['account_data']['expire_date'])
    print(user_info)

def repay(user_data):
    """
    实现还款功能
    :param user_data:
    :return:
    """
    back_flag = True    # 标志位
    while back_flag:
        account_data = accounts.load_account(user_data['account_id'])  # 加载用户最新的数据
        current_balance = ''' ----- BALANCE INFO -----
            Credit_limit :    %s
            Credit_balance:   %s''' % (account_data['credit_limit'], account_data['credit_balance'])
        print(current_balance)
        repay_amount = input("请输入还款金额：").strip()
        # 用户输入整型数字
        if len(repay_amount) > 0 and repay_amount.isdigit():
            # 如果信用卡余额跟信用卡额度一致则证明没花过钱，则不用还款
            if account_data['credit_balance'] == account_data['credit_limit']:
                print("信用卡已还清，无需还款")
                continue
            elif account_data['credit_balance'] + float(repay_amount) > account_data['credit_limit']:
                print("当前还款金额大于信用卡已使用金额，请输入正确还款金额")
                continue
            new_account_data = transaction.make_transaction(account_data, "repay", repay_amount, transaction_logger)
            if new_account_data:
                print("最新余额为：%s" % new_account_data['credit_balance'])
        elif repay_amount == "b" or repay_amount == "back":         # 返回功能
            back_flag = False
        else:
            print("请合法输入数字或者返回键b")

@login_require
def withdraw(user_data):
    """
    实现取款功能
    :param user_data:
    :return:
    """
    back_flag = True    # 标志位
    while back_flag:
        account_data = accounts.load_account(user_data['account_id'])   # 加载用户最新信息
        current_balance = ''' ----- BALANCE INFO -----
                    Credit_limit :    %s
                    Credit_balance:   %s''' % (account_data['credit_limit'], account_data['credit_balance'])
        print(current_balance)
        withdraw_amount = input("请输入取款金额：").strip()     # 用户输入取款金额
        # 判断用户是否输入整型数字
        if len(withdraw_amount) > 0 and withdraw_amount.isdigit():
            # 取款计算，返回取款后的值
            new_account_data = transaction.make_transaction(account_data, "withdraw", withdraw_amount, transaction_logger)
            if new_account_data:
                print("最新余额为：%s" % new_account_data['credit_balance'])
        elif withdraw_amount == "b" or withdraw_amount == "back":         # 返回功能
            back_flag = False
        else:
            print("请合法输入数字或者返回键b")

@login_require
def transfer(user_data):
    """
    实现转账功能
    :param user_data:
    :return:
    """
    back_flag = True  # 标志位
    while back_flag:
        account_data = accounts.load_account(user_data['account_id'])  # 加载用户最新信息
        current_balance = ''' ----- BALANCE INFO -----
                        Credit_limit :    %s
                        Credit_balance:   %s''' % (account_data['credit_limit'], account_data['credit_balance'])
        print(current_balance)
        transfer_account = input("请输入收款人账号：").strip()  # 用户输入收款人账号
        if transfer_account.isdigit():
            transfer_account_data = accounts.load_account(int(transfer_account))  # 加载收款人用户信息
            if not transfer_account_data:                   # 判断是否存在该卡号
                print("你输入的卡号有误，请重新输入")
                continue
            transfer_amount = input("请输入转账金额：").strip()  # 用户输入转账金额
            # 判断用户是否输入整型数字
            if len(transfer_amount) > 0 and transfer_amount.isdigit():
                # 当前卡转账后剩余的钱
                new_account_data = transaction.make_transaction(account_data, "withdraw", transfer_amount, transaction_logger)
                if new_account_data:
                    # 收款方进账的钱
                    new_transfer_account_data = transaction.make_transaction(transfer_account_data, "accept", transfer_amount, transaction_logger)
                    print("当前卡最新余额为：%s" % new_account_data['credit_balance'])
            elif transfer_amount == "b" or transfer_amount == "back":  # 返回功能
                back_flag = False
            else:
                print("请合法输入数字或者返回键b")
        elif transfer_account == "b" or transfer_account == "back":         # 返回功能
            back_flag = False
        else:
            print("请合法输入数字或者返回键b")

def pay_check(user_data):
    """
    查看账单
    :param user_data:
    :return:
    """
    # log_time = input("请输入开始时间，格式为Y-M-D").strip()
    transaction_log = os.path.join(setting.BASE_DIR, "logs", setting.LOG_TYPES['transaction'])
    with open(transaction_log, "r") as log_f:
        for i in log_f:
            if "account:%s"%(user_data['account_id']) in i:
                print(i, end='')

def logout(user_data):
    """
    实现退出功能
    :return:
    """
    account_info(user_data)         # 打印个人账户信息
    exit()                          # 退出程序

if __name__ == '__main__':
    repay(user_data)


import numpy as np
import pandas as pd

# from pandasgui import show
import utils as u
from timer import Timer
from tqdm import tqdm

ourDepartment = ["ESD02 - Pflugerville", "ESD02"]

def recalcDict(arr, time):
    # print("=========================\n", arr)
    for bucket in arr:
        arr[bucket] = list(filter(lambda x: x > time, arr[bucket]))
    # print("\n------\n", arr, "\n")
    return arr

def addConcurrentUse(orig, startName, endName):
    """
    Add a column of concurrent values to a dataset

    Parameters
    --------------------------------
    Original : dataframe
        data to which you want to add the columns
    Start Name : str - ex: Unit Time Assigned
        the time the bucket shipped out
    End Name : str - ex: Unit Time Call Cleared
        the time the bucket will finish its current call

    Returns
    --------------------------------
    Dataframe
        a new dataframe which is a copy of orig, but with an extra column used to identify concurrent use at the time of bucket assignment
    """
    # create a dictionary of buckets, and when they will be done
    bucketDict = {}

    # create the column with a obviously default number
    orig["Concurrent Usage"] = np.NaN

    # ---------------- SECONDARY - TIME IN RANGE CALCULATIONS ---------------
    # =======================================================================
    # set up timeInterval for easier overlap detection

    # dont crash the program when no close is given please...
    def makeInterval(inc, start, end):
        interval = pd.Interval(0, 0, closed="neither")
        try:
            interval = pd.Interval(start, end, closed="right")
        except Exception as e:
            if not (pd.isnull(start) or pd.isnull(end)):
                print(f"{inc}: {start} - {end} : {e}")
            else:
                pass
            try:
                interval = pd.Interval(start, start, closed="right")
            except Exception as err:
                if not (pd.isnull(start)):
                    print(err)
        return interval

    orig["Time_Interval"] = orig.apply(
        lambda row: makeInterval(
            row["Master Incident Number"], row[startName], row[endName]
        ),
        axis=1,
    )

    # Set up columns to reveal specific time overlap
    for x in range(10):
        orig[f"Time_{x}_Active"] = 0
    #  -----------------------------------------------------------------------

    # limit the dictionary as much as possible, since this will go quite slow
    # start with just our jurisdiction
    # distArr = orig.index[(orig["Jurisdiction"].isin(["ESD02", "ESD17"]))].tolist()
    distArr = orig.index[(orig["Department"].isin(ourDepartment))].tolist()
    with tqdm(total=len(distArr), desc=f"Getting Concurrency") as pbar:
        for ind in distArr:
            # get start and end time of incident
            startTime = orig.loc[ind, startName]
            endTime = orig.loc[ind, endName]

            # get bucket type from the name
            # use the column if it exists, since this work should already be done.
            try:
                bucketType = str(orig.loc[ind, "Bucket Type"])
            except:
                bucketType = u.getUnitBucket(u.getUnitType(orig.loc[ind, "Radio_Name"]))

            # store end time for this type into the dictionary
            bucketDict[bucketType] = [endTime] + (
                bucketDict[bucketType] if bucketType in bucketDict else []
            )

            # remove those that are already finished
            recalcDict(bucketDict, startTime)

            # store current count as concurrent usage
            orig.loc[ind, "Concurrent Usage"] = (
                len(bucketDict[bucketType])
                - 1  # remove on since this one is being counted
            )

            # ---------------- SECONDARY - TIME IN RANGE CALCULATIONS ---------------
            # =======================================================================
            orig = getTimes(orig, ind, orig.loc[ind, "Time_Interval"], bucketType)
            # =======================================================================
            pbar.update(1)

    # remove the new useless interval column
    orig = orig.drop(
        [
            "Time_Interval",
        ],
        axis=1,
    )
    return orig  # .astype({"Concurrent Usage": "Int64"})

# ===================================
#       SECONDARY - TIME IN RANGE CALCULATIONS
# ===================================
def getTimes(df, ind, interval, bucket):
    """
    Get get all time breakdowns for a specific passed row of the passed DF
    """
    # filter on same bucket
    nearbyInd = df[abs(df.index - ind) < 15]
    commonTimes = nearbyInd[
        (nearbyInd["Bucket Type"] == bucket)
        & (nearbyInd["Department"].isin(ourDepartment))
        # & (nearbyInd["include_in_concurrency"])
    ]

    # Remove broken time intervals before comparing them

    # filter that on overlap times - lets use only those within 20
    try:
        commonTimes = commonTimes[
            commonTimes.apply(
                lambda row: interval.overlaps(row["Time_Interval"]), axis=1
            )
        ]
    except Exception as e:
        print(f"{ind} - {interval}")

    # this should never actually happen afterall, you should ALWAYS find yourself.
    # if commonTimes.empty:
    #     return df

    # get list of all overlapping start/end points
    timeList = (
        commonTimes["Unit Time Assigned"].tolist()
        + commonTimes["Unit Time Call Cleared"].tolist()
    )

    timeList.sort()
    # remove everything before this units start and everything after this unit end
    # after opening set to eliminate overlap issues, the original interval now needs to be added in manually
    tempTime = [interval.left]
    for x in timeList:
        if (x in interval) and (x not in tempTime):
            tempTime.append(x)

    # WTF is this list not sorted?

    # print(f"---------------------------------------------------------\n{timeList}")
    # print(f"\nfiltered:\n{tempTime}\n\n")

    # use the list to group out concurrency
    # -----------------------
    inc = df.loc[ind, "Master Incident Number"]
    # print(
    #     f"==================================================================================\n----- {inc}: \n{interval}\n\n{timeList}"
    # )
    timeList = tempTime

    timeDict = {}
    prevTime = timeList[0]
    # create a breakdown of
    # skip the first, as it should always be 0 seconds
    for time in timeList[1:]:
        timeRange = time - prevTime
        try:
            setLength = (
                commonTimes[
                    commonTimes.apply(lambda row: time in row["Time_Interval"], axis=1)
                ].shape[0]
                - 1
            )
        except Exception as e:
            pass
            # show(commonTimes)I just want to finish my cabinets
        # print(f"  {str(time):<30}: {str(timeRange):<23}-   {setLength}")
        # max out the time to be 9+ units
        if setLength > 9:
            setLength = 9
        try:
            timeDict[setLength] += timeRange
        except:
            timeDict[setLength] = timeRange
        prevTime = time

    # print(timeDict)
    for x in timeDict:
        # store each time as seconds into the rows new fields
        df.loc[ind, f"Time_{x}_Active"] = int(timeDict[x] / np.timedelta64(1, "s"))

    # show(commonTimes)

    return df

## Main - Used for testing, and will be ignored on import.
def main():
    import loadTestFile

    df = loadTestFile.get()

    # remove data not useful for the testing
    # limit = [
    #     "Master Incident Number",
    #     "Department",
    #     "Radio_Name",
    #     "Unit Time Assigned",
    #     "Unit Time Call Cleared",
    # ]
    # df = df[limit]

    # =================================================================
    #     Add unit type column to simplify analysis
    # =================================================================
    df = u.addUnitType(df)
    df = u.addBucketType(df)

    # test the function
    df = addConcurrentUse(df, "Unit Time Assigned", "Unit Time Call Cleared")
    # show the results
    show(df)

if __name__ == "__main__":
    main()


# Take the number 192 and multiply it by each of 1, 2, and 3:
# 192 × 1 = 192
# 192 × 2 = 384
# 192 × 3 = 576
# By concatenating each product, we get the 1 to 9 pandigital, 192384576.
# We will call 192384576 the concatenated product of 192 and (1,2,3)
# The same can be achieved by starting with 9 and multiplying by 1, 2, 3, 4, and 5,
# giving the pandigital, 918273645, which is the concatenated product of 9 and(1,2,3,4,5).
# What is the largest 1 to 9 pandigital 9-digit number that can be formed
# as the concatenated product of an integer with (1,2, ... , n) where n >1?

# Check if number is 1 to 9 pandigital
def isPan(x):
    l1 = []
    for i in str(x):
        if i == "0":
            return False
        else:
            l1.append(i)
    return True if len(set(l1)) == 9 and len(l1) == 9 else False

# Generate pandigital number from an int x and a provided array
def getPan(x, l1):
    ans = ""
    for i in l1:
        ans += str(x * i)
    return int(ans)

# largest pandigital number with provided integer and n
def largestPan(x, n):
    l1 = []
    panList = []
    for i in range(1, n + 1):
        l1.append(i)
        z = getPan(x, l1)
        if isPan(z):
            panList.append(z)
    return "No 1-9 pan digit found for this set of x and list of range n" if len(panList) == 0 else max(panList)

if __name__ == "__main__":
    print(largestPan(192, 3))  # test case 9 is int and x is range for list


from django.urls import path
from django.conf.urls.static import static

from sgdtaxi import settings
from .views import index, PropietarioAPi, getDepartamentos, VehiculoApi, PropietarioUpdateAPi, \
    VehiculoUpdateApi, VinculacionApi, VinculacionDocumentosApi

urlpatterns = [
    path('', index, name='index'),
    path('api/propietario/', PropietarioAPi.as_view()),
    path('api/propietario/<int:pk>/', PropietarioAPi.as_view()),
    path('api/propietario/actualizar/', PropietarioUpdateAPi.as_view()),
    path('api/vehiculo/', VehiculoApi.as_view()),
    path('api/vehiculo/actualizar/', VehiculoUpdateApi.as_view()),
    path('api/vehiculo/<int:doc>/', VehiculoApi.as_view()),
    path('api/vehiculo/<str:placa>/', VehiculoUpdateApi.as_view()),
    path('api/vinculacion/', VinculacionApi.as_view()),
    path('api/vinculacion/<int:pk>/', VinculacionApi.as_view()),
    path('api/vinculacion/documento/', VinculacionDocumentosApi.as_view()),
    path('departamentos/', getDepartamentos),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


# This file is focused on the preprocessing of the two datasets that were given
# by the authors of Identification of Speakers in Novels
# The first file is Jane Austen's Pride & Prejudice book, and the second is an annotation
# file labelling each utterance with its speaker

import re
import pickle
import tqdm

def replace_names_with_codes(sentence, people):
    """For each character `p` in the `people` list,
    replaces the occurences of `p["aliases"]` in `sentence` with the main name
    p["main"]
    """
    codes = {}
    replacements = []
    for code_i, p in enumerate(people):
        code = "@{}@".format(str(code_i))
        codes[code] = p["main"]
        for a in p['aliases']:
            replacements.append((a, code))
    for a, code in sorted(replacements, key=lambda x: len(x[0]), reverse=True):
        sentence = re.sub(a, code, sentence)
    for code, main in codes.items():
        sentence = re.sub(code, main, sentence)
    return sentence

def strip_equal(a, b, l):
    """Tries to match a and b by removing "[X]" tokens and extra spaces, and truncating `a` and `b` to length `l` """
    return re.sub(r'(\[X\])|\s', '', a)[:l] == re.sub(r'(\[X\])|\s', '', b)[:l]

def build_dataset(text_file, people):
    """Takes the path `text_file`, list of people `people` ({"main": "main name", "aliases": [list of aliases], "code": "code to be used for Prolog"})
    and splits the text in utterances, and each utterance in narrator/speaker parts
    """
    with open(text_file, 'r+') as raw_text_file:
        # go through all lines in the book
        text = raw_text_file.read()

    utterances = []
    is_utterance = False
    processed = ""
    source = ""
    sample_parts = []
    text = re.sub('[_]', '', text)
    text = replace_names_with_codes(text, people)
    text = re.sub(' +', ' ', " "+text)
    parts = list(p for p in re.split("(``)|('')", text) if p is not None)
    i = 0
    discussion_index = 0
    index = 0
    while i < len(parts):
        part = parts[i]
        if part == '``' or part == "''":
            is_utterance = part == '``'
            source += part
            i += 1
            continue
        if not is_utterance:
            if next(re.finditer('\n\n', part), None) is not None: # before or after an utterance
                lines = [s for s in re.split("\n\n\.?", part)]
                end_index = index + len(source) + len(part)
                if processed != "":
                    if len(lines)>0 and re.sub('\s+|--', '', lines[0]) != "":
                        sample_parts.append({"text": lines[0], "utterance": False})
                        source += lines[0]
                    if processed[-5:] == " [X] ":
                        processed = processed[:-5]
                    if processed != "":
                        utterances.append({
                            "only_utterance_us": processed,
                            "source": source,
                            "parts": sample_parts,
                            "discussion_index": discussion_index,
                            "begin": index,
                            "end": index + len(source)
                        })
                    if len(re.findall('\n\n', part)) > 3:
                        discussion_index += 1
                    index = end_index
                processed = ""
                if len(lines) > 1 and re.sub('\s+|--', '', lines[-1]) != "":
                    sample_parts = [({"text": lines[-1], "utterance": False})]
                else:
                    sample_parts = []
                source = lines[-1] if len(lines) > 1 else ''
            else: # in the middle of an utterance
                if re.sub('\s+|--', '', part) != "":
                    sample_parts.append({"text": part, "utterance": False})
                source += part
                if part != " -- ":
                    if processed[-5:] != " [X] ":
                        processed += " [X] "
                else:
                    processed += " "
        else:
            sample_parts.append({"text": part, "utterance": True})
            monoline = " ".join(part.split("\n\n"))
            processed += monoline
            source += part
        i += 1

    return utterances

def match_with_annoted_file(path, utterances, people):
    """Matches the `utterances` found by the `build_dataset` function to those described in the `path` file,
    and transforms the target in the annoted file with the main name of the `people` list
    """
    processed_to_index = {annotation["only_utterance_us"]: i for i, annotation in reversed(list(enumerate(utterances)))}

    # annotation matching part
    with open(path) as annoted_text_file:
        annotated_text_lines = annoted_text_file.readlines()

    annoted_utterances = []

    for annoted_line in annotated_text_lines:
        annotation_i, label, utterance_text = annoted_line.split('\t')
        utterance_text = re.sub('_', '', utterance_text)
        utterance_text = re.sub('\s+', ' ', utterance_text)
        utterance_text = utterance_text.strip()
        utterance_text = replace_names_with_codes(utterance_text, people)

        # If there is multiple speakers, then create two examples out of it
        # There are too few cases like this to transforms this problem into
        # a multi-target classification
        for speaker in label.split(' and '):
            speaker = replace_names_with_codes(speaker, people)
            # Look up in the utterances to match the annotated line
            if utterance_text in processed_to_index and "target" not in utterances[processed_to_index[utterance_text]]:
                utterance = utterances[processed_to_index[utterance_text]]
            else:
                # If we can't match it directly, then make an approximation match using `strip_equal`
                utterance = next((a for a in utterances if strip_equal(a['only_utterance_us'], utterance_text, 100) and "target" not in a), None)
                if utterance is None:
                    print("No match :")
                    print(utterance_text)
                    print("--")
                if utterance['only_utterance_us'] != utterance_text:
                    print("Almost match :")
                    print(utterance['only_utterance_us'])
                    print(utterance_text)
                    print("--")
            assert "target" not in utterance
            annoted_utterance = utterance.copy()
            annoted_utterance["only_utterance_article"] = utterance_text
            annoted_utterance["target"] = speaker
            annoted_utterances.append(annoted_utterance)

    return annoted_utterances


#From AQA AS Computing June 2015 COMP1 Paper - psuedocode about printing prime numbers up to 50.
print("The first few prime numbers are: ")
for Count1 in range(2, 50):
  Count2 = 2
  Prime = "Yes"
  while Count2 * Count2 <= Count1:
    if Count1 % Count2 == 0:
      Prime = "No"
    Count2 += 1
  if Prime == "Yes":
    print(Count1)

School Project Recreations/COMP1 June 2015 Section B/main.py


from sklearn.impute import KNNImputer
from utils import *
import matplotlib.pyplot as plt
import scipy.spatial.distance as scidist
import pandas as pd
import numpy as np

#used this function to test out different distance metrics
def cdist_single_scidist(Xa, Xb, missing_values):
    return scidist.jaccard(Xa.T, Xb.T)

 #‘braycurtis’, ‘canberra’, ‘chebyshev’, ‘cityblock’, ‘correlation’, ‘cosine’, ‘dice’, ‘euclidean’, ‘hamming’, ‘jaccard’, ‘jensenshannon’, ‘kulsinski’, ‘mahalanobis’, ‘matching’, ‘minkowski’, ‘rogerstanimoto’, ‘russellrao’, ‘seuclidean’, ‘sokalmichener’, ‘sokalsneath’, ‘sqeuclidean’, ‘wminkowski’, ‘yule
def sparse_matrix_evaluate_item(data, matrix, threshold=0.5):
    """ Given the sparse matrix represent, return the accuracy of the prediction on data.

    :param data: A dictionary {user_id: list, question_id: list, is_correct: list}
    :param matrix: 2D matrix
    :param threshold: float
    :return: float
    """
    total_prediction = 0
    total_accurate = 0
    for i in range(len(data["is_correct"])):
        cur_user_id = data["user_id"][i]
        cur_question_id = data["question_id"][i]
        if matrix[cur_question_id, cur_user_id] >= threshold and data["is_correct"][i]:
            total_accurate += 1
        if matrix[cur_question_id, cur_user_id] < threshold and not data["is_correct"][i]:
            total_accurate += 1
        total_prediction += 1
    return total_accurate / float(total_prediction)

def knn_impute_by_user(matrix, valid_data, k):
    """ Fill in the missing values using k-Nearest Neighbors based on
    student similarity. Return the accuracy on valid_data.

    See https://scikit-learn.org/stable/modules/generated/sklearn.
    impute.KNNImputer.html for details.

    :param matrix: 2D sparse matrix
    :param valid_data: A dictionary {user_id: list, question_id: list,
    is_correct: list}
    :param k: int
    :return: float
    """
    nbrs = KNNImputer(n_neighbors=k)
    # We use NaN-Euclidean distance measure.
    mat = nbrs.fit_transform(matrix)
    acc = sparse_matrix_evaluate(valid_data, mat)
    print("Validation Accuracy: {}".format(acc))
    return acc

def knn_impute_by_item(matrix, valid_data, k):
    """ Fill in the missing values using k-Nearest Neighbors based on
    question similarity. Return the accuracy on valid_data.

    :param matrix: 2D sparse matrix
    :param valid_data: A dictionary {user_id: list, question_id: list,
    is_correct: list}
    :param k: int
    :return: float
    """
    #the underlying assumption of this function is that if  question A has the same correct and incorrect answers from other users as question B,
    #(the same students who got question A correct would also get question B correct), question A's correctness for a specific user would match that of that users correctness on question B

    nbrs = KNNImputer(n_neighbors=k)

    #in the implementation above, they take the sparse matrix as-is (where students are rows and questions are columns) to predict based on students. If we want to predict based on questions, we should transpose the matrix
    #transpose the matrix so questions are now the samples and users are the features

    matrix_t = matrix.transpose()
    mat = nbrs.fit_transform(matrix_t)
    acc = sparse_matrix_evaluate_item(valid_data, mat)
    print("Validation Accuracy: {}".format(acc))
    #####################################################################
    # TODO:                                                             #
    # Implement the function as described in the docstring.             #
    #####################################################################

    #####################################################################
    #                       END OF YOUR CODE                            #
    #####################################################################
    return acc

def main():
    sparse_matrix = load_train_sparse("./data").toarray()
    val_data = load_valid_csv("./data")
    test_data = load_public_test_csv("./data")
    train_data = load_train_csv("./data")

    print("Sparse matrix:")
    print(sparse_matrix)
    print("Shape of sparse matrix:")
    print(sparse_matrix.shape)

    ks = range(1,30)

    #compute validation accuracy for each k and plot as a function of k
    accuracy = []
    for k in ks:
      acc = knn_impute_by_user(sparse_matrix, val_data, k)
      accuracy.append(acc)

    print(accuracy)
    #plot
    plt.plot(ks, accuracy)
    #plt.title("K-NN alidation accuracy (impute user) as a function of k")
    plt.xlabel('k')
    plt.ylabel('Validation Accuracy')
    plt.show()

    #choose the k with the highest accuracy
    k_star = ks[np.argmax(accuracy)]

    #report the test accuracy using k_star

    test_accuracy = knn_impute_by_user(sparse_matrix, test_data, k_star)

    print("the test accuracy on K* for the impute by user model is: " + str(test_accuracy))

    ##now complete a) and b) for the version "impute by item"

    accuracy_item = []
    for k in ks:
      acc_item = knn_impute_by_item(sparse_matrix, val_data, k)
      accuracy_item.append(acc_item)

    #plot
    plt.plot(ks, accuracy_item)
    #plt.title("K-NN validation accuracy (impute item) as a function of k")
    plt.xlabel('k')
    plt.ylabel('Validation Accuracy')
    plt.show()

    #choose the k with the highest accuracy

    k_star_item = ks[np.argmax(accuracy_item)]

    #report the test accuracy using k_star

    test_accuracy_item = knn_impute_by_item(sparse_matrix, test_data, k_star_item)

    print("the test accuracy on K* for the impute by item model is: " + str(test_accuracy_item))

    #####################################################################
    # TODO:                                                             #
    # Compute the validation accuracy for each k. Then pick k* with     #
    # the best performance and report the test accuracy with the        #
    # chosen k*.                                                        #
    #####################################################################
    pass
    #####################################################################
    #                       END OF YOUR CODE                            #
    #####################################################################

if __name__ == "__main__":
    main()


from bs4 import BeautifulSoup
import urllib.request, urllib.error, urllib.parse, time

def getAndProcessArtistsPage(artists):
    for currentArtist in artists.split("*"):
        currentArtist = currentArtist.lower().replace(" ", "")
        firstLetter = currentArtist[:1]
        generate_url = 'http://azlyrics.com/' + firstLetter + '/' + currentArtist + ".html"
        alternativeProcessing(generate_url, currentArtist, save=True)

def generating(artist, title, save):
    artist = artist.lower().replace(" ", "")
    title = title.lower().replace(" ", "")
    generate_url = 'http://azlyrics.com/lyrics/' + artist + '/' + title + '.html'
    processSong(generate_url, artist, title, save)

def alternativeProcessing(generate_url, artist, save):
    print("generating url: " + generate_url)
    response = urllib.request.urlopen(generate_url)
    read_artist_page = response.read()
    soup = BeautifulSoup(read_artist_page).find_all("a")
    i = 0
    for x in soup:
        i = i + 1
        completeLink = x.extract()
        stringToCompare = '<a href="../lyrics/' + artist
        if completeLink.decode().startswith(stringToCompare):
            sep = '/'
            currentSongName = completeLink.decode().split(sep, 3)[3]
            sep = '.html'
            currentSongName = currentSongName.split(sep, 1)[0]
            print("processing " + artist + "'s song " + currentSongName + "...")
            generating(artist, currentSongName, save)

def processSong(generate_url, artist, title, save):
    response = urllib.request.urlopen(generate_url)
    read_lyrics = response.read()
    soup = BeautifulSoup(read_lyrics)
    lyrics = soup.find_all("div", attrs={"class": None, "id": None})
    lyrics = [x.getText() for x in lyrics]
    printing(artist, title, save, lyrics)

def printing(artist, title, save, lyrics):
    for x in lyrics:
        print(x)
    if save:
        saving(artist, title, lyrics)
    else:
        pass

def saving(artist, title, lyrics):
    f = open(artist + '_' + title + '.txt', 'w')
    f.write("\n".join(lyrics).strip())
    f.close()
    time.sleep(15) #in order to avoid being disconnected from the server


import csv

base_a = 'fortune500-{}.csv.bak'
base_b = 'fortune500-{}.csv'

def remove_comma(year):
    """
    Given the CSV file for the particular year, remove comma separators
    in the revenue and profit columns. Also, remove stock symbols in the
    company name column (which is only applicable to 2006).
    """

    filename_a = base_a.format(year)  # in-file
    filename_b = base_b.format(year)  # out-file

    data = []
    with open(filename_a, 'r') as f1:
        reader = csv.reader(f1)
        for row in reader:
            data.append(row)

    assert len(data)==501  # first row is header

    with open(filename_b, 'w') as f2:
        writer = csv.writer(f2)
        writer.writerow(data[0])
        for row in data[1:]:
            row[2] = row[2].replace(',', '')  # revenue numbers: remove comma separator
            row[3] = row[3].replace(',', '')  # profit numbers: remove comma separator

            # remove trailing stock symbol
            if row[1].count('('):
                assert row[1][-1] == ')'
                idx = row[1].find('(')
                assert row[1][idx-1] in ('\xa0', ' ')  # \xa0 is space for latin1 encoding
                row[1] = row[1][:idx-1]  # remove trailing stock symbol
                # print(row)
            writer.writerow(row)

if __name__ == '__main__':
    for year in range(2006, 2013):
        remove_comma(year)