# 25개구 for문으로 돌려서 카페 정보 크롤링하기
import os
from time import sleep
import time
import re
from bs4 import BeautifulSoup # 아나콘다 파이썬으로 실행하면 BeautifulSoup을 다운 받지 않아도 된다.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.common.exceptions import ElementNotInteractableException
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 크롬 크롤링 디버깅용
from selenium.webdriver.chrome.options import Options

##########################################################################
##################### variable related selenium ##########################
##########################################################################

# 서울 특별시 구 리스트
# gu_list = ['마포구','서대문구','은평구','종로구','중구','용산구','성동구','광진구',
#            '동대문구','성북구','강북구','도봉구','노원구','중랑구','강동구','송파구',
#            '강남구','서초구','관악구','동작구','영등포구','금천구','구로구','양천구','강서구']
gu_list = ['영등포구']

# csv 파일에 헤더 만들어 주기
for index, gu_name in enumerate(gu_list):
    fileName = gu_name + 'cafe.csv' # index.__str__() + '_' + gu_name + '.'+'csv'
    file = open(fileName, 'w', encoding='utf-8')
    # 파일 만들기
    file.write("구"+ "|" + "URL_ID" + "|" + "카페명" + "|" + "평점" + "|" + "리뷰개수" + "|" + "주소" + "|"
               + "영업시간" + "|" + "전화번호" + "|" + "홈페이지주소" + "|"
               + "태그" + "|"  + "메뉴"  + "|" + "대표사진주소" + "|" + "\n") # 처음에 csv파일에 칼럼명 만들어주기
    file.close()

    # 크롬 크롤링 디버깅용
    # chrome_options = Options()
    # chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
    ### C드라이브에 크롬이 깔려있는 곳에 가서 cmd 실행 후 'chrome.exe --chrome.exe --remote-debugging-port=9222 --user-data-dir="C:/ChromeTEMP"'입력하면 디버깅용 크롬이 나옴

    # 진짜 크롤링용
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-logging"])
    # options.add_argument('headless')
    options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36")
    # options.add_argument('lang=ko_KR')
    driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)

    # 카카오맵
    url = 'https://map.kakao.com/'
    driver.get(url)  # 주소 가져오기
    search_area = driver.find_element_by_xpath('//*[@id="search.keyword.query"]') # 검색 창
    search_area.send_keys('서울 ' + gu_name + ' 카페')  # 검색어 입력
    driver.find_element_by_xpath('//*[@id="search.keyword.submit"]').send_keys(Keys.ENTER)  # Enter로 검색
    driver.implicitly_wait(3) # 기다려 주자
    more_page = driver.find_element_by_id("info.search.place.more")
    more_page.send_keys(Keys.ENTER) # 더보기 누르고
    # 첫 번째 검색 페이지 끝
    # 기다려주기
    time.sleep(1)

    # next 사용 가능?
    next_btn = driver.find_element_by_id("info.search.page.next")
    has_next = "disabled" not in next_btn.get_attribute("class").split(" ")
    Page = 1

    while has_next: # 다음 페이지가 있으면 loop
        time.sleep(1)
        # 페이지 루프
        #info\.search\.page\.no1 ~ .no5
        page_links = driver.find_elements_by_css_selector("#info\.search\.page a")
        pages = [link for link in page_links if "HIDDEN" not in link.get_attribute("class").split(" ")]
        # print(len(pages), "개의 페이지 있음")
        # pages를 하나씩 클릭하면서
        for i in range(1, 6):
            xPath = '//*[@id="info.search.page.no' + str(i) + '"]'
            try:
                page = driver.find_element_by_xpath(xPath)
                page.send_keys(Keys.ENTER)
            except ElementNotInteractableException:
                print('End of Page')
                break
            sleep(3)
            place_lists = driver.find_elements_by_css_selector('#info\.search\.place\.list > li')
            for p in place_lists: # WebElement
                file = open(fileName, 'a', encoding='utf-8')
                # time.sleep(10)
                store_html = p.get_attribute('innerHTML')
                # print(store_html)
                store_info = BeautifulSoup(store_html, "html.parser")

                place_name = store_info.select('.head_item > .tit_name > .link_name')
                if len(place_name) == 0:
                    continue # 광고는 제외
                # 가게 이름
                place_name = store_info.select('.head_item > .tit_name > .link_name')[0].text
                print(place_name)
                # 가게 카테고리
                place_category = store_info.select('.head_item > .subcategory.clickable')[0].text
                place_category = '#' + place_category + " "
                # 가게 주소
                place_address = store_info.select('.info_item > .addr > p')[0].text
                # 가게 전화번호
                place_tel = store_info.select('.info_item > .contact > span')[0].text
                # 가게 평점
                place_rate = ""
                review_count = ""
                try:
                    place_rate = store_info.select('.rating.clickArea > .score > em')[0].text
                    review_count = store_info.select('.rating.clickArea > .score > a')[0].text
                except:
                    place_rate = ""
                    review_count = ""

                # print(place_rate, review_count)

                # 카페 상세페이지 이동
                detail = p.find_element_by_css_selector('div.info_item > div.contact > a.moreview')
                detail.send_keys(Keys.ENTER)

                driver.switch_to.window(driver.window_handles[-1])

                # 가게 URL ID(PK예정)
                place_url = driver.current_url
                place_url = place_url.strip('https://place.map.kakao.com/')

                # 가게 사진
                place_photo = ""
                try:
                    photo = driver.find_element_by_css_selector('span.bg_present')
                    photo_url = photo.get_attribute('style')
                    m = re.search('"(.+?)"', photo_url)
                    if m:
                        place_photo = m.group(1)
                    else:
                        place_photo = ""
                except:
                    place_photo = ""

                # 가게 홈페이지
                try:
                    place_homepage = driver.find_element_by_css_selector('div.placeinfo_default.placeinfo_homepage > div.location_detail > div.location_present > a.link_homepage').text
                except:
                    place_homepage = ""
                # 가게 태그
                try:
                    place_tags = driver.find_element_by_css_selector('div.placeinfo_default > div.location_detail > div.txt_tag > span.tag_g').text
                    place_tags = place_category + place_tags
                except:
                    place_tags = ""
                    place_tags = place_category + place_tags
                # print(place_tags)

                # 가게 영업시간
                flag = False
                try:
                    if driver.find_element_by_css_selector(
                        '#mArticle > div.cont_essential > div.details_placeinfo > div:nth-child(3) > div > div.fold_floor'
                    ):
                        flag = True
                except:
                    pass
                place_hour = ""
                if flag:
                    try:
                        # find elements로 여러개 뽑아와서 반복문 돌리기
                        elements = driver.find_elements_by_css_selector(
                            '#mArticle > div.cont_essential > div.details_placeinfo > div:nth-child(3) > div > div.fold_floor > div'
                        )
                        # print(flag)
                        # print('good')
                        for i in elements:
                            j = i.get_attribute('innerHTML')
                            k = BeautifulSoup(j, "html.parser")
                            a = (k.text).strip('\n')
                            times = a.split('\n')
                        for j in range(len(times)-1):
                            times[j] = times[j].rstrip()
                            if times[j]:
                                place_hour += '&' + times[j]
                        place_hour = place_hour.lstrip('&')

                    except:
                        print('except')

                else:
                    try:
                        element = driver.find_element_by_css_selector(
                            '#mArticle > div.cont_essential > div.details_placeinfo > div:nth-child(3) > div > div > ul')
                        # print(flag)
                        # print(element.text)
                        place_hour = '영업시간&' + element.text
                        # selling_day_dict[mydict].append(element.text)
                        # print(selling_day_dict)
                    except:
                        print('except noflag')

                # print('카페이름: ' + place_name)

                # 카페 메뉴
                place_menu = ""
                try:
                    if driver.find_element_by_class_name('cont_menu'):
                        # print('있음1')
                        # menu_lists = driver.find_element_by_css_selector('div.cont_menu' > 'ul.list_menu')
                        menu_lists = driver.find_element_by_xpath('//*[@id="mArticle"]/div[3]/ul')
                        # print(menu_lists)
                        menu_lists = menu_lists.get_attribute('innerHTML')
                        # print(menu_lists)
                        menu_lists = BeautifulSoup(menu_lists, "html.parser")
                        # print(menu_lists)
                        for menu in menu_lists:
                            tmp = menu.text.strip('\n')
                            menu = tmp.split('\n')
                            if len(menu) > 1:
                                if '추천' in menu[1]:
                                    Menu = menu[1].strip('추천')
                                    menu_name = '메뉴 이름: ' + Menu
                                else:
                                    menu_name = '메뉴 이름: ' + menu[1]
                                menu_price = menu[2]
                                place_menu += (menu_name + ' ' + menu_price) + '&'
                        place_menu = place_menu.rstrip('&')

                except:
                    print('없음')

                driver.close()
                driver.switch_to.window(driver.window_handles[0])
                file.write(gu_name + "|" + place_url + "|" + place_name + "|" + place_rate + "|" + review_count + "|" + place_address + "|" + place_hour + "|" + place_tel + "|" + place_homepage + "|"
                           + place_tags + "|" + place_menu + "|" +  place_photo + "\n")
                file.close()
            print(i, ' of', ' [ ' , Page, ' ] ')

        next_btn = driver.find_element_by_id("info.search.page.next")
        has_next = "disabled" not in next_btn.get_attribute("class").split(" ")
        if not has_next:
            print('Arrow is Disabled')
            driver.close()
            file.close()
            break # 다음 페이지 없으니까 종료
        else: # 다음 페이지 있으면
            Page += 1
            next_btn.send_keys(Keys.ENTER)
    print("End of Crawl")


import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation

#from fields import SCATTER_2_ELECTRIC_NODES

def PLOT_TIME_SOURCE(v_f,time_source,current_density,del_l,fig_num,location,del_t):
    #plots the source over time in terms of electric field components
    #time_source - holds the sources scatter components at each time step - np.array, shape(n_t,n_f)
    #del_l - space step in all three directions - float

    n_t,n_f = np.shape(time_source)
    eta_0 = 119.9169832*np.pi

    plt.figure(fig_num[0])
    plt.plot(np.arange(n_t)*del_t*1.0e15,-v_f[location[0],location[1],location[2],2,:]/del_l)
    plt.ylabel('V/m')
    plt.xlabel('fs')
    plt.title('free source fields at source location - z component')

    plt.figure(fig_num[1])
    plt.plot(np.arange(n_t)*del_t*1.0e15,time_source[:,2])
    plt.ylabel('V')
    plt.xlabel('fs')
    plt.title('free voltage source - z component')

    plt.figure(fig_num[2])
    plt.plot(np.arange(n_t)*del_t*1.0e15,current_density)
    plt.ylabel('A/m^2')
    plt.xlabel('fs')
    plt.title('current density')

def PLOT_TIME_SOURCE_LUMERICAL(v_f,fig_num,location):
    #plots the source over time in terms of electric field components
    #time_source - holds the sources scatter components at each time step - np.array, shape(n_t,n_f)

    plt.figure(fig_num)
    plt.plot(v_f[location[0],location[1],location[2],2])
    plt.title('free source fields - z component')

def PLOT_RESULTS_2(f_final,del_l,fig_num):

    plt.figure(fig_num)
    plt.plot(np.squeeze(-f_final/del_l), 'b')
    plt.ylabel('V/m')
    plt.title('final field value - z polarized')

def PLOT_VIDEO_1D(f_time,del_l,fig_num):

    fig = plt.figure(fig_num)

    ims = []

    #get number of time steps
    n_x,n_y,n_z,n_t = np.shape(f_time)

    for t in range(n_t):

        im, = plt.plot(np.squeeze(-f_time[:,:,:,t]/del_l), 'b',animated=True)
        plt.title('Lorentz Dielectric - Wrapping Boundary Conditions')
        plt.ylabel('V/m')

        ims.append([im])

    ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,
                                    repeat_delay=1000)

    plt.show()

    ani.save("foward_movie.mp4")

