import matplotlib.pyplot as plt
import read_csv as rcsv

def get_values_labels(countries_list):

  labels = list(filter(lambda count: int(count["Rank"]) < 10, countries_list))
  labels = list(map(lambda count: count["Country/Territory"], labels))

  values = list(filter(lambda count: int(count["Rank"]) < 10, countries_list))
  values = list(map(lambda count: count["2022 Population"], values))

  return labels, values

def show_population_countries_bars(countries_list):
  fig, ax = plt.subplots()

  values = []
  labels = []

  labels, values = get_values_labels(countries_list)

  ax.bar(labels, values, color = "#027a6a", width = 0.8)
  plt.show()

def show_population_countries_pie(countries_list):
  fig, ax = plt.subplots()

  values = []
  labels = []
  explode = [0, 0, 0.2, 0, 0, 0, 0, 0, 0]

  labels, values = get_values_labels(countries_list)

  ax.pie(values, labels=labels, explode = explode)
  ax.axis("equal")
  plt.legend(title = "Most Population by 2022:")
  plt.show()

if __name__ == "__main__":
  popl_list = rcsv.read_csv("./app/data.csv")
  # Graph by area
  choice = 0
  while choice != 1 and choice != 2:
    choice = int(
      input("What do you want to see?\n| 1 |  Bar Chart\n| 2 |  Pie Chart\n"))
    if (choice != 1 and choice != 2):
      print("| X | SELECT A VALID OPTION | X |")

  if choice == 1:
    show_population_countries_bars(popl_list)
  else:
    show_population_countries_pie(popl_list)


from setuptools import setup, find_packages
from artwork import __version__

def read(file):
    with open(file, 'r') as f:
        return f.read()

setup(
    name='django-artwork',
    version='.'.join(str(x) for x in __version__),
    description='A package for the Django Framework that provides functionality for associating multiple images with a model',
    long_description=read('README.rst'),
    long_description_content_type='text/x-rst',
    packages=find_packages(),
    install_requires=[
        'django>=3',
        'Pillow>=7',
    ],
    python_requires='>=3.6',
    author='Gerard Krijgsman',
    author_email='python@visei.com',
    url='https://github.com/ghdpro/django-artwork',
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Environment :: Web Environment',
        'Framework :: Django :: 3.0',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python :: 3.7',
        'Programming Language :: Python :: 3.8',
        'Programming Language :: Python :: 3 :: Only',
    ]
)


from bs4 import BeautifulSoup
import requests
from util import init_logger, Logger, log_args
import logging
import argparse
import xml.etree.ElementTree as ET
import config
import time
import random
import pickle as pkl

def _build_parser():
    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument('--log_level',
                        help=str([value for key, value in logging._levelToName.items()]) + " ( default : INFO )",
                        default=logging._levelToName[logging.INFO])
    # parser.add_argument('--job_type', help=str([value for value in JOB_TYPE_LIST]), required=True)

    return parser

def _indent(elem, level=1):
    i = "\n" + level * "  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            _indent(elem, level + 1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

'''
    h2 tag + class = jobtitle
'''

def _get_html(url):
    _html = ""
    resp = requests.get(url)
    if resp.status_code == 200:
        _html = resp.text
    return _html

'''
    각 페이지에서 채용 공고의 Key들을 불러옴
'''

def get_emp_key(url,index):
    # 해당 페이지에 "다음" 글씨가 있는지 여부
    # next_page_exist=True

    req_url = url +"&start=" + str(index * 50)
    Logger.debug("get_emp_key request URL = " + url)
    html = _get_html(url)

    soup = BeautifulSoup(html, 'html.parser')

    job_key_list = []

    # a_tag 중 채용공고에 대한 Tag를 찾는 방식
    # -> 일반 채용공고 뿐만 아니라 유료 광고도 불러옴 (일반 채용 공고 10개 + 유료 광고 6개)
    for a_tag in soup.find_all("a", {"data-tn-element": "jobTitle"}):
        split_id = a_tag.parent["id"].split("_")

        id_type = split_id[0]
        emp_id = split_id[1]

        job_key_list.append(emp_id)

    return job_key_list

'''
    API를 이용하여 job key 가져오기
'''

def get_emp_key_from_api(location, index):
    # api는 최대 25개 까지 1번에 읽기 가능...
    url = config.INDEED_API_SEARCH_URL + "&l=" + location + "&start=" + str(index * 25)

'''
    채용 공고 내용 불러오기

    # Return
        xml : 채용 공고 내용을 xml 형태로 구성

'''

def get_job_detail(key):
    job_dict = {}
    req_url = config.INDEED_JOB_SEARCH_URL + key
    html = _get_html(req_url)
    soup = BeautifulSoup(html, 'html.parser')

    # job header 내용 Parsing
    job_header = soup.find("div", {"data-tn-component": "jobHeader"})
    Logger.debug("request URL =" + req_url)
    # print(job_header)

    job_title = job_header.find("b", {"class": "jobtitle"}).contents[0].get_text()
    company = job_header.find("span", {"class": "company"}).get_text()
    location = job_header.find("span", {"class": "location"}).get_text()
    cmp_description = ""

    soup.find("span", {"class": "company"})
    # company description이 없는 페이지도 있음
    try:
        cmp_description = soup.find("div", {"class": "cmp_description"}).get_text()
    except AttributeError:
        Logger.debug("cmp_description does not exists")

    job_summary = soup.find("span", {"id": "job_summary"}).get_text()

    Logger.debug("jobtitle = " + job_title)
    Logger.debug("company = " + company)
    Logger.debug("location = " + location)
    Logger.debug("cmp_description = " + cmp_description)
    Logger.debug("job_summary = " + job_summary)

    xml = ET.Element("root")
    ET.SubElement(xml, "job_key").text = key
    ET.SubElement(xml, "jobtitle").text = job_title
    ET.SubElement(xml, "company").text = company
    ET.SubElement(xml, "location").text = location
    ET.SubElement(xml, "cmp_description").text = cmp_description
    ET.SubElement(xml, "job_summary").text = job_summary

    Logger.debug(ET.tostring(xml, encoding="utf=8"))
    _indent(xml)

    return xml

def _write_xml(xml, file_path):
    ET.ElementTree(xml).write(file_path, encoding="UTF-8")

# 0.1~sec초 간격으로 randomly sleep
def rand_sleep(sec):
    sleep_len = random.uniform(0.1, sec)
    Logger.debug("sleep " + str(sleep_len) + "sec")
    time.sleep(sleep_len)

'''
    url_list에 해당하는
    채용 공고를 읽어와서 xml로 씀
'''
def write_emp_detail(url_list,max_sleep):

    crawling_data_num = 0
    start_time = time.time()

    # job detail을 불러와 xml파일로 쓴 job key들
    key_dict = {}

    # 요청시 실패한 key list 저장
    failed_key_list = []
    url_index=0
    # URL 당 최대 1000개의 job detail적음
    for url in url_list:
        Logger.info(str(url_index+1) + "/"+str(len(url_list))+" job list request URL = "+url.replace("\n",""))
        url_index+=1
        job_key_list=[]

        # 채용 공고 목록 페이지에서 job key들을 받아옴
        # 50개씩 최대 20번 불러옴
        try:
            req_url = config.INDEED_URL+url+"&limit=50"
            prev_key_list=[]
            for index in range(20):
                cur_key_list = get_emp_key(req_url,index)
                # 페이지 index가 넘어간 경우 계속 똑같은 list를 반복하므로 이 경우 더 이상 job key를 받아오지 않음
                if prev_key_list==cur_key_list:
                    break
                else:
                    prev_key_list=cur_key_list
                job_key_list=job_key_list+cur_key_list
                rand_sleep(max_sleep)
        except:
            continue

        Logger.info("job key list length = "+str(len(job_key_list)))

        not_exist_cnt = 0

        # job key들의 채용 공고 detail 받아옴
        for key in job_key_list:
            # 해당 key에 대해서 아직 Crwaling 안한 경우
            # Crawling 수행하고 xml 파일 적음
            if not key in key_dict:
                key_dict[key] = True
                try:
                    xml = get_job_detail(key)
                except:
                    Logger.warn(key + " parsing failed")
                    failed_key_list.append(key)
                    rand_sleep(max_sleep)
                    continue

                file_path = config.JOB_DETAIL_FILE_PATH + key + ".xml"
                _write_xml(xml, file_path)
                Logger.debug(file_path+" is written")
                not_exist_cnt += 1
                crawling_data_num += 1
                rand_sleep(max_sleep)
            else:
                Logger.debug("key " + key + " already exist")

        # url
        Logger.info("total data num =" + str(crawling_data_num) + " added data num =" + str(
                            not_exist_cnt) + " elapsed time = " + str(time.time() - start_time)+"\n")

        # 현재까지 가져온 모든 key들을 pkl로 저장
        key_dict_path = "key_dict.pkl"
        # 적은 job key의 dictionary를 pickle 파일로 저장
        with open(key_dict_path, "wb") as f:
            pkl.dump(key_dict, f)

        Logger.info(key_dict_path + "has been written")

                        # if not_exist_cnt==0:
                        #     Logger.info("threre are not any employment not written")
                        #     break

# if __name__ == "__main__":
#
#     parser = _build_parser()
#     FLAGS = parser.parse_args()
#     init_logger(logging._nameToLevel[FLAGS.log_level])
#     log_args(FLAGS)
#
#     job_type = FLAGS.job_type
#
#     key_dict = {}
#
#     # 요청시 실패한 key list 저장
#     failed_key_list = []
#
#     index = 0
#     crawling_data_num = 0
#
#     start_time = time.time()
#
#     while True:
#
#         Logger.info(str(index) + "th job list request")
#         job_key_list = get_emp_key(job_type, 25)
#         # job_key_list = get_emp_key(job_type,index)
#
#         rand_sleep(MAX_SLEEP_SEC)
#         index += 1
#
#         not_exist_cnt = 0
#         for key in job_key_list:
#             # 해당 key에 대해서 아직 Crwaling 안한 경우
#             # Crawling 수행
#             if not key in key_dict:
#                 key_dict[key] = True
#                 try:
#                     xml = get_job_detail(key)
#                 except:
#                     Logger.warn(key + " parsing failed")
#                     failed_key_list.append(key)
#                     rand_sleep(MAX_SLEEP_SEC)
#                     continue
#
#                 file_path = XML_FILE_PATH + key + ".xml"
#                 _write_xml(xml, file_path)
#                 not_exist_cnt += 1
#                 crawling_data_num += 1
#                 rand_sleep(MAX_SLEEP_SEC)
#
#         Logger.info("total data num =" + str(crawling_data_num) + " added data num =" + str(
#             not_exist_cnt) + " elapsed time = " + str(time.time() - start_time))
#
#         # if not_exist_cnt==0:
#         #     Logger.info("threre are not any employment not written")
#         #     break
#
#     # 실패한 Key들 적음
#     with open("failed_key_list.txt", "w") as f:
#         f.write("\n".join(failed_key_list))
#
#

        # html = _get_html(INDEED_QUERY_URL)
        # soup = BeautifulSoup(html, 'html.parser')
        # result = soup.find_all("h2")
        # result = soup.h2['job']
        # # print(soup)
        # print(result)


import os
import pandas
import re
from urllib.request import urlopen
from urllib.parse import urlparse
from bs4 import BeautifulSoup
from nltk.stem.wordnet import WordNetLemmatizer

