import pandas as pd
from urllib.parse import urlparse
from tld import get_tld
import re
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

url_list=pd.read_csv('malicious_phish.csv')

url_list.loc[651191,'url']='http://verzeomarch64.eu5.org/fb/facebook.html'
url_list.loc[651191,'type']='benign'
print(url_list.head())
print(url_list.tail())

def first_d(urlpath):
    try:
        return len(urlpath.split('/')[1])
    except:
        return 0
def tld_length(tld):
    try:
        return len(tld)
    except:
        return -1
def digit_count(url):
    digits = 0
    for i in url:
        if i.isnumeric():
            digits = digits + 1
    return digits
def letter_count(url):
    letters = 0
    for i in url:
        if i.isalpha():
            letters = letters + 1
    return letters
def having_ip_address(url):
    match = re.search(
        '(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.'
        '([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\/)|'  # IPv4
        '((0x[0-9a-fA-F]{1,2})\\.(0x[0-9a-fA-F]{1,2})\\.(0x[0-9a-fA-F]{1,2})\\.(0x[0-9a-fA-F]{1,2})\\/)' # IPv4 in hexadecimal
        '(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}', url)  # Ipv6
    if match:
        return -1
    else:
        return 1
def shortening_service(url):
    match = re.search('bit\.ly|goo\.gl|shorte\.st|go2l\.ink|x\.co|ow\.ly|t\.co|tinyurl|tr\.im|is\.gd|cli\.gs|'
                      'yfrog\.com|migre\.me|ff\.im|tiny\.cc|url4\.eu|twit\.ac|su\.pr|twurl\.nl|snipurl\.com|'
                      'short\.to|BudURL\.com|ping\.fm|post\.ly|Just\.as|bkite\.com|snipr\.com|fic\.kr|loopt\.us|'
                      'doiop\.com|short\.ie|kl\.am|wp\.me|rubyurl\.com|om\.ly|to\.ly|bit\.do|t\.co|lnkd\.in|'
                      'db\.tt|qr\.ae|adf\.ly|goo\.gl|bitly\.com|cur\.lv|tinyurl\.com|ow\.ly|bit\.ly|ity\.im|'
                      'q\.gs|is\.gd|po\.st|bc\.vc|twitthis\.com|u\.to|j\.mp|buzurl\.com|cutt\.us|u\.bb|yourls\.org|'
                      'x\.co|prettylinkpro\.com|scrnch\.me|filoops\.info|vzturl\.com|qr\.net|1url\.com|tweez\.me|v\.gd|'
                      'tr\.im|link\.zip\.net',
                      url)
    if match:
        return -1
    else:
        return 1
def copied_html(url):
    if("Facebook.html" in url):
        return 1
    elif("Instagram.html" in url):
        return 1
    elif("Twitter.html" in url):
        return 1
    elif("Skype.html" in url):
        return 1
    else:
        return 0

url_list['length']=url_list['url'].apply(lambda i: len(str(i)))
url_list['path_length'] = url_list['url'].apply(lambda i: len(urlparse(i).path))
url_list['firstd_length'] = url_list['url'].apply(lambda i: first_d(urlparse(i).path))
url_list['.ext_length'] = url_list['url'].apply(lambda i: tld_length(get_tld(i,fail_silently=True)))
url_list['count-'] = url_list['url'].apply(lambda i: i.count('-'))
url_list['count@'] = url_list['url'].apply(lambda i: i.count('@'))
url_list['count?'] = url_list['url'].apply(lambda i: i.count('?'))
url_list['count%'] = url_list['url'].apply(lambda i: i.count('%'))
url_list['count.'] = url_list['url'].apply(lambda i: i.count('.'))
url_list['count='] = url_list['url'].apply(lambda i: i.count('='))
url_list['count/'] = url_list['url'].apply(lambda i: (urlparse(i).path).count('/'))
url_list['count-http'] = url_list['url'].apply(lambda i : i.count('http'))
url_list['count-https'] = url_list['url'].apply(lambda i : i.count('https'))
url_list['count-www'] = url_list['url'].apply(lambda i: i.count('www'))
url_list['count-digits']= url_list['url'].apply(lambda i: digit_count(i))
url_list['count-letters']= url_list['url'].apply(lambda i: letter_count(i))
url_list['use_of_ip'] = url_list['url'].apply(lambda i: having_ip_address(i))
url_list['short_url'] = url_list['url'].apply(lambda i: shortening_service(i))
url_list['fake_html'] = url_list['url'].apply(lambda i: copied_html(i))

x = url_list[['length','path_length', 'firstd_length', '.ext_length', 'count-', 'count@', 'count?','count%', 'count.', 'count=', 'count/','count-http','count-https', 'count-www', 'count-digits','count-letters', 'use_of_ip','short_url','fake_html']]

y = url_list['type']

x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.8, random_state=41)

dt_model = DecisionTreeClassifier()
dt_model.fit(x_train,y_train)
p=dt_model.predict([x_test.iloc[-1]])

dt_predictions = dt_model.predict(x_test)
print(accuracy_score(y_test,dt_predictions))
print(p)


import json
from types import MethodType

from browser import document, html, ajax, window  # type: ignore

import data
from data import START_POS, SCALE, PIXELS, Ability, abilities

def factory_activate_abl(box):
    ability_id = box.id.lstrip('box-')
    div = box.parent
    spec_id = div.id.lstrip('options-')
    spec = document[f'spec-{spec_id}']
    bar = [el for el in spec.children if el.id == f'abl-{ability_id}'][0]
    def _activate(ev):
        if bar.style.height == '0px':
            bar.style.height = ''
            bar.style.visibility = ''
        else:
            bar.style.height = '0px'
            bar.style.visibility = 'hidden'
    return _activate

def factory_activate_spec(box):
    div = box.parent
    abl_boxes = div.select('.ability-checkbox')
    spec_id = box.id.lstrip('box-')
    spec = document[f'spec-{spec_id}']

    def _activate(ev):
        if spec.style.height == '0px':
            spec.style.height = ''
            spec.style.visibility = ''
            for abl_box in abl_boxes:
                abl_box.disabled = False
        else:
            spec.style.height = '0px'
            spec.style.visibility = 'hidden'
            for abl_box in abl_boxes:
                abl_box.disabled = True
    return _activate

def factory_change_specs(inp):
    spec_name = inp.id.lstrip('count-')
    spec_obj = next(spec for spec in data.specs if spec.name == spec_name)
    spec_div = document[f'spec-{spec_name}']
    opt_div = document[f'options-{spec_name}']

    def _add(ev):
        max_id = min(int(inp.value) - 1, 3)

        specs = spec_div.children
        for spec in specs:
            if int(spec.id[-1]) <= max_id:
                spec.style.height = ''
                spec.style.visibility = ''
            else:
                spec.style.height = '0px'
                spec.style.visibility = 'hidden'
        for i in range(len(specs), max_id + 1):
            spec_div <= Spec(spec_obj, i)

        opts = list(filter(lambda x: isinstance(x, html.DIV), opt_div.children))
        for spec_opts in opts:
            if int(spec_opts.id[-1]) <= max_id:
                spec_opts.style.height = ''
                spec_opts.style.visibility = ''
            else:
                spec_opts.style.height = '0px'
                spec_opts.style.visibility = 'hidden'
        for i in range(len(opts), max_id + 1):
            opt_div <= SpecOpts(spec_obj, i)
        ability_boxes()
        spec_boxes()
        nicknames_inputs()
    return _add

def factory_change_nick(inp):
    spec_id = inp.id.lstrip('nick-')
    lbl = document[f'lbl-{spec_id}']

    def change_nick(ev):
        lbl.textContent = inp.value
    return change_nick

def ability_boxes():
    checkboxes = document.select('.ability-checkbox')
    for box in checkboxes:
        box.unbind('click')
        box.bind('click', factory_activate_abl(box))

def spec_boxes():
    checkboxes = document.select('.spec-checkbox')
    for box in checkboxes:
        box.unbind('click')
        box.bind('click', factory_activate_spec(box))

def spec_inps():
    spec_inputs = document.select('.spec-inp')
    for inp in spec_inputs:
        inp.unbind('input')
        inp.bind('input', factory_change_specs(inp))

def nicknames_inputs():
    inps = document.select('.spec-nick')
    for inp in inps:
        inp.unbind('input')
        inp.bind('input', factory_change_nick(inp))

def px_to_float(px: str) -> float:
    return float(px[:-2])

def px_to_time(px: str) -> str:
    time_stamp = int((px_to_float(px) - START_POS) / SCALE)
    return f'{time_stamp // 60}:{time_stamp % 60:02d}'

def float_to_time(n: float) -> str:
    time_stamp = int((n - START_POS) / SCALE)
    return f'{time_stamp // 60}:{time_stamp % 60:02d}'

class Draggable(html.DIV):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def drag(self, ev):
        start_pos = ev.clientX

        def _stop_drag(ev):
            self.unbind('mousemove')
            self.unbind('mouseup')

        def _drag(ev):
            nonlocal start_pos
            delta = start_pos - ev.clientX
            start_pos = ev.clientX
            self.move(delta)

        self.bind('mouseup', _stop_drag)
        self.bind('mouseleave', _stop_drag)
        self.bind('mousemove', _drag)

    def move(self, delta: int, target=None):
        new_pos = self.offsetLeft - delta
        new_pos_right = new_pos + self.ability.cool_down
        obstacles_right = \
            False if not self._right else px_to_float(self._right.style.left) < new_pos_right
        obstacles_left = \
            False if not self._left else px_to_float(self._left.style.right) > new_pos

        if obstacles_left and delta > 0:
            self._left.move(SCALE, self)
        elif obstacles_right and delta < 0:
            self._right.move(-SCALE, self)
        elif new_pos <= PIXELS and new_pos >= START_POS:
            self._move(new_pos)
            if target:
                target.move(delta)

    def _move(self, new_pos: int):
        self.style.left = f'{new_pos}px'
        self.style.right = f'{new_pos + self.ability.cool_down}px'
        self.tooltip.text = px_to_time(self.style.left)

class AbilityBar(Draggable):
    """Draggable bar with ability name"""
    def __init__(self, ability: Ability, position: float, id: str):
        super().__init__(Class='ability-bar higher20')
        self.ability = ability
        self.pos = position
        self.id = f"abl-bar-{ability.name}{id}"

        self <= self._content()
        self.tooltip = html.SPAN(px_to_time(self.style.left), Class='tooltiptext')
        self <= self.tooltip

    @classmethod
    def new(cls, bar: html.DIV, ability: Ability):
        bar.ability = ability
        bar.drag = MethodType(cls.drag, bar)
        bar.move = MethodType(cls.move, bar)
        bar._move = MethodType(cls._move, bar)
        bar.tooltip = bar.select('.tooltiptext')[0]
        return bar

    def _content(self):
        self.style.left = f'{self.pos}px'
        self.style.right = f'{self.pos + self.ability.cool_down}px'
        self.style.width = self.ability.cool_down

        duration_style = {
            'max-width': self.ability.duration,
            'width': self.ability.duration,
            'background-color': self.ability.color_main,
        }
        duration = html.TD(
            self.ability.name,
            style=duration_style,
            Class='duration'
        )

        cd_length = self.ability.cool_down - self.ability.duration
        cd_style = {
            'width': cd_length,
            'background-color': self.ability.color_cd,
        }
        cd = html.TD(style=cd_style)

        tr = html.TR()
        tr <= duration
        tr <= cd
        tbody = html.TBODY()
        tbody <= tr
        ability_tbl = html.TABLE(Class='ability-tbl')
        ability_tbl <= tbody
        return ability_tbl