def PLOT_COMPARISON_VIDEO_1D(f_time,f_lumerical_time,del_l,fig_num):

    fig = plt.figure(fig_num)

    ims = []

    #get number of time steps
    _,_,_,n_t = np.shape(f_time)

    for t in range(n_t):

        im1,im2 = plt.plot(np.squeeze(-f_time[:,:,:,t]/del_l), 'b',np.squeeze(-f_lumerical_time[:,:,:,t]/del_l),'r',animated=True)
        plt.title('Lorentz Dielectric - Wrapping Boundary Conditions')
        #plt.ylim(-2,2)

        ims.append([im1,im2])

    ani = animation.ArtistAnimation(fig, ims, interval=5, blit=True,
                                    repeat_delay=1000)

    ani.save("foward_movie.mp4")
    plt.show()

def PLOT_VIDEO_2D(f_time,del_l,fig_num):

    fig = plt.figure(fig_num)

    ims = []

    #get number of time steps
    n_x,n_y,n_z,n_t = np.shape(f_time)

    for t in range(n_t):

        im, = plt.imshow(np.squeeze(-f_time[:,:,:,t]/del_l),animated=True)
        plt.colorbar

        ims.append([im])

    ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,
                                    repeat_delay=1000)

    #ani.save("foward_movie.mp4")
    plt.show()

def PLOT_BOUNDARY_1D(boundary,fig_num):
    #plots boundary tensor assuming 1d simulation
    #boundary: boundary tensor - np.array data_type, shape (n_x,n_y,n_z,n_c)
    #fig_num: figure number - int, shape(1,)

    plt.figure(fig_num)
    plt.imshow(np.squeeze(boundary))
    plt.colorbar()
    plt.title('boundary')

def PLOT_DISPERSION_PARAMETERS_1D(inf_x,w_0,damp,del_x,fig_num):
    #plot the dispersion parameters assuming number of field components equals 3
    # inf_x: high frequency susceptibility tensor - np.constant, shape(n_1)
    # w_0: Lorentz resonance frequency tensor (rad/s) - np.constant, shape(n_1,n_r)
    # damp: Lorentz damping frequency tensor (rad/s) - np.constant, shape(n_1,n_r)
    # del_x: change in susceptibility tensor (unitless) - np.constant, shape(n_1,n_r)
    # fig_num: numbers for figures - list, shape(2,)

    #get size of first spatial axis, number of electric field components and number of resonances
    n_1,n_r = np.shape(w_0)

    #susceptibility
    plt.figure(fig_num[0])
    plt.plot(inf_x,label = 'infinite susceptibility')

    #over all resonances
    for r in range(n_r):

        plt.plot(del_x[:,r],label = 'change in susceptibility: ' + str(r))
        plt.ylabel('Susceptibility')
        plt.xlabel('Simulation points')
        plt.title("Susceptibility for each Resonance")

    plt.legend()

    #resonant frequency
    plt.figure(fig_num[1])

    #over all resonances
    for r in range(n_r):

        plt.plot(w_0[:,r]*10**-12,label = 'resonance frequency: ' + str(r))
        plt.plot(damp[:,r]*10**-12,label = 'damping frequency: ' + str(r))
        plt.ylabel('THz')
        plt.xlabel('Simulation point')
        plt.title("frequency")

    plt.legend()