def parse_page(filename,page):

    soup = BeautifulSoup(urlopen(filename), 'html.parser')
    lmtzr = WordNetLemmatizer()

    keyword = soup.find('input',{'id':'lst-ib'}).get('value').lower()
    keyword_token = list(set([lmtzr.lemmatize(token) for token in keyword.split(' ')]))

    combined_result = []

    search_results = soup.find_all('div', {'class': 'g'})
    position = 0
    for search_result in search_results:

        ## Position of the search result in this page
        position += 1

        ## Title flag and keyword density in title
        title = search_result.find('div',{'class':'rc'}).find('h3',{'class':'r'}).get_text()
        title_token = re.sub('[^a-zA-Z0-9\'\.\n]+', ' ', title.lower()).split()
        title_token = [lmtzr.lemmatize(token) for token in title_token]

        title_flag_count = list(filter(lambda token:token in title_token, keyword_token))
        title_flag = 1 if len(title_flag_count) == len(keyword_token) else 0
        title_density_count = sum([keyword_token.count(token) for token in title_token])
        title_density = round(title_density_count / len(title_token),4)

        ## URL flag and keyword density in URL
        url = search_result.find('div',{'class':'rc'}).find('h3',{'class':'r'}).find('a').get('href')

        url_path_token = re.sub('[^a-zA-Z0-9\']+', ' ', urlparse(url).path).lower().split()
        url_path_token = [lmtzr.lemmatize(token) for token in url_path_token]
        url_netloc_token = re.sub('[^a-zA-Z0-9\']+', ' ', urlparse(url).netloc).lower().split()
        url_netloc_token = [lmtzr.lemmatize(token) for token in url_netloc_token]
        url_query_token = re.sub('[^a-zA-Z0-9\']+', ' ', urlparse(url).query).lower().split()
        url_query_token = [lmtzr.lemmatize(token) for token in url_query_token]
        url_flag_count = list(filter(lambda token:token in url_path_token+url_netloc_token+url_query_token,keyword_token))
        url_flag = 1 if len(url_flag_count) == len(keyword_token) else 0

        url_density_count = sum([keyword_token.count(token) for token in url_path_token+url_netloc_token+url_query_token])
        url_density = round(url_density_count / (len(url_path_token)+len(url_netloc_token)+len(url_query_token)) ,4)

        ## Meta description and keyword density in meta description
        meta = search_result.find('div',{'class':'rc'}).find('div',{'class':'s'}).find('span',{'class':'st'})
        meta_description = re.sub('[^a-zA-Z0-9\n\.\']+', ' ',meta.get_text().strip().lower())
        meta_token = [lmtzr.lemmatize(token) for token in meta_description.split()]
        meta_em =  ' '.join([x.get_text() for x in meta.find_all('em')]).split()
        meta_em_token = [lmtzr.lemmatize(token) for token in meta_em]

        meta_flag_count = list(filter(lambda token:token in meta_token,keyword_token))
        meta_flag = 1 if len(meta_flag_count) == len(keyword_token) else 0
        meta_density = round(len(meta_em_token) / len(meta_token), 4)

        ## Append the result to list
        combined_result.append([position,page,title,url,meta_description,title_flag,title_density,url_flag,url_density,meta_flag,meta_density])

    return combined_result

## The filepath where you store your downloaded HTML pages,please change accordingly
filepath = '/Users/apple/Google Drive/Study/NUS/SEM 7/BT4212/Assignment/Assignment 3/SEOtask_final_v2/Example'
all_files = os.listdir(filepath)
output = []
for index, page in enumerate(all_files):
    ## to skip the temp file generated on Mac
    if (page == '.DS_Store') or (".html" not in page):
        continue
    filename = 'file://127.0.0.1' + filepath + '/' + page
    result = parse_page(filename,page)
    output.extend(result)

df = pandas.DataFrame(output, columns =['Position','Filename','Title','URL','Meta','TitleFlag','TitleDensity','URLFlag','URLDensity','MetaFlag','MetaDensity'])
df.to_csv('output.csv',header = True, index = False,encoding = 'utf-8')

print('Output successfully generated!')


"""
Utilities for processing waveforms
"""
import numpy as np
from scipy import signal

from obspy import Stream
from obspy.geodetics import gps2dist_azimuth
from pysep import logger
from pysep.utils.fmt import get_codes

def format_streams_for_rotation(st):
    """
    ObsPy requires specific channel naming to get stream rotation working.
    Comb through the stream and check that this is correct before passing
    stream to rotation

    :type st: obspy.core.stream.Stream
    :param st: Stream to format for rotation
    :rtype st: obspy.core.stream.Stream
    :return st: Stream that has been formatted for rotation
    """
    st_original = st.copy()
    logger.info(f"formatting stream of length {len(st)} for component rotation")
    codes = get_codes(st, choice="channel", suffix="?", up_to=True)

    st_out = Stream()
    for code in codes:
        net, sta, loc, cha = code.split(".")
        st = st_original.select(network=net, station=sta, location=loc,
                                channel=cha).copy()
        missing_vertical, missing_horizontal = _check_component_availability(st)

        if missing_vertical and missing_horizontal:
            logger.debug(f"{code} is missing vertical and at least 1 "
                         f"horizontal, skipping over")
            continue
        elif missing_vertical and not missing_horizontal:
            logger.debug(f"{code} is missing vertical, replacing vertical "
                         f"component with zeros")
            st = _append_null_trace(st, component="Z", cmpaz=0, cmpinc=-90.)
        elif not missing_vertical and missing_horizontal:
            logger.debug(f"{code} is missing at least 1 horizontal component, "
                         f"removing existing horizontal data and writing zeros "
                         f"to North and East components")
            for comp in ["E", "N", "1", "2"]:
                for tr in st.select(component=comp)[:]:
                    st.remove(tr)
                    logger.debug(f"{code} replacing existing component "
                                 f"'{comp}' with zeros")

            st = _append_null_trace(st, component="E", cmpaz=90., cmpinc=0.)
            st = _append_null_trace(st, component="N", cmpaz=0., cmpinc=0.)

        st_out += st

    logger.info(f"stream formatting returned {len(st_out)} traces")

    return st_out

def append_back_azimuth_to_stats(st, inv, event):
    """
    ObsPy rotation requires back azimuth information which is accessed through
    trace.stats.back_azimuth. This function appends back azimuth values to the
    stream by cacluating using metadata from the inventory and event objects.

    .. note::
        This was written and then I realized that `_append_sac_headers_trace`
        already does this, so it is unused, but left incase it's useful later.

    :type st: obspy.core.stream.Stream
    :param st: Stream with missing components
    :type inv: obspy.core.inventory.Inventory
    :param inv: optional user-provided inventory object which will force a
        skip over StationXML/inventory searching
    :type event: obspy.core.event.Event
    :param event: optional user-provided event object which will force a
        skip over QuakeML/event searching
    :rtype: obspy.core.stream.Stream
    :return: stream with back azimuth values appended
    """
    st_out = st.copy()
    ev_lat = event.preferred_origin().latitude
    ev_lon = event.preferred_origin().longitude
    for net in inv:
        for sta in net:
            _, _, baz = gps2dist_azimuth(lat1=ev_lat, lon1=ev_lon,
                                         lat2=sta.latitude, lon2=sta.longitude
                                         )
            # Apply back azimuth changes to stream in place
            for tr in st_out.select(network=net.code, station=sta.code):
                tr.stats.back_azimuth = baz
    return st_out

def _append_null_trace(st, component, cmpaz=None, cmpinc=None):
    """
    Create a copy of a trace with zeroed out data, used for rotation

    :type st: obspy.core.stream.Stream
    :param st: Stream with missing components
    :type component: str
    :param component: component of data to turn into a null trace
    :type cmpaz: float
    :param cmpaz: component azimuth for SAC header
    :type cmpinc: float
    :param cmpinc: component inclination for SAC header
    :rtype st: obspy.core.stream.Stream
    :return st: Stream that has had null traces appended
    """
    st_out = st.copy()
    trace_null = st_out[0].copy()
    trace_null.data = np.zeros(len(trace_null.data))
    trace_null.stats.component = component
    if cmpaz is not None:
        trace_null.stats.sac["cmpaz"] = cmpaz
    if cmpinc is not None:
        trace_null.stats.sac["cmpinc"] = cmpinc
    st_out.append(trace_null)

    return st_out

def _check_component_availability(st):
    """
    Quick logic check to see if stream is missing horizontals or vertical

    :type st: obspy.core.stream.Stream
    :param st: Steam to check
    :rtype: tuple of bool
    :return: (is the vertical component missing?,
              is one or both horizontal components missing?)
    """
    comps = sorted([tr.stats.component.upper() for tr in st])
    missing_vertical, missing_horizontal = False, False

    if comps:
        if "Z" not in comps:
            missing_vertical = True

        # Any one of these criteria will trigger a 'missing_horizontal' flag
        for pairs in [("N", "E"), ("R", "T"), ("1", "2")]:
            first, second = pairs
            if first in comps and second not in comps:
                missing_horizontal = True
            elif second in comps and first not in comps:
                missing_horizontal = True
    # Deal with the case where we have an empty Stream
    else:
        missing_vertical, missing_horizontal = True, True

    return missing_vertical, missing_horizontal

def rotate_to_uvw(st):
    """
    UVW orthogonal frame rotation

    In Symmetric Triaxial Seismometers, the sensing elements are also arranged
    to be mutually orthogonal, but instead of one axis being vertical, all
    three are inclined upwards from the horizontal at precisely the same angle,
    as if they were aligned with the edges of a cube balanced on a corner.

    TODO test this, not sure how it's supposed to work

    See reference:
    http://link.springer.com/referenceworkentry/10.1007/978-3-642-36197-5_194-1

    Rotation matrix reference:
    http://link.springer.com/referenceworkentry/10.1007/
                                                  978-3-642-36197-5_194-1#page-1

    :type st: obspy.core.stream.Stream
    :param st: three-component stream to rotate the UVW
    :rtype: obspy.core.stream.Stream
    :return: Stream that has been rotated to UVW
    """
    st_out = st.copy()
    assert(len(st) == 3), f"UVW rotation requires 3 component stream input"

    xyz = np.array([[st_out[0].data],
                    [st_out[1].data],
                    [st_out[2].data]])
    xyz = np.asmatrix(xyz)

    rotation_matrix = np.matrix([[2, 0, np.sqrt(2)],
                                 [-1, np.sqrt(3), np.sqrt(2)],
                                 [-1, -np.sqrt(3), np.sqrt(2)]])
    rotation_matrix *= 1 / np.sqrt(6)

    # Theta is the angle between the axis and the horizontal plane
    theta = (np.arcsin(1 / np.sqrt(3))) * (180.0 / np.pi)

    uvw = rotation_matrix * xyz
    for i, comp in enumerate(["U", "V", "W"]):
        st_out[i].data = np.reshape(np.asarray(uvw[i]), uvw.shape[1])
        st_out[i].stats.component = comp
        st_out[i].stats.sac["kcmpnm"] = st_out[i].stats.channel
        st_out[i].stats.sac["cmpaz"] *= (120 * i)  # azimuth
        st_out[i].stats.sac["cmpinc"] -= theta  # inclination
        if comp == "W":
            st_out[i].stats.sac["cmpinc"] += 90.

    return st_out