class AbilityRow(html.DIV):
    """Several draggable bars in one row"""
    def __init__(self, ability: Ability, id_: int):
        self.ability = ability
        abl_id = f'abl-{ability.name}{id_}'
        super().__init__(id=abl_id, Class='tooltip abl-bar')
        self._bars = [AbilityBar(ability, START_POS, '0')]
        self.bind_bars()

        self.btn_add = html.BUTTON('+', Class='btn-add', id=f'btn-{ability.name}{id_}')
        self.btn_add.unbind('click')
        self.btn_add.bind('click', self.add_bar())
        self <= self.btn_add
        self <= self._bars
        if not ability.check:
            self.style.visibility = 'hidden'
            self.style.height = '0px'

    @classmethod
    def new(cls, bar: html.DIV):
        bar.add_bar = MethodType(cls.add_bar, bar)
        bar.bind_bars = MethodType(cls.bind_bars, bar)

        ability_id = bar.id.lstrip('abl-')
        ability_name = ability_id[:-1]
        ability = next(abl for abl in abilities if abl.name == ability_name)
        bar.ability = ability
        abl_bars = bar.select('.ability-bar')
        bar._bars = [AbilityBar.new(abl_bar, ability) for abl_bar in abl_bars]
        bar.bind_bars()

        bar.btn_add = document[f'btn-{ability_id}']
        bar.btn_add.unbind('click')
        bar.btn_add.bind('click', bar.add_bar())
        return bar

    def add_bar(self):
        def adder(ev):
            bar_count = len(self._bars)
            last_bar = self._bars[-1]
            new_bar = AbilityBar(self.ability, px_to_float(last_bar.style.right), id=bar_count)
            self._bars.append(new_bar)
            self.bind_bars()
            self <= self._bars
        return adder

    def bind_bars(self):
        bar_count = len(self._bars)
        for i, bar in enumerate(self._bars):
            bar._left = self._bars[i - 1] if i > 0 else None
            bar._right = None if i == (bar_count - 1) else self._bars[i + 1]
            bar.unbind('mousedown')
            bar.bind('mousedown', bar.drag)

class Spec(html.DIV):
    """Division with several ability rows belonging to one specialization or player"""
    def __init__(self, spec: data.Spec, id: int):
        div_id = f'spec-{spec.name}{id}'
        super().__init__(id=div_id, Class=div_id.rstrip(str(id)))
        self.spec = spec
        self._id = id
        self._fill()
        self.inp.bind('input', self.change_nick)

    def _fill(self):
        name = self.spec.name
        self.inp = html.INPUT(
            id=f'nick-{name}{self._id}',
            Class='spec-nick',
            type='text',
            name=name,
            value=name,
            size=12
        )
        self <= self.inp
        for ability in self.spec.abilities:
            self <= AbilityRow(ability, self._id)
            self <= html.BR()

    def change_nick(self, ev):
        pass

    @classmethod
    def new(cls, div: html.DIV):
        return div

class SpecOpts(html.DIV):
    """Set of options for a spec - spec on/off, abilities on/off."""
    def __init__(self, spec: data.Spec, id: int):
        div_id = f'options-{spec.name}{id}'
        super().__init__(id=div_id)
        self.spec = spec
        self._id = id
        self._fill()

    def _fill(self):
        name = self.spec.name
        inp = html.INPUT(
            id=f'box-{name}{self._id}',
            Class='spec-checkbox',
            type='checkbox',
            name=f'box-{name}',
            checked=True
        )
        self <= inp
        self <= html.LABEL(html.B(name, id=f'lbl-{name}{self._id}'), For=f'box-{name}{self._id}')
        self <= html.BR()
        for ability in self.spec.abilities:
            name = ability.name
            inp = html.INPUT(
                id=f'box-{name}{self._id}',
                Class='ability-checkbox',
                type='checkbox',
                name=f'box-{name}{self._id}')
            if ability.check:
                inp.checked = True
            lbl = html.LABEL(name, For=f'box-{name}{self._id}')
            self <= inp
            self <= lbl
            self <= html.BR()

def phase_serialize():
    # Serialize phases to list of dicts.
    boss_phases = []
    phases = document['phases']
    for phase_div in phases.children:
        phase_name = phase_div.textContent.strip()
        try:
            phase = list(filter(lambda x: x['name'] == phase_name, boss_phases))[0]
        except IndexError:
            phase = dict(
                name=phase_name,
                color=phase_div.style['background-color'],
                intervals=[]
            )
        interval = [float_to_time(px_to_float(phase_div.style.left) - SCALE),
                    float_to_time(px_to_float(phase_div.style.right) - SCALE)]
        phase['intervals'].append(interval)
        if len(phase['intervals']) == 1:
            boss_phases.append(phase)
    return boss_phases

def casts_serialize():
    # Serialize boss casts to list of dicts.
    boss_casts = []
    boss_actions = document['boss-casts']
    for action_div in boss_actions.children:
        action = dict(
            name=action_div.text.strip(),
            color=action_div.children[0].style['background-color'],
            casts=[]
        )
        for cast in action_div.children:
            tooltip = cast.select('.tooltiptext')[0]
            text = tooltip.textContent.strip()
            time = text.split(' at')[1]
            action['casts'].append(time)
        boss_casts.append(action)
    return boss_casts

def layout_serialize():
    layout = []
    specs = document['specs']
    for spec_div in specs.children:
        spec = {
            'spec': {
                'name': spec_div.id.lstrip('spec-')
            },
            'players': []
        }
        for player in spec_div.children:
            inst = {
                'nick': player.select('input')[0].value,
                'is_visible': player.style.visibility != 'hidden',
                'abilities': []
            }
            for abl in player.select('.abl-bar'):
                ability = {
                    'casts': [],
                    'name': abl.id.lstrip('abl-')[:-1]
                }
                for a in abl.select('.ability-bar'):
                    tooltip = a.select('.tooltiptext')[0]
                    time = tooltip.textContent.strip()
                    ability['casts'].append(time)
                ability['is_visible'] = abl.style.visibility != 'hidden'
                inst['abilities'].append(ability)
            spec['players'].append(inst)
        layout.append(spec)
    # Without this line dragging brakes ^^.
    enable()
    return layout

def serialize(ev):
    seconds = (len(document.select('.timeline-ruler-tick')) /
               len(document.select('.timeline-ruler')))
    res = {
        'encounter': {
            'seconds': seconds,
            'name': document['boss-select'].selectedOptions[0].text,
            # 'phases': phase_serialize(),
            'boss_actions': casts_serialize()
        },
        'layout': layout_serialize()
    }
    send(res)

def send(d: dict):
    req = ajax.Ajax()
    req.open('POST', '/save_layout')
    req.set_header('content-type', 'application/json')
    _data = json.dumps(d)
    print(_data)
    req.send(_data)
    req.bind('complete', show_msg)

def show_msg(req):
    document['modal'].style.display = 'block'
    p = document['modal-content']

    if req.status == 200:
        msg = f'{window.location.hostname}/{req.text}'

    else:
        msg = f'Error {req.status}'

    p.textContent = msg

def modal_and_save():
    btn = html.BUTTON('Save', id='save-btn')
    btn.bind('click', serialize)
    document <= btn

    # modal = document['modal']
    span = document['close-modal']
    span.bind('click', close_modal)
    window.bind('keydown', esc_close_modal)
    # window.bind('click', close_modal)

def esc_close_modal(ev):
    if ev.keyCode == 27:
        document['modal'].style.display = 'none'

def close_modal(ev):
    document['modal'].style.display = 'none'

def lock_unlock():
    lock_btn = document['lock']

    def _lock_bind(ev):
        if lock_btn.textContent == 'Lock':
            lock()
            lock_btn.textContent = 'Unlock'
        else:
            unlock()
            lock_btn.textContent = 'Lock'

    lock_btn.bind('click', _lock_bind)

def lock():
    for el in document.select('.ability-bar'):
        el.unbind('mousedown')
    for el in document.select('input'):
        el.disabled = True

def unlock():
    enable()
    for el in document.select('input'):
        el.disabled = False

def enable():
    [AbilityRow.new(bar) for bar in document.select('.abl-bar')]

if __name__ == '__main__':
    ability_boxes()
    spec_boxes()
    spec_inps()
    nicknames_inputs()
    enable()
    modal_and_save()
    lock_unlock()


class MoveClass:
    def __init__(self, controller, view, canvas):
        self.controller = controller
        self.view = view
        self.canvas = canvas

    def setBinds(self, className):
        self.canvas.tag_bind(className, '<ButtonPress-1>', lambda e, tag=className: self.startDrag(e, tag))
        self.canvas.tag_bind(className, '<B1-Motion>', lambda e, tag=className: self.drag(e, tag, className))
        self.canvas.tag_bind(className, '<ButtonRelease-1>', lambda e, tag=className: self.stopDrag(e, tag, className))

    def changeBinds(self, oldClassName, newClassName):
        self.removeBinds(oldClassName)
        self.setBinds(newClassName)

    def removeBinds(self, className):
        self.canvas.tag_unbind(className, '<ButtonPress-1>')
        self.canvas.tag_unbind(className, '<B1-Motion>')
        self.canvas.tag_unbind(className, '<ButtonRelease-1>')

    # Starts move class drag
    def startDrag(self, event, tag):
        widget = event.widget
        widget.startX = event.x
        widget.startY = event.y

    # Moves class with left click
    def drag(self, event, tag, className):
        widget = event.widget
        x = event.x - widget.startX
        y = event.y - widget.startY

        self.canvas.move(tag, x, y)
        self.view.classDict[className].updateCoordinateList()
        self.view.updateLineDict(className)
        widget.startX = event.x
        widget.startY = event.y

    def stopDrag(self, event, tag, className):
        widget = event.widget
        coordinates = self.canvas.coords(tag)
        x = coordinates[0]
        y = coordinates[1]
        self.view.classDict[className].updateAllCoordinates(x, y)
        self.view.drawLines()
        self.controller.updateClassCoordinates(className, x, y)


# Given an array of integers, find the one that appears an odd number of times.

# There will always be only one integer that appears an odd number of times.

def find_it(seq):
    count = 0

    #create a dictionary of key:value tuples where key is the number in the seq and value is the count
    occ = {item : seq.count(item) for item in seq}
    #loop through the tuples created above and check the values for odd counts if an odd count is found, return the key
    for ct in occ.items():
        if (ct[1] == 1) or (ct[1]%2 == 1):
            return ct[0]
    return None


from random import randint

LOWER_LIMIT = 0
UPPER_LIMIT = 1001
AMOUNT_OF_GUESSES = 10

rand_num = randint(LOWER_LIMIT, UPPER_LIMIT)

for _ in range(AMOUNT_OF_GUESSES):
    guess_num = int(input("Введите число: "))
    if guess_num == rand_num:
        print("Вы угадали")
        break
    elif guess_num > rand_num:
        print("Введенное число больше загаданного")
    elif guess_num < rand_num:
        print("Введенное число меньше загаданного")


def lettercount(inp):
    count = 0
    for letter in inp:
        if letter == 'a':
            count = count + 1
    print('Count is:',count)

word = input('Input a word:\n')
selection = input('Pick a letter to count:\n')
if selection in word:
     lettercount(word)
else:
    print('Select a letter in the word chosen')


from django.db.models.signals import pre_save, post_save, post_delete
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile, FriendRequestNotification

# def upadateUser(sender, instance, **kwargs):
#     user = instance
#     if user.email != '':
#         user.username = user.email

# pre_save.connect(upadateUser, sender=User)

# Once a user is created, a profile is automatically created as well
@receiver(post_save, sender=User)
def post_save_create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

@receiver(post_save, sender=FriendRequestNotification)
def post_save_add_to_friends(sender, created, instance, **kwargs):
    sender_ = instance.sender
    receiver_ = instance.receiver
    if instance.action==2:
        sender_.friends.add(receiver_)
        receiver_.friends.add(sender_)
        sender_.save()
        receiver_.save()

@receiver(post_save, sender=FriendRequestNotification)
def post_save_delete_from_friends(sender, created, instance, **kwargs):
    sender_ = instance.sender
    receiver_ = instance.receiver
    if instance.action==3:
        sender_.friends.remove(receiver_.profile)
        receiver_.friends.remove(sender_.profile)
        sender_.save()
        receiver_.save()
        instance.delete()