def PLOT_SPECTRUM_Z(fig_num,f_time,location,del_t):
    # fig_num: the figure number
    # f_time: the field over all time - shape(n_x,n_y,n_z,6,n_t)
    # location: the location of the point monitor - shape(3,)

    #get number of time steps
    _,_,_,_,n_t = np.shape(f_time)

    plt.figure(fig_num)

    #determine location
    x = location[0]
    y = location[1]
    z = location[2]

    time_signal = f_time[x,y,z,2,:]

    t = np.arange(0,del_t*n_t,del_t)
    sp = np.fft.fft(time_signal)
    freq = np.fft.fftfreq(t.shape[-1])
    l = len(freq)
    plt.plot(10**-12*freq[0:l//2-1]/del_t, np.abs(sp[0:l//2-1]))
    plt.xlabel('THz')
    plt.ylabel('Spectrum')
    plt.show()


import pymc3 as pm
import numpy as np
from numpy import random as nr
import numpy.testing as npt
import pytest
import theano.tensor as tt
import theano

from pymc3.distributions.distribution import _draw_value, draw_values
from .helpers import SeededTest

def test_draw_value():
    npt.assert_equal(_draw_value(np.array([5, 6])), [5, 6])
    npt.assert_equal(_draw_value(np.array(5.)), 5)

    npt.assert_equal(_draw_value(tt.constant([5., 6.])), [5, 6])
    assert _draw_value(tt.constant(5)) == 5
    npt.assert_equal(_draw_value(2 * tt.constant([5., 6.])), [10, 12])

    val = theano.shared(np.array([5., 6.]))
    npt.assert_equal(_draw_value(val), [5, 6])
    npt.assert_equal(_draw_value(2 * val), [10, 12])

    a = tt.scalar('a')
    a.tag.test_value = 6
    npt.assert_equal(_draw_value(2 * a, givens=[(a, 1)]), 2)

    assert _draw_value(5) == 5
    assert _draw_value(5.) == 5
    assert isinstance(_draw_value(5.), type(5.))
    assert isinstance(_draw_value(5), type(5))

    with pm.Model():
        mu = 2 * tt.constant(np.array([5., 6.])) + theano.shared(np.array(5))
        a = pm.Normal('a', mu=mu, sigma=5, shape=2)

    val1 = _draw_value(a)
    val2 = _draw_value(a)
    assert np.all(val1 != val2)

    with pytest.raises(ValueError) as err:
        _draw_value([])
    err.match('Unexpected type')

class TestDrawValues:
    def test_empty(self):
        assert draw_values([]) == []

    def test_vals(self):
        npt.assert_equal(draw_values([np.array([5, 6])])[0], [5, 6])
        npt.assert_equal(draw_values([np.array(5.)])[0], 5)

        npt.assert_equal(draw_values([tt.constant([5., 6.])])[0], [5, 6])
        assert draw_values([tt.constant(5)])[0] == 5
        npt.assert_equal(draw_values([2 * tt.constant([5., 6.])])[0], [10, 12])

        val = theano.shared(np.array([5., 6.]))
        npt.assert_equal(draw_values([val])[0], [5, 6])
        npt.assert_equal(draw_values([2 * val])[0], [10, 12])

    def test_simple_model(self):
        with pm.Model():
            mu = 2 * tt.constant(np.array([5., 6.])) + theano.shared(np.array(5))
            a = pm.Normal('a', mu=mu, sigma=5, shape=2)

        val1 = draw_values([a])
        val2 = draw_values([a])
        assert np.all(val1[0] != val2[0])

        point = {'a': np.array([3., 4.])}
        npt.assert_equal(draw_values([a], point=point), [point['a']])

    def test_dep_vars(self):
        with pm.Model():
            mu = 2 * tt.constant(np.array([5., 6.])) + theano.shared(np.array(5))
            sd = pm.HalfNormal('sd', shape=2)
            tau = 1 / sd ** 2
            a = pm.Normal('a', mu=mu, tau=tau, shape=2)

        point = {'a': np.array([1., 2.])}
        npt.assert_equal(draw_values([a], point=point), [point['a']])

        val1 = draw_values([a])[0]
        val2 = draw_values([a], point={'sd': np.array([2., 3.])})[0]
        val3 = draw_values([a], point={'sd_log__': np.array([2., 3.])})[0]
        val4 = draw_values([a], point={'sd_log__': np.array([2., 3.])})[0]

        assert all([np.all(val1 != val2), np.all(val1 != val3),
                    np.all(val1 != val4), np.all(val2 != val3),
                    np.all(val2 != val4), np.all(val3 != val4)])

class TestJointDistributionDrawValues(SeededTest):
    def test_joint_distribution(self):
        with pm.Model() as model:
            a = pm.Normal('a', mu=0, sigma=100)
            b = pm.Normal('b', mu=a, sigma=1e-8)
            c = pm.Normal('c', mu=a, sigma=1e-8)
            d = pm.Deterministic('d', b + c)

        # Expected RVs
        N = 1000
        norm = np.random.randn(3, N)
        eA = norm[0] * 100
        eB = eA + norm[1] * 1e-8
        eC = eA + norm[2] * 1e-8
        eD = eB + eC

        # Drawn RVs
        nr.seed(self.random_seed)
#        A, B, C, D = list(zip(*[draw_values([a, b, c, d]) for i in range(N)]))
        A, B, C, D = draw_values([a, b, c, d], size=N)
        A = np.array(A).flatten()
        B = np.array(B).flatten()
        C = np.array(C).flatten()
        D = np.array(D).flatten()

        # Assert that the drawn samples match the expected values
        assert np.allclose(eA, A)
        assert np.allclose(eB, B)
        assert np.allclose(eC, C)
        assert np.allclose(eD, D)

        # Assert that A, B and C have the expected difference
        assert np.all(np.abs(A - B) < 1e-6)
        assert np.all(np.abs(A - C) < 1e-6)
        assert np.all(np.abs(B - C) < 1e-6)

        # Marginal draws
        mA = np.array([draw_values([a]) for i in range(N)]).flatten()
        mB = np.array([draw_values([b]) for i in range(N)]).flatten()
        mC = np.array([draw_values([c]) for i in range(N)]).flatten()
        # Also test the with model context of draw_values
        with model:
            mD = np.array([draw_values([d]) for i in range(N)]).flatten()

        # Assert that the marginal distributions have different sample values
        assert not np.all(np.abs(B - mB) < 1e-2)
        assert not np.all(np.abs(C - mC) < 1e-2)
        assert not np.all(np.abs(D - mD) < 1e-2)

        # Assert that the marginal distributions do not have high cross
        # correlation
        assert np.abs(np.corrcoef(mA, mB)[0, 1]) < 0.1
        assert np.abs(np.corrcoef(mA, mC)[0, 1]) < 0.1
        assert np.abs(np.corrcoef(mB, mC)[0, 1]) < 0.1


from math import factorial
n = int(input())
X = list(map(int, input().split()))

cnt = []

cnt = [1]

for i in range(2, n):
    for j in range(len(cnt)):
        cnt[j] *= i
    cnt.append(cnt[-1] + cnt[0] // i)
# print(cnt)

print(cnt)
ans = 0
for i in range(1, n):
    r = abs(X[i] - X[i - 1])
    ans += r * cnt[i - 1]
    print(r, cnt[i-1])
    ans %= 10 ** 9

print(ans)


# @param S, a string
# @param L, a list of string
# @return a list of integer
"""
Initially miss this line
                            if curdict[temp] < dict[temp]:
                                cnt-=1
"""
def findSubstring_steal(S, L):
    res = []
    if not S or not L or len(L) == 0:
        return res
    dict = {}
    for word in L:
        if word not in dict:
            dict[word] = 1
        else:
            dict[word]+=1
    wordlen = len(L[0])
    for i in range(wordlen):
        cnt = 0
        index = i
        curdict = {}
        for j in range(i,len(S)-wordlen+1,wordlen):
            curword = S[j:j+wordlen]
            if curword not in dict:
                curdict.clear()
                cnt = 0
                index = j + wordlen
            else:
                if curword not in curdict:
                    curdict[curword] = 1
                else:
                    curdict[curword] +=1
                if curdict[curword] <= dict[curword]:
                    cnt+=1
                else:
                    while curdict[curword] > dict[curword]:
                        temp = S[index:index+wordlen]
                        if temp in curdict:
                            curdict[temp]-=1
                            if curdict[temp] < dict[temp]:
                                cnt-=1
                        index+=wordlen
                if cnt == len(L):
                    res.append(index)
                    temp = S[index:index+wordlen]

                    curdict[temp]-=1
                    cnt-=1
                    index+=wordlen
    return res

class Solution:
    # @param S, a string
    # @param L, a list of string
    # @return a list of integer
    def findSubstring(self, S, L):
        lenS,lenL,lenWord = len(S),len(L),len(L[0])
        res = []
        for i in range(lenS-lenL*lenWord+1):
            listS = [S[j:j+lenWord] for j in range(i,i+lenL*lenWord,lenWord)]
            flag = True
            for item in L:
                if item in listS:
                    listS.remove(item)
                else:
                    flag = False
                    break
            if flag:
                res.append(i)
        return res


# 897. 递增顺序搜索树
# 给你一棵二叉搜索树，请你 按中序遍历 将其重新排列为一棵递增顺序搜索树，使树中最左边的节点成为树的根节点，并且每个节点没有左子节点，只有一个右子节点。

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def increasingBST(self, root: TreeNode) -> TreeNode:
        ans = []
        def midRe(node):
            if node is None:
                return
            midRe(node.left)
            ans.append(node)
            midRe(node.right)
        midRe(root)
        for i in range(1,len(ans)):
            ans[i-1].right=ans[i]
            ans[i].left=None
        return ans[0]

class Solution2:
    def increasingBST(self, root: TreeNode) -> TreeNode:
        dummy = TreeNode(0)
        pre = dummy
        def midRe(node):
            nonlocal pre
            if node is None:
                return
            midRe(node.left)
            pre.right = node
            pre = pre.right
            node.left= None
            midRe(node.right)
        midRe(root)
        return dummy.right


import owncloud
import argparse
import numpy as np
import pickle
import json
import csv
import sys
import os

def setup_cmdline_parser():
    parser = argparse.ArgumentParser(description='Submission system setup!')
    parser.add_argument(
        '--student_link_file',
        dest='student_link_file',
        default=None,
        help='Student pickle file with link and path information')
    parser.add_argument(
        '--config_file',
        dest='config_file',
        default=None,
        help='JSON config file (e.g., config.json)')
    args = parser.parse_args()
    return args

def main(argv):
    args = setup_cmdline_parser()

    assert args.config_file is not None
    if not os.path.exists(args.config_file):
        print('Config file {} not found!'.format(args.config_file))
        sys.exit(-1)

    with open(args.config_file) as json_file:
        data = json.load(json_file)
        url = data['url']
        login = data['user']
        app_key = data['app_key']

    oc = owncloud.Client(url)
    oc.login(login, app_key)

    students = pickle.load( open( args.student_link_file, "rb" ) )
    for k,v in students.items():
        share_list = oc.get_shares(v['path'])
        if len(share_list)>0:
            oc.delete_share(share_list[0].get_id())

if __name__ == '__main__':
    main(sys.argv)


import orange
import orngChem_Old as orngChem
import getopt
import sys

smilesFilename="smiles.tab"
fragmentFilename="fragments.txt"
freq=0.4
opt=dict(getopt.getopt(sys.argv[1:], "s:f:o:a:")[0])
smilesFilename=opt.get("-s", None) or smilesFilename
fragmentFilename=opt.get("-o", None) or fragmentFilename
freq=float(opt.get("-f", freq))
attrName=opt.get("-a",None) or 1

if smilesFilename.endswith(".tab"):
    smilesData=orange.ExampleTable(smilesFilename)
    smiles=map(str, [e[attrName] for e in smilesData if not e[attrName].isSpecial()])
else:
    smiles=map(lambda s:s.strip(), open(smilesFilename).read().split("\n"))

fragments=orngChem.find_fragments(smiles,freq)
file=open(fragmentFilename, "w")
file.write("\n".join(fragments))
file.close()


from .models import *
from .forms import *
from django.shortcuts import render, redirect, get_object_or_404
from datetime import datetime, timedelta
from django.utils import timezone

# 스플래쉬 화면
def splash(request):
    return render(request, 'splash.html')
# 홈페이지
def home(request):

    # DB에 담긴 product 데이터 전부 가져오기
    products = Product.objects.all()

    return render(request, 'index.html', {'products':products })

# 상세페이지 보여지도록 하는 함수 ; 어떤 데이터를 넘겨줄지 정의하는 부분
# url path 정의할 때 blog_id 변수 가져옴.
def detail(request, product_id):
    # blog_id 번째 블로그 글을 데이터베이스로부터 가져와서
    # Blog 객체를 가져올 건데 pk값이 blog_id인 객체를 가져올 거야.
    product_detail = get_object_or_404(Product, pk=product_id)
    bid_info = Bid.objects.filter(product_id=product_id).first()
    bid_list = product_detail.bid.all()
    # 댓글 입력 폼
    comment_form = CommentForm()
    # blog_id 번째 블로그 글을 detail.html 로 띄워주는 코드
    return render(request, 'detail.html', {'product_detail': product_detail, 'bid_info':bid_info, 'bid_list':bid_list ,'comment_form':comment_form})

# 입찰 페이지
def bid(request):
    return render(request, 'bid.html')

# model form으로 만들어진 form은 models.py에서 정의한 모델을 기반으로 만들어져 자체적으로 save 메서드를 갖고 있다.
# 반면 django form 으로 만들어진 form은 models.py에서 정의한 객체를 만들고 값을 넣어준 다음 그 객체에서 save해줘야함.
# def productformcreate(request):
#     # post 요청
#     if (request.method == 'POST' or request.method == 'FILES'):
#         form = ProductForm(request.POST)
#         if form.is_valid():
#             form.save()
#             return redirect('home')

#     # get요청 ; 모델 폼 틀 보여줌.
#     else:
#         form = ProductForm()

#     # 'form_create.html' 그대로 사용해도 상관없음.
#     return render(request, 'formcreate.html', {'form': form})

# 사용자가 작성한 댓글을 저장하는 함수
def create_comment(request, product_id):
    # POST형식으로 들어온 요청을 처리
    filled_form = CommentForm(request.POST)

    # 사용자가 작성한 댓글이 유효하다면 저장.
    if filled_form.is_valid():
        # 근데 주의. 저장하기 전에 어떤 글의 댓글인지 알기 위한 blog_id도 함께 저장해야함.
        # -> 아직 저장하지 않고 대기
        finished_form = filled_form.save(commit=False)
        # -> 어떤 글에 대한 댓글인지 CommentForm 의 post 정보 입력
        finished_form.product_id = get_object_or_404(Product, pk=product_id)
        # -> 그 다음 저장.
        finished_form.save()

    return redirect('detail', product_id)

def productformcreate(request):
    # post 요청
    if (request.method == 'POST' or request.method == 'FILES'):
      form = ProductForm(request.POST, request.FILES)

      if form.is_valid():
        filled_form = form.save(commit=False)
        I = range(1, 5)
        i = 1
        for i in I:
          b = Locker.objects.get(id = i)
          if b.locker_status ==  0:
            break
          i = i+1
        filled_form.locker = b
        filled_form.save()
      filled_locker = Locker.objects.get(id = i)
      filled_locker.locker_status = 1
      filled_locker.save()
      return render(request, 'product_check.html', {'filled_locker':filled_locker})

    # get요청 ; 모델 폼 틀 보여줌.
    else:
        form = ProductForm()

    return render(request, 'formcreate.html', {'form': form})

# 바로구매 확정페이지로 렌더링하는 함수
def purchase(request, product_id):
    # get요청 ; 모델 폼 틀 보여줌.
    product_info = get_object_or_404(Product, pk=product_id)

    return render(request, 'confirm_purchase.html',{'product_info': product_info})

def bidformcreate(request, product_id):
    # post 요청
    # if (request.method == 'POST'):
    #     form = BidForm(request.POST)
    #     if form.is_valid():
    #         form.save()
    #         return redirect('detail', product_id)

    # get요청 ; 모델 폼 틀 보여줌.
    if (request.method == "GET"):
        # 상품정보 불러오기 위해 product 객체 가져옴.
        product_info = get_object_or_404(Product, pk=product_id)
        # 현재 최고입찰가 가져오는 객체
        latest_bid = Bid.objects.filter(product_id=product_id).last()

        # 입력폼
        form = BidForm()

    # 'form_create.html' 그대로 사용해도 상관없음.
    return render(request, 'bid.html', {'form': form, 'product_info': product_info, 'latest_bid':latest_bid})

# 사용자가 작성한 입찰정보를 저장하는 함수
def create_bid(request, product_id):
    # POST형식으로 form에 입력된 요청을 처리
    filled_form = BidForm(request.POST)

    # 사용자가 작성한 댓글이 유효하다면 저장.
    if filled_form.is_valid():
        # 아직 저장하지 않고 대기
        finished_form = filled_form.save(commit=False)

        # filter는 쿼리셋 받아옴.
        # before_bid = Bid.objects.filter(product_id=product_id, pk=pk_count)
        latest_bid = Bid.objects.filter(product_id=product_id).first()
        # first_bid id가 가장 최근.id - 1

        # filter로 받아온 쿼리셋을 get하면 객체 불러옴.
        # before_bid_test = before_bid.get()
        # print(before_bid_test)
        print(latest_bid)
        # 존재하는지 확인
        if latest_bid is not None:
            # before_bid = Bid.objects.get(pk=pk_count)

            print(f"bid 객체 status : {latest_bid.product_id.product_status}")
            # 낙찰될 때까지 입찰과정 반복
            if latest_bid.product_id.product_status == 0 :
                # 이전 bid객체의 bid_price 보다 입력된 입찰가가 높을 4
                if (finished_form.bid_price > latest_bid.bid_price):

                    # -> 어떤 상품에 대한 입찰인지 BidForm 의 post 정보 입력
                    finished_form.product_id = get_object_or_404(Product, pk=product_id)
                    # -> 그 다음 저장.
                    finished_form.save()

                    print('굳굳')
                    # first_bid.product_id.product_status = 1
                # 입찰가가 즉시거래가와 같으면 객체 생성되면서, product_status = 1로 바꿔주기
                elif (finished_form.bid_price == latest_bid.product_id.buyout_price):
                    finished_form.product_id = get_object_or_404(Product, pk=product_id)

                    latest_bid.product_id.product_status = 1
                    print(f"bid 객체 status : {latest_bid.product_id.product_status}")

                    finished_form.save()

                    print('즉시구매 되엇습니다!')

                # 마감시간 지나면 status 바뀌는 것도 짜야함. -> 시간설정 필요; 타임델타

                # 입찰가가 이전 입찰가보다 낮을 때 객체생성x
                else:
                    print('이전 입찰가보다 높은 가격을 입력해주세요!!')

        # 즉시거래가 입력하면 바로 낙찰
        # 기존에 입찰이 없으면 첫번째 입찰 생성
        else:
            finished_form.product_id = get_object_or_404(Product, pk=product_id)
            finished_form.save()

            print('첫번째 Bid 객체 생성. ')
        return redirect('detail', product_id)

# 사용자가 작성한 바로구매정보를 저장하는 함수
def create_purchase(request, product_id):
    # POST요청 처리 ; 바로구매 정보 담김
    if (request.method =="POST"):
        product_info = get_object_or_404(Product, pk=product_id)
        # Bid 객체 생성
        Bid.objects.create(
            product_id = product_info,
            bid_price = product_info.buyout_price,
            bid_time = timezone.now(),

        )
        # 낙찰
        product_info.product_status = 1
        product_info.save()
    # render는 같은 url안에 렌더링만 바꿔줌. redirect는 url 바꿔줌.
    # redirect 는 url name만 적어줘도 됨.
    return render(request, 'buy_locker_check.html', {'product_info':product_info})

    # filled_form = BidForm(request.POST)

    # # 사용자가 작성한 댓글이 유효하다면 저장.
    # if filled_form.is_valid():
    #     # 근데 주의. 저장하기 전에 어떤 글의 댓글인지 알기 위한 blog_id도 함께 저장해야함.
    #     # -> 아직 저장하지 않고 대기
    #     finished_form = filled_form.save(commit=False)
    #     # -> 어떤 글에 대한 댓글인지 CommentForm 의 post 정보 입력
    #     finished_form.product_id = get_object_or_404(Product, pk=product_id)
    #     # -> 그 다음 저장.
    #     finished_form.save()

    # return redirect('detail', product_id)


from lib.fetch import fetch_url
from lib.networks import Network
import json
import sys

# Public location of the services.json file.
SERVICES_URL = "https://s3.us-east-2.amazonaws.com/ndau-json/services_localnet.json"

def fetch_services():
    """
    Fetch and return the json text from services.json.
    """

    services_response = fetch_url(SERVICES_URL)
    if services_response is None:
        sys.exit(f"Unable to fetch {SERVICES_URL}")

    return services_response.content

def parse_all_services(services_json):
    """
    Return API and RPC dictionaries with network name keys and values from parse_services().
    """

    network_apis = {}
    network_rpcs = {}

    for network in list(Network):
        network_name = str(network)
        network_apis[network_name], network_rpcs[network_name] = parse_services(
            network_name, None, services_json
        )

    return network_apis, network_rpcs

def parse_services(network_name, node_name, services_json):
    """
    Return a dictionary with node name keys and protocol://domain:port for the values for the
    given network's node from services_json.
    The dictionary will contain all urls on the given network if node_name is None.
    Two dictionaires are returned, one with ndauapi urls, one with tendermint RPC urls.
    """

    # Key names in services.json
    networks_name = "networks"
    nodes_name = "nodes"
    api_name = "api"
    rpc_name = "rpc"

    try:
        services_obj = json.loads(services_json)
    except:
        services_obj = None
    if services_obj is None:
        sys.exit("Unable to parse services json")

    if not networks_name in services_obj:
        sys.exit("Unable to find networks object")
    networks_obj = services_obj[networks_name]

    if not network_name in networks_obj:
        sys.exit(f"Unable to find {network_name} network object")
    network_obj = networks_obj[network_name]

    if not nodes_name in network_obj:
        sys.exit("Unable to find nodes object")
    nodes_obj = network_obj[nodes_name]

    # Ensure support for testnet-backup and mainnet-backup.  They are not published in
    # services.json, but we know of their existence and we want to manage them on AWS.
    if network_name == "testnet" or network_name == "mainnet":
        new_node_name = f"{network_name}-backup"
        if not new_node_name in nodes_obj:
            nodes_obj[new_node_name] = {
                api_name: f"{new_node_name}.ndau.tech:3030",
                rpc_name: f"{new_node_name}.ndau.tech:26670",
            }

    apis = {}
    rpcs = {}

    for node_obj_name in nodes_obj:
        if node_name is None or node_name == node_obj_name:
            node_obj = nodes_obj[node_obj_name]
            if not api_name in node_obj:
                sys.exit(f"Unable to find api object in {node_obj}")
            if not rpc_name in node_obj:
                sys.exit(f"Unable to find rpc object in {node_obj}")
            if network_name == "localnet":
                apis[node_obj_name] = f"http://{node_obj[api_name]}"
                rpcs[node_obj_name] = f"http://{node_obj[rpc_name]}"
            else:
                apis[node_obj_name] = f"https://{node_obj[api_name]}"
                rpcs[node_obj_name] = f"https://{node_obj[rpc_name]}"

    return apis, rpcs


import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.express as px
import plotly.graph_objs as go
from dash.dependencies import Input, Output

from load_data import get_dataframe

df = get_dataframe()

# remove fucking spam posts
df.drop(df[df.price > 10000000].index, inplace=True)
tdf = df[['state', 'price']].groupby('state').mean()

def model_brand_df():
    dd = df.groupby(['model', 'manufacturer'], as_index=False).count().sort_values('Unnamed: 0')
    dd.rename(columns={'Unnamed: 0': 'count'}, inplace=True)
    return dd[dd['count'] > 2000]

def count_by_manufacturer(ddf):
    dic = ddf.groupby('manufacturer').count()['Unnamed: 0'].to_dict()
    return {'x': list(dic.keys()), 'y': list(dic.values())}

external_stylesheets = ['static/app.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.title = 'داشبرد تحلیلی خودرو'

wk_days = [
    'monday',
    'tuesday',
    'wednesday',
    'thursday',
    'friday',
    'saturday',
    'sunday',
]

def generate_submission_choro(states):
    tdf = df
    if states:
        tdf = tdf[tdf.state.apply(lambda x: x.upper() in states)]

    return {
        'data': [
            {**count_by_manufacturer(tdf), 'type': 'bar', 'name': 'SF'},
        ],
        'layout': {
            'title': 'تعداد آگهی‌های ثبت شده به ازای هر تولید‌کننده'
        }
    }

def generate_submission_time_hm(states):
    hm = []
    ddf = df
    if states:
        ddf = df[df.state.apply(lambda x: x.upper() in states)]

    for i in range(24):
        hm_df = ddf[ddf.hour == i].groupby('day').count()['image_url']
        hm.append(hm_df)

    hm_df = pd.concat(hm, axis=1)

    y = list(wk_days)

    trace = dict(
        type="heatmap",
        z=hm_df.to_numpy(),
        x=list(f"{i}:00" for i in range(24)),
        y=y,
        colorscale=[[0, "#71cde4"], [1, "#ecae50"]],
        reversescale=True,
        showscale=True,
        xgap=2,
        ygap=2,
        colorbar=dict(
            len=0.7,
            ticks="",
            title="Submissions",
            titlefont=dict(family="Gravitas One", color="#515151"),
            thickness=15,
            tickcolor="#515151",
            tickfont=dict(family="Open Sans, sans serif", color="#515151"),
        ),
    )

    title = f'زمان ارسال آگهی در ایالات {states} بر حسب روز و ساعت'

    layout = dict(
        title=dict(
            text=title,
            font=dict(family="Open Sans, sans-serif", size=15, color="#515151"),
        ),
        font=dict(family="Sahel, Open Sans, sans-serif", size=13),
        automargin=True,
        dir='rtl',
    )

    return {"data": [trace], "layout": layout}

def generate_odometer_price_sctr(model):
    return {
        'data': [dict(
            x=df[df.model == model].odometer,
            y=df[df.model == model].price,
            mode='markers+line'
        )],
        'layout': dict(
            title=dict(
                text='قیمت / کارکرد',
                font=dict(family="Open Sans, sans-serif", size=15, color="#515151"),
            ),
            font=dict(family="Sahel, Open Sans, sans-serif", size=13),
            automargin=True,
            dir='rtl',
        )
    }

app.layout = html.Div(className='container', children=[
    html.Div(id='head-row', children=[
        html.H1(children='داشبرد تحلیلی بازار خودرو آمریکا', dir='rtl'),
        html.H4(children='بر اساس داده‌ی منتشر شده از سایت CraigsList', dir='rtl'),
        html.A(dir='rtl', target='_blank', href='/static/blog.html', children=html.H5(children='توضیحات بیشتر در بلاگ')),
    ]),
    dcc.Loading(children=dcc.Graph(id='submission_count')),
    html.Div(
        id="top-row",
        className="row",
        children=[
            html.Div(
                id="map_geo_outer",
                className="six columns",
                # avg arrival/dep delay by destination state
                children=dcc.Loading(children=dcc.Graph(id="choropleth", figure={"data": [go.Choropleth(
                    locations=list(tdf.index.str.upper()),  # Spatial coordinates
                    z=list(tdf['price'].astype(float)),  # Data to be color-coded
                    locationmode='USA-states',  # set of locations match entries in `locations`
                    colorscale='Reds',
                    colorbar_title="USD",
                )], "layout": dict(
                    title=dict(
                        text='میانگین قیمت بر حسب ایالت',
                        font=dict(family="Open Sans, sans-serif", size=15, color="#515151"),
                    ),
                    margin=dict(l=20, r=20, b=20, pad=5),
                    automargin=False,
                    clickmode="event+select",
                    geo=go.layout.Geo(
                        scope="usa", projection=go.layout.geo.Projection(type="albers usa")
                    ),
                )})),
            ),
            html.Div(
                dir='rtl',
                className='six columns',
                id="dropdown-select-outer",
                children=[
                    html.Div(
                        [
                            html.P("نوع خودرو را انتخاب کنید"),
                            dcc.Loading(children=dcc.Dropdown(
                                id="dropdown-select",
                                options=[
                                    {'label': str(model), 'value': str(model)} for model in list(df.model.unique())
                                ],
                                value=list(df.model.unique())[0],
                            )),
                        ],
                        className="selector",
                    ),
                    html.Div(
                        id="bottom-row",
                        className="twelve columns",
                        children=[
                            html.Div(
                                id='sctr_outer',
                                children=dcc.Loading(children=dcc.Graph(id='odometer_price_sctr'))
                            )
                        ]
                    )
                ],
            ),
        ],
    ),
    html.Div(
        id="mid-row",
        className="row",
        children=[
            html.Div(
                id="submissions_by_day_hm_outer",
                className="six columns",
                children=dcc.Loading(children=dcc.Graph(id="submission_time_hm")),
            ),
            html.Div(
                id="models_by_brand_sunburst",
                className="six columns",
                children=[
                    dcc.Loading(children=dcc.Graph(id="model_by_brand", figure=px.sunburst(
                        model_brand_df(),
                        path=['manufacturer', 'model'],
                        values='count',
                    )))],
            ),
        ],
    ),
])

@app.callback(
    Output('odometer_price_sctr', 'figure'),
    [Input("dropdown-select", "value")]
)
def update_sctr(model):
    return generate_odometer_price_sctr(model)

@app.callback(
    Output("submission_time_hm", "figure"),
    [Input("choropleth", "clickData"), Input("choropleth", "figure")],
)
def update_hm(choro_click, choro_figure):
    if choro_click is not None:
        states = []
        for point in choro_click["points"]:
            states.append(point["location"])

        return generate_submission_time_hm(states)
    else:
        return generate_submission_time_hm([])

@app.callback(
    Output("submission_count", "figure"),
    [Input("choropleth", "clickData"), Input("choropleth", "figure")],
)
def update_choro(choro_click, choro_figure):
    if choro_click is not None:
        states = []
        for point in choro_click["points"]:
            states.append(point["location"])
            return generate_submission_choro(states)
    else:
        return generate_submission_choro([])

if __name__ == '__main__':
    import os
    app.run_server(debug=True or os.environ.get('DEBUG', 'False').lower() == 'true')


def removeElement(nums: [int], val: int) -> int:
    """
    O(n)  time loop once with two pointers

    当慢指针和快指针指向同一个不等于value的元素时候，一起向前进一步，
    当快指针指向等于value的元素时候，慢指针不动，快指针继续，直到找到下一个不一样的，然后与慢指针相互交换位置，同时慢指针向前走一步
    这里慢指针会停下来一定是找到了一个等于value的数值，并且会刚好停在这个数前一个index处
    """
    slow_index = 0
    for fast_index in range(len(nums)):
        if val != nums[fast_index]:
            nums[slow_index] = nums[fast_index]  # 快慢指针相互交换位置
            slow_index += 1  # 慢指针向前走一步

    return slow_index

index = removeElement([1, 2, 3, 4, 5, 3, 3], 3)
print(index)


# reference:
#   https://www.youtube.com/watch?v=rVQpK6NcYIE
#   https://www.youtube.com/watch?v=wXB-V_Keiu8

import math
import secrets
import threading
import multiprocessing
from time import time
from timeit import timeit

from tqdm import tqdm

def EEA(b, m):
    '''
    Return the inverse of b from b (mod m), using Extended
    Euclidean Algorithm (EEA) algorithm.

    b and m fulfill: (b * b^-1) mod m = 1
    '''
    a1, a2, a3 = 1, 0, m
    b1, b2, b3 = 0, 1, b
    while (True):
        if b3 == 0:
            return None  # gcd(m, b) = a3
        if b3 == 1:
            while(b2 < 0):
                b2 += m
            return b2  # gcd(m, b) = b3
        q = int(a3 / b3)  # quotient
        a1, a2, a3, b1, b2, b3 = b1, b2, b3, a1-q*b1, a2-q*b2, a3-q*b3

def rsaGenKey(primeStart: int = None):
    '''
    @param primeStart: start point of prime numbers (p, q >= primeStart). default 12345
    @return pubKey(e, n), privKey(d, n), (p, q)
    '''

    def getPQ(start: int = None):
        '''
        Get the 2 primes, p and q, which form phi_n, for RSA algorithm.
        p and q are large and roughly equal-length, e.g., |p|=|q|=512-bits.
        @param start: start point of the primes, default 12345.
        '''

        def gen_primes(start: int = None):
            """
            (Fast prime generator)
            Generate an infinite sequence of prime numbers.
            @param start: the start point of prime searching process, default 2.

            Sieve of Eratosthenes
            Code by David Eppstein, UC Irvine, 28 Feb 2002
            http://code.activestate.com/recipes/117119/
            """
            # Maps composites to primes witnessing their compositeness.
            # This is memory efficient, as the sieve is not "run forward"
            # indefinitely, but only as long as required by the current
            # number being tested.
            #
            D = {}

            # The running integer that's checked for primeness
            q = 2

            while True:
                if q not in D:
                    # q is a new prime.
                    # Yield it and mark its first multiple that isn't
                    # already marked in previous iterations
                    #
                    if q > start:
                        yield q
                    D[q * q] = [q]
                else:
                    # q is composite. D[q] is the list of primes that
                    # divide it. Since we've reached q, we no longer
                    # need it in the map, but we'll mark the next
                    # multiples of its witnesses to prepare for larger
                    # numbers
                    #
                    for p in D[q]:
                        # if D.has_key(p+q):
                        #     D[p+q].append(p)
                        # else:
                        #     D[p+q] = [p]
                        D.setdefault(p + q, []).append(p)
                    del D[q]

                q += 1

        start = start or 12345

        cnt = 0
        for i in gen_primes(start):
            if cnt == 0:
                p = i
            elif cnt == 1:
                q = i
            else:
                break
            cnt += 1
        return p, q

    def getE(phi_n):
        '''
        Generate e of the public key of RSA (PK=(e, n)).
        1 < e < phi(n), n % e != 0
        '''

        def gcd(a, b):
            ''' Return gcd of a and b'''
            if a == 0 and b == 0:
                raise ValueError("a and b cannot be both 0")
            if a < b:
                a, b = b, a
            # print("In gcd, a={}, b={}".format(a, b))
            if b == 0:
                return a
            while True:
                tmp = a % b
                if tmp == 0:
                    return b
                a, b = b, tmp

        i = secrets.randbelow(int(math.sqrt(phi_n)))
        while i < phi_n:
            # i must be co-prime to phi and
            # smaller than phi.
            if gcd(i, phi_n) == 1:
                return i
            i += 1

    def getD(e, phi_n):
        '''Get d of the private key of RSA.'''
        def slowMethod():
            '''Simple way, extremely slow.'''
            print(
                f"Trying to get d (e={e}, phi_n={phi_n}), this may take some time...", end='')
            timer = time()
            d = 1
            while (d * e) % phi_n != 1:
                d += 1
            print("finished in {:.3}s".format(time.time()-timer))
            return d

        def fastMethod():
            def EEA(b, m):
                '''
                Return the inverse of b from b (mod m), using Extended
                Euclidean Algorithm (EEA) algorithm.

                b and m fulfill: (b * b^-1) mod m = 1
                '''
                a1, a2, a3 = 1, 0, m
                b1, b2, b3 = 0, 1, b
                while (True):
                    if b3 == 0:
                        return None  # gcd(m, b) = a3
                    if b3 == 1:
                        while(b2 < 0):
                            b2 += m
                        return b2  # gcd(m, b) = b3
                    q = int(a3 / b3)  # quotient
                    a1, a2, a3, b1, b2, b3 = b1, b2, b3, a1-q*b1, a2-q*b2, a3-q*b3

            d = EEA(e, phi_n)
            assert d > 0, f"d should be positive (e={e}, phi_n={phi_n})"
            return d

        res = fastMethod()
        return res

    # Public key
    p, q = getPQ(primeStart)
    n = p * q  # public modulus
    phi_n = (p-1) * (q-1)
    e = getE(phi_n)
    pubKey = (e, n)

    # Private key
    d = getD(e, phi_n)
    privKey = (d, n)

    return pubKey, privKey, (p, q)

def fastMod(x: int, p: int, m: int):
    '''Fast modular square operation. Return x^p mod m.'''
    binP = format(p, 'b')
    pList = []
    for k in range(len(binP)):
        c = binP[len(binP) - 1 - k]
        if c == '1':
            pList.append(2**k)

    tmp = x
    xList = [tmp]  # [x^1 % m, x^2 % m, x^4 % m, ...]
    for i in range(len(binP)-1):
        tmp = (tmp*tmp) % m
        xList.append(tmp)

    x = 1
    for i in range(len(binP)):
        if binP[::-1][i] == '1':
            x *= xList[i]

    return x % m

def rsaEncrypt(data: int, pk: tuple) -> int:
    '''Encrypt data using RSA public key. Return encrypted data.'''
    e, n = pk
    # How to simplify the calculation:
    #    if x = a * b, then
    #    x mod n = [(a mod n) * (b mod n)] mod n
    # e.g., 16 mod 3 = (4 mod 3)(4 mod 3) mod 3 = 1*1 mod 3 = 1
    # for more: https://chenyangwang.gitbook.io/mathematical-base-for-information-safety/tong-yu-shi/fu-za-qu-mo-yun-suan-jian-hua
    # return (data**e) % n
    return fastMod(data, e, n)

def rsaDecrypt(encrypted: int, sk: int) -> int:
    '''Decrypt data using RSA private key. Return decrypted data.'''
    d, n = sk
    # return (encrypted**d) % n
    return fastMod(encrypted, d, n)

corruptTime = 0

def rsaDemo(info: bool = False, data: int = None):
    pk, sk, (p, q) = rsaGenKey()
    if info:
        print("Primes     : (p={}, q={})".format(p, q))
        print("Public key : (e={}, n={})".format(pk[0], pk[1]))
        print("Private key: (d={}, n={})".format(sk[0], sk[1]))

    data = data or 123456
    enc = rsaEncrypt(data, pk)
    dec = rsaDecrypt(enc, sk)
    if info:
        print("Data     :", data)
        print("Encrypted:", enc)
        print("Decrypted:", dec)

    global corruptTime
    if data != dec:
        corruptTime += 1

def rsaDemoTimeit():
    runTime = 200
    t = timeit(rsaDemo, number=runTime)
    print("Finished in {:.3}s ({:.3}s/round)".format(t, t/runTime))
    print("{}% success ({} failed)".format(
        int((runTime-corruptTime)/runTime*100), corruptTime))

def hackDemo():
    '''
    Bob's old d is leaked, but he didn't change p and q, and
    directly generate new e2, n2, and d2. How to hack d2.
    '''

    # Unknown
    p = 12347
    q = 12373
    phi_n = (p-1)*(q-1)
    # Known
    e = 9833
    n = 152769431
    d = 55455977
    e2 = 2
    # Target
    d2 = EEA(e2, phi_n)

    # Try to guess d2
    # phi_n=(e*d-1)/k (k<min(e,d))
    print("Start hacking...")
    timer = time()
    guessed = []
    k_limit = min(e, d)
    for k in tqdm(range(1, k_limit)):
        # for k in range(1, k_limit):
        gphi_n = (e*d-1)/k
        gp_limit = min(n, gphi_n)
        for gp in tqdm(range(1, gp_limit)):
            # for gp in range(1, gp_limit):
            if n % gp == 0:
                gq = n/gp
                if gp*gq == n and (gp-1)*(gq-1) == gphi_n:
                    gd = EEA(e2, gphi_n)
                    print("Guessed d: {}. {}".format(
                        gd, 'Correct' if gd == d2 else 'Wrong'))
                    guessed.append(gphi_n)
    # for gphi_n in guessed:
    #     gd = EEA(e2, gphi_n)
    #     print("Guessed d: {}. {}".format(
    #         gd, 'Correct' if gd == d2 else 'Wrong'))
    print("Finished in {:.3}s.".format(time()-timer))

def threadHackDemo():
    '''
    Threading accelated hacking process:
    Bob's old d is leaked, but he didn't change p and q, and
    directly generate new e2, n2, and d2. How to hack d2.
    '''

    # Unknown
    p, q = 12347, 12373
    phi_n = (p-1)*(q-1)
    # Known
    e, n, d, e2 = 9833, 152769431, 55455977, 2
    # Target
    d2 = EEA(e2, phi_n)

    def hack(k_start, k_end, childID):
        # Try to guess d2
        print("Start hacking...")
        timer = time()
        guessed = []
        for k in tqdm(range(k_start, k_end), desc=f"Child {childID} (k:[{k_start}~{k_end}])"):
            if (e*d-1) % k != 0:
                continue
            gphi_n = int((e*d-1)/k)
            gp_limit = min(n, gphi_n)
            for gp in tqdm(range(1, gp_limit), desc=f"Child {childID} (gp:[1~{gp_limit}])"):
                if n % gp == 0:
                    gq = n/gp
                    if gp*gq == n and (gp-1)*(gq-1) == gphi_n:
                        gd = EEA(e2, gphi_n)
                        if gd == None:
                            tqdm.write(
                                "Find the good p,q, but dont have an inversion e.")
                            continue
                        tqdm.write("Guessed d: {}. {}".format(
                            gd, 'Correct' if gd == d2 else 'Wrong'))
                        guessed.append([gp, gq])
        print("All guessed results (in form of [p, q]):", guessed)
        print("Finished in {:.3}s.".format(time()-timer))

    k_limit = min(e, d)
    cpuCnt = multiprocessing.cpu_count() - 2  # prevent killing computer
    step = math.ceil(k_limit/cpuCnt)
    for i in range(cpuCnt):
        k_start, k_end = step*i, step*(i+1)
        if k_start == 0:
            k_start = 1
        if k_end > k_limit:
            k_end = k_limit
        t = threading.Thread(target=hack, args=(k_start, k_end, i+1))
        t.start()

if __name__ == '__main__':
    rsaDemo(True, 114514)
    # threadHackDemo()


print('Importing...')
import os
import sys
import sqlite3 as sql
from ttk import *
from tkinter import *
from tkinter import Button as TkButton
from tkinter import messagebox
from PIL.ImageTk import PhotoImage
print('Done.')

'''
retarded
'''

__author__ = 'retarded'

class player(object):

    '''player data container'''

    def __init__(self, name, slot):

        self.slot = slot
        self.kills = 0
        self.sds = 0
        self.games = 0
        #once all player classes have been instantiated,
        #have all player classes sync to create relative
        #kill variables

    def export(self):

        #export data to a file in the form of a dictionary
        pass

class Smash(Frame):

    '''the gooey bit'''

    def __init__(self, master):

        '''
        Initializes the gui by creating the main frame, calling the title
        screen and doing whatever background work.
        '''

        Frame.__init__(self, master)
        self.canvas = Canvas(master = self, width = 800, height = 600)
        self.canvas.pack()
        root.geometry('800x600+0+440')
        self.datahandler(init = True)
        self.titlescreen()

    def datahandler(self, init = False, namelist=False):

        '''Consider wrapping this in a class external to the GUI.'''

        originalpath = os.getcwd()
        class smashcontainer:

            pass

        def databasesearch():
            # seach cwd for correct file, maybe use a custom extension
            # for convenience
            # os.chdir('..') for wider search

            path = None
            for tuple in os.walk(os.getcwd()):
                for item in tuple[2]:
                    if item == 'smashdatabase.db':
                        path = tuple[0]
                        return path

        def database_skeleton():

            print('Creating stat skeleton...')
            skeleton = ('CREATE TABLE basic(Name text, Kills int)',
                        """INSERT INTO basic VALUES ('Matt', 0),
                                                    ('Karel', 0),
                                                    ('Kevin', 0)""")
            self.cur.execute(skeleton[0])
            self.cur.execute(skeleton[1])
            self.con.commit()
            print('Done.')

        def import_stats():

            pass

        if init:
            print('Looking for stats...')
            database_path = databasesearch()
            if not database_path:
                print('Stats not found.\n'\
                      'Creating stat database in {}...'.format(originalpath))
                self.con = sql.connect('smashdatabase.db')
                self.cur = self.con.cursor()
                database_skeleton()
            else:
                print('Stats found.')
                self.con = sql.connect('smashdatabase.db')
                self.cur = self.con.cursor()

        # to do:
        #   -prompt the user to find it themselves if autosearch fails or
        #    search with wider scope
        #   -create import functions for handling the demands of statdisplay
        #    and stat analysis

    def titlescreen(self):

        '''
        Main menu screen.
        Options:
            -display records
            -begin stat recording:
            -stat analysis
            -whatever
            -quit

        # unfocused color, focused text color: #040D24
        # focused color, unfocused text color: #FFCB00, #C89632
        # button widthxheight = 325x45
        # screen widthxheight = 800x600
        '''

        def button_highlight(event):
            event.widget.config(foreground = '#040D24',
                                background = '#FFCB00')
        def button_dehighlight(event):
            event.widget.config(foreground = '#C89632',
                                background = '#040D24')

        try: self.canvas.delete('all')
        except: pass

        self.titleimage = PhotoImage(file = 'titleimage.png')
        self.canvas.create_image((400, 300),
                                      image = self.titleimage)

        RecordingButton = TkButton(master = self,
                            text = 'Start Recording',
                            font = ('Helectiva', 20, 'bold'),
                            fg = '#C89632', bg = '#040D24', bd = 1,
                            command = self.playerselect)
        StatDisplayButton = TkButton(master = self,
                            text = 'Stat Display',
                            font = ('Helectiva', 20, 'bold'),
                            fg = '#C89632', bg = '#040D24', bd = 1,
                            command = self.statdisplay)
        AnalysisButton = TkButton(master = self,
                            text = 'Stat Analysis',
                            font = ('Helectiva', 20, 'bold'),
                            fg = '#C89632', bg = '#040D24', bd = 1,
                            command = self.statanalysis)

        RecordingButton.bind('<Enter>', button_highlight)
        StatDisplayButton.bind('<Enter>', button_highlight)
        AnalysisButton.bind('<Enter>', button_highlight)
        RecordingButton.bind('<Leave>', button_dehighlight)
        StatDisplayButton.bind('<Leave>', button_dehighlight)
        AnalysisButton.bind('<Leave>', button_dehighlight)

        self.canvas.create_window((322,186), window = RecordingButton,
                                  width = 323, height = 40)
        self.canvas.create_window((255,245), window = StatDisplayButton,
                                  width = 320, height = 40)
        self.canvas.create_window((204,308), window = AnalysisButton,
                                  width = 320, height = 41)

        #create a dynamic focus-based label in bottom text slot
        #maybe recreate the focus-based 'select-ball' on right of option

    def playerselect(self, init=True):
        '''
        A new toplevel screen or replacement canvas inside main_frame.
        Called before stat recording begins, used to selecting
        participating players. Method uncertain. Must initialize
        players and player relations to before recordingscreen because
        recordingscreen will depend on current players.
        '''

        try: self.canvas.delete('all')
        except Exception as ex: print(ex)

        #canvas cosmetics, image resourcing

        self.backimage = PhotoImage(file = 'back.png')
        self.toggleon = PhotoImage(file = 'toggleon.png')
        self.toggleoff = PhotoImage(file = 'toggleoff.png')
        self.pselectbackground = PhotoImage(file = 'listboxbackground.png')
        self.p1coin = PhotoImage(file = 'p1coin.png')
        self.p2coin = PhotoImage(file = 'p2coin.png')
        self.p3coin = PhotoImage(file = 'p3coin.png')
        self.p4coin = PhotoImage(file = 'p4coin.png')
        self.coinlist = [self.p1coin, self.p2coin, self.p3coin, self.p4coin]

        def back():
            self.titlescreen()

        def namefill():
            print('Trying to fill list with names.')
            self.cur.execute("""SELECT Name FROM basic""")
            for name in self.cur:
                print(name)
                self.playerlist.insert(END, name)
            print('Done trying.')

        def playercoin(self, event):

            def move_coin(event):
                self.canvas.move('p{}coin'.format(coinslot),
                                 event.x - 20, event.y - 20)

            def determine_character(event):
                # consider storing this grid info and grid arithmetic in
                # a separate module
                character_array = {
                    'dr. mario' : (45, 100), 'mario' : (125, 95),
                    'luigi': (205, 95), 'bowser' : (285, 95),
                    'peach': (365, 95), 'yoshi' : (445, 95),
                    'dk': (525, 95), 'falcon' : (610, 95),
                    'ganondorf' : (690, 100), 'falco' : (45, 175),
                    'fox' : (125, 170), 'ness' : (205,170),
                    'ice climbers' : (285, 170), 'kirby' : (365, 170),
                    'samus' : (445, 170), 'zelda' : (525, 170),
                    'link' : (610, 170), 'young link':(690, 175),
                    'pichu' : (130, 250), 'pikachu' : (205, 245),
                    'jigglypuff' : (285, 245), 'mewtwo' : (365, 245),
                    'game and watch' : (445, 245), 'marth' : (525, 245),
                    'roy' : (610, 250)}

                coin_x = coin.winfo_x() + 20
                coin_y = coin.winfo_y() + 20
                x = portrait_width = 70; y = portrait_height = 65
                for character in character_array.keys():
                    pivot = portrait_corner = character_array[character]
                    if coin_x >= pivot[0] and coin_x <= pivot[0] + x:
                        if coin_y >= pivot[1] and coin_y <= pivot[1] + y:
                            print('Selected {}'.format(character))

            coinslot = event.widget.slot
            print('Creating p{} coin.'.format(coinslot))
            coin_origin = ((event.widget.winfo_x() + 120,
                            event.widget.winfo_y()))
            coin = Label(self, borderwidth = 0,
                              image = self.coinlist[coinslot - 1])
            coin.bind('<B1-Motion>', move_coin)
            coin.bind('<ButtonRelease-1>', determine_character)
            self.canvas.create_window(coin_origin,
                                      window = coin,
                                      tags = ('p{}coin'.format(coinslot),
                                              'p{}'.format(coinslot)))

        def playerselectbox(self, event):

            xpos = event.widget.winfo_x() + 90
            ypos = event.widget.winfo_y() + 135
            self.playerlist = Listbox(self,
                              bg = 'black', fg = 'white',
                              font = ('Helectiva', 15, 'bold'),
                              selectmode = SINGLE, takefocus = True)
            self.canvas.create_window((xpos, ypos),
                                      window = self.playerlist,
                                      width = 160,  height = 210,
                                      tags = ('p{}box'
                                              .format(event.widget.slot),
                                              'p{}'
                                              .format(event.widget.slot)))
            self.playerlist.focus(); namefill()

            #create name entry button
            #handle name selection/creation

        def buttontoggle(event):
            '''changes the image on the player toggle button'''

            if event.widget.var.get() == 0:
                event.widget.var.set(1)
                event.widget.config(image = self.toggleon)
                playerselectbox(self, event)
                playercoin(self, event)

            else:
                event.widget.var.set(0)
                event.widget.config(image = self.toggleoff)
                self.canvas.delete('p{}'.format(event.widget.slot))

        #button widget creations
        backbutton = Button(self,
                            image = self.backimage, bd = 0, command = back)
        self.canvas.create_window((720, 65), window = backbutton)
        toggle_xpos = 90; toggle_ypos = 335
        for slot in range(1,5):
            toggle = BooleanVar(self)
            button = Checkbutton(self, indicatoron = False,
                                 image = self.toggleoff, borderwidth = 0)
            button.var = toggle
            button.slot = slot
            button.bind('<Button-1>', buttontoggle)
            self.canvas.create_window((toggle_xpos, toggle_ypos),
                                      window = button,
                                      tag = 'p{}toggle'.format(slot))
            toggle_xpos += 175

        # this next block somehow fails if placed in resourcing block above
        self.pselectbackground = PhotoImage(file = 'playerselect.png')
        self.canvas.create_image((400,300), image = self.pselectbackground)

        #to do:
        #   -provide an option for adding a completely new player
        #   -instantiate player classes from given names

    def recordingscreen(self):

        '''Possibly integrate playerselection and recording.'''

        pass

    def statdisplay(self):

        '''Display session and all-time stats.'''

        pass

    def statanalysis(self):

        '''In depth analysis.'''

        pass

    def guiquit(self):

        '''Clean up and close.'''

        pass

if __name__ == '__main__':

    root = Tk()
    retardedlifeless = Smash(root)
    retardedlifeless.pack()
    root.mainloop()

##if __name__ == '__main__':
##
##    try:
##        root = Tk()
##        retardedlifeless = Smash(root)
##        retardedlifeless.pack()
##        root.mainloop()
##
##    except Exception as ex:
##
##        print(ex)
##        input()


# Echo client program
import socket
import sys
import signal
import sys
def signal_handler(signal, frame):
        # close the socket here
        print("exiting")
        s.close()
        sys.exit(0)

HOST = '172.22.94.48'    # The remote host
PORT = 1234          # The same port as used by the server
signal.signal(signal.SIGINT, signal_handler)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))

    while True:
        for line in sys.stdin:
            print(line, end='')
            s.sendall(str.encode(line))


# -*- coding: utf-8 -*-
"""
Created on Tue May 26 13:17:06 2020

@author: Chandan
"""

import engine as en
from engine import Engine, wait_for_command
import query
import process

ass = Engine()
ass.engine_rate(210)

def listen():

    command = en.wait_for_command()
    try:
        result = None
        if query.close(command.lower()):
            flag_close = False
            ass.speak("are you sure sir? like, its ok ill wait for your command")
            confirm = en.wait_for_command()
            if query.confirm(confirm.lower()):
                ass.speak("fine sir! please call me if you need any assisstent")
                result = "close"
            if "ok" == command.lower():
                ass.speak("i am always hear for you sir")
            return result
        elif query.read(command.lower()):
            flag_read = True
            ass.speak("for you sir... always")
            run_jarvis()
        else:
            return None
    except:
        return None

def run_jarvis():
    result = None
    query = wait_for_command()
    result = process.take_jarvis_query(query.lower())
    if result!=None:
        ass.speak(result)
    ass.speak("any thing else sir")
    query = en.wait_for_command()
    if "no" == query.lower():
        ass.speak("ok sir")
    if "yes" == query.lower():
        ass.speak("cammand me sir")
        run_jarvis()
    ass.engine_rate(210)

if __name__ == "__main__":
    ass.speak("Initializing jarvis...")
    while True:
        res = listen()
        if res == "close":
            break


import random

def seq_to_dist(seq):
    """Creates an empirical distribution of elements given a sequence.

    Distribution is represented as a dictionary where key is an element and value is the
    number of such elements.
    """
    dist={}
    for item in seq:
        dist[item]=dist.get(item,0)+1
    return dist

def dist_to_seq(dist):
    """Creates a sequence with arbitrary order of elements from an empirical distribution of elements.
    """
    seq=[]
    for item,num in dist.items():
        seq.extend(num*[item])
    seq.sort(reverse=True)
    return seq

class BurstTree(object):
    def __init__(self):
        """Construct an empty burst tree."""
        #We only store the splits in the tree and no information on the IETs
        #Each split is a tuple of form (left,right) where left is the index of the
        #split on the left and right is the index of the split on the right. If left
        #or right bracnh is not a split but a leaf then they are set to None.
        #For example:
        # splits = [(1,None),(None,None)] would correspond to  the following tree:
        #         0
        #       /   \
        #      1    leaf
        #    /   \
        # leaf   leaf
        self.splits=[]

    def decompose(self,timeseq):
        """Decomposes the time sequence into burst tree and IET distribution."""
        assert timeseq==sorted(timeseq), "Time sequence needs to be sorted."

        #Find the IETs and build the IET distribution
        iets=[timeseq[i+1]-timeseq[i] for i in range(len(timeseq)-1)]
        iet_dist=seq_to_dist(iets)
        niets=len(iets)

        #Clusters are indexed with their rank-order of the corresponding IETs. Large IET means small index
        #We build a mapping from cluster index to iet index and another one from iet index to cluster index
        cluster_to_iet_index = list(map(lambda x:x[0],sorted(enumerate(iets), key= lambda x:-x[1])))
        iet_index_to_cluster=[None]*niets
        for i in range(niets):
            iet_index_to_cluster[cluster_to_iet_index[i]]=i

        #From now on we do not need the iet values
        del iets

        #For merging clusters we need to know the IETs at their borders
        #We make a dict where key is the cluster index and value is tuple giving the IET indices at the
        #left and right borders of the cluster
        cluster_to_left_right_iet={}

        #Go through the clusters in reverse order, i.e., the low IET ones first
        for cluster in reversed(range(niets)):
            iet_index = cluster_to_iet_index[cluster]

            #Left side of the cluster
            if iet_index>0 and iet_index_to_cluster[iet_index-1]>cluster: #merge
                cluster_left=iet_index_to_cluster[iet_index-1]
                #update the cluster of the left-most iet
                if cluster_left in cluster_to_left_right_iet:
                    iet_left=cluster_to_left_right_iet[cluster_left][0]
                else:
                    iet_left=iet_index-1
                iet_index_to_cluster[iet_left]=cluster
            else: #no merge
                cluster_left=None
                iet_left=iet_index

            #Right side of the cluster
            if iet_index<niets-1 and iet_index_to_cluster[iet_index+1]>cluster: #merge
                cluster_right=iet_index_to_cluster[iet_index+1]
                #update the cluster of the right-most iet
                if cluster_right in cluster_to_left_right_iet:
                    iet_right=cluster_to_left_right_iet[cluster_right][1]
                else:
                    iet_right=iet_index+1
                iet_index_to_cluster[iet_right]=cluster
            else: #no merge
                cluster_right=None
                iet_right=iet_index

            #update left-right map and the clusters where the IETs belong to
            cluster_to_left_right_iet[cluster]=(iet_left,iet_right)
            iet_index_to_cluster[iet_left]=cluster
            iet_index_to_cluster[iet_right]=cluster

            #Add a new split, we add in reverse order, and reverse the splits at the end
            self.splits.append((cluster_left,cluster_right) )

        self.splits.reverse() #reverse the splits

        return iet_dist

    def recompose(self,ietdist,firsttime=0):
        """Recompose this tree structure and the given inter-event time distribution (ietdist).

        Parameters
        ----------
        ietdist : Dict
           The distribution of inter-event times: a dictionary with keys as IETs and values
           as counts of those IETs.
        firsttime: int, optional
           The time of the first event in the recomposed time sequences

        Returns
        -------
        list
           The reconstructed time sequence of the events.
        """
        ietseq=dist_to_seq(ietdist)

        seq=[firsttime]
        for index in self.traverse_from_left():
            iet=ietseq[index]
            seq.append(seq[-1]+iet)
        return seq

    def traverse_from_left(self, next=0):
        """A generator for traversing this tree from the left.
        """
        left = self.splits[next][0]
        right = self.splits[next][1]
        if left!=None:
            yield from self.traverse_from_left(left)
        yield next
        if right != None:
            yield from self.traverse_from_left(right)

    def number_of_leaves(self):
        return len(self.splits)+1

    def burst_sizes(self):
        """Returns the burst sizes for all the splits.
        """
        b=[None]*len(self.splits)
        for i in reversed(range(len(self.splits))):
            left=self.splits[i][0]
            right=self.splits[i][1]

            nleft=1 if left==None else b[left]
            nright=1 if right==None else b[right]

            b[i]=nleft+nright

        return b

def test_decomposition(size,ietrange=10**8,verbose=True):
    #Generate a random time sequence
    if verbose: print("Generating a random time sequence with", size, "events.")
    seq=sorted(random.sample(range(ietrange),size))

    #Decompose the time sequences
    if verbose: print("Decomposing the time sequence.")
    tree=BurstTree()
    iet_dist=tree.decompose(seq)
    first=seq[0] #save the first event time, as this information is not in the IET or the tree

    #Make sure that we can recompose the time sequence just with the tree, IET distribution and the first IET
    if verbose: print("Recomposing the time sequence.")
    recomposed = tree.recompose(iet_dist,first)
    if verbose: print("Comparing the original time sequence and the recomposed one...")
    assert seq==recomposed
    if verbose: print("Success!")

if __name__ == "__main__":
    test_decomposition(10**6)


import random as rnd
import lib.list_functions as lfunc

def sum_of_inbetweens(arr: list):
    sum_val = 0
    index_0 = -1
    index_1 = -1

    for c in range(len(arr)):
        if arr[c] > 0 and index_0 == -1:
            index_0 = c

        if arr[c] > 0 and index_0 != -1:
            index_1 = c

    start = (index_0 if index_0 < index_1 else index_1) + 1
    stop = index_1 if index_1 > index_0 else index_0

    for c in range(start, stop):
        sum_val += arr[c]

    return sum_val

def zero_first_sort(arr: list):
    zeros = [i for i in arr if i == 0]
    not_zeros = [i for i in arr if i != 0]

    return zeros + not_zeros

def main():
    n = int(input("Enter the amount of numbers [n value]: "))
    zeros_amount = rnd.randint(-1, n // 2) + 1

    if n <= 0:
        print("n value must be greater than 0")
        return

    arr = [round(rnd.uniform(-100, 100), 2) for i in range(n)]

    for i in range(zeros_amount):
        arr[rnd.randint(0, n - 1)] = 0

    print("[")
    for elem in arr:
        print("    ", elem, sep="")
    print("]")

    print("Min", lfunc.min(arr), "at", lfunc.min_index(arr))
    print("Sum of inbetweens", sum_of_inbetweens(arr))
    print("Zeros first sorted array:", zero_first_sort(arr))

if __name__ == "__main__":
    main()


import os
import subprocess
import sys

def main():
    """Entry point for the application script"""
    here = os.path.abspath(os.path.dirname(__file__))
    app_file = os.path.join(here, "app.py")
    os.environ["FLASK_APP"] = app_file
    os.environ["FLASK_ENV"] = "development"
    command = "python -m flask run"
    command = command.replace("python", sys.executable)
    print(" --- Interactive Bayesian Optimisation ---")
    print(" * Please, open your browser at the address shown below")
    subprocess.run(command.split(" "))

if __name__ == '__main__':
    main()


def get_average():
    with open("data.txt", "r") as file:
        vals = file.readlines()

    temps = vals[1:]
    temps = [float(i) for i in temps]
    avg = sum(temps) / len(temps)

    return avg

average = get_average()
print(average)


# -*- coding: utf-8 -*-
"""
Created on Sun Jan  6 14:41:16 2019

@author: E442282
"""

import argparse
import sys
import cv2
import os

def getzoomout(image):

    row, col= image.shape[:2]
    bordersize=100
    border=cv2.copyMakeBorder(image, top=bordersize, bottom=bordersize, left=bordersize,
                              right=bordersize, borderType= cv2.BORDER_CONSTANT,
                              value=[0,255,0] )
    return border

def video2images(inputvideofile,outputimagesfolder):
       vidcap = cv2.VideoCapture(inputvideofile)
       returnvalue,image = vidcap.read() #returns true/false and an image
       count = 0
       while returnvalue:
         returnvalue,image = vidcap.read()
         if returnvalue==False:
             break
         filename=os.path.join(outputimagesfolder,"image%d.jpg" % count)
#         image=getzoomout(image)
         cv2.imwrite(filename, image)     # save frame as JPEG/png file
         print('Read next frame: ', returnvalue)
         cv2.imshow('video',image)

         if (cv2.waitKey(1) & 0xFF) == ord('q'): # Hit `q` to exit\
             break

         count += 1
       vidcap.release()
       cv2.destroyAllWindows()
       print('\nCompleted Saving video frames to',outputimagesfolder)

def main(argv):
   ap = argparse.ArgumentParser()
   ap.add_argument("-i", "--input", required=True,  help="Input video file ")
   ap.add_argument("-o", "--output", required=False, default='.', help="output images directory")
   args = vars(ap.parse_args())

   inputvideofile = args['input']
   outputimagesfolder = args['output']

#   inputvideofile = 'popeye3.mp4'
#   outputimagesfolder=r' C:\SAI\IIIT\2019_Spring\images'
   video2images(inputvideofile,outputimagesfolder)

if __name__ == "__main__":
   main(sys.argv[1:])


"""users

Revision ID: ecd26b70c923
Revises: 4c3ae4a9abc1
Create Date: 2023-07-10 18:49:50.609928

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'ecd26b70c923'
down_revision = '4c3ae4a9abc1'
branch_labels = None
depends_on = None

def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('user',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('email', sa.String(), nullable=False),
    sa.Column('hashed_password', sa.String(), nullable=False),
    sa.Column('fio', sa.String(), nullable=False),
    sa.Column('is_active', sa.Boolean(), nullable=False),
    sa.Column('is_verified', sa.Boolean(), nullable=False),
    sa.Column('is_superuser', sa.Boolean(), nullable=False),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_user_email'), 'user', ['email'], unique=True)
    op.create_index(op.f('ix_user_id'), 'user', ['id'], unique=False)
    op.create_table('refresh_session',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('refresh_token', sa.UUID(), nullable=False),
    sa.Column('expires_in', sa.Integer(), nullable=False),
    sa.Column('created_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.Column('user_id', sa.UUID(), nullable=False),
    sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_refresh_session_id'), 'refresh_session', ['id'], unique=False)
    op.create_index(op.f('ix_refresh_session_refresh_token'), 'refresh_session', ['refresh_token'], unique=False)
    # ### end Alembic commands ###

def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f('ix_refresh_session_refresh_token'), table_name='refresh_session')
    op.drop_index(op.f('ix_refresh_session_id'), table_name='refresh_session')
    op.drop_table('refresh_session')
    op.drop_index(op.f('ix_user_id'), table_name='user')
    op.drop_index(op.f('ix_user_email'), table_name='user')
    op.drop_table('user')
    # ### end Alembic commands ###


import pandas as pd
import numpy as np
import os
from scipy import stats
import matplotlib.pyplot as plt

def to_print(data): #print 10 grayscale matrix

  for index in range(10):
    title = "class: "+ str(index)
    new_data = data[np.where(data[:,1] == index)]
    rows = np.size(new_data, 0)
    new_data[:,0] = np.arange(rows)
    selected = np.random.randint(0, rows, 1)
    chosed = new_data[selected[0],]
    matrix = np.reshape(chosed[2:], (-1, 28))
    plt.imshow(matrix, cmap="gray")
    plt.title(title)
    # plt.show()
    plt.savefig(os.sep.join([os.path.expanduser('~'), 'Desktop', str(index+10000)+'.png']))

def to_color(data):

  plt.clf()
  rows = np.size(data, 0)
  row_index = np.random.randint(0, rows, 1000)
  label = np.take(data[:,1], row_index)
  chosed_x = np.take(data[:,2], row_index)
  chosed_y = np.take(data[:,3], row_index)
  pic = plt.scatter(chosed_x, chosed_y, c = label)
  # plt.colorbar(pic)
  plt.title("1000 examples")
  # plt.show()
  plt.savefig(os.sep.join([os.path.expanduser('~'), 'Desktop', 'gg'+'.png']))

def main():

  np.random.seed(0)
  input_df = "digits-raw.csv"
  other_df = "digits-embedding.csv"
  df = pd.read_csv(input_df)
  df2 = pd.read_csv(other_df)
  data = df.values
  data2 = df2.values
  to_print(data)
  to_color(data2)

if __name__== "__main__":
  main()


import os
import cv2
import numpy as np
import json
import copy
import pycocotools
from pycocotools.coco import COCO
from .dataset import DetDataset
from ppdet.core.workspace import register, serializable

@serializable
class Pose3DDataset(DetDataset):
    """Pose3D Dataset class.

    Args:
        dataset_dir (str): Root path to the dataset.
        anno_list (list of str): each of the element is a relative path to the annotation file.
        image_dirs (list of str): each of path is a relative path where images are held.
        transform (composed(operators)): A sequence of data transforms.
        test_mode (bool): Store True when building test or
            validation dataset. Default: False.
        24 joints order:
        0-2: 'R_Ankle', 'R_Knee', 'R_Hip',
        3-5:'L_Hip', 'L_Knee', 'L_Ankle',
        6-8:'R_Wrist', 'R_Elbow', 'R_Shoulder',
        9-11:'L_Shoulder','L_Elbow','L_Wrist',
        12-14:'Neck','Top_of_Head','Pelvis',
        15-18:'Thorax','Spine','Jaw','Head',
        19-23:'Nose','L_Eye','R_Eye','L_Ear','R_Ear'
    """

    def __init__(self,
                 dataset_dir,
                 image_dirs,
                 anno_list,
                 transform=[],
                 num_joints=24,
                 test_mode=False):
        super().__init__(dataset_dir, image_dirs, anno_list)
        self.image_info = {}
        self.ann_info = {}
        self.num_joints = num_joints

        self.transform = transform
        self.test_mode = test_mode

        self.img_ids = []
        self.dataset_dir = dataset_dir
        self.image_dirs = image_dirs
        self.anno_list = anno_list

    def get_mask(self, mvm_percent=0.3):
        num_joints = self.num_joints
        mjm_mask = np.ones((num_joints, 1)).astype(np.float)
        if self.test_mode == False:
            pb = np.random.random_sample()
            masked_num = int(
                pb * mvm_percent *
                num_joints)  # at most x% of the joints could be masked
            indices = np.random.choice(
                np.arange(num_joints), replace=False, size=masked_num)
            mjm_mask[indices, :] = 0.0

        mvm_mask = np.ones((10, 1)).astype(np.float)
        if self.test_mode == False:
            num_vertices = 10
            pb = np.random.random_sample()
            masked_num = int(
                pb * mvm_percent *
                num_vertices)  # at most x% of the vertices could be masked
            indices = np.random.choice(
                np.arange(num_vertices), replace=False, size=masked_num)
            mvm_mask[indices, :] = 0.0

        mjm_mask = np.concatenate([mjm_mask, mvm_mask], axis=0)
        return mjm_mask

    def filterjoints(self, x):
        if self.num_joints == 24:
            return x
        elif self.num_joints == 14:
            return x[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 18], :]
        elif self.num_joints == 17:
            return x[
                [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 18, 19], :]
        else:
            raise ValueError(
                "unsupported joint numbers, only [24 or 17 or 14] is supported!")

    def parse_dataset(self):
        print("Loading annotations..., please wait")
        self.annos = []
        im_id = 0
        for idx, annof in enumerate(self.anno_list):
            img_prefix = os.path.join(self.dataset_dir, self.image_dirs[idx])
            dataf = os.path.join(self.dataset_dir, annof)
            with open(dataf, 'r') as rf:
                anno_data = json.load(rf)
                annos = anno_data['data']
                new_annos = []
                print("{} has annos numbers: {}".format(dataf, len(annos)))
                for anno in annos:
                    new_anno = {}
                    new_anno['im_id'] = im_id
                    im_id += 1
                    imagename = anno['imageName']
                    if imagename.startswith("COCO_train2014_"):
                        imagename = imagename[len("COCO_train2014_"):]
                    elif imagename.startswith("COCO_val2014_"):
                        imagename = imagename[len("COCO_val2014_"):]
                    imagename = os.path.join(img_prefix, imagename)
                    if not os.path.exists(imagename):
                        if "train2017" in imagename:
                            imagename = imagename.replace("train2017",
                                                          "val2017")
                            if not os.path.exists(imagename):
                                print("cannot find imagepath:{}".format(
                                    imagename))
                                continue
                        else:
                            print("cannot find imagepath:{}".format(imagename))
                            continue
                    new_anno['imageName'] = imagename
                    new_anno['bbox_center'] = anno['bbox_center']
                    new_anno['bbox_scale'] = anno['bbox_scale']
                    new_anno['joints_2d'] = np.array(anno[
                        'gt_keypoint_2d']).astype(np.float32)
                    if new_anno['joints_2d'].shape[0] == 49:
                        #if the joints_2d is in SPIN format(which generated by eft), choose the last 24 public joints
                        #for detail please refer: https://github.com/nkolot/SPIN/blob/master/constants.py
                        new_anno['joints_2d'] = new_anno['joints_2d'][25:]
                    new_anno['joints_3d'] = np.array(anno[
                        'pose3d'])[:, :3].astype(np.float32)
                    new_anno['mjm_mask'] = self.get_mask()
                    if not 'has_3d_joints' in anno:
                        new_anno['has_3d_joints'] = int(1)
                        new_anno['has_2d_joints'] = int(1)
                    else:
                        new_anno['has_3d_joints'] = int(anno['has_3d_joints'])
                        new_anno['has_2d_joints'] = int(anno['has_2d_joints'])
                    new_anno['joints_2d'] = self.filterjoints(new_anno[
                        'joints_2d'])
                    self.annos.append(new_anno)
                del annos

    def __len__(self):
        """Get dataset length."""
        return len(self.annos)

    def _get_imganno(self, idx):
        """Get anno for a single image."""
        return self.annos[idx]

    def __getitem__(self, idx):
        """Prepare image for training given the index."""
        records = copy.deepcopy(self._get_imganno(idx))
        imgpath = records['imageName']
        assert os.path.exists(imgpath), "cannot find image {}".format(imgpath)
        records['image'] = cv2.imread(imgpath)
        records['image'] = cv2.cvtColor(records['image'], cv2.COLOR_BGR2RGB)
        records = self.transform(records)
        return records

    def check_or_download_dataset(self):
        alldatafind = True
        for image_dir in self.image_dirs:
            image_dir = os.path.join(self.dataset_dir, image_dir)
            if not os.path.isdir(image_dir):
                print("dataset [{}] is not found".format(image_dir))
                alldatafind = False
        if not alldatafind:
            raise ValueError(
                "Some dataset is not valid and cannot download automatically now, please prepare the dataset first"
            )


import matplotlib.pyplot as plt
import csv

x = []
y = []

with open('temperature.csv','r') as csvfile:
    plots = csv.reader(csvfile, delimiter = ';')

    for row in plots:
        x.append(row[2])
        y.append(row[1])

# plt.bar(x, y, color = 'g', width = 0.72, label = "Temperature")
# plt.bar(x, y, color = 'g', width = 0.72, label = "Temperature")
plt.plot(x, y, color = 'g', linestyle = 'solid', marker = 'o',label = "Temperature")
plt.xlabel('Time')
plt.ylabel('Value')
plt.title('Temperature')
plt.legend()
plt.show()


import csv
import sqlite3

if __name__ == '__main__':
  with open('DADOS_ABERTOS_MEDICAMENTOS.csv', 'r', newline='', encoding='latin-1') as medicines:
    medicines_csv = csv.DictReader(medicines, delimiter=';', quotechar='\n')
    nome_length = 0
    for index, row in enumerate(medicines_csv):
      print(row['NOME_PRODUTO'], row['EMPRESA_DETENTORA_REGISTRO'])
      sqlite_path = '../backend/tmp/db.sqlite3'
      sqlite_connection = sqlite3.connect(sqlite_path)
      query = 'INSERT INTO medicamentos (id, nome, farmaceutica) VALUES (NULL, ?, ?)'
      sqlite_connection.execute(query, (row['NOME_PRODUTO'], row['EMPRESA_DETENTORA_REGISTRO']))
      sqlite_connection.commit()
    sqlite_connection.close()


# 1128. 等价多米诺骨牌对的数量
# 给你一个由一些多米诺骨牌组成的列表 dominoes。

# 如果其中某一张多米诺骨牌可以通过旋转 0 度或 180 度得到另一张多米诺骨牌，我们就认为这两张牌是等价的。

# 形式上，dominoes[i] = [a, b] 和 dominoes[j] = [c, d] 等价的前提是 a==c 且 b==d，或是 a==d 且 b==c。

# 在 0 <= i < j < dominoes.length 的前提下，找出满足 dominoes[i] 和 dominoes[j] 等价的骨牌对 (i, j) 的数量。

# 来源：力扣（LeetCode）
# 链接：https://leetcode-cn.com/problems/number-of-equivalent-domino-pairs
# 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
import collections
class Solution:
    def numEquivDominoPairs(self, dominoes: list) -> int:
        dominDict=collections.defaultdict(int)
        ans = 0
        for v1,v2 in dominoes:
            key = None
            if v1<=v2:
                key=(v1,v2)
            else:
                key=(v2,v1)
            ans+=dominDict[key]
            dominDict[key]+=1
        return ans


#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# lock_deadlock.py
#
# An example of write code acquires more than one mutex lock at time

import threading

X = 0  # A shared Value
Y = 0
COUNT = 10000000
# Primarily used to synchronize threads so that only one thread can make modifications to shared data at any given time.
X_Lock = threading.Lock()  # A lock for synchronizing access to X
Y_Lock = threading.Lock()

def addition():
    global X, Y
    for i in range(COUNT):
        X_Lock.acquire()  # Acquire the lock
        # Example critical section
        try:
            X += 1  # Critical Section
            Y_Lock.acquire()
            try:
                Y += 1
            finally:
                Y_Lock.release()
        finally:
            X_Lock.release()  # Release the lock

def subtraction():
    global X, Y
    for i in range(COUNT):
        Y_Lock.acquire()
        try:
            Y -= 1
            X_Lock.acquire()
            try:
                X -= 1
            finally:
                X_Lock.release()
        finally:
            Y_Lock.release()

t1 = threading.Thread(target=subtraction)
t2 = threading.Thread(target=addition)

t1.start()
t2.start()

t1.join()
t2.join()

print(X,Y)

"""
    Only one thread can successfully acquire the lock at any given time
    If another thread tries to acquire the lock when its already in use. it gets blocked until the lock is released.

"""