def trim_start_end_times(st, starttime=None, endtime=None, fill_value=None):
    """
    Trim all traces in a Stream to a uniform start and end times. If no
    `starttime` or `endtime` are provided, they are selected as the outer
    bounds of the Streams time bounds.

    :type st: obspy.core.stream.Stream
    :param st: stream to merge and trim start and end times for
    :type starttime: obspy.core.UTCDateTime
    :param starttime: user-defined starttime to trim stream. If None, will get
        the maximum starttime in entire stream
    :type endtime: obspy.core.UTCDateTime
    :param endtime: user-defined endtime to trim stream. If None, will get
        the minimum endtime in entire stream
    :type fill_value: str or int or float
    :param fill_value: How to deal with data gaps (missing sections of
        waveform before trace start or trace end w.r.t requested start and end
        times). NoneType by default, which means data with gaps are removed
        completely.

        Options include:

        - 'mean': fill with the mean of all data values in the gappy data
        - <int or float>: fill with a constant, user-defined value, e.g.,
        0 or 1.23 or 9.999
        - None: do not fill data gaps
    """
    st_edit = st.copy()

    if starttime is None:
        starttime = min([tr.stats.starttime for tr in st_edit])
    if endtime is None:
        endtime = max([tr.stats.endtime for tr in st_edit])

    # Trace.trim() can only take float or int as fill values
    if fill_value in ["interpolate", "latest"]:
        logger.warning("ObsPy cannot use `fill_value` 'interpolate' or "
                       "'latest' for missing boundary times. Setting to 'mean'")
        fill_value = "mean"

    # Go through all stations and look for those with late starts or early ends.
    # Then either remove short traces or fill them with acceptable values
    for tr in st_edit:
        if tr.stats.starttime > starttime or tr.stats.endtime < endtime:
            if fill_value is not False:
                if fill_value == "mean":
                    _fillval = np.nanmean(tr.data).astype(tr.data.dtype)
                else:
                    _fillval = fill_value

                logger.info(f"{tr.get_id()} filling start/endtime data gap w/: "
                            f"{_fillval}")

                tr.trim(starttime=starttime, endtime=endtime, pad=True,
                        nearest_sample=False, fill_value=_fillval)
            else:
                # Directly remove stations with late starttime or early endtime
                logger.warning(f"{tr.get_id()} start or endtime does not match "
                               f"requested bounds, remove")
                st_edit.remove(tr)
        else:
            tr.trim(starttime=starttime, endtime=endtime, nearest_sample=False)

    return st_edit

def merge_gapped_data(st, fill_value=None, gap_fraction=1.):
    """
    Merges traces with the same ID, filling gappy data with values if requested,
    otherwise removes traces that have gapped data.

    .. note::
        Be careful about `fill_value` data types, as there are no checks that
        the fill value matches the internal data types. This may cause
        unexpected errors.

    :type st: obspy.core.stream.Stream
    :param st: stream to merge and trim start and end times for
    :type fill_value: str or int or float
    :param fill_value: How to deal with data gaps (missing sections of
        waveform over a continuous time span). NoneType by default, which
        means data with gaps are removed completely. Users who want access
        to data with gaps must choose how gaps are filled. See API for
        ObsPy.core.stream.Stream.merge() for how merge is handled:

        Options include:

        - 'mean': fill with the mean of all data values in the gappy data
        - <int or float>: fill with a constant, user-defined value, e.g.,
        0 or 1.23 or 9.999
        - 'interpolate': linearly interpolate from the last value pre-gap
        to the first value post-gap
        - 'latest': fill with the last value of pre-gap data
        - False: do not fill data gaps, which will lead to stations w/
        data gaps being removed.
    :type gap_fraction: float
    :param gap_fraction: if `fill_data_gaps` is not None, determines the
        maximum allowable fraction (percentage) of data that gaps can
        comprise. For example, a value of 0.3 means that 30% of the data
        (in samples) can be gaps that will be filled by `fill_data_gaps`.
        Traces with gap fractions that exceed this value will be removed.
        Defaults to 1. (100%) of data can be gaps.
    :rtype: obspy.core.stream.Stream
    :return: Stream that has been trimmed
    """
    st_edit = st.copy()

    logger.info("trimming start and end times on a per-station basis")
    st_out = Stream()
    # e.g., NN.SSS.LL.CC?  i.e., only getting per-component codes
    codes = get_codes(st=st_edit, choice="component")

    for code in codes:
        # Subset the stream at each component
        net, sta, loc, cha = code.split(".")
        st_edit_select = st_edit.select(network=net, station=sta,
                                        location=loc, channel=cha)

        # Try-except catches any general ObsPy merge errors to keep code going
        try:
            data_gaps = st_edit_select.get_gaps()
            fillval = fill_value  # dummy value to allow in-place changes

            # Check if there are data gaps that we need to address
            if data_gaps and fill_value is not False:
                # Determine the percentage of data that comprises gaps
                gap_duration_samp = data_gaps[0][-1]  # assuming only one set
                starttime = min([tr.stats.starttime for tr in st_edit_select])
                endtime = max([tr.stats.endtime for tr in st_edit_select])
                total_samps = \
                    (endtime - starttime) / st_edit_select[0].stats.delta

                gap_percentage = gap_duration_samp / total_samps

                # If we exceed the allowable amount of data gap, do not fill
                if gap_percentage > gap_fraction:
                    logger.info(f"{code} has gap fraction "
                                f"({gap_percentage:.2f}) > allowable "
                                f"{gap_fraction}, will not fill gaps")
                    fillval = None
                else:
                    # Decide how we're going to fill the gaps
                    if fill_value == "mean":
                        # Collect mean value over all data surrounding the gap
                        # Convert to data type expected by array
                        fillval = np.nanmean(
                            [np.nanmean(tr.data) for tr in st_edit_select]
                        ).astype(st_edit_select[0].data.dtype)
                    else:
                        fillval = fill_value

                    logger.info(f"{code} has data gaps, filling with: "
                                f"{fillval}")
            else:
                fillval = None

            st_edit_select.merge(fill_value=fillval)  # combine like trace ID
        except Exception as e:  # NOQA
            logger.warning(f"{code} merge error: {e}")
            continue

        st_out += st_edit_select

    return st_out

def resample_data(st, resample_freq, method="interpolate"):
    """
    Apply a lowpass filter and taper data before resampling it using
    one of a choice of resampling strategies

    TODO did not refactor `resample_cut` which doesn't seem to do anything but
        is included in old code

    :type st: obspy.core.stream.Stream
    :param st: Stream to resample data for
    :type resample_freq: float
    :param resample_freq: frequency to resample for
    :type method: str
    :param method: choice of ObsPy resampling strategy:
        - interpolate: interpolate data, requires anti-aliasing lowpass filter
            before interpolating
        - resample: reample data with fourier methods
    :rtype: obspy.core.stream.Stream
    :return: Stream that has been resampled and maybe filtered
    """
    if method not in ["interpolate", "resample"]:
        logger.warning(f"unexpected resample method {method}, defaulting to "
                       f"'interpolate'")
        method = "interpolate"

    logger.info(f"resampling data to sampling rate: {resample_freq}Hz with "
                f"method '{method}'")
    st_out = st.copy()
    for i, tr in enumerate(st_out[:]):
        target_nyquist = 0.5 * resample_freq
        current_nyquist = 0.5 * tr.stats.sampling_rate
        if target_nyquist < current_nyquist:
            try:
                logger.debug(f"{tr.get_id()} applying lowpass filter to prep "
                             f"for new nyquist freq: "
                             f"{current_nyquist} -> {target_nyquist}")
                # This function affects the trace in-place
                zerophase_chebychev_lowpass_filter(
                    tr=tr, freqmax=target_nyquist
                )
            except Exception as e:
                logger.warning(f"exception in lowpass filtering "
                               f"{tr.get_id()}, remove: {e}")
                logger.debug(e)
                st_out.remove(tr)
        else:
            tr.detrend("linear")
        tr.taper(max_percentage=0.01, type="hann")
        # Enforce that this data array is 'c'ontiguous
        tr.data = np.require(tr.data, requirements=["C"])
        if method == "interpolate":
            tr.interpolate(sampling_rate=resample_freq, method="lanczos", a=8)
        elif method == "resample":
            tr.resample(sampling_rate=resample_freq, strict_length=True)

    return st_out

def zerophase_chebychev_lowpass_filter(tr, freqmax):
    """
    Custom Chebychev type two zerophase lowpass filter useful for decimation
    filtering. This filter is stable up to a reduction in frequency with a
    factor of 10. If more reduction is desired, simply decimate in steps.
    Partly based on a filter in ObsPy.

    Filter parameters:
        rp: maximum ripple of passband
        rs: attenuation of stopband
        ws: stop band frequency
        wp: pass band frequency

    .. note::
        Should be replaced once ObsPy has a proper decimation filter.

    .. note::
        This function affects the trace in place!

    :type tr: obspy.core.trace.Trace
    :param tr: The trace to be filtered.
    :type freqmax: float
    :param freqmax: The desired lowpass frequency.
    """
    rp, rs, order = 1, 96, 1e99
    ws = freqmax / (tr.stats.sampling_rate * 0.5)
    wp = ws
    wn = None

    while True:
        if order <= 12:
            break
        wp *= 0.99
        order, wn = signal.cheb2ord(wp=wp, ws=ws, gpass=rp, gstop=rs,
                                    analog=False)
    b, a = signal.cheby2(N=order, rs=rs, Wn=wn, btype="low", analog=0,  # NOQA
                         output="ba")                                   # NOQA
    # Apply twice to get rid of the phase distortion.
    tr.data = signal.filtfilt(b, a, tr.data)

def estimate_prefilter_corners(tr):
    """
    Estimates corners for pre-deconvolution (instrument response removal)
    Essentially band limits the data based on the minimum and maximum allowable
    periods based on the sampling rate and overall waveform length.

    See also: https://ds.iris.edu/files/sac-manual/commands/transfer.html

    Replaces the old `get_pre_filt` function

    :type tr: obspy.core.trace.Trace
    :param tr: trace from which stats are taken
    :rtype: tuple of float
    :return: frequency corners (f0, f1, f2, f3)
    """
    # filtering constants
    fcut1_par = 4.0
    fcut2_par = 0.5

    f1 = fcut1_par / (tr.stats.endtime - tr.stats.starttime)
    nyquist_freq = tr.stats.sampling_rate / 2
    f2 = nyquist_freq * fcut2_par
    f0 = 0.5 * f1
    f3 = 2.0 * f2

    return f0, f1, f2, f3


from django.shortcuts import render

from django.http import HttpResponse

import json
import redis

def index(request):
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)
    r = redis.StrictRedis(connection_pool=pool)
    displayData = r.zrangebyscore("mydata",1000000,9999999)
    for i, val in enumerate(displayData):
    	#byte==string to dict
    	displayData[i] = eval(val)
    #displayData = [{"ID":123456}]
    context = {"displayData":displayData}
    return render(request, 'display/index.html', context)

def findByID(request,id):
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)
    r = redis.StrictRedis(connection_pool=pool)
    displaySingleData = r.zrangebyscore("mydata",id,id)
    for i, val in enumerate(displaySingleData):
    	#byte==string to dict
    	displaySingleData[i] = eval(val)
    #displaySingleData = [{"ID":123456}]
    context = {"displaySingleData":displaySingleData}
    return render(request, 'display/displaySingleData.html', context)


from ..common.basetrackservice import BaseTrackService, track_registry
import requests
from ..models.model import StatusChoice
import parsel

# from dateutil.parser import parse