@receiver(post_save, sender=FriendRequestNotification)
def post_save_delete_from_friends(sender, created, instance, **kwargs):
    sender_ = instance.sender
    receiver_ = instance.receiver
    if instance.action==4:
        sender_.friends.remove(receiver_.profile)
        receiver_.friends.remove(sender_.profile)
        sender_.save()
        receiver_.save()
        instance.delete()


from itertools import *

def alpha(st_):
    for i in range(1, len(st_)):
        if (st_[i - 1] in 'ЕЯ' and st_[i] in 'ЕЯ') or (st_[i - 1] in 'ЛС' and st_[i] in 'ЛС'):
            return False
    return True

s = list(map(''.join, product('ЛЕСЯ ', repeat=5)))

count = 0

for i in s:
    if i.count(' ') == 1:
        st = i.split(' ')
        if all(len(j) > 0 for j in st):
            if alpha(i):
                count += 1
print(count)


#!/usr/bin/python
#Call python module for OS commands

import os
import subprocess

#Define variable for stop the container

#Calling the variable for stopping the container
def execute_cmd(cmd):

    start = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) ###execution, non-blocking
    out, err = start.communicate()
    ret = start.returncode
    return (ret,out,err)

#Function denine for stubby

def stubby():
    cmd = "docker run --init -d -p 127.0.0.1:53:53/udp mintooraj/stubby-quad9"
    return execute_cmd(cmd)

#check if stubby is running, if not then start it up

ret,out,err = stubby()
if ("ret == 1"):
        print ("stubby not running , starting it up")
stubby()


from itertools import combinations
from collections import defaultdict

def solution(infos, querys):
    answer = []
    # 딕셔너리 초기화
    info_dict = defaultdict(list)
    # 각각의 요소 딕셔너리에 넣기 (마지막값은 score)
    for info in infos:
        temp = info.split(" ")
        key = temp[0:-1]
        score = int(temp[-1])
        # 가능한 조합 경우의수 집어넣기
        for i in range(5):
            combi = list(combinations(key, i))
            for c in combi:
                temp_key = ''.join(c)
                info_dict[temp_key].append(score)
    # 키값순으로 정렬
    for key in info_dict.keys():
        info_dict[key].sort()
    # 쿼리값 정리
    for query in querys:
        query = query.split(" ")
        query_score = int(query[-1])
        query_key = query[:-1]
        # and 제거
        for _ in range(3):
            query_key.remove("and")
        # '-' 제거
        while "-" in query_key:
            query_key.remove("-")
        query_key = ''.join(query_key)
        # 경우의 수가 존재하면
        if query_key in info_dict:
            scoreList = info_dict[query_key]
            # 스코어 비교 ( 이진 탐색 )
            if len(scoreList) > 0:
                left, right = 0, len(scoreList)
                while left < right:
                    mid = (left + right) // 2
                    if scoreList[mid] >= query_score:
                        right = mid
                    else:
                        left = mid+1
                answer.append(len(scoreList)-left)
        # 경우의 수가 없다면 0 추가
        else:
            answer.append(0)

    return answer


from django.shortcuts import render

# Create your views here.
from rest_framework import generics

from quiz.serializers import CategorySerializer, QuestionSerializer, QuizSerializer
from .models import Options, Category, Question, Quiz

from django_filters.rest_framework import DjangoFilterBackend

### search filter
from rest_framework import filters

    ## category leri api seklinde json formatinda gönderme
class CategoryList(generics.ListAPIView):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer

    ## frontend e gönderme
class QuizList(generics.ListAPIView):
    queryset = Quiz.objects.all()
    serializer_class = QuizSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["category"]  ## bu category nin id sine göre filtreleme yapar.
    # filterset_fields = ["category__name"]
    ## neye göre filtreleme yapacagim. filters diye bir tus gelir.
    ## child dan parent a ulasmak icin __ kullanilir. yani buradan Category tablosundaki name e ulasiyoruz ve ona göre filtreleme yapiyoruz.
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    search_fields = ["title"] ## filters dan sonra filter butonu cikar.

## backend e tikladigimizda json veri de sadece backend e ait quizler gelsin istersek django filter kullaniriz.  pip install django-filter sonra settings e ekleme.