def get_elem_text(el):
    sentence = ""
    if el:
        for word in el:
            s_word = word.strip()
            if s_word[0].isalpha():
                sentence = sentence + s_word + " "
        return sentence.strip()

@track_registry.register("rl-carriers")
class RLCarriers(BaseTrackService):
    def status_mapper(self, status):
        """
        docstring
        """
        if status.startswith("Picked Up"):
            return StatusChoice.InTransit.value
        elif status.startswith("Departed"):
            return StatusChoice.InTransit.value
        elif status.startswith("Accepted"):
            return StatusChoice.InTransit.value
        elif status.startswith("Arrived"):
            return StatusChoice.InTransit.value
        elif status.startswith("Out for Delivery"):
            return StatusChoice.OutForDelivery.value
        elif status.startswith("Delivered"):
            return StatusChoice.Delivered.value
        elif "Delivered" in status:
            return StatusChoice.Delivered.value
        else:
            return "Exception"

    def __init__(self, waybill, *args, **kwargs):
        super().__init__(waybill, "rl-carriers", *args, **kwargs)

    """
    This method will populate self.raw_data
    """

    def _fetch(self):
        self.raw_data = requests.post(
            " https://www.rlcarriers.com/freight/shipping/shipment-tracing?source=web",
            data={
                " https://www.rlcarriers.com/freight/shipping/shipment-tracing?source=web": self.waybill
            },
        ).text
        # print(self.raw_data, "####")

    """
    This method will convert self.raw_data to self.data
    """

    def _transform(self):
        selector = parsel.Selector(text=self.raw_data)
        sub_status = selector.xpath(
            '//*[@id="result-container"]/h4/span[3]/text()'
        ).get()
        print(sub_status)
        # sub_status = sub_status.strip() if sub_status else ''

        # soup= BeautifulSoup(self.raw_data, 'html.parser')
        # soup_data= soup.find('table').find_all('tr')

        # checkpoints = []
        # checkpoints_data= []
        # checkpoint_table = soup_data
        # for row in checkpoint_table:
        #     if row == []:
        #         continue
        #     cols= row.find_all('td')
        #     cols = [ele.text.strip() for ele in cols]
        #     cols = [ele for ele in cols if ele]
        #     if len(cols) != 3:
        #         continue
        #     checkpoints.append(self._transform_checkpoint(cols))
        #     checkpoints_data.append(cols)
        # delivered_date = None
        # delivered_time = None
        # if sub_status == 'Delivered':
        #     delivered_date= checkpoints_data[0][0].split(' at ')[0]
        #     delivered_time= checkpoints_data[0][0].split(' at ')[1]
        # data = {
        #     'waybill': self.waybill,
        #     'provider': self.provider,
        #     'status': self.status_mapper(sub_status),
        #     'substatus': sub_status,
        #     'estimated_date': '',
        #     'delivered_date' : delivered_date,
        #     'delivered_time' : delivered_time,
        #     'reference_no' : '',
        #     'destination' : '',
        #     'receiver_name': ''
        # }

        # data['checkpoints'] = checkpoints

        # self.data = data

    def _transform_checkpoint(self, scan):

        checkpoint = {
            "slug": self.provider,
            "location": scan[2],
            "country_name": "Unites States",
            "message": "",
            "submessage": "",
            "country_iso3": "US",
            "status": self.status_mapper(scan[1]),
            "substatus": scan[1],
            "checkpoint_time": scan[0],
            "state": None,
            "zip": None,
        }

        return checkpoint


# x = "besyuwgnjkmbhuynrngejnjknvkiue"
#
# if "e" in x and "b" in x:
#     print("YES")
# else:
#     print("NO")
#
from pytest_lessons.lesson2 import CardsKinds
import random
class DataProvider():
    def __init__(self):
        self.cards = (
            CardsKinds.NO_CARD,
            CardsKinds.NORMAL_CARD,
            CardsKinds.GOLD_CARD,
            CardsKinds.PLATINUM_CARD)

    def __call__(self, normal:int, gold:int, platinum:int):
        norm = (random.randint(1,normal), CardsKinds.NORMAL_CARD)
        gol = (random.randint(normal+1,gold), CardsKinds.GOLD_CARD)
        pl = (random.randint(gold+1,platinum), CardsKinds.PLATINUM_CARD)
        tupl = (norm, gol, pl)
        return tupl

data_provider = DataProvider()
print(data_provider(1,10000,100000))


# https://www.acmicpc.net/problem/1562
# Hard version of 10844.
# DP: dp[n][i][j] = length n, end with i, bit j: j is 0~2**10-1 (check visited num of 0~9)

from sys import stdin

n = int(stdin.readline().strip())
dp = [[[0 for _ in range(1024)] for __ in range(10)] for ___ in range(n + 1)]
for i in range(1, 10):
    dp[1][i][1 << i] = 1

for now in range(1, n):
    for end in range(10):
        for bit in range(1024):
            if dp[now][end][bit] > 0:
                if end != 0:
                    dp[now + 1][end - 1][bit | (1 << (end - 1))] += dp[now][end][bit]
                if end != 9:
                    dp[now + 1][end + 1][bit | (1 << (end + 1))] += dp[now][end][bit]

print(sum(dp[n][i][1023] for i in range(10)) % 10 ** 9)

# for 1~40 check
# ans = 0
# for foo in range(41):
#     ans += sum(dp[foo][i][1023] for i in range(10))
# print(ans)
#


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

import logging
import ask_sdk_core.utils as ask_utils

from ask_sdk_core.skill_builder import SkillBuilder
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.dispatch_components import AbstractExceptionHandler
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model.interfaces.videoapp import LaunchDirective, VideoItem, Metadata
from ask_sdk_model.interfaces.audioplayer import (
    PlayDirective, PlayBehavior, AudioItem, Stream, AudioItemMetadata,
    StopDirective)
from ask_sdk_model.interfaces import display
from ask_sdk_model import Response

from pytube import YouTube
import urllib.request, json
from urllib.error import  URLError, HTTPError

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

class LaunchRequestHandler(AbstractRequestHandler):
    """Handler for Skill Launch."""
    def can_handle(self, handler_input):
        # type: (handler_input) -> bool

        return ask_utils.is_request_type("LaunchRequest")(handler_input)

    def handle(self, handler_input):
        # type: (handler_input) -> Response

        logger.info(">>>>> In LaunchRequestHandler")
        interfaces = (ask_utils.request_util
            .get_supported_interfaces(handler_input)
            .to_dict())

        with open("parameters.json") as conf_data:
            conf = json.load(conf_data)
        locale = ask_utils.get_locale(handler_input)
        logger.debug(f"Locale is {locale}")
        # localized strings stored in language_strings.json
        with open("language_strings.json") as language_prompts:
            language_data = json.load(language_prompts)
        try:
            loc_data = language_data[locale[:2]]
            skill_name = loc_data['SKILL_NAME']
        except KeyError:
            loc_data = language_data['en']
            skill_name = loc_data['SKILL_NAME']
        speak_output = loc_data['NO_VIDEO']
        channel_id = loc_data['CHANNEL']
        youtube_url = (
            "https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=" +
            channel_id +
            "&maxResults=1&order=date&type=video&key=" +
            conf['youtube_key']
        )
        success = True
        try:
            url = urllib.request.urlopen(youtube_url)
        except URLError as e:
            speak_output = loc_data['URL_ERROR']
            logger.info("URLError %s", e)
            success = False
        except HTTPError as e:
            logger.info("HTTPError %s, %e", e, e.code)
            if e.code == 429:
                speak_output = loc_data['TOO_MANY_REQUESTS']
            success = False
        if success:
            try:
                data = json.loads(url.read().decode())
                videoId = data['items'][0]['id']['videoId']
                yt = YouTube('https://www.youtube.com/watch?v=' + videoId)
            except Exception as e:
                speak_output = loc_data['YOUTUBE_ERROR']
                success = False
        if success:
            logger.info("List of the available interfaces: %s", interfaces)
            if interfaces['video_app'] is not None: # device has video support
                for stream in yt.streams.order_by('resolution').desc():
                    if stream.includes_audio_track:
                        break
                speak_output = loc_data['VIDEO_MESSAGE'] + ": " + stream.title + ". " + yt.description
                logger.info("Video {}. "
                            "Locale='{}'. "
                            "channel_id='{}'. "
                            "speak_output='{}'. "
                            "youtube_key='{}'".format(
                    stream,
                    locale[:2],
                    channel_id,
                    speak_output,
                    conf['youtube_key'])
                )
                directive = LaunchDirective(video_item=VideoItem(
                    source=stream.url,
                    metadata=Metadata(title=stream.title, subtitle=yt.description)))
                return (
                    handler_input.response_builder
                        .speak(speak_output)
                        .add_directive(directive)
                        .response
                )
            elif interfaces['audio_player'] is not None: # device has only audio support (no video)
                stream = (yt.streams
                            .filter(only_audio=True, subtype='mp4')
                            .order_by('fps')
                            .desc()
                            .first()
                )
                speak_output = loc_data['AUDIO_MESSAGE'] + ": " + stream.title + ". " + yt.description
                logger.info("Audio {}. "
                            "Locale='{}'. "
                            "channel_id='{}'. "
                            "speak_output='{}'. "
                            "youtube_key='{}'".format(
                    stream,
                    locale[:2],
                    channel_id,
                    speak_output,
                    conf['youtube_key'])
                )
                directive = PlayDirective(
                    play_behavior=PlayBehavior.REPLACE_ALL,
                    audio_item=AudioItem(
                        stream=Stream(
                            expected_previous_token=None,
                            token=stream.url,
                            url=stream.url,
                            offset_in_milliseconds=0
                        ),
                        metadata=AudioItemMetadata(
                            title=stream.title,
                            subtitle=yt.description,
                            art=display.Image(
                                content_description=stream.title,
                                sources=[
                                    display.ImageInstance(
                                        url=yt.thumbnail_url
                                    )
                                ]
                            ),
                            background_image=display.Image(
                                content_description=stream.title,
                                sources=[
                                    display.ImageInstance(
                                        url=yt.thumbnail_url
                                    )
                                ]
                            )
                        )
                    )
                )
                return (
                    handler_input.response_builder
                        .speak(speak_output)
                        .add_directive(directive)
                        .set_should_end_session(True)
                        .response
                )
            else:
                speak_output = loc_data['NO_INTERFACE'] + ": " + stream.title + ". " + yt.description
        return (
            handler_input.response_builder
                .speak(speak_output)
                .response
        )

class MainIntentHandler(AbstractRequestHandler):
    """Handler for Main Intent."""
    def can_handle(self, handler_input):
        # type: (handler_input) -> bool
        return (ask_utils.is_intent_name("mainIntent")(handler_input) or
                ask_utils.is_intent_name("AMAZON.ResumeIntent")(handler_input) or
                ask_utils.is_intent_name("AMAZON.NavigateHomeIntent")(handler_input))

    def handle(self, handler_input):
        # type: (handler_input) -> Response
        logger.info(">>>>> In MainIntentHandler: %s", handler_input.request_envelope.request)
        speak_output = "No main intent implemented"

        return (
            handler_input.response_builder
                .speak(speak_output)
                .ask(speak_output)
                .response
        )

class HelpIntentHandler(AbstractRequestHandler):
    """Handler for Help Intent."""
    def can_handle(self, handler_input):
        # type: (handler_input) -> bool
        return ask_utils.is_intent_name("AMAZON.HelpIntent")(handler_input)

    def handle(self, handler_input):
        # type: (handler_input) -> Response
        logger.info(">>>>> In HelpIntentHandler")
        speak_output = "No help intent implemented"

        return (
            handler_input.response_builder
                .speak(speak_output)
                .ask(speak_output)
                .response
        )

class AudioPlaybackHandler(AbstractRequestHandler):
    """Handler for audio playback events."""
    def can_handle(self, handler_input):
        # type: (handler_input) -> bool
        return (ask_utils.is_request_type("AudioPlayer.PlaybackStarted")(handler_input) or
                ask_utils.is_request_type("AudioPlayer.PlaybackFinished")(handler_input) or
                ask_utils.is_request_type("AudioPlayer.PlaybackStopped")(handler_input) or
                ask_utils.is_request_type("AudioPlayer.PlaybackNearlyFinished")(handler_input) or
                ask_utils.is_request_type("AudioPlayer.PlaybackFailed")(handler_input))

    def handle(self, handler_input):
        # type: (handler_input) -> Response
        logger.debug(">>>>> In AudioPlaybackHandler")
        return handler_input.response_builder.response

class CancelOrStopIntentHandler(AbstractRequestHandler):
    """Single handler for Cancel and Stop Intent."""
    def can_handle(self, handler_input):
        # type: (handler_input) -> bool
        return (ask_utils.is_intent_name("AMAZON.CancelIntent")(handler_input) or
                ask_utils.is_intent_name("AMAZON.PauseIntent")(handler_input) or
                ask_utils.is_intent_name("AMAZON.StopIntent")(handler_input))

    def handle(self, handler_input):
        # type: (handler_input) -> Response

        logger.info(">>>>> In CancelOrStopIntentHandler")
        locale = ask_utils.get_locale(handler_input)
        with open("language_strings.json") as language_prompts:
            language_data = json.load(language_prompts)
        try:
            loc_data = language_data[locale[:2]]
            skill_name = loc_data['SKILL_NAME']
        except KeyError:
            loc_data = language_data['en']
            skill_name = loc_data['SKILL_NAME']
        speak_output = loc_data['GOODBYE']
        directive = StopDirective()

        return (
            handler_input.response_builder
                .speak(speak_output)
                .add_directive(directive)
                .set_should_end_session(True)
                .response
        )

class SessionEndedRequestHandler(AbstractRequestHandler):
    """Handler for Session End."""
    def can_handle(self, handler_input):
        # type: (handler_input) -> bool
        return ask_utils.is_request_type("SessionEndedRequest")(handler_input)

    def handle(self, handler_input):
        # type: (handler_input) -> Response

        logger.info(">>>>> In SessionEndedRequestHandler")
        logger.debug("Session ended with reason: {}".format(
            handler_input.request_envelope.request.reason)
        )
        # Any cleanup logic goes here.

        return handler_input.response_builder.response

class IntentReflectorHandler(AbstractRequestHandler):
    """The intent reflector is used for interaction model testing and debugging.
    It will simply repeat the intent the user said. You can create custom handlers
    for your intents by defining them above, then also adding them to the request
    handler chain below.
    """
    def can_handle(self, handler_input):
        # type: (handler_input) -> bool
        return ask_utils.is_request_type("IntentRequest")(handler_input)

    def handle(self, handler_input):
        # type: (handler_input) -> Response

        logger.info(">>>>> In IntentReflectorHandler")
        intent_name = ask_utils.get_intent_name(handler_input)
        logger.info("Triggered intent: %s", intent_name)
        speak_output = "You just triggered " + intent_name + "."

        return (
            handler_input.response_builder
                .speak(speak_output)
                # .ask("add a reprompt if you want to keep the session open for the user to respond")
                .response
        )

class CatchAllExceptionHandler(AbstractExceptionHandler):
    """Generic error handling to capture any syntax or routing errors. If you receive an error
    stating the request handler chain is not found, you have not implemented a handler for
    the intent being invoked or included it in the skill builder below.
    """
    def can_handle(self, handler_input, exception):
        # type: (handler_input, exception) -> bool
        return True

    def handle(self, handler_input, exception):
        # type: (handler_input, exception) -> Response

        logger.info(">>>>> In CatchAllExceptionHandler: check handler '%s'",
            ask_utils.get_request_type(handler_input)
        )
        logger.debug("Dump of request_envelope: %s",
            str(handler_input.request_envelope)
        )
        logger.error(exception, exc_info=True)

        return handler_input.response_builder.response

# The SkillBuilder object acts as the entry point for your skill, routing all request and response
# payloads to the handlers above. Make sure any new handlers or interceptors you've
# defined are included below. The order matters - they're processed top to bottom.

sb = SkillBuilder()

sb.add_request_handler(LaunchRequestHandler())
sb.add_request_handler(HelpIntentHandler())
sb.add_request_handler(MainIntentHandler())
sb.add_request_handler(AudioPlaybackHandler())
sb.add_request_handler(CancelOrStopIntentHandler())
sb.add_request_handler(SessionEndedRequestHandler())
sb.add_request_handler(IntentReflectorHandler()) # make sure IntentReflectorHandler is last so it doesn't override your custom intent handlers

sb.add_exception_handler(CatchAllExceptionHandler())

lambda_handler = sb.lambda_handler()


# c'è bisogno di importare un file nella cartella "code",
# quindi devo aggiungerla al path di python
# (l'operazione è locale per questo programma soltanto)
import sys, os
sys.path.append(os.path.abspath('../code'))

import q_function as q_fn_module
import numpy as np
import gym

# Cominciamo creando una piccola q
# Prima devo definire dei semplici spazi
# fatti senza particolare attenzione
obs_lo = np.full(3, -float('inf'), dtype=np.float32)
obs_hi = np.full(3, float('inf'), dtype=np.float32)
observation_space = gym.spaces.Box(obs_lo, obs_hi)
act_lo = np.full(2, -0.4, dtype=np.float32)
act_hi = np.full(2, 0.4, dtype=np.float32)
action_space = gym.spaces.Box(act_lo, act_hi)

# E ora la policy
q = q_fn_module.Q_Function(observation_space, action_space)

print(q.q_model.summary())

# Se superiamo questo punto, vuol dire che __init__ è almeno "compilabile".
print()
print("---------- EVVIVA ----------")
print()

# Ora vediamo come si comportano i due/tre metodi che mi preme esporre
# Cominciamo con quello facile
# print(polisi.trainable_weights)
# In realtà è un po' grandicello, mostrami soltanto un elemento
print(q.trainable_weights[-1])

# Per il prossimo devo inventarmi qualche osservazione e azione
oss0 = np.array([0.0,0.1,0.2])
oss1 = np.array([1.0,1.1,1.2])
oss2 = np.array([2.0,2.1,2.2])
oss3 = np.array([3.0,3.1,3.2])
oss_batch = np.array([oss0,oss1,oss2,oss3])
azn0 = np.array([0.0,0.1])*0.01
azn1 = np.array([1.0,1.1])*0.01
azn2 = np.array([2.0,2.1])*0.01
azn3 = np.array([3.0,3.1])*0.01
azn_batch = np.array([azn0,azn1,azn2,azn3])
# E poi cerchiamo di farci dare i valori q
values = q.compute_q_values(oss_batch, azn_batch)
print("--- [*] ---")
print(values)

# Ovviamente adesso i valori numerici puri non c'azzeccano niente,
# ma voglio solo controllare che i metodi si eseguano senza problemi
print()
print("---------- FINE ----------")


import os
from pathlib import Path, PureWindowsPath
from google.cloud.bigquery import dbapi
import utils.bq as ubq
from utils.string_formatter import FormatSQLString
from config.conf import gcp, logger

def path_formatter(path_str):
    """
    This function helps format file paths to meet operating system
    requirements. So issues can be avoided in a linux environment.
    :param path_str:
    :return:
    """
    if os.name == 'nt':
        return PureWindowsPath(path_str)
    else:
        return Path(path_str)

def execute_query_task(sql_file,
                       destination_table,
                       dataset_id=gcp['dataset'],
                       run_disposition='WRITE_TRUNCATE',
                       use_legacy=False):
    """
    This function is used to open and execute files containing SQL scripts.
    The query results are stored in given destination table id.
    :param sql_file:
    :param destination_table:
    :param dataset_id:
    :param run_disposition:
    :param use_legacy:
    :return:
    """
    path = path_formatter(sql_file)
    sql_string = FormatSQLString.format_dataset_id(open(path).read(), dataset_id)

    try:
        ubq.bq_query_to_table(destination_table,
                              sql_string,
                              dataset_id=dataset_id,
                              write_disposition=run_disposition,
                              use_legacy=use_legacy)
        success = True
    except dbapi.Error as err:
        logger.exception("The following exception occured: \n" + err)
        logger.info("Something went wrong during query run."
                    "An unknown error was detected in the script.")
        success = False
    return success

def archive_tables(sql_file, source_table, destination_table, run_disposition='WRITE_APPEND'):
    """
    This function is used for archiving tables before overwriting for historical record.
    :param sql_file:
    :param source_table:
    :param destination_table:
    :param run_disposition:
    :return:
    """
    path = path_formatter(sql_file)
    sql_string = open(path).read()
    sql_string.format(source_table)

    try:
        ubq.bq_query_to_table(destination_table, sql_string, write_disposition=run_disposition)
        success = True
    except dbapi.Error as err:
        logger.exception("The following exception occured: \n" + err)
        logger.info("Something went wrong during query run."
                    "An unknown error was detected in the script.")
        success = False
    return success

def move_and_rename_tables(sql_file, source, destination, run_disposition='WRITE_TRUNCATE'):
    path = path_formatter(sql_file)
    sql_string = open(path).read().format(table_id=source)

    try:
        ubq.bq_query_to_table(destination, sql_string, write_disposition=run_disposition)
        success = True
    except dbapi.Error as err:
        logger.exception("The following exception occured: \n" + err)
        logger.info("Something went wrong during query run."
                    "An unknown error was detected in the script.")
        success = False
    return success

def test_summary(sql_file, destination, test_tables, dataset_id=gcp['dataset']):
    """
    :param sql_file:
    :param destination:
    :param test_tables:
    :param dataset_id=gcp['dataset']:
    """
    path = path_formatter(sql_file)
    temp_sql_string = open(path).read()

    lst_sql_str = [
        temp_sql_string.format(table_id=table_id, dataset_id=dataset_id)
        for table_id in test_tables
    ]

    sql_str = '\nunion all\n'.join(lst_sql_str)

    logger.info(f'sql script to execute: {sql_str}')

    try:
        ubq.bq_query_to_table(destination, sql_str)
        run_success = True
    except dbapi.Error as err:
        logger.exception("The following exception occured: \n" + err)
        logger.info("Something went wrong during query run."
                    "An unknown error was detected in the script.")

    return run_success


#LZW编码 15030140050 刘超
import math
import numpy as np
#字母集

def init():
    en_dict = {'A': 1, 'B': 2, 'C': 3, 'D':4}
    dict_num = 5
    return en_dict,dict_num