class QuestionList(generics.ListAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    search_fields = ["quiz", "difficulty"] ## question tablosundaki quiz e göre filtreleme

## https://anthony67-react-drf-quizapp.vercel.app/


from wiki_requests import get_topic_page
import re
from bs4 import BeautifulSoup as BS

def get_topic_words(topic):
    html_content = get_topic_page(topic)

    more_link_word = get_some_more_links_word(html_content)

    if len(more_link_word):
        #Ограничение тремя ссылками, чтобы быстрее было
        for word in more_link_word[0:3]:
            html_content+= get_topic_page(word)

    words = re.findall("[а-яА-я\-\']{3,}", html_content)
    return words

def get_some_more_links_word(content):
    soup = BS(content, 'html.parser')

    def is_none(attr):
        return attr is None
    # Можно еще улучшить выборку. У меня остались ссылка на снутренние страницы, которые разделены :
    # Так же остались ссылки на языки
    li = soup.find_all('a', href=re.compile("^/wiki/"), class_=is_none, accesskey=is_none)

    strArr=[]

    for a in li:
        str1 = re.findall('>([а-яА-Я].+)</', str(a))
        if len(str1):
            strArr.append(str1[0])

    return strArr

def get_common_words(topic):
    words_list = get_topic_words(topic)
    rate = {}
    for word in words_list:
        if word in rate:
            rate[word] += 1
        else:
            rate[word] = 1

    rate_list = list(rate.items())
    rate_list.sort(key = lambda x: -x[1])
    return rate_list

def visualize_common_words(topic):
    words = get_common_words(topic)

    print("Список: ", words)

def main():
    topic = input("Topic")
    visualize_common_words(topic)


# nums = 123456789

# def descending_order(num):
#     # Bust a move right here
#     out = [int(x) for x in str(num)]
#     print(out)
#     sortedOut = out.sort(reverse=True)
#     print(sortedOut)
# descending_order(nums)

import re

# with open('names.txt') as file:
#     data = file.readlines()
#     # print(data)
#     i = 0
#     for n in data:
#         pat = re.compile('(?P<first>[A-Z][a-zA-Z]+), (?P<last>[A-Z][a-zA-Z-]+)(?P<op>[\w\W]+)(?P<domain>)(?P<twitter>@[a-z]+)')

#         m = pat.search(data[i])
#         if m:
#             print(f"{m.group('first')} {m.group('last')} / {m.group('twitter')}")
#             i += 1
#         else:
#             print('None')
#             i += 1

with open('regex_test.txt') as file:
    data = file.readlines()
    # print(data)
    i = 0
    pat = re.compile('(?P<first>[A-Z][a-z]+) (?P<op>[A-Z]+|[A-Z][a-z]+) (?P<last>[A-Z][a-z]+)')
    for n in data:
        m = pat.search(data[i])
        if m:
            print(f"{m.group('first')}{m.group('op')}{m.group('last')}")
            i += 1
    else:
        print('None')
        i += 1


from django.urls import path
from .views import *

urlpatterns = [
    path('login/', login_user, name='login'),
    path('register/', register_user, name='register'),
    path('redirect-user/base-location/', redirect_origin, name='redirect_origin'),
    path('logout/', logout_user, name='logout'),

    # Staff Area

    # Product Handler

    path('staff-main-1/', staff_main1, name='staff_main1'),
    path('pending-orders/', pending_orders, name='pending_orders'),
    path('pending-order-action/', pending_order_action, name='pending_order_action'),

    # Product Adder

    path('staff-main-2/', staff_main2, name='staff_main2'),
    path('add-edit-products/', add_products, name='add_products'),
    path('add-edit-products/<str:pk>/', edit_products, name='edit_products'),

    # Normal & unregistered user

    path('', account, name='account'),
    path('order-history/', order_history, name='order_history'),
    path('query-order-history/', query_order_history, name='query_order_history'),
    path('save-wishlist-item/', save_wishlist_item, name='save_wishlist_item'),
    path('check-wishlist-item-availability/', check_product_availability, name='check_product_availability'),
    path('remove-wishlist-item/', remove_wishlist_item, name='remove_wishlist_item'),
    path('wishlist/', wishlist, name='wishlist'),
    path('transaction/', transactions, name='transaction'),

    # Admin

    path('admin/', dashboard, name='admin_dashboard'),
    path('statistics/', statistics, name='statistics'),
    path('admin/product-list/', admin_product_list, name='admin_product_list'),
    path('admin/orders/', admin_orders, name='admin_orders'),
    path('admin/add-edit-product/', admin_add_product, name='admin_add_product'),
    path('admin/add-edit-product/<str:pk>/', admin_edit_product, name='admin_edit_product'),
    path('admin/transactions/', admin_transactions, name='admin_transactions'),

]


import pygame

class Button():
    def __init__(self,screen,settings,message):
        self.screen = screen
        self.screen_rect = self.screen.get_rect()
        self.settings = settings
        self.rect = pygame.Rect(0,0,settings.button_width,settings.button_height)
        self.rect.center = self.screen_rect.center
        self.font = pygame.font.SysFont(None,48)
        self.print_message(message)

    def print_message(self,message):
        self.message = self.font.render(message,True,self.settings.text_color,self.settings.button_color)
        self.message_rect = self.message.get_rect()
        self.message_rect.center = self.rect.center

    def draw_button(self):
        self.screen.fill(self.settings.button_color,self.rect)
        self.screen.blit(self.message,self.message_rect)


from pyswip import Prolog
import studente as s
import funzionalita as f

prolog = Prolog()
prolog.consult("KB.pl")

#mostra la lista completa degli studenti
def destinationList():

    myTrueQuery= "destinazione(ID,FACOLTA,DISPONIBILITA)"
    f.outputResult(myTrueQuery, True)

def addDestination():

    destinationID = ""

    #controllo numero caratteri della matricola inserita
    while(not 1 <= len(str(destinationID)) <= 3):

        destinationID = input("Inserisci codice destinazione:\n").lower()

        queryCheck = "destinazione("+str(destinationID)+",FACOLTA,DISPONIBILITA)"

        #messaggio errore nel caso la lunghezza dell'ID non rovesse rientrare nel range (1-3)
        if(not 1 <= len(str(destinationID)) <= 3):
            print("Valore inserito non valido. Max 3 caratteri!\n")

        #messaggio errore nel caso sono presenti dei numeri nell'ID inserito
        if(any(chr.isdigit() for chr in str(destinationID))):
            destinationID=""
            print("Valore inserito non valido. Inserire solo lettere!\n")

    #controllo presenza id nel database
    if(not f.outputResult(queryCheck, False)):
        facultyFound = False
            #controllo presenza facoltà nel database
        while(not facultyFound):

            faculty = input("Inserisci la facolta': ").lower()
            checkFaculty = "dipartimento("+str(faculty)+",INDIRIZZO,COORDINATORE)"
            facultyFound = f.outputResult(checkFaculty, False)

            if (not facultyFound):

                print("Valore inserito non valido, inserire una destinazione presente nel database.\n")

        availability = ""

        #controllo inserimento disponibilità
        while(availability == ""):

            availability = input("Inserisci la disponibilita': ")

            if(not availability.isdigit()):

                print("Valore inserito non valido, inserire solo valori numerici.\n")
                availability = ""

        queryCheck = "destinazione("+str(destinationID)+","+faculty+","+availability+")"
        prolog.assertz(queryCheck)

        print("Destinazione inserita nel database.")

    else:
        print("Destinazione gia' presente nel database.\n")

#rimuove una destinazione in seguito alla rimozione di un dipartimento
def removeDestination(departmentFaculty):
    destinationID=""
    queryCheck = "destinazione(ID,"+str(departmentFaculty)+",DISPONIBILITA)"

    #controllo presenza facolta' nel database
    if(f.outputResult(queryCheck, False)):

        destination=list(prolog.query("destinazione(ID,"+str(departmentFaculty)+",_)"))

        f.outputResult(queryCheck, True)

        for elem in destination:
            destinationID = str(destination[0]).split("'")
            s.removeStudentForDestination(destinationID[3])
            prolog.retractall(queryCheck)

def modifyAvailability(ID,operation):

    queryCheck = "destinazione("+str(ID)+",FACOLTA,DISPONIBILITA)"
    destination=list(prolog.query(queryCheck))
    #salvataggio occorrenze di FACOLTA' e DISPONIBILITA'
    for elem in destination:
        infoDestination = extractDestination(destination, operation)

        if(infoDestination[1] != 0):
            prolog.retractall(queryCheck)
            prolog.assertz("destinazione("+str(ID)+","+str(infoDestination[0])+","+str(infoDestination[1])+")")
            return True
        else:
            return False

def extractDestination(list, operation):
        listInfo=[]
        destinationID = str(list[0]).split("'")
        listInfo.append(destinationID[3])

        if(operation == 0):
            listInfo.append(int(destinationID[6][destinationID[6].find(' ')+1:destinationID[6].find('}')]) - 1)
            return listInfo

        elif(operation == 1):
            listInfo.append(int(destinationID[6][destinationID[6].find(' ')+1:destinationID[6].find('}')]) + 1)
            return listInfo

        else:
            return destinationID[7]


import yfinance as yf

stock_pair = []

def checar_precos():

    first_pair = []
    second_pair = []

    for i in range(0, len(stock_pair),1):
        if i == 0:
            ticker = yf.Ticker(stock_pair[i])
            price = ticker.info['regularMarketPrice']
            name = ticker.info['symbol']
            first_pair.append(name)
            first_pair.append(price)
        else:
            ticker = yf.Ticker(stock_pair[i])
            price = ticker.info['regularMarketPrice']
            name = ticker.info['symbol']
            second_pair.append(name)
            second_pair.append(price)

    if round(first_pair[1],2) > round(second_pair[1],2):
        diferenca_preco = (first_pair[1] - second_pair[1])
        diferenca_preco = '{:.2f}'.format(float(diferenca_preco))
    else:
        diferenca_preco = (second_pair[1] - first_pair[1])
        diferenca_preco = '{:.2f}'.format(float(diferenca_preco))

    ativo1 = first_pair[0].split('.')
    ativo2 = second_pair[0].split('.')

    diferenca_preco = str(diferenca_preco).replace('.', ',')

    print(f'A diferença de preços entre {ativo1[0]} e {ativo2[0]} é de R$ {diferenca_preco}')

ticker1 = input('Digite o ticker do primeiro par: ')+'.SA'
ticker2 = input('Digite o ticker do segundo par: ')+'.SA'
stock_pair.append(ticker1)
stock_pair.append(ticker2)

checar_precos()


'''
Link        : https://www.acmicpc.net/problem/14891
Difficulty  : GOLD-5
Category    : 구현, 시뮬레이션
Title       : 톱니바퀴
'''

import sys
from collections import deque

# 데이터 입력
gearStatusList = list()
for i in range(4):
    gearStatusList.append(deque(list(sys.stdin.readline().rstrip())))

K = int(sys.stdin.readline().rstrip())
rotateDataList = list()
for i in range(K):
    rotateDataList.append(list(map(int, sys.stdin.readline().rstrip().split())))

# 톱니바퀴 회전 함수
def rotate(gearStatus, direction):
    if(direction == 1): # 시계 방향
        temp = gearStatus.pop()
        gearStatus.appendleft(temp)
    else: # 반시계 방향
        temp = gearStatus.popleft()
        gearStatus.append(temp)

    return gearStatus

# 톱니바퀴 회전 실행
for i in range(K):
    target = rotateDataList[i][0] - 1

    newGearStatusList = list(gearStatusList)
    newGearStatusList[target] = rotate(deque(gearStatusList[target]), rotateDataList[i][1])

    # 좌측으로 인접한 톱니바퀴 회전
    if(target > 0):
        for j in range(target-1, -1, -1):
            if(gearStatusList[j+1][6] != gearStatusList[j][2]):
                # 회전 방향 계산
                if((target - j) % 2 == 0):
                    direction = rotateDataList[i][1]
                else:
                    direction = rotateDataList[i][1] * -1
                # 회전
                newGearStatusList[j] = rotate(deque(gearStatusList[j]), direction)
            else:
                # 회전하지 않음
                break

    # 우측으로 인접한 톱니바퀴 회전
    if(target < 3):
        for k in range(target+1, 4):
            if(gearStatusList[k-1][2] != gearStatusList[k][6]):
                # 회전 방향 계산
                if((k - target) % 2 == 0):
                    direction = rotateDataList[i][1]
                else:
                    direction = rotateDataList[i][1] * -1
                # 회전
                newGearStatusList[k] = rotate(deque(gearStatusList[k]), direction)
            else:
                # 회전하지 않음
                break

    # 톱니바퀴 상태 갱신
    gearStatusList = list(newGearStatusList)

# 점수 합 계산
result = 0
for i in range(4):
    if(newGearStatusList[i][0] == '1'):
        result += (2 ** i)

# 점수 합 출력
print(result)


if __name__ == '__main__':
     #Abertura Arquivo
    #Informe o nome do Arquivo para Leitura do Compilador:
    arq = open("Exemplo.afd", 'r')
    #Inclui AFD na String
    todo_texto = arq.read()
    arq.close()
    #String list, cada linha 1 item.
    linhas = todo_texto.split("\n")
    FuncaoPrograma = []

    #Acessando todos items da lista por linha.
    for i in range(0,len(linhas)-1):
        if i == 0:
            #Estado Inicial
            EstadoI = linhas[i]

        if i == 1:
            #Conjunto de Estados
            ConjuntoE = linhas[i].split(" ")
            #Contador Estados
            ContadorE = int(ConjuntoE[0])
            del(ConjuntoE[0])

        if i == 2:
            #Conjunto EstadoFinal
            EstadoFinal = linhas[i].split(" ")
            #Contador EstadoFinal
            ContadorEF = int(EstadoFinal[0])
            del(EstadoFinal[0])

        if i == 3:
            #Conjunto alfabeto
            Alfabeto = linhas[i].split(" ")
            #Contador Alfabeto
            ContadorAlf = int(Alfabeto[0])
            del(Alfabeto[0])
        #Contador Transição
        if i == 4:
            ContadorTrans = int(linhas[i])
        #Função programa:
        if i > 4:
            FuncaoPrograma.append(linhas[i].split(" "))
    del(todo_texto)
    del(linhas)

    #Congela 5 atributo AFD
    print("DEFINIÇÃO AFD --  M = \n ( Alfabeto > ", Alfabeto,", \n \n Conjuntos > ", ConjuntoE,",  \n \n  FunçãoPrograma(Exibirá abaixo) \n \n  Estado Inicial > ", EstadoI,", \n \n Estado Final > ",EstadoFinal,")")
    print(" \n \n FunctProgramaExib = {")

    #Congela palavra Vazia
    for i in range(0, len(FuncaoPrograma)):
        print("\t", FuncaoPrograma[i])
    print("\t}")

    palavra = input("DIGITE A PALAVRA PARA TESTE ")
    print()

    E_atual = EstadoI
    print("O ESTADO INICIAL É: ",E_atual)
    Resultado = 0
    #Teste palavra vazia:
    if len(palavra) == 0:
        aux = 0
        for q in EstadoFinal:
            if E_atual == q:
                aux += 1
        if aux > 0:
            Resultado = 1
            print("VAZIA ESTÁ CONTIDA NA LINGUAGEM.")
        else:
            Resultado = 0
            print("VAZIA NAO ESTA NA LINGUAGEM.")
    else:
        aux = 0
        #http://www.pythondiario.com/2015/06/afd-en-python-automata-finito.html
        #Teste todos simbolos da palavra inserida, se esta contida no alfabeto
        for simbolo in palavra:
            for letra in Alfabeto:
                if simbolo == letra:
                    aux += 1
        #Todos simbolos existentes no alfabeto
        if aux == len(palavra):
            for i in range(0, len(palavra)):
                simbolo = palavra[i]
                TesteDefinicao = 0
                #http://www.pythondiario.com/2015/06/afd-en-python-automata-finito.html
                #Faz Transição, verifica se cai por indefinição
                for trans in FuncaoPrograma:
                    if E_atual == trans[0] and simbolo == trans[1]:
                        TesteDefinicao += 1
                        novo_estado = trans[2]
                        print("Esta no estado", E_atual,", le o simbolo '%s' vai para o estado" % simbolo,novo_estado)
                if TesteDefinicao == 0:
                    Resultado = 2
                E_atual = novo_estado
            if Resultado != 2:
                teste_fim = 0
                #Verifica se Estado atual é Estado Final
                for q in EstadoFinal:
                    if E_atual == q:
                        teste_fim += 1
                if teste_fim > 0:
                    Resultado = 1
                else:
                    Resultado = 0
        else:
            Resultado = 3
    #Testes:
    if Resultado == 0:
        print(" PALAVRA NAO PASSA ")
    if Resultado == 1:
        print(" PALAVRA PASSA COM SUCESSO \n ")
    if Resultado == 2:
        print(" CAI POR INDEFINIÇÃO ")
    if Resultado == 3:
        print("  PALAVRA POSSUI UM OU MAIS SIMBOLOS FORA DO ALFABETO [Execute o Programa Novamente] \n")

    #KWARGS - DESCOMPACTA
    print("**Minimiza AFD:**\n")

   #https://github.com/vicmarbe/pytomata/blob/master/pytomata.py
   #Função programa deve ser total para minimização
   #Verifica se função programa é total, se não transforma.
    if ContadorTrans < (ContadorAlf * ContadorE):
        ConjuntoE.append('')
        aux = 0
        for q in ConjuntoE:
            for simbolo in Alfabeto:
                for trans in FuncaoPrograma:
                    if q == trans[0] and simbolo == trans[1]:
                        aux = 1
                if aux == 0:
                    FuncaoPrograma.append([q, simbolo, ConjuntoE[len(ConjuntoE)-1]])
                aux = 0
        print("CONJUNTO DE ESTADOS:")
        print(ConjuntoE)
        print()
        print("TODAS AS TRANSIÇÕES:")
        print(FuncaoPrograma)
        print()

    #http://www.decom.ufop.br/anderson/BCC242/MinimizacaoDeAFD.pdf
    #https://github.com/vicmarbe/pytomata/blob/master/pytomata.py
    #Step 1/2 : Cria Tabela e Marca estados normalmente não Equivalentes
    print(" Step 1/2 : CRIA TABELA E MARCA ESTADOS NORMALMENTE NÃO EQUIVALENTES  \n")
    pares_NEq = []
    for i in range(0, len(ConjuntoE)-1):
        for j in range(1, len(ConjuntoE)):
            if(((ConjuntoE[i] in EstadoFinal) and (ConjuntoE[j] not in EstadoFinal)) or ((ConjuntoE[j] in EstadoFinal) and (ConjuntoE[i] not in EstadoFinal))) and i < j:
                pares_NEq.append([ConjuntoE[i],ConjuntoE[j]])
    print(" PARES DE ESTADOS TRIVIAMENTES NÃO EQUIVALENTES: \n")
    print(pares_NEq)
    print()
    #http://www.decom.ufop.br/anderson/BCC242/MinimizacaoDeAFD.pdf
    #https://github.com/vicmarbe/pytomata/blob/master/pytomata.py
    #Step 3: Marca estados não equivalentes
    print(" Step 3: MARCA ESTADOS NÃO EQUIVALENTES \n ")
    par = []
    p1 = []
    p2 = []
    lista_enc = []
    for i in range(0, len(ConjuntoE)-1):
        for j in range(1, len(ConjuntoE)):
            if ConjuntoE[i] != ConjuntoE[j] and i < j:
                par = [ConjuntoE[i], ConjuntoE[j]]
                #Se par não marca - nos pares não equivalentes.
                if par not in pares_NEq:
                    aux1 = 0
                    aux2 = 0
                    for simbolo in Alfabeto:
                        for trans in FuncaoPrograma:
                            if ConjuntoE[i] == trans[0] and simbolo == trans[1]:
                                p1.append(trans[2])
                                aux1 += 1
                            if ConjuntoE[j] == trans[0] and simbolo == trans[1]:
                                p2.append(trans[2])
                                aux2 += 1
                    for k in range(0, len(p1)):
                        #Se pu = pv
                        if p1[k] == p2[k]:
                            continue
                        #Se pu != pv e {pu,pv} Não Marca
                        elif p1[k] != p2[k] and ([p1[k], p2[k]]) not in pares_NEq:
                            if p1[k] < p2[k] and ([p1[k], p2[k], ConjuntoE[i], ConjuntoE[j]] not in lista_enc):
                                lista_enc.append([p1[k], p2[k], ConjuntoE[i], ConjuntoE[j]])
                            elif ([p1[k], p2[k], ConjuntoE[i], ConjuntoE[j]]) not in lista_enc:
                                lista_enc.append([p2[k], p1[k], ConjuntoE[i], ConjuntoE[j]])
                        #Se pu != pv e {pu,pv} Tem Marcação
                        elif p1[k] != p2[k] and ([p1[k], p2[k]]) in pares_NEq:
                            if ([ConjuntoE[i], ConjuntoE[j]]) not in pares_NEq:
                                pares_NEq.append([ConjuntoE[i], ConjuntoE[j]])
                    p1.clear()
                    p2.clear()

    for i in range(0, len(lista_enc)):
        for aux in lista_enc:
            if (([aux[0], aux[1]]) or ([aux[1], aux[0]])) in pares_NEq:
                if ([aux[2], aux[3]]) not in pares_NEq:
                    pares_NEq.append([aux[2], aux[3]])
                else:
                    lista_enc.remove(aux)
            elif ([aux[2], aux[3]]) in pares_NEq:
                lista_enc.remove(aux)
    print(" PARES NÃO EQUIVALENTES  OU SEJA NÃO ESTÃO LIGADOS ATRAVÉS DE TRANSIÇÃO")
    print(pares_NEq)
    print()
    #https://github.com/vicmarbe/pytomata/blob/master/pytomata.py
    #Step 4: Junção estados Equivalentes
    print(" Step 4: JUNÇÃO DOS ESTADOS EQUIVALENTES OU SEJA LIGADOS POR TRANSIÇÕES ")
    pares_todos = []
    #Pega lista de pares possíveis:
    for i in range(0, len(ConjuntoE)-1):
        for j in range(1, len(ConjuntoE)):
            if i < j:
                pares_todos.append([ConjuntoE[i], ConjuntoE[j]])

    for aux in lista_enc:
        for par in pares_todos:
            if par not in pares_NEq:
                if (([aux[0], aux[1]] not in pares_NEq and par == ([aux[0], aux[1]])) or ([aux[1], aux[0]] not in pares_NEq and par == ([aux[1], aux[0]]))):

                    if((aux[0]+aux[1] or aux[1]+aux[0]) not in ConjuntoE):
                        ConjuntoE.append(aux[0]+aux[1])
                        if((aux[0] and aux[1]) in EstadoFinal):
                            EstadoFinal.append(aux[0]+aux[1])
                    if ((aux[2] + aux[3] or aux[3] + aux[2]) not in ConjuntoE):
                        ConjuntoE.append(aux[2]+aux[3])
                        if((aux[2] and aux[3]) in EstadoFinal):
                            EstadoFinal.append(aux[2] + aux[3])

                    for letra in Alfabeto:
                        if ([aux[0]+aux[1], letra, aux[2]+aux[3]]) not in FuncaoPrograma:
                            FuncaoPrograma.append([aux[0]+aux[1], letra, aux[2]+aux[3]])

                    k = 0
                    #Len Pega tamanho da String
                    j = len(FuncaoPrograma)
                    for i in range(0,j-k):
                        while FuncaoPrograma[i-k][0] == aux[0] or FuncaoPrograma[i-k][0] == aux[1]:
                            del(FuncaoPrograma[i-k])
                            k += 1
                    #if (aux[0] and aux[1]) in ConjuntoE:
                        #ConjuntoE.remove(aux[0])
                        #if(aux[0] in EstadoFinal):
                         #   EstadoFinal.remove(aux[0])
                        #ConjuntoE.remove(aux[1])
                        #if (aux[1] in EstadoFinal):
                         #   EstadoFinal.remove(aux[1])

    print()
    print("NOVO CONJUNTO DE ESTADOS")
    print(ConjuntoE)
    print("NOVA FUNCAO PROGRAMA")
    print(FuncaoPrograma)
    print("RESULTADO DE CONJUNTO FINAIS:")
    print(EstadoFinal)


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def rightSideView(self, root: TreeNode) -> List[int]:
        tem = []
        res = []
        depth = 1
        if root:
            tem.append((root, depth))
        else:
            return res
        while len(tem) >= 1:
            top = tem[0][0]
            depth = tem[0][1]
            if top.left:
                tem.append((top.left, depth + 1))
            if top.right:
                tem.append((top.right, depth + 1))
            tem.pop(0)
            if len(tem) > 0 and depth != tem[0][1]:
                res.append(top.val)
        if len(res) == 0 or depth != len(res):
            res.append(top.val)
        return res


# -*- coding: utf-8 -*-

import threading
import time

from enum import Enum, unique
from urllib.parse import urlparse
from lxml import etree
from tempfile import NamedTemporaryFile
from pathlib import Path
from pathvalidate import sanitize_filename

from PySide6.QtCore import QObject

from scihub_eva.globals.preferences import *
from scihub_eva.utils.preferences_utils import *
from scihub_eva.utils.logging_utils import *
from scihub_eva.utils.api_utils import *

@unique
class SciHubAPIRampageType(Enum):
    # Raw query
    RAW = 0

    # Query with captcha
    WITH_CAPTCHA = 1

@unique
class SciHubAPIError(Enum):
    # Unknown error
    UNKNOWN = 0

    # Cannot find a valid PDF when fetching PDF URL
    NO_VALID_PDF = 1

    # Cannot download automatically due to captcha
    BLOCKED_BY_CAPTCHA = 2

    # Wrong captcha
    WRONG_CAPTCHA = 3

class SciHubAPI(QObject, threading.Thread):
    def __init__(
            self,
            logger,
            callback,
            scihub_url,
            sess,
            raw_query=None,
            query=None,
            rampage_type=None
    ):
        QObject.__init__(self)
        threading.Thread.__init__(self)

        self._logger = logger
        self._callback = callback

        self._scihub_url = scihub_url
        self._sess = sess
        self._raw_query = raw_query
        self._query = query
        self._rampage_type = rampage_type
        self._captcha_answer = None

    def __del__(self):
        self._sess.close()

    @property
    def raw_query(self):
        return self._raw_query

    @raw_query.setter
    def raw_query(self, raw_query):
        self._raw_query = raw_query

    @property
    def query(self):
        return self._query

    @query.setter
    def query(self, query):
        self._query = query

    @property
    def rampage_type(self):
        return self._rampage_type

    @rampage_type.setter
    def rampage_type(self, rampage_type):
        self._rampage_type = rampage_type

    @property
    def captcha_answer(self):
        return self._captcha_answer

    @captcha_answer.setter
    def captcha_answer(self, captcha_answer):
        self._captcha_answer = captcha_answer

    def fetch_pdf_url(self, query):
        self._logger.info(
            self.tr('Using Sci-Hub URL: ') +
            f'{self._scihub_url}')

        query_type = guess_query_type(query)
        self._logger.info(self.tr('Query type: ') + query_type.upper())

        pdf_url = query
        err = None

        if query_type != 'pdf':
            try:
                self._logger.info(self.tr('Fetching PDF URL ...'))

                pdf_url_response = self._sess.post(
                    self._scihub_url, data={'request': query}, verify=False,
                    timeout=Preferences.get_or_default(
                        NETWORK_TIMEOUT_KEY,
                        NETWORK_RETRY_TIMES_DEFAULT,
                        type=int) / 1000.0)

                if pdf_url_response.status_code != 200:
                    self._logger.error(self.tr('Error {}').format(
                        pdf_url_response.status_code))
                    self._logger.info(
                        self.tr('You may need check it manually.'))
                    err = SciHubAPIError.UNKNOWN
                else:
                    html = etree.HTML(pdf_url_response.content)
                    article = \
                        html.xpath('//div[@id="article"]/embed[1]') or \
                        html.xpath('//div[@id="article"]/iframe[1]') if \
                        html is not None else None

                    if article and len(article) > 0:
                        pdf_url = urlparse(article[0].attrib['src'])
                        response_url = urlparse(pdf_url_response.url)

                        if pdf_url.scheme == '':
                            pdf_url = pdf_url._replace(
                                scheme=response_url.scheme)

                        if pdf_url.netloc == '':
                            pdf_url = pdf_url._replace(
                                netloc=response_url.netloc)

                        pdf_url = pdf_url.geturl()
                        pdf_url_html = f'{pdf_url}'

                        self._logger.info(
                            self.tr('Got PDF URL: ') + pdf_url_html)
                    else:
                        err = SciHubAPIError.NO_VALID_PDF

                        self._logger.error(self.tr('Failed to get PDF URL!'))
                        self._logger.info(
                            self.tr('You may need check it manually.'))
            except Exception as e:
                err = SciHubAPIError.UNKNOWN

                self._logger.error(self.tr('Failed to get PDF URL!'))
                self._logger.info(self.tr('You may need check it manually.'))
                self._logger.error(str(e))

        return pdf_url, err

    def get_captcha_info(self, pdf_captcha_response):
        captcha_id, captcha_img_url = None, None

        html = etree.HTML(pdf_captcha_response.content)
        imgs = html.xpath('//img[@id="captcha"]')
        ids = html.xpath('//input[@name="id"]')

        if len(imgs) > 0 and len(ids) > 0:
            captcha_id = ids[0].attrib['value']
            captcha_img_url = urlparse(imgs[0].attrib['src'])
            response_url = urlparse(pdf_captcha_response.url)

            if captcha_img_url.scheme == '':
                captcha_img_url = captcha_img_url._replace(
                    scheme=response_url.scheme)

            if captcha_img_url.netloc == '':
                captcha_img_url = captcha_img_url._replace(
                    netloc=response_url.netloc)

            captcha_img_url = captcha_img_url.geturl()

        return captcha_id, captcha_img_url

    def download_captcha_img(self, captcha_img_url):
        captcha_img_file = NamedTemporaryFile(delete=False)
        captcha_img_file_path = Path(captcha_img_file.name)

        captcha_img_res = self._sess.get(captcha_img_url, stream=True)

        if captcha_img_res.status_code == 200:
            for chuck in captcha_img_res:
                captcha_img_file.write(chuck)

        captcha_img_file.flush()
        captcha_img_file.close()

        return captcha_img_file_path

    def fetch_pdf_with_captcha(self, pdf_captcha_response):
        pdf, err = None, None

        captcha_id, _ = self.get_captcha_info(pdf_captcha_response)

        pdf_response = self._sess.post(
            pdf_captcha_response.url,
            data={'answer': self._captcha_answer, 'id': captcha_id},
            verify=False,
            timeout=Preferences.get_or_default(
                NETWORK_TIMEOUT_KEY,
                NETWORK_RETRY_TIMES_DEFAULT,
                type=int) / 1000.0)

        if pdf_response.status_code != 200:
            self._logger.error(self.tr('Error {}').format(
                pdf_response.status_code))
            self._logger.info(self.tr('You may need check it manually.'))
            err = SciHubAPIError.UNKNOWN
        elif pdf_response.headers['Content-Type'] == 'application/pdf':
            self._logger.info(self.tr('Angel [CAPTCHA] down!'))
            pdf = pdf_response.content
        else:
            pdf = pdf_response
            err = SciHubAPIError.WRONG_CAPTCHA

        return pdf, err

    def fetch_pdf(self, pdf_url):
        self._logger.info(self.tr('Fetching PDF ...'))

        pdf, err = None, None

        try:
            pdf_response = self._sess.get(
                pdf_url, verify=False,
                timeout=Preferences.get_or_default(
                    NETWORK_TIMEOUT_KEY,
                    NETWORK_RETRY_TIMES_DEFAULT,
                    type=int) / 1000.0)

            if pdf_response.status_code != 200:
                self._logger.error(self.tr('Error {}').format(
                    pdf_response.status_code))
                self._logger.info(self.tr('You may need check it manually.'))
                err = SciHubAPIError.UNKNOWN
            elif pdf_response.headers['Content-Type'] == 'application/pdf':
                pdf = pdf_response.content
            elif pdf_response.headers['Content-Type'].startswith('text/html'):
                self._logger.warn(self.tr('Angel [CAPTCHA] is coming!'))
                err = SciHubAPIError.BLOCKED_BY_CAPTCHA
                pdf = pdf_response
            else:
                self._logger.error(self.tr('Unknown PDF Content-Type!'))
                self._logger.info(self.tr('You may need check it manually.'))
        except Exception as e:
            err = SciHubAPIError.UNKNOWN

            self._logger.error(self.tr('Failed to get PDF!'))
            self._logger.info(self.tr('You may need check it manually.'))
            self._logger.error(str(e))

        return pdf, err

    def save_pdf(self, pdf, filename):
        pdf_name_formatter = Preferences.get_or_default(
            FILE_FILENAME_PREFIX_FORMAT_KEY,
            FILE_FILENAME_PREFIX_FORMAT_DEFAULT)

        if not Preferences.get_or_default(
                FILE_OVERWRITE_EXISTING_FILE_KEY,
                FILE_OVERWRITE_EXISTING_FILE_DEFAULT,
                type=bool):
            pdf_name_formatter += '_' + str(round(time.time() * 1000000))

        pdf_metadata = get_pdf_metadata(pdf)
        query_type = guess_query_type(self._raw_query)

        if query_type in ['doi', 'pmid']:
            pdf_metadata['id'] = self._raw_query
        else:
            for patten in ['_{id}', '{id}_', '{id}']:
                pdf_name_formatter = pdf_name_formatter.replace(patten, '')

        pdf_name_formatter += '_' + filename if pdf_name_formatter else filename

        try:
            pdf_name = pdf_name_formatter.format(**pdf_metadata)
        except Exception as e:
            self._logger.error(
                self.tr('Unsupported filename keywords: ') + pdf_name_formatter)
            return

        pdf_name = sanitize_filename(pdf_name, replacement_text='-')
        pdf_path = Path(Preferences.get(FILE_SAVE_TO_DIR_KEY)) / pdf_name

        with open(pdf_path, 'wb') as fp:
            fp.write(pdf)

        pdf_link = f'{pdf_path.as_posix()}'

        self._logger.info(self.tr('Saved PDF as: ') + pdf_link)

    def rampage(self, query, rampage_type):
        if rampage_type == SciHubAPIRampageType.RAW:
            self._logger.info(LOGGER_SEP)
            self._logger.info(self.tr('Dealing with query: ') + query)

            # Fetch PDF URL
            pdf_url, err = self.fetch_pdf_url(query)
            if err is not None:
                return None, err

            # Fetch PDF
            pdf, err = self.fetch_pdf(pdf_url)
            if err == SciHubAPIError.BLOCKED_BY_CAPTCHA:
                return pdf, err
            elif err is not None:
                return None, err

            # Save PDF
            filename = urlparse(pdf_url).path[1:].split('/')[-1]
            self.save_pdf(pdf, filename)
        elif rampage_type == SciHubAPIRampageType.WITH_CAPTCHA:
            # Fetch PDF with Captcha
            pdf, err = self.fetch_pdf_with_captcha(query)
            if err == SciHubAPIError.WRONG_CAPTCHA:
                self._logger.error(
                    self.tr('Wrong captcha, failed to kill Angel [CAPTCHA]!'))
                return None, err

            # Save PDF
            filename = urlparse(query.url).path[1:].split('/')[-1]
            self.save_pdf(pdf, filename)

        return None, None

    def run(self):
        res, err = self.rampage(self._query, self._rampage_type)
        self._callback(res, err)

__all__ = [
    'SciHubAPIRampageType',
    'SciHubAPIError',
    'SciHubAPI'
]


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 22 23:35:10 2020

@author: hao
"""

import pandas as pd
import os
import matplotlib.pyplot as plt
import numpy as np
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
import itertools
from sklearn.metrics import roc_curve,roc_auc_score
from sklearn.metrics import confusion_matrix,accuracy_score,cohen_kappa_score
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection  import train_test_split
from sklearn.feature_selection import f_regression
from sklearn.linear_model import LogisticRegression
#%%
def sleep_wake_score(score):
    conscious=[]
    for i in range(len(score)):
        if score[i] == 5:
            conscious.append(1)
        else:
            conscious.append(0)
    return conscious

def state(post):
    get_state=[]
    for i in range(len(post)):
        if post[i] == 5:
            get_state.append(2)
        else:
            get_state.append(1)
    return get_state

def plot_confusion_matrix(cm, classes,normalize=True,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues,
                          fontname="Arial",
                          xlabel=False,ylabel=False):
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title,fontname='Arial',fontsize=18)
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes,fontsize=14)
    plt.yticks(tick_marks, classes,fontsize=14)
    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),fontsize=14,
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")
    plt.xlim(-0.5,len(classes)-0.5)
    plt.ylim(len(classes)-0.5,-0.5)
    plt.tick_params(axis='both',which='both',bottom=False,top=False,length = 0)
    if ylabel:
        plt.ylabel('Scored by TD1',fontname="Arial",fontsize=16)
    if xlabel:
        plt.xlabel('Scored by algorithm',fontname="Arial",fontsize=16)
#%%
path='/Users/hao/Desktop/python/sleep_data_process/2_stage/health'
lista = os.listdir(path)
Score_list=[]
Score_len=[]
act_list=[]
act_len=[]
HR_list=[]
HR_len=[]
Time_list=[]
Post_list=[]
Post_len=[]
lie_list=[]
stand_list=[]
multi_layer_list=[]
for i in range(len(lista)):
    if('.xls' in lista[i]):
#        xls=pd.ExcelFile(path+'/'+lista[i])
#        sheet=xls.parse('whole data')
        sheet=pd.read_excel(path+'/'+lista[i],sheet_name='whole data')
        sheet=sheet.dropna(axis=0, how='any')
        Score=list(map(int,sheet['Score']))
        act=np.array(sheet['act']).tolist()
        HR=np.array(sheet['HR']).tolist()
        Time=sheet['Time'].tolist()
        Pre_post=sheet['post'].tolist()
        Post=state(Pre_post)
        TD1=sleep_wake_score(Score)
        Score_list.append(TD1)
        Score_len+=TD1
        Post_len+=Post
        Post_list.append(Post)
        act_len+=act
        act_list.append(act)
        HR_len+=HR
        HR_list.append(HR)
        Time_list.append(Time)
act_len=np.array(act_len)
Score_len=np.array(Score_len)
Post_len=np.array(Post_len)
HR_len=np.array(HR_len)
#%%
#x=np.vstack([act_len,HR_len])
#act_train,act_test,Score_train,Score_test=train_test_split(x.T,Score_len,test_size=0.2,random_state=0) #random_state 種子值
act_train,act_test,Score_train,Score_test=train_test_split(act_len,Score_len,test_size=0.2,random_state=0)
#%%
act_train=act_train.reshape(-1, 1)
act_test=act_test.reshape(-1, 1)
score_train=Score_train.T.ravel()
score_test=Score_test.T.ravel()
sc=StandardScaler()
sc.fit(act_train)
act_train_nor=sc.transform(act_train)
act_test_nor=sc.transform(act_test)
#%%LogisticRegression

lr=LogisticRegression(solver='liblinear') #solver:消除警告的方法
#lr=lr.fit(act_train_nor,score_train)      #ravel:不規範模式
lr=lr.fit(act_train,score_train)
#print(lr.coef_)# 印出係數
#print(lr.intercept_ )# 印出截距
#print(f_regression(act_train_nor,score_train)[1])# 印出p_value

predictions = lr.predict(act_test)
accuracy = lr.score(act_test_nor,Score_test)

my_yticks1 = ["Sleep","Wake"]
plot_confusion_matrix(confusion_matrix(score_test,predictions),classes=my_yticks1,
                      title='Unfiltered activity',ylabel=True)
#%%
from matplotlib.colors import ListedColormap
def plot_decision_regions(X, y, classifier, test_idx=None, resolution=0.02):

    # setup marker generator and color map
    markers = ('s', 'x', 'o', '^', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])

    # plot the decision surface
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                           np.arange(x2_min, x2_max, resolution))
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    Z = Z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0],
                    y=X[y == cl, 1],
                    alpha=0.6,
                    c=cmap(idx),
                    edgecolor='black',
                    marker=markers[idx],
                    label=cl)

    # highlight test samples
    if test_idx:
        # plot all samples
        X_test, y_test = X[test_idx, :], y[test_idx]

        plt.scatter(X_test[:, 0],
                    X_test[:, 1],
                    c='',
                    alpha=1.0,
                    edgecolor='black',
                    linewidths=1,
                    marker='o',
                    s=55, label='test set')
fig1=plt.figure(figsize=(20,20))
#plot_decision_regions(act_test,score_test, classifier=lr)
#plt.legend(loc='upper left')
#plt.tight_layout()
#plt.show()
#%%
fig2=plt.figure(figsize=(20,20))
lr_roc_auc = roc_auc_score(score_test, lr.predict(act_test))
fpr, tpr, thresholds = roc_curve(score_test, lr.predict_proba(act_test)[:,1])
plt.plot(fpr, tpr, label='Logistic Regression (area = %0.2f)' % lr_roc_auc)
plt.plot([0, 1], [0, 1],'r--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic')
plt.legend(loc="lower right")
plt.show()
#%%


def sum_natural( number):
    sum = 0
    for i in range(1,number+1):
        sum += i
    print("sum = ",sum)
def fibo_series(n):
    fibo0 = 0
    fibo1 = 1
    sum = 0
    for i in range(0,n):
        print(fibo0)
        sum = fibo1+fibo0
        fibo0 = fibo1
        fibo1 = sum
sum_natural(int(input("Enter n: ")))
fibo_series(int(input("Enter n: ")))


from typing import List

from copy import deepcopy

class Side(object):
    def __init__(self, height: int, width: int):
        self.__array = [[0 for i in range(width)] for k in range(height)]

    @property
    def value(self) -> List[List[int]]:
        return self.__array

    @property
    def width(self) -> int:
        return len(self.__array[0])

    @property
    def height(self) -> int:
        return len(self.__array)

    def __repr__(self):
        _str_board = [' '.join([str(self.__array[y][x]) for x in range(self.width)]) for y in range(self.height)]
        return "\n".join(_str_board)

    def __str__(self):
        return self.__repr__()

    def fill(self, side: List) -> any:
        if len(side) != self.height:
            raise Exception("Wrong height")
        if len(side[0]) != self.width:
            raise Exception("Wrong width")

        self._check_data(side)
        self.__array = deepcopy(side)

    def calculate_square(self) -> int:
        _square = 0
        for row in self.__array:
            for value in row:
                _square += value

        return _square

    def _check_data(self, side: List) -> None:
        for x in side:
            for value in x:
                if value != 0 and value != 1:
                    raise Exception("Wrong data")

    def rotate(self, direction=1) -> None:
        # direction = 1 (left)
        # direction = -1 (Right)

        _new_array = [[0 for i in range(self.height)] for k in range(self.width)]

        if direction == 1:
            self._rotate_left(_new_array, self.__array)
        elif direction == -1:
            self._rotate_right(_new_array, self.__array)
        else:
            raise Exception("Wrong direction")
        self.__array = _new_array

    @staticmethod
    def _rotate_left(new_array: List, old_array: List) -> None:
        i = 0
        for row in old_array:
            j = 0
            for _ in new_array:
                new_array[j][i] = row[len(row) - j - 1]
                j += 1
            i += 1

    @staticmethod
    def _rotate_right(new_array: List, old_array: List) -> None:
        i = 0
        for row in old_array[::-1]:
            j = 0
            for _ in new_array:
                new_array[j][i] = row[j]
                j += 1
            i += 1

class Detail(object):

    def __init__(self, height: int, width: int, depth: int, name: str = '', symbol: str = '1'):
        self.__object = [[[0 for k in range(depth)] for j in range(width)] for i in range(height)]
        self.__side: int = 2
        self.__rotation_steps: List[int] = []
        self.__name = name
        self.__symbol = symbol

    @property
    def name(self):
        return self.__name

    @property
    def value(self) -> List[List[List[int]]]:
        return self.__object

    @property
    def width(self) -> int:
        return len(self.__object[0])

    @property
    def height(self) -> int:
        return len(self.__object)

    @property
    def depth(self) -> int:
        return len(self.__object[0][0])

    @property
    def side_index(self) -> int:
        return self.__side

    @property
    def symbol(self):
        return self.__symbol

    def __repr__(self) -> str:
        return "\nName: %s\nside: %d\nSteps: %s\nDetail\n%s\n" % \
               (self.__name, self.__side, self.__rotation_steps, str(self.get_current_side()))

    def __str__(self) -> str:
        return self.__repr__()

    def rotate(self, direction=1) -> None:
        # direction = 1 - left,
        # direction = -1 - Right
        if direction != 1 and direction != -1:
            raise Exception("Wrong direction")

        last_step = [self.__rotation_steps[-1]] \
            if len(self.__rotation_steps) else []
        if len(last_step) and last_step[0] != direction:
            self.__rotation_steps = self.__rotation_steps[:-1]
        else:
            self.__rotation_steps.append(direction)
            total_length = len(self.__rotation_steps)
            if total_length >= 4:
                if self.__rotation_steps[-1] == \
                        self.__rotation_steps[-2] == \
                        self.__rotation_steps[-3] == \
                        self.__rotation_steps[-4]:
                    self.__rotation_steps = self.__rotation_steps[0: -4]

    def chose_side(self, side_index: int) -> None:
        if side_index < 0 or side_index > 5:
            raise Exception("Only 0..5 sides")

        self.__side = side_index

    def fill(self, array: List) -> None:
        if len(array) != self.height:
            raise Exception("Wrong height")
        if len(array[0]) != self.width:
            raise Exception("Wrong width")
        if len(array[0][0]) != self.depth:
            raise Exception("Wrong depth")

        self._check_data(array)
        self.__object = deepcopy(array)

    def _check_data(self, array: List[List[List[int]]]):
        for h in range(self.height):
            for w in range(self.width):
                for d in range(self.width):
                    if array[h][w][d] != 1 \
                            and array[h][w][d] != 0:
                        raise Exception("Wrong data")

    def get_side(self, side: int) -> Side:
        if side < 0 or side > 5:
            raise Exception("Side has to be 0..5")
        _return: Side = None
        if side == 0:
            _return = Side(self.width, self.depth)
            _return.fill(self.__object[0])
        elif side == 1:
            _return = Side(self.depth, self.width)
            _return.fill(self.__object[-1][::-1])
        elif side == 2:
            _return = Side(self.height, self.width)
            _return.fill([el[-1] for el in self.__object])
        elif side == 3:
            _return = Side(self.height, self.depth)
            _return.fill([[side[-1] for side in el[::-1]] for el in self.__object])
        elif side == 4:
            _return = Side(self.height, self.width)
            _return.fill([el[0][::-1] for el in self.__object])
        elif side == 5:
            _return = Side(self.height, self.depth)
            _return.fill([[side[0] for side in el] for el in self.__object])
        if side != 0 and side != 1:
            self._apply_rotation(_return)
        return _return

    def _apply_rotation(self, side: Side) -> None:
        for direction in self.__rotation_steps:
            side.rotate(direction)

    def get_current_side(self) -> Side:
        return self.get_side(self.__side)

    def get_opposite_side(self) -> Side:
        _opposite_sides = {
            0: 1,
            1: 0,
            2: 4,
            3: 5,
            4: 2,
            5: 3
        }

        return self.get_side(_opposite_sides[self.__side])

    @property
    def sides(self):
        return [2, 3, 4, 5]

def create_detail_from_data(name: str, symbol: str, data: List[List[List[int]]]) -> Detail:
    _return = Detail(len(data), len(data[0]), len(data[0][0]), name, symbol)
    _return.fill(data)
    return _return


"""
How do we call other functions from `main`?

The important case is when this function wants to say or do anything on behalf of the bot.
We call such functions "Routines", and to call them, you need to use `yield Subroutine`.
In the following example, we call `questionnaire` subroutine and then get the returned values from it.
It's not a perfect solution, but we will improve it in the following demos.

If it's just a normal Python function, such as `datetime.now()` below, you can of course
just call it and use the returned value normally.
"""

from demos.eaglesong.common import *
from datetime import datetime

def questionnaire(c: BotContext):
    yield 'What is your name?'
    yield Listen()
    name = c.input

    yield f'Where are you from, {name}?'
    yield Listen()
    country = c.input

    yield Return(name, country)

def main(c: BotContext):
    subroutine = Subroutine(questionnaire)
    yield subroutine
    name, country = subroutine.returned_value()

    current_time = datetime.now()
    yield f"Nice to meet you, {name} from {country}! By the way, the current time is {current_time}"

bot = Bot("quest1", main)

if __name__ == '__main__':
    run(bot)


import os
from datetime import datetime
from Settings.AppInfo import AppInfo
from PyUtils.DirUtils import DirUtils
from Settings.ProfileManager import ProfileManager

class ReportAudioDetails:

    HTML_REPORT_HEADER = """<!DOCTYPE html>

  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">

Dialog Audio Details' Report

      #
      quest_id
      actor
      file
      mp3
      wav
      xwm
      lip
      fuz
      subtitle
      file_path
      dialog_type
      emotion
      voice_type
      topic_id
      branch_id
      scene_id
      scene_phase

"""
    HTML_REPORT_FOOTER = """

  ###_replace_footer_text###

    """
    HTML_REPORT_TABLE: str = """

      ###_replace_conter###
      ###_replace_quest_id###
      ###_replace_actor###
      ###_replace_file###
      ###_replace_mp3###
      ###_replace_wav###
      ###_replace_xwm###
      ###_replace_lip###
      ###_replace_fuz###
      ###_replace_subtitle###
      ###_replace_file_path###
      ###_replace_dialog_type###
      ###_replace_emotion###
      ###_replace_voice_type###
      ###_replace_topic_id###
      ###_replace_branch_id###
      ###_replace_scene_id###
      ###_replace_scene_phase###

    """
    FOOTER_MESSAGE = "Documentation generated by {0}. Access the project Github for new versions and updates."

    def __init__(self):
        self.quest_id = ""
        self.actor = ""
        self.file = ""
        self.mp3 = ""
        self.wav = ""
        self.xwm = ""
        self.lip = ""
        self.fuz = ""
        self.subtitle = ""
        self.file_path = ""
        self.dialog_type = ""
        self.emotion = ""
        self.voice_type = ""
        self.topic_id = ""
        self.branch_id = ""
        self.scene_id = ""
        self.scene_phase = ""

    @staticmethod
    def file_ext_color(item_value: str):
        color = 'black'
        if item_value.upper() == "OK":
            color = 'blue'
        elif item_value.upper() == "MISSING":
            color = 'red'
        return color

    @staticmethod
    def html_color(text, color):
        return "{1}".format(color, text)

    @staticmethod
    def file_ext_tag(file_info):
        return ReportAudioDetails.html_color(file_info, ReportAudioDetails.file_ext_color(file_info))

    @staticmethod
    def export_report(list_audio_details, output_dir, app_name, url_github):
        """
        Create a details' report about all the dialogues.
        :param list_audio_details:
        :param output_dir:
        :param app_name:
        :param url_github:
        :return:
        """
        directory = os.getcwd()
        # print("=======================" + directory)
        filename = "reportAudioDetails_"
        now = datetime.now()
        dt_string = now.strftime("-%d-%m-%Y_%H-%M-%S")
        # create directory just in case
        DirUtils.mkdir(output_dir)
        filename = os.path.join(output_dir, filename + dt_string + ".html")
        # filename = output_dir + filename + dt_string + ".html"
        html_str = ReportAudioDetails.HTML_REPORT_HEADER
        item: ReportAudioDetails
        item_count = 0
        for item in list_audio_details:
            item_count_str = str(item_count)
            mp3_html = ReportAudioDetails.file_ext_tag(item.mp3)
            wav_html = ReportAudioDetails.file_ext_tag(item.wav)
            xwm_html = ReportAudioDetails.file_ext_tag(item.xwm)
            lip_html = ReportAudioDetails.file_ext_tag(item.lip)
            fuz_html = ReportAudioDetails.file_ext_tag(item.fuz)
            current_table = ReportAudioDetails.HTML_REPORT_TABLE
            # replace strings
            # print("before: " + current_table)
            current_table = current_table.replace("###_replace_conter###", item_count_str)
            current_table = current_table.replace("###_replace_quest_id###", item.quest_id)
            current_table = current_table.replace("###_replace_actor###", item.actor)
            current_table = current_table.replace("###_replace_file###", item.file)
            current_table = current_table.replace("###_replace_mp3###", mp3_html)
            current_table = current_table.replace("###_replace_wav###", wav_html)
            current_table = current_table.replace("###_replace_xwm###", xwm_html)
            current_table = current_table.replace("###_replace_lip###", lip_html)
            current_table = current_table.replace("###_replace_fuz###", fuz_html)
            current_table = current_table.replace("###_replace_subtitle###", item.subtitle)
            current_table = current_table.replace("###_replace_file_path###", item.file_path)
            current_table = current_table.replace("###_replace_dialog_type###", item.dialog_type)
            current_table = current_table.replace("###_replace_emotion###", item.emotion)
            current_table = current_table.replace("###_replace_voice_type###", item.voice_type)
            current_table = current_table.replace("###_replace_topic_id###", item.topic_id)
            current_table = current_table.replace("###_replace_branch_id###", item.branch_id)
            current_table = current_table.replace("###_replace_scene_id###", item.scene_id)
            current_table = current_table.replace("###_replace_scene_phase###", str(item.scene_phase))
            # print("AFTER: " + current_table)
            html_str += current_table
            item_count += 1
        footer_template = ReportAudioDetails.HTML_REPORT_FOOTER
        footer_msg = ReportAudioDetails.FOOTER_MESSAGE.format(app_name, url_github)
        footer_template = footer_template.replace("###_replace_footer_text###", footer_msg)
        html_str += footer_template
        with open(filename, "w") as text_file:
            text_file.write(html_str)
        return filename

if __name__ == '__main__':
    app_dir = ".\\App\\"
    app = AppInfo(app_dir=app_dir)
    profile_manager = ProfileManager(app_dir)
    file_rep1 = ReportAudioDetails()
    file_rep2 = ReportAudioDetails()
    file_rep1.quest_id = "quest_id" + "1"
    file_rep1.actor = "actor" + "1"
    file_rep1.file = "file" + "1"
    file_rep1.mp3 = "ok"
    file_rep1.wav = "ok"
    file_rep1.xwm = "missing"
    file_rep1.lip = "missing"
    file_rep1.fuz = "missing"
    file_rep1.subtitle = "subtitle" + "1"
    file_rep1.file_path = "file_path" + "1"
    file_rep1.dialog_type = "dialog_type" + "1"
    file_rep1.emotion = "emotion" + "1"
    file_rep1.voice_type = "voice_type" + "1"
    file_rep1.topic_id = "topic_id" + "1"
    file_rep1.branch_id = "branch_id" + "1"
    file_rep1.scene_id = "scene_id" + "1"
    file_rep1.scene_phase = "scene_phase" + "1"
    file_rep2.quest_id = "quest_id" + "2"
    file_rep2.actor = "actor" + "2"
    file_rep2.file = "file" + "2"
    file_rep2.mp3 = "MISSING"
    file_rep2.wav = "OK"
    file_rep2.xwm = "OK"
    file_rep2.lip = "OK"
    file_rep2.fuz = "MISSING"
    file_rep2.subtitle = "subtitle" + "2"
    file_rep2.file_path = "file_path" + "2"
    file_rep2.dialog_type = "dialog_type" + "2"
    file_rep2.emotion = "emotion" + "2"
    file_rep2.voice_type = "voice_type" + "2"
    file_rep2.topic_id = "topic_id" + "2"
    file_rep2.branch_id = "branch_id" + "2"
    file_rep2.scene_id = "scene_id" + "2"
    file_rep2.scene_phase = "scene_phase" + "2"
    list_details = []
    list_details.append(file_rep1)
    list_details.append(file_rep2)
    ReportAudioDetails.export_report(list_audio_details=list_details,
                                     output_dir=profile_manager.profile_docgen_dir(),
                                     app_name=app.app_name_LARGE,
                                     url_github=app.url_github)


import os
from datetime import datetime, timedelta

import numpy as np
import pdb
import pandas as pd
import plotly.express as px
import streamlit as st

from src.frontend import get_config, get_kds
from src.frontend import create_gsheets_database_connection, run_query

conn = create_gsheets_database_connection()

dirname = os.path.dirname(__file__)
cfg = get_config(os.path.join("src", "config.yml"))

st.markdown("# Player Stats")

# Retrieve Data
sheet_url_match = st.secrets["private_gsheets_url_match"]
sheet_url_match_legacy = st.secrets["private_gsheets_url_match_legacy"]
sheet_url_player = st.secrets["private_gsheets_url_player"]
sheet_url_player_legacy = st.secrets["private_gsheets_url_player_legacy"]
sheet_url_roster = st.secrets["private_gsheets_url_roster"]

with st.spinner("Retrieving Player and Match Data..."):
    df_team = run_query(f'SELECT * FROM "{sheet_url_match}"', conn)
    # team_rows_legacy = run_query(f'SELECT * FROM "{sheet_url_match_legacy}"', conn)
    df_player = run_query(f'SELECT * FROM "{sheet_url_player}"', conn)
    # player_rows_legacy = run_query(f'SELECT * FROM "{sheet_url_player_legacy}"', conn)
    df_roster = run_query(f'SELECT * FROM "{sheet_url_roster}"', conn)

df_player = df_player.merge(
    df_team.loc[:, ["match_id", "date", "map"]],
    on="match_id",
    how="left",
)
df_player = df_player.merge(
    df_roster,
    on=['Riot_IDs', 'name', 'tag'],
    how='left'
)

df_player = df_player[~df_player['Riot_IDs'].isin(cfg["retired_players"])]

df_team["date"] = pd.to_datetime(df_team["date"], utc=True)
min_date = df_team.date.min()
max_date = df_team.date.max() + timedelta(days=1)

select_col1, select_col2, select_col3 = st.columns(3)
with select_col1:
    start_date = st.date_input("Start Date", min_date)
with select_col2:
    end_date = st.date_input("End Date", max_date)

# convert to datetimes for comparison
start_date = datetime(start_date.year, start_date.month, start_date.day)
end_date = datetime(end_date.year, end_date.month, end_date.day)

df_player["date"] = pd.to_datetime(df_player["date"])
df_player = df_player.loc[
    (df_player.date >= start_date) & (df_player.date <= end_date), :
]

int_cols = {col: "int64" for col in cfg["integer_columns"]}
float_cols = {col: "float" for col in cfg["float_columns"]}

df_player.loc[:, cfg["integer_columns"]] = df_player.loc[
    :, cfg["integer_columns"]
].fillna(0)
df_player.loc[:, cfg["float_columns"]] = df_player.loc[:, cfg["float_columns"]].fillna(
    0
)
df_player = df_player.astype(int_cols)
df_player = df_player.astype(float_cols)

# Calculate z-scores
df_player['KDA'] = (df_player['kills'] + df_player['assists']) / df_player['deaths']

st.header("General Player Statistics")

df_c = (
    df_player.loc[:, ["Riot_IDs", "clutch_wins", "clutch_counts"]]
    .fillna(0)
    .groupby("Riot_IDs")
    .sum()
    .reset_index()
)
df_c["clutch_percent"] = df_c["clutch_wins"] / df_c["clutch_counts"] * 100
df_c["clutch_percent"] = df_c["clutch_percent"].round(2)
general_cols = [
    "kills",
    "deaths",
    "assists",
    "first_bloods",
    "first_duels",
    "first_deaths",
    "bodyshots",
    "headshots",
    "legshots",
]
pivot_general = (
    df_player.loc[
        :,
        ["Riot_IDs"] + general_cols,
    ]
    .groupby("Riot_IDs")
    .sum()
    .rename(columns={"first_bloods": "first bloods"})
)
pivot_acs = (
    df_player.loc[:, ["Riot_IDs", "acs"]]
    .groupby("Riot_IDs")
    .mean()
    .rename(columns={"acs": "avg. acs"})
)
pivot_general = pd.merge(pivot_general, pivot_acs, left_index=True, right_index=True)
pivot_general = pd.merge(
    pivot_general,
    df_c.set_index("Riot_IDs").loc[:, "clutch_percent"],
    left_index=True,
    right_index=True,
)
match_counts = (
    df_player.groupby(["Riot_IDs"])
    .count()
    .agent.reset_index()
    .rename(columns={"agent": "match counts"})
    .set_index("Riot_IDs")
)
pivot_general = pd.merge(pivot_general, match_counts, left_index=True, right_index=True)
# Calculate per match stats
pivot_general["kills / match"] = pivot_general.kills / pivot_general["match counts"]
pivot_general["deaths / match"] = pivot_general.deaths / pivot_general["match counts"]
pivot_general["assists / match"] = pivot_general.assists / pivot_general["match counts"]
pivot_general["headshot %"] = (
    pivot_general["headshots"]
    / (
        pivot_general["headshots"]
        + pivot_general["bodyshots"]
        + pivot_general["legshots"]
    )
    * 100
)
pivot_general = pivot_general.rename(
    columns={"first_duels": "first duels", "first_deaths": "first deaths"}
)
display_cols = [
    "match counts",
    "kills",
    "kills / match",
    "deaths",
    "deaths / match",
    "assists",
    "assists / match",
    "headshot %",
    "first bloods",
    "first duels",
    "first deaths",
    "avg. acs",
]
# pivot_general.columns=['kills', 'deaths', 'assists', 'first_bloods', 'eco_score', 'acs']

kill_pivot_agent = (
    df_player.pivot_table(values="kills", columns="agent", index="Riot_IDs", aggfunc="sum")
    .fillna(0)
    .astype("int64")
)
kill_pivot_agent["Total"] = kill_pivot_agent.apply(lambda row: sum(row), axis=1)

st.header("Average K/D by Agent")

wavg_col = "Weight. Avg. K/D"
df_player_kd, kd_pivot = get_kds(df_player, wavg_col)
# Change order of columns
new_cols = list(kd_pivot.columns)
new_cols.reverse()
kd_pivot = kd_pivot.loc[:, new_cols]
st.write(kd_pivot.sort_values(by=wavg_col, ascending=False).round(4))
st.write(
    "Note: Weighted Average K/D controls for the amount of times a player plays as a certain agent"
)

# Calculate Ranks
teams = df_player_kd.team.unique()
team_rank_list = []
for team in teams:
    df_filter = df_player_kd[df_player_kd.team == team]
    team_perc_ranks = df_filter.groupby('Riot_IDs').mean(numeric_only=True)['K/D'].rank(pct=True).round(2).reset_index().rename(columns={'K/D':'Team Rank'})
    team_rank_list.append(team_perc_ranks)
df_player_team_perc = pd.concat(team_rank_list)
# Calculate percentile scores for each player across the entire dataset
df_player_global_perc = df_player_kd.groupby('Riot_IDs').mean(numeric_only=True)['K/D'].rank(pct=True).round(2).reset_index().rename(columns={'K/D':'Global Rank'})
df_ranks = df_player_team_perc.merge(df_player_global_perc, on=['Riot_IDs'])
st.header("Average K/D by Map")
kd_pivot_map = df_player_kd.pivot_table(
    values="K/D", columns="map", index="Riot_IDs"
).fillna(0)
st.write(kd_pivot_map.round(4))
# st.plotly_chart(px.imshow(kd_pivot_map.round(4), title="Average K/D by Map Viz"))

st.header('Individual Statistics')
player_list = list(df_player['Riot_IDs'].unique())
player_list.extend(['All'])
player_select = st.selectbox(label='Select Player', options=player_list)

if player_select == 'All':
    st.write(pivot_general.loc[:, display_cols].sort_values(by="kills", ascending=False))
else:
    disp_pivot = pivot_general.loc[pivot_general.index==player_select, display_cols].\
        sort_values(by="kills", ascending=False).merge(df_ranks.loc[:, ['Riot_IDs', 'Global Rank', 'Team Rank']], on='Riot_IDs', how='left')
    st.write(disp_pivot)
st.header("Shooting Breakdown")
df_headshot_ts = df_player.loc[
    df_player['Riot_IDs'] == player_select, ["Riot_IDs", "date", "bodyshots", "legshots", "headshots"]
].dropna()
shot_types = {'headshots': int, 'bodyshots': int, 'legshots': int}
df_headshot_ts = df_headshot_ts.astype(shot_types)
df_headshot_ts["headshot %"] = (
    df_headshot_ts["headshots"]
    / (
        df_headshot_ts["headshots"]
        + df_headshot_ts["bodyshots"]
        + df_headshot_ts["legshots"]
    )
    * 100
)
fig = px.histogram(
    df_headshot_ts,
    x="Riot_IDs",
    y=["legshots", "bodyshots", "headshots"],
    barmode="stack",
    barnorm="percent",
).update_xaxes(categoryorder="total descending")
st.plotly_chart(fig)
# fig_shots = px.line(df_headshot_ts, x="date", y="count", color='Riot_IDs', line_shape="linear")
# st.plotly_chart(fig_shots)


class Solution:
    def solve(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        if board and board[0]:
            m, n = len(board), len(board[0])
            step = [(1, 0), (-1, 0), (0, 1), (0, -1)]

            border = [(i, j) for i in range(m) for j in range(n) if (i == 0 or i == m-1 or j == 0 or j == n-1) and board[i][j] == 'O']

            # go through the border and change any connected 'O' to 'B'
            while border:
                i, j = border.pop()
                board[i][j] = 'B'
                border.extend([(i+si,j+sj) for (si, sj) in step if 0<= i+si < m and 0 <= j + sj < n and board[i+si][j+sj] == 'O'])

            # go through the board and change any remaining 'O' to 'X'
            for i in range(m):
                for j in range(n):
                    if board[i][j] == 'O':
                        board[i][j] = 'X'
                    elif board[i][j] == 'B':
                        board[i][j] = 'O'