def encode(in_str,en_dict,dict_num):
    #传参：输入字符串，编码字典，字典中word的个数
    length = len(in_str)
    i = 0
    code = []
    while(i<length):
        isexise = in_str[i] in en_dict      #是否存在于字典中
        newin_str = in_str[i]
        tmp = i
        while(isexise and (tmp+1 < length)):
            newin_str = newin_str+in_str[tmp+1]
            tmp = tmp+1
            isexise = newin_str in en_dict  #判断是否结束

        #将其及下一位添加至词典中去
        if(not isexise):
            en_dict[newin_str] = dict_num
            dict_num = dict_num+1
            jnum = newin_str[0:-1]
            code.append(en_dict[jnum])
            #print(i, ":", newin_str[0:-1])
            i = tmp
        else:
            #print(i, ":",newin_str)
            jnum = newin_str
            code.append(en_dict[jnum])
            i = tmp + 1
    #print(en_dict)
    return code

def decode(code,en_dict,dict_num):
    #传参：编码，初始编码字典，字典中word的个数
    #方便操作做如下处理
    de_dict = dict(map(lambda t: (t[1], t[0]), en_dict.items()))
    length = len(code)
    #存储结果
    res = ""

    #将字典中第一个加入到解码字符串中去
    res = res + de_dict[code[0]]
    for step in range(length-1):
        #前缀和当前 要解码的码字
        pre = code[step]
        now = code[step+1]
        pre_str = de_dict[pre]

        if now in de_dict:
            #码字对应的字符串在译码词典中，直接解码
            now_str = de_dict[now]
            #print(now_str)
            res = res + now_str
            now_str = pre_str + de_dict[now][0]

            de_dict[dict_num] = now_str
            dict_num = dict_num + 1
        else:
            #码字对应的字符串不在译码字典中
            #将前缀和前缀的第一个字符作为当前串
            now_str = pre_str + pre_str[0]
            #print(now_str)
            res = res + now_str

            de_dict[dict_num] = now_str
            dict_num = dict_num + 1
    #print(de_dict)
    #print(res)
    return res

if __name__ == "__main__":
    en_dict = {'A': 1, 'B': 2, 'C': 3}
    dict_num = 4
    op = input("请输入请求(0:退出 1:编码 2:解码):")
    while (1):
        if op == '0':
            exit(0)
        elif op == '1':
            en_dict, dict_num = init()
            in_str = input("请输入要进行编码的字符串:")
            #in_str = "ABBABABACABA"
            res = encode(in_str,en_dict,dict_num)
            print("编码结果是:",res)
            op = input("请输入请求(0:退出 1:编码 2:解码):")

        elif op == '2':
            in_str = input("请输入要进行译码的字符串:")
            code = []
            for i in in_str:
                code.append(int(i))
            en_dict, dict_num = init()
            ans = decode(code,en_dict,dict_num)
            print("译码结果是:",ans)
            op = input("请输入请求(0:退出 1:编码 2:解码):")
        else:
            raise ValueError("input error")
            exit(0)


#!/usr/bin/env python

from paho.mqtt import client

def message_received(client, userdata, message):
    print(message.payload)

c = client.Client()
c.connect('localhost', 1883)
c.on_message = message_received

c.subscribe('/random/topic')
c.loop_forever()


import cherrypy
import re, json

class RatingController(object):
	def __init__(self, mdb=None):
		self.mdb = mdb

	def GET(self, movie_id):
		output = {'result': 'success'}
		movie_id = int(movie_id)
		try:
			output['rating'] = self.mdb.get_rating(movie_id)
			output['movie_id'] = movie_id
		except Exception as ex:
			output['result'] = 'error'
			output['message'] = 'could not retrieve the average rating for a movie'
		return json.dumps(output)


#!/usr/bin/env python

if __name__ == "__main__" and __package__ is None:
    __package__ = "ngff_zarr"

import argparse
import atexit
import signal
import sys
from pathlib import Path

import dask.utils
import zarr
from rich.console import Console
from rich.live import Live
from rich.panel import Panel
from rich.pretty import Pretty
from rich.progress import (
    MofNCompleteColumn,
    SpinnerColumn,
    TimeElapsedColumn,
)
from rich.progress import (
    Progress as RichProgress,
)
from rich.spinner import Spinner
from zarr.storage import DirectoryStore

from .cli_input_to_ngff_image import cli_input_to_ngff_image
from .config import config
from .detect_cli_io_backend import (
    ConversionBackend,
    conversion_backends_values,
    detect_cli_io_backend,
)
from .from_ngff_zarr import from_ngff_zarr
from .methods import Methods, methods_values
from .ngff_image_to_itk_image import ngff_image_to_itk_image
from .rich_dask_progress import NgffProgress, NgffProgressCallback
from .to_multiscales import to_multiscales
from .to_ngff_image import to_ngff_image
from .to_ngff_zarr import to_ngff_zarr
from .zarr_metadata import is_unit_supported

def _multiscales_to_ngff_zarr(
    live, args, output_store, rich_dask_progress, multiscales
):
    if not args.output:
        if args.quiet:
            live.update(Pretty(multiscales))
        else:
            live.update(
                Panel(
                    Pretty(multiscales),
                    title="[red]NGFF OME-Zarr",
                    subtitle="[red]information",
                    style="magenta",
                )
            )
        return
    to_ngff_zarr(output_store, multiscales, progress=rich_dask_progress)

def _ngff_image_to_multiscales(
    live, ngff_image, args, progress, rich_dask_progress, subtitle, method
):
    data = ngff_image.data
    if args.dims:
        if len(args.dims) != len(ngff_image.dims):
            live.console.print(
                f"[red]Provided number of dims do not match expected: {len(ngff_image.dims)}"
            )
            sys.exit(1)
        ngff_image.dims = args.dims
    if args.scale:
        if len(args.scale) % 2 != 0:
            live.console.print(
                "[red]Provided scales are expected to be dim value pairs"
            )
            sys.exit(1)
        n_scale_args = len(args.scale) // 2
        for scale in range(n_scale_args):
            dim = args.scale[scale * 2]
            value = float(args.scale[scale * 2 + 1])
            ngff_image.scale[dim] = value
    if args.translation:
        if len(args.translation) % 2 != 0:
            live.console.print(
                "[red]Provided translations are expected to be dim value pairs"
            )
            sys.exit(1)
        n_translation_args = len(args.translation) // 2
        for translation in range(n_translation_args):
            dim = args.translation[translation * 2]
            value = float(args.translation[translation * 2 + 1])
            ngff_image.translation[dim] = value
    if args.units:
        if len(args.units) % 2 != 0:
            live.console.print(
                '[red]Provided units are expected to be dim value pairs, i.e. "x" "meter" ...'
            )
            sys.exit(1)
        unit_pairs = {
            str(args.units[unit * 2]).lower(): str(args.units[unit * 2 + 1]).lower()
            for unit in range(len(args.units) // 2)
        }
        unsupported_units = [
            value for value in unit_pairs.values() if not is_unit_supported(value)
        ]
        if any(unsupported_units):
            live.console.print(
                f"[red]The following unit(s) were requested but are not supported: {unsupported_units}"
            )
            sys.exit(1)
        ngff_image.axes_units = unit_pairs
    if args.name:
        ngff_image.name = args.name

    # Generate Multiscales
    cache = data.nbytes > config.memory_target
    if not args.output:
        cache = False
    if not args.quiet:
        live.update(
            Panel(
                progress, title="[red]NGFF OME-Zarr", subtitle=subtitle, style="magenta"
            )
        )
    chunks = args.chunks
    if chunks is not None:
        chunks = chunks[0] if len(chunks) == 1 else tuple(chunks)
    return to_multiscales(
        ngff_image,
        method=method,
        progress=rich_dask_progress,
        chunks=chunks,
        cache=cache,
    )

def main():
    parser = argparse.ArgumentParser(
        description="Convert datasets to and from the OME-Zarr Next Generation File Format."
    )
    parser.add_argument(
        "-i", "--input", nargs="+", help="Input image(s)", required=True
    )
    parser.add_argument(
        "-o",
        "--output",
        help="Output image. If not specified just print information to stdout.",
    )

    metadata_group = parser.add_argument_group("metadata", "Specify output metadata")
    metadata_group.add_argument(
        "-d",
        "--dims",
        nargs="+",
        help='Ordered OME-Zarr NGFF dimensions from {"t", "z", "y", "x", "c"}',
        metavar="DIM",
    )
    metadata_group.add_argument(
        "-u",
        "--units",
        nargs="+",
        help="Ordered OME-Zarr NGFF axes spatial or temporal units",
        metavar="UNITS",
    )
    metadata_group.add_argument(
        "-s",
        "--scale",
        nargs="+",
        help="Override scale / spacing for each dimension, e.g. z 4.0 y 1.0 x 1.0",
        metavar="SCALE",
    )
    metadata_group.add_argument(
        "-t",
        "--translation",
        nargs="+",
        help="Override translation / origin for each dimension, e.g. z 0.0 y 50.0 x 40.0",
        metavar="TRANSLATION",
    )
    metadata_group.add_argument("-n", "--name", help="Image name")
    metadata_group.add_argument(
        "--output-scale",
        help="Scale to pick from multiscale input for a single-scale output format",
        type=int,
        default=0,
    )

    processing_group = parser.add_argument_group("processing", "Processing options")
    processing_group.add_argument(
        "-c",
        "--chunks",
        nargs="+",
        type=int,
        help="Dask array chunking specification, either a single integer or integer per dimension, e.g. 64 or 8 16 32",
        metavar="CHUNKS",
    )
    processing_group.add_argument(
        "-m",
        "--method",
        default="dask_image_gaussian",
        choices=methods_values,
        help="Downsampling method",
    )
    processing_group.add_argument(
        "-q", "--quiet", action="store_true", help="Do not display progress information"
    )
    processing_group.add_argument(
        "-l",
        "--local-cluster",
        action="store_true",
        help="Create a Dask Distributed LocalCluster. Better for large datasets.",
    )
    processing_group.add_argument(
        "--input-backend",
        choices=conversion_backends_values,
        help="Input conversion backend",
    )
    processing_group.add_argument("--memory-target", help="Memory limit, e.g. 4GB")
    processing_group.add_argument(
        "--cache-dir", help="Directory to use for caching with large datasets"
    )

    args = parser.parse_args()

    if args.memory_target:
        config.memory_target = dask.utils.parse_bytes(args.memory_target)

    if args.cache_dir:
        cache_dir = Path(args.cache_dir).resolve()
        if not cache_dir.exists():
            Path.makedirs(cache_dir, parents=True)
        config.cache_store = zarr.storage.DirectoryStore(
            cache_dir, dimension_separator="/"
        )

    console = Console()
    progress = RichProgress(
        SpinnerColumn(),
        MofNCompleteColumn(),
        TimeElapsedColumn(),
        *RichProgress.get_default_columns(),
        transient=False,
        console=console,
    )
    rich_dask_progress = None

    # Setup LocalCluster
    if args.local_cluster:
        from dask.distributed import Client, LocalCluster

        n_workers = 4
        worker_memory_target = config.memory_target // n_workers
        try:
            import psutil

            n_workers = psutil.cpu_count(False) // 2
            worker_memory_target = config.memory_target // n_workers
        except ImportError:
            pass

        cluster = LocalCluster(
            n_workers=n_workers,
            memory_target=worker_memory_target,
            processes=True,
            threads_per_worker=2,
        )
        client = Client(cluster)

        def shutdown_client(sig_id, frame):  # noqa: ARG001
            client.shutdown()

        atexit.register(shutdown_client, None, None)
        signal.signal(signal.SIGTERM, shutdown_client)
        signal.signal(signal.SIGINT, shutdown_client)

        if not args.quiet:
            console.log(f"[yellow]Dashboard: [cyan]{client.dashboard_link}")

        if not args.quiet:
            rich_dask_progress = NgffProgress(progress)
    else:
        if not args.quiet:
            rich_dask_progress = NgffProgressCallback(progress)
            rich_dask_progress.register()

    # Parse conversion options
    if args.input_backend is None:
        input_backend = detect_cli_io_backend(args.input)
    else:
        input_backend = ConversionBackend(args.input_backend)
    method = Methods.ITK_GAUSSIAN if args.method is None else Methods(args.method)

    if args.output:
        output_backend = detect_cli_io_backend(
            [
                args.output,
            ]
        )
    output_store = None
    if args.output and output_backend is ConversionBackend.NGFF_ZARR:
        output_store = DirectoryStore(args.output, dimension_separator="/")

    subtitle = "[red]generation"
    if not args.output:
        subtitle = "[red]information"
    initial = Panel(
        Spinner("point", text="Loading input..."),
        title="[red]NGFF OME-Zarr",
        subtitle=subtitle,
        style="magenta",
    )
    if args.quiet:
        initial = None
    with Live(initial, console=console) as live:
        if args.output and output_backend is ConversionBackend.ITK:
            import itk

            ngff_image = cli_input_to_ngff_image(
                input_backend, args.input, args.output_scale
            )
            if isinstance(rich_dask_progress, NgffProgressCallback):
                rich_dask_progress.add_callback_task(
                    "[green]Converting Zarr Array to NumPy Array"
                )
            itk_image = ngff_image_to_itk_image(ngff_image, wasm=False)
            itk.imwrite(itk_image, args.output)
            return

        if input_backend is ConversionBackend.NGFF_ZARR:
            store = zarr.storage.DirectoryStore(args.input[0])
            multiscales = from_ngff_zarr(store)
            _multiscales_to_ngff_zarr(
                live, args, output_store, rich_dask_progress, multiscales
            )
        elif input_backend is ConversionBackend.TIFFFILE:
            try:
                import tifffile

                files = args.input[0] if len(args.input) == 1 else args.input
                with tifffile.imread(files, aszarr=True) as store:
                    root = zarr.open(store, mode="r")
                    ngff_image = to_ngff_image(root)
                    multiscales = _ngff_image_to_multiscales(
                        live,
                        ngff_image,
                        args,
                        progress,
                        rich_dask_progress,
                        subtitle,
                        method,
                    )
                    _multiscales_to_ngff_zarr(
                        live, args, output_store, rich_dask_progress, multiscales
                    )
            except ImportError:
                sys.stdout.write("[red]Please install the [i]tifffile[/i] package.\n")
                sys.exit(1)
        else:
            # Generate NgffImage
            ngff_image = cli_input_to_ngff_image(input_backend, args.input)
            multiscales = _ngff_image_to_multiscales(
                live, ngff_image, args, progress, rich_dask_progress, subtitle, method
            )
            _multiscales_to_ngff_zarr(
                live, args, output_store, rich_dask_progress, multiscales
            )

if __name__ == "__main__":
    main()


n = 3
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

print("--- Original Matrix ---")

for i in range(n):
    for j in range(n):
        print(matrix[i][j], end=" ")
    print("")

print("--- Rotated Matrix ---")

# Transpose of a matrix
for i in range(n):
    for j in range(i, n):
        matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

# Interchange columns from start and end
for i in range(n):
    for j in range(n//2):
        matrix[i][j], matrix[i][n-1-j] = matrix[i][n-1-j], matrix[i][j]

# Printing a matrix
for i in range(n):
    for j in range(n):
        print(matrix[i][j], end=" ")
    print("")

####### OUTPUT #######
'''
--- Original Matrix ---
1 2 3
4 5 6
7 8 9
--- Rotated Matrix ---
7 4 1
8 5 2
9 6 3
'''


from torch import nn
import torch.nn.functional as F

class ResidualConvBlock(nn.Module):

    def __init__(self, c_in, c_out, k_size=3, stride=1, pad=1, bn=False, conv_layers=4, lrelu=True, conv_residual=False):
        nn.Module.__init__(self)
        self.c_in = c_in
        self.c_out = c_out
        self.k_size = k_size
        self.stride = stride
        self.pad = pad
        self.bn = bn
        self.conv_layers = conv_layers

        if bn:
            self.bns = nn.ModuleList([nn.BatchNorm2d(c_out) for i in range(conv_layers)])

        self.convs = nn.ModuleList([nn.Conv2d(c_in, c_out, k_size, stride=stride, padding=pad)])
        for i in range(conv_layers - 1):
            self.convs.append(nn.Conv2d(c_out, c_out, k_size, stride=stride, padding=pad))

        self.residual_conv = nn.Conv2d(c_in, c_out, 1)

    def forward(self, x):
        conv_out = x
        # conv_out = self.convs(conv_out)
        for layer_index in range(self.conv_layers):
            if self.bn:
                conv_out = self.bns[layer_index](conv_out)
            conv_out = self.convs[layer_index](F.relu(conv_out))

        return F.interpolate(self.residual_conv(x), scale_factor=1, mode='bilinear') + conv_out


from flask import Flask, request, make_response, Response, jsonify;
from flask_jwt_extended import jwt_required, get_jwt, JWTManager
from redis import Redis;
import io
import csv
import json
from configuration import Configuration;
from models import database;

app = Flask(__name__);
app.config.from_object(Configuration);

jwt = JWTManager(app);

@app.route("/", methods=["GET", "POST"])
def index():
    return "Officials page working";

@app.route("/vote", methods=["POST"])
@jwt_required()
def vote():
    if not request.files or "file" not in request.files or not request.files["file"]:
        return make_response(jsonify(message="Field file is missing."), 400);
    content = request.files["file"].stream.read().decode("utf-8");
    stream = io.StringIO(content);
    reader = csv.reader(stream);
    voteList = [];
    officialJMBG = get_jwt()["jmbg"];
    with Redis(host=Configuration.REDIS_HOST, port=6379) as redis:
        i = 0;
        for row in reader:
            if len(row) != 2:
                return make_response(jsonify(message=("Incorrect number of values on line {}.".format(i))), 400);
            try:
                voteData = {
                    "guid": row[0],
                    "pollNumber": int(row[1]),
                    "officialJMBG": officialJMBG
                }
                if voteData["pollNumber"] <= 0:
                    raise ValueError;
            except ValueError:
                return make_response(jsonify(message=("Incorrect poll number on line {}.".format(i))), 400);
            voteList.append(voteData);
            i = i + 1;

        voteList.reverse();
        print(voteList);

        for voteData in voteList:
            redis.lpush(Configuration.REDIS_VOTES_LIST, json.dumps(voteData));

    return Response(status=200);

if __name__ == "__main__":
    database.init_app(app);
    app.run(debug=True, host="0.0.0.0", port=5003);


import pytest
from task1.task1 import ValueCannotBeConvertedError

class TestConverter:
    @pytest.mark.xfail(raises=ValueCannotBeConvertedError)
    @pytest.mark.parametrize('test_in', [
        ("30", 30),
        ("30s", 30),
        ("S", 1),
        ("60.5m", 3630),
        ("10seconds", None),
        ("1m30s", None),
        ("1y", None),
        ("", None)]
    )
    def test_converter_work(self, test_in, converter):
        res = converter.to_seconds(test_in[0])
        print(res)
        assert res == test_in[1]


import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
from esphome.const import CONF_ADDRESS, CONF_ID
from .. import (
    ExtraflameComponent,
    extraflame_ns,
    EXTRAFLAME_COMPONENT_SCHEMA,
    get_memory_address,
)
from ..const import CONF_EXTRAFLAME_ID, CONF_MEMORY

DEPENDENCIES = ["extraflame"]
CODEOWNERS = ["@edenhaus"]

ExtraflameSensor = extraflame_ns.class_(
    "ExtraflameSensor", ExtraflameComponent, sensor.Sensor
)

CONFIG_SCHEMA = EXTRAFLAME_COMPONENT_SCHEMA.extend(
    sensor.SENSOR_SCHEMA.extend(
        {
            cv.GenerateID(): cv.declare_id(ExtraflameSensor),
        }
    )
)

async def to_code(config):
    var = cg.new_Pvariable(
        config[CONF_ID], get_memory_address(config[CONF_MEMORY]), config[CONF_ADDRESS]
    )
    await cg.register_component(var, config)
    await sensor.register_sensor(var, config)
    await cg.register_parented(var, config[CONF_EXTRAFLAME_ID])


#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
from PyQt5 import QtGui
from PyQt5 import QtCore
from PyQt5 import QtWidgets

style = '''
    QDialog{
        border:4px solid green;
    }

    QPushButton
    {
        color: rgb(255, 255, 255);
        background-color: rgb(167, 205, 255);
        background: green;
        border:none;
        font-family: "Verdana";
        font-size: 15px;
        text-align: center;
        width: 60px;
    }
    QPushButton:hover, QPushButton:pressed , QPushButton:checked
    {
        background-color: rgb(85, 170, 255);
        text-align: center;
        font-family: "Verdana";
    }
    QPushButton:hover
    {
        background-repeat:no-repeat;
        background-position: center left;
    }
    QPushButton:pressed, QPushButton:checked
    {
        background-repeat:no-repeat;
        background-position: center left;
    }

    QPushButton:disabled{
        color: gray;
        background-color: rgb(167, 205, 255);
    }

    QLineEdit {
        padding: 1px;
        border-style: solid;
        border: 2px solid lightgray;
        border-radius: 8px;
        width:40px;
        height: 30px;
    }
'''

class BaseDialog(QtWidgets.QDialog):

    def __init__(self, styleoptions, parent=None):
        super(BaseDialog, self).__init__(parent)
        title = styleoptions['title']
        windowicon = styleoptions['windowicon']
        minsize = styleoptions['minsize']
        size = styleoptions['size']
        logo_title = styleoptions['logo_title']
        logo_img_url = styleoptions['logo_img_url']

        self.setWindowTitle(title)
        self.setWindowIcon(QtGui.QIcon(windowicon))  # 设置程序图标
        self.setMinimumSize(minsize[0], minsize[1])
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMinimizeButtonHint)  # 无边框， 带系统菜单， 可以最小化

        self.logowidget = DynamicTextWidget(logo_title, logo_img_url)

        # 主布局
        mainlayout = QtWidgets.QVBoxLayout()
        mainlayout.addWidget(self.logowidget)
        self.setLayout(mainlayout)

        self.setStyleSheet(style) # 设置主窗口样式
        self.resize(size[0], size[1])

    def mousePressEvent(self, event):
        # 鼠标点击事件
        if event.button() == QtCore.Qt.LeftButton:
            self.dragPosition = event.globalPos() - self.frameGeometry().topLeft()
            event.accept()

    def mouseReleaseEvent(self, event):
        # 鼠标释放事件
        if hasattr(self, "dragPosition"):
            del self.dragPosition

    def mouseMoveEvent(self, event):
        # 鼠标移动事件
        if hasattr(self, "dragPosition"):
            if event.buttons() == QtCore.Qt.LeftButton:
                self.move(event.globalPos() - self.dragPosition)
                event.accept()

class DynamicTextWidget(QtWidgets.QWidget):
    def __init__(self, text, bg, parent=None):
        super(DynamicTextWidget, self).__init__(parent)
        self.setFixedSize(443, 132)
        self.bg = bg
        self.text = text

        newFont = self.font()
        newFont.setPointSize(newFont.pointSize() + 10)
        self.setFont(newFont)

        self.painter = QtGui.QPainter()

        self.timer = QtCore.QBasicTimer()

        self.step = 0
        self.timer.start(60, self)

    def paintEvent(self, event):
        self.painter.begin(self)
        self.drawBackground(self.painter)
        self.drawDynamicText(self.painter)
        self.painter.end()

    def set_painterpencolor(self, painter):
        color = QtGui.QColor()
        import random
        i = random.randint(1, 15)
        color.setHsv((15 - i) * 16, 255, 191)
        painter.setPen(color)

    def drawBackground(self, painter):
        painter.drawPixmap(0, 0, self.width(), self.height(), QtGui.QPixmap(self.bg))

    def drawDynamicText(self, painter):
        sineTable = (0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38)
        metrics = QtGui.QFontMetrics(self.font())
        x = (self.width() - metrics.width(self.text)) / 2
        y = (self.height() + metrics.ascent() - metrics.descent()) / 2
        color = QtGui.QColor()

        for i, ch in enumerate(self.text):
            index = (self.step + i) % 16
            color.setHsv((15 - index) * 16, 255, 191)
            painter.setPen(color)
            painter.drawText(x, y - ((sineTable[index] * metrics.height()) / 400), ch)
            x += metrics.width(ch)

    def setText(self, newText):
        self.text = newText

    def setspreed(self, spreed):
        self.spreed = spreed
        self.timer.stop()
        self.timer.start(self.spreed, self)

    def timerEvent(self, event):
        if self.text:
            if event.timerId() == self.timer.timerId():
                self.step += 1
                self.update()
            else:
                super(DynamicTextWidget, self).timerEvent(event)
        else:
            self.timer.stop()

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    styleoptions = {
        'title': u'退出设置',
        'windowicon': "../skin/images/ov-orange-green.png",
        'minsize': (400, 300),
        'size': (400, 300),
        'logo_title': u'dssssssss',
        'logo_img_url': "../skin/images/ov-orange-green.png"
    }
    dialog = BaseDialog(styleoptions)
    dialog.show()
    sys.exit(app.exec_())


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

import pickle
from datetime import datetime
from io import StringIO
from pathlib import Path

from ruamel.yaml import YAML, RoundTripRepresenter

from sl_maptools import CoordType, RegionsDBRecord3

DB_PATH = Path(r"C:\Cache\SL-Carto\RegionsDB3.pkl")
CUTOFF = 3

_NAO = datetime.now().astimezone()

DATABASE: dict[CoordType, RegionsDBRecord3] = {}

def main():
    global DATABASE

    with DB_PATH.open("rb") as fin:
        DATABASE.update(pickle.load(fin))

    yaml = YAML()
    yaml.Representer = RoundTripRepresenter

    region_locations: dict[str, set[CoordType]] = {}
    for co, data in DATABASE.items():
        if not data["current_name"]:
            continue
        if data["current_name"] == "Beorn City":
            with StringIO() as fout:
                yaml.dump({str(co): data}, fout)
                fout.seek(0)
                print(fout.read())
        region_locations.setdefault(data["current_name"], set()).add(co)
        for hname in data["name_history3"]:
            if not hname:
                continue
            region_locations.setdefault(hname, set()).add(co)

    for name, locs in sorted(region_locations.items()):
        if len(locs) < 2:
            continue
        print(f"{name}: {locs}")

if __name__ == '__main__':
    main()


from collections import defaultdict

dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

def bfs(v, y, x, edges):
    n = len(v)
    m = len(v[0])

    q = [(y, x)]
    vis = set()
    vis.add((y, x))

    while len(q) > 0:
        (y, x) = q.pop(0)

        for i in range(4):
            ny = y + dy[i]
            nx = x + dx[i]

            if ny < 0 or nx < 0 or ny == n or nx == m: continue
            if v[y][x] != v[ny][nx]:
                edges[v[y][x]].add(v[ny][nx])
            if (ny, nx) not in vis:
                vis.add((ny, nx))
                q.append((ny, nx))

def check(edges, color):
    for x, v in edges.items():
        for y in v:
            if color[x] == color[y]: return False
    return True

def dfs(x, c, edges, color):
    if x == len(edges):
        return check(edges, color)
    for i in range(c):
        color[list(edges.keys())[x]] = i
        if dfs(x + 1, c, edges, color): return True
    return False

def can_color(c, edges):
    return dfs(0, c, edges, {})

def color(testmap):
    edges = defaultdict(set)
    bfs(testmap.strip().split('\n'), 0, 0, edges)

    if len(edges) <= 1: return 1
    if can_color(2, edges): return 2
    if can_color(3, edges): return 3
    return 4

codewars/4kyu/4_Four Color Theorem (Easy Version).py


# test for tm1637.py

import time
import datetime
import RPi.GPIO as GPIO
import tm1637

def show_time():
   while(True):
       now = datetime.datetime.now()
       hour = now.hour
       minute = now.minute
       second = now.second
       currenttime = [ repr(int(hour / 10)), repr(hour % 10),
                       repr(int(minute / 10)), repr(minute % 10) ]

       Display.Show(currenttime)
       Display.ShowDoublepoint(second % 2) # 0, 1

       time.sleep(1)

Display = tm1637.TM1637(23,24,tm1637.BRIGHT_TYPICAL)

Display.Clear() #
Display.SetBrightnes(2)

Display.Show(['0', '1', '2', '3'])
Display.ShowDoublepoint(0)
time.sleep(3)

Display.Show(['C', 'O', 'O', 'L'])
Display.ShowDoublepoint(1)
time.sleep(3)

Display.Show([' ', '-', '*', 'Unknown'])
Display.ShowDoublepoint(1)
time.sleep(3)

Display.Clear()
show_time()


from typing import Any, Dict, Tuple

from gymnasium.core import ActionWrapper

class UsefulActionsWrapper(ActionWrapper):
    """
    A wrapper returning negative reward in observation doesn't change.

    >>> import gymnasium as gym
    >>> env = gym.make("Vampair-v0", max_clauses=10)
    >>> wrapped_env = UsefulActionsWrapper(env)

    although it's an action wrapper, the ``action`` method does nothing

    >>> wrapped_env.action(0)
    0
    >>> _ = wrapped_env.reset()
    >>> _, reward, _, _, _ = wrapped_env.step((0, 2))
    >>> reward
    0.0

    repeating an action is useless and results in a negative reward

    >>> _, reward, _, _, _ = wrapped_env.step((0, 2))
    >>> reward
    -1.0
    """

    def step(
        self, action: Any
    ) -> Tuple[Any, float, bool, bool, Dict[str, Any]]:
        """
        Run the ``step`` and modify ``action``.

        :param action: action selected by an agent
        :return: standard Gymnasium ``step`` results
        """
        old_state_size = len(self.env.unwrapped.state.clauses)  # type: ignore
        observation, reward, terminated, truncated, info = self.env.step(
            action
        )
        return (
            observation,
            -1.0
            if len(self.env.unwrapped.state.clauses)  # type: ignore
            == old_state_size
            else reward,
            terminated,
            truncated,
            info,
        )

    def action(self, action: Any) -> Any:
        """Return the non-modified action. Left for compatibility.

        :param action: the original  actions
        :returns: the non-modified actions
        """
        return action


n=int(input())
a=sorted(set(list(map(int,input().split()))))
if(len(a)==1):
    print('0')
elif(len(a)==2):
    x=a[1]-a[0]
    if(x%2==0):
        print(x//2)
    else:
        print(x)
elif(len(a)==3):
    if(a[1]-a[0]==a[2]-a[1]):
        print(a[1]-a[0])
    else:
        print('-1')
else:
    print('-1')


# coding: utf-8
'''
Created on Dec 30, 2019

@author: guimaizi
'''
import config_function,http_testing
class waf_test:
    def __init__(self):
        '''waf测试'''
        self.config=config_function.config_function()
        self.http_testing=http_testing.http_testing()
    def dict_waf(self,data):
        for i in ['501page.html','501 Not Implemented','501 by TSW']:
            if i in data:
                return False
        return True
    def run(self):
        data=self.config.callback_target()
        data['url']=data['url']+'<img src=a onerror=alert()>'
        if self.dict_waf(self.http_testing.callback_response(data))==False:
            self.config.Generated_text('have waf...')
            return 0

if __name__ == '__main__':
    p1=waf_test()
    p1.run()


from django.db import models

# Create your models here.

class Comment(models.Model):
    text = models.TextField(max_length=240)
    quote = models.ForeignKey(
      'quotes.quotes',
      related_name='comments',
      on_delete=models.CASCADE
  )


import argparse
import json
import logging
import os
from pathlib import Path
from traceback import format_exc
from typing import List, IO, Dict, Any

class Config(object):
    DIR_KEY: str = "_dir"
    FILE_KEY: str = "_file"

    # Command line arguments take precedence over config file values
    def __init__(self, name: str, args: Dict):
        self.name = name
        self.base_dir = f"{Path.home()}/.{name}"
        self._defaults = {}
        self.conf = {}

        try:
            # the slash does work either way on windows, but including a standard one for compatibility
            conf_file_locations: List[str] = [args.get('config_file', ''),
                                              f"{self.base_dir}/config.json",
                                              f"{os.getcwd()}/config.json",
                                              f"{os.getcwd()}\\config.json"]

            f = self._open_config(conf_file_locations)
            conf: Dict = json.load(f)
            # We want to remove all the keys with value None so that the merge works as expected. At this point
            # writing our own merge method that does all of this in one pass is prob more efficient but not worth the
            # effort.args is of type Namespace, we want a dict, hence vars()

            # In this merge, command line arguments take precedence over config file values, which take precedence over
            # hardcoded default values
            self.conf: Dict = {**self.defaults(), **conf, **args}
        except Exception as ex:
            logging.error(f"Failed to initialize {self.name}: {repr(ex)}")
            logging.debug(format_exc())

    def defaults(self):
        return self._defaults

    @classmethod
    def from_args(cls, name: str, args: argparse.Namespace):
        args_dict: Dict = {k: v for k, v in vars(args).items() if v is not None}
        return cls(name, args_dict)

    def _open_config(self, paths: List[str]) -> IO:
        for p in paths:
            try:
                f = open(p, 'r')
                logging.info(f"Using config file at {p}")
                return f
            except OSError as err:
                logging.debug(f"Could not find/open config file {p}: {repr(err)}")

        logging.error("Failed to find any configuration file. Exiting")

    def __getitem__(self, key: str) -> Any:
        attr = ''  # type checker error if not defined

        try:
            attr = self.conf[key]
        except KeyError:
            logging.warning(f"Property {key} not found in configuration")
            return None

        # Some smarts to try and provide absolute paths when the attribute requested is a dir or a file
        if key.endswith(self.DIR_KEY) or key.endswith(self.FILE_KEY):
            logging.debug(f"Converted {attr} to a path because it ({key}) ends with {self.DIR_KEY} or {self.FILE_KEY}")
            try:
                attr = Path(attr).resolve()
            except TypeError:
                logging.error(f"Tried to convert {attr} to a Path but failed.")
                logging.debug(format_exc())
        return attr

    def __setitem__(self, key: str, value: Any) -> None:
        # We really probably don't want to be overwriting any of our config stuff, but don't prevent it
        if key in self.conf:
            logging.warning(f"Overwriting {key} with value {value} (previously {self.conf[value]}")
        else:
            logging.debug(f"Setting {key} to {value}")

        self.conf[key] = value