import datetime
import os.path
import re
import shutil

from lxml import etree

import log
from app.conf import SiteConf
from app.helper import OpenSubtitles
from app.utils import RequestUtils, PathUtils, SystemUtils, StringUtils, ExceptionUtils
from app.utils.commons import singleton
from app.utils.types import MediaType
from config import Config, RMT_SUBEXT

@singleton
class Subtitle:
    opensubtitles = None
    _save_tmp_path = None
    _server = None
    _host = None
    _api_key = None
    _remote_path = None
    _local_path = None
    _opensubtitles_enable = False

    def __init__(self):
        self.init_config()

    def init_config(self):
        self.opensubtitles = OpenSubtitles()
        self._save_tmp_path = Config().get_temp_path()
        if not os.path.exists(self._save_tmp_path):
            os.makedirs(self._save_tmp_path)
        subtitle = Config().get_config('subtitle')
        if subtitle:
            self._server = subtitle.get("server")
            if self._server == "chinesesubfinder":
                self._api_key = subtitle.get("chinesesubfinder", {}).get("api_key")
                self._host = subtitle.get("chinesesubfinder", {}).get('host')
                if self._host:
                    if not self._host.startswith('http'):
                        self._host = "http://" + self._host
                    if not self._host.endswith('/'):
                        self._host = self._host + "/"
                self._local_path = subtitle.get("chinesesubfinder", {}).get("local_path")
                self._remote_path = subtitle.get("chinesesubfinder", {}).get("remote_path")
            else:
                self._opensubtitles_enable = subtitle.get("opensubtitles", {}).get("enable")

    def download_subtitle(self, items, server=None):
        """
        字幕下载入口
        :param items: {"type":, "file", "file_ext":, "name":, "title", "year":, "season":, "episode":, "bluray":}
        :param server: 字幕下载服务器
        :return: 是否成功，消息内容
        """
        if not items:
            return False, "参数有误"
        _server = self._server if not server else server
        if not _server:
            return False, "未配置字幕下载器"
        if _server == "opensubtitles":
            if server or self._opensubtitles_enable:
                return self.__download_opensubtitles(items)
        elif _server == "chinesesubfinder":
            return self.__download_chinesesubfinder(items)
        return False, "未配置字幕下载器"

    def __search_opensubtitles(self, item):
        """
        爬取OpenSubtitles.org字幕
        """
        if not self.opensubtitles:
            return []
        return self.opensubtitles.search_subtitles(item)

    def __download_opensubtitles(self, items):
        """
        调用OpenSubtitles Api下载字幕
        """
        if not self.opensubtitles:
            return False, "未配置OpenSubtitles"
        subtitles_cache = {}
        success = False
        ret_msg = ""
        for item in items:
            if not item:
                continue
            if not item.get("name") or not item.get("file"):
                continue
            if item.get("type") == MediaType.TV and not item.get("imdbid"):
                log.warn("【Subtitle】电视剧类型需要imdbid检索字幕，跳过...")
                ret_msg = "电视剧需要imdbid检索字幕"
                continue
            subtitles = subtitles_cache.get(item.get("name"))
            if subtitles is None:
                log.info(
                    "【Subtitle】开始从Opensubtitle.org检索字幕: %s，imdbid=%s" % (item.get("name"), item.get("imdbid")))
                subtitles = self.__search_opensubtitles(item)
                if not subtitles:
                    subtitles_cache[item.get("name")] = []
                    log.info("【Subtitle】%s 未检索到字幕" % item.get("name"))
                    ret_msg = "%s 未检索到字幕" % item.get("name")
                else:
                    subtitles_cache[item.get("name")] = subtitles
                    log.info("【Subtitle】opensubtitles.org返回数据：%s" % len(subtitles))
            if not subtitles:
                continue
            # 成功数
            subtitle_count = 0
            for subtitle in subtitles:
                # 标题
                if not item.get("imdbid"):
                    if str(subtitle.get('title')) != "%s (%s)" % (item.get("name"), item.get("year")):
                        continue
                # 季
                if item.get('season') \
                        and str(subtitle.get('season').replace("Season", "").strip()) != str(item.get('season')):
                    continue
                # 集
                if item.get('episode') \
                        and str(subtitle.get('episode')) != str(item.get('episode')):
                    continue
                # 字幕文件名
                SubFileName = subtitle.get('description')
                # 下载链接
                Download_Link = subtitle.get('link')
                # 下载后的字幕文件路径
                Media_File = "%s.chi.zh-cn%s" % (item.get("file"), item.get("file_ext"))
                log.info("【Subtitle】正在从opensubtitles.org下载字幕 %s 到 %s " % (SubFileName, Media_File))
                # 下载
                ret = RequestUtils(cookies=self.opensubtitles.get_cookie(),
                                   headers=self.opensubtitles.get_ua()).get_res(Download_Link)
                if ret and ret.status_code == 200:
                    # 保存ZIP
                    file_name = self.__get_url_subtitle_name(ret.headers.get('content-disposition'), Download_Link)
                    if not file_name:
                        continue
                    zip_file = os.path.join(self._save_tmp_path, file_name)
                    zip_path = os.path.splitext(zip_file)[0]
                    with open(zip_file, 'wb') as f:
                        f.write(ret.content)
                    # 解压文件
                    shutil.unpack_archive(zip_file, zip_path, format='zip')
                    # 遍历转移文件
                    for sub_file in PathUtils.get_dir_files(in_path=zip_path, exts=RMT_SUBEXT):
                        self.__transfer_subtitle(sub_file, Media_File)
                    # 删除临时文件
                    try:
                        shutil.rmtree(zip_path)
                        os.remove(zip_file)
                    except Exception as err:
                        ExceptionUtils.exception_traceback(err)
                else:
                    log.error("【Subtitle】下载字幕文件失败：%s" % Download_Link)
                    continue
                # 最多下载3个字幕
                subtitle_count += 1
                if subtitle_count > 2:
                    break
            if not subtitle_count:
                if item.get('episode'):
                    log.info("【Subtitle】%s 第%s季 第%s集 未找到符合条件的字幕" % (
                        item.get("name"), item.get("season"), item.get("episode")))
                    ret_msg = "%s 第%s季 第%s集 未找到符合条件的字幕" % (
                        item.get("name"), item.get("season"), item.get("episode"))
                else:
                    log.info("【Subtitle】%s 未找到符合条件的字幕" % item.get("name"))
                    ret_msg = "%s 未找到符合条件的字幕" % item.get("name")
            else:
                log.info("【Subtitle】%s 共下载了 %s 个字幕" % (item.get("name"), subtitle_count))
                ret_msg = "%s 共下载了 %s 个字幕" % (item.get("name"), subtitle_count)
                success = True
        if success:
            return True, ret_msg
        else:
            return False, ret_msg

    def __download_chinesesubfinder(self, items):
        """
        调用ChineseSubFinder下载字幕
        """
        if not self._host or not self._api_key:
            return False, "未配置ChineseSubFinder"
        req_url = "%sapi/v1/add-job" % self._host
        notify_items = []
        success = False
        ret_msg = ""
        for item in items:
            if not item:
                continue
            if not item.get("name") or not item.get("file"):
                continue
            if item.get("bluray"):
                file_path = "%s.mp4" % item.get("file")
            else:
                if os.path.splitext(item.get("file"))[-1] != item.get("file_ext"):
                    file_path = "%s%s" % (item.get("file"), item.get("file_ext"))
                else:
                    file_path = item.get("file")

            # 路径替换
            if self._local_path and self._remote_path and file_path.startswith(self._local_path):
                file_path = file_path.replace(self._local_path, self._remote_path).replace('\\', '/')

            # 一个名称只建一个任务
            if file_path not in notify_items:
                notify_items.append(file_path)
                log.info("【Subtitle】通知ChineseSubFinder下载字幕: %s" % file_path)
                params = {
                    "video_type": 0 if item.get("type") == MediaType.MOVIE else 1,
                    "physical_video_file_full_path": file_path,
                    "task_priority_level": 3,
                    "media_server_inside_video_id": "",
                    "is_bluray": item.get("bluray")
                }
                try:
                    res = RequestUtils(headers={
                        "Authorization": "Bearer %s" % self._api_key
                    }).post(req_url, json=params)
                    if not res or res.status_code != 200:
                        log.error("【Subtitle】调用ChineseSubFinder API失败！")
                        ret_msg = "调用ChineseSubFinder API失败"
                    else:
                        # 如果文件目录没有识别的nfo元数据， 此接口会返回控制符，推测是ChineseSubFinder的原因
                        # emby refresh元数据时异步的
                        if res.text:
                            job_id = res.json().get("job_id")
                            message = res.json().get("message")
                            if not job_id:
                                log.warn("【Subtitle】ChineseSubFinder下载字幕出错：%s" % message)
                                ret_msg = "ChineseSubFinder下载字幕出错：%s" % message
                            else:
                                log.info("【Subtitle】ChineseSubFinder任务添加成功：%s" % job_id)
                                ret_msg = "ChineseSubFinder任务添加成功：%s" % job_id
                                success = True
                        else:
                            log.error("【Subtitle】%s 目录缺失nfo元数据" % file_path)
                            ret_msg = "%s 目录下缺失nfo元数据：" % file_path
                except Exception as e:
                    ExceptionUtils.exception_traceback(e)
                    log.error("【Subtitle】连接ChineseSubFinder出错：" + str(e))
                    ret_msg = "连接ChineseSubFinder出错：%s" % str(e)
        if success:
            return True, ret_msg
        else:
            return False, ret_msg

    @staticmethod
    def __transfer_subtitle(sub_file, media_file):
        """
        转移字幕
        """
        new_sub_file = "%s%s" % (os.path.splitext(media_file)[0], os.path.splitext(sub_file)[-1])
        if os.path.exists(new_sub_file):
            return 1
        else:
            return SystemUtils.copy(sub_file, new_sub_file)

    def download_subtitle_from_site(self, media_info, cookie, ua, download_dir):
        """
        从站点下载字幕文件，并保存到本地
        """
        if not media_info.page_url:
            return
        # 字幕下载目录
        log.info("【Subtitle】开始从站点下载字幕：%s" % media_info.page_url)
        if not download_dir:
            log.warn("【Subtitle】未找到字幕下载目录")
            return
        # 读取网站代码
        request = RequestUtils(cookies=cookie, headers=ua)
        res = request.get_res(media_info.page_url)
        if res and res.status_code == 200:
            if not res.text:
                log.warn(f"【Subtitle】读取页面代码失败：{media_info.page_url}")
                return
            html = etree.HTML(res.text)
            sublink_list = []
            for xpath in SiteConf.SITE_SUBTITLE_XPATH:
                sublinks = html.xpath(xpath)
                if sublinks:
                    for sublink in sublinks:
                        if not sublink:
                            continue
                        if not sublink.startswith("http"):
                            base_url = StringUtils.get_base_url(media_info.page_url)
                            if sublink.startswith("/"):
                                sublink = "%s%s" % (base_url, sublink)
                            else:
                                sublink = "%s/%s" % (base_url, sublink)
                        sublink_list.append(sublink)
            # 下载所有字幕文件
            for sublink in sublink_list:
                log.info(f"【Subtitle】找到字幕下载链接：{sublink}，开始下载...")
                # 下载
                ret = request.get_res(sublink)
                if ret and ret.status_code == 200:
                    # 创建目录
                    if not os.path.exists(download_dir):
                        os.makedirs(download_dir)
                    # 保存ZIP
                    file_name = self.__get_url_subtitle_name(ret.headers.get('content-disposition'), sublink)
                    if not file_name:
                        log.warn(f"【Subtitle】链接不是字幕文件：{sublink}")
                        continue
                    if file_name.lower().endswith(".zip"):
                        # ZIP包
                        zip_file = os.path.join(self._save_tmp_path, file_name)
                        # 解压路径
                        zip_path = os.path.splitext(zip_file)[0]
                        with open(zip_file, 'wb') as f:
                            f.write(ret.content)
                        # 解压文件
                        shutil.unpack_archive(zip_file, zip_path, format='zip')
                        # 遍历转移文件
                        for sub_file in PathUtils.get_dir_files(in_path=zip_path, exts=RMT_SUBEXT):
                            target_sub_file = os.path.join(download_dir,
                                                           os.path.splitext(os.path.basename(sub_file))[0])
                            log.info(f"【Subtitle】转移字幕 {sub_file} 到 {target_sub_file}")
                            self.__transfer_subtitle(sub_file, target_sub_file)
                        # 删除临时文件
                        try:
                            shutil.rmtree(zip_path)
                            os.remove(zip_file)
                        except Exception as err:
                            ExceptionUtils.exception_traceback(err)
                    else:
                        sub_file = os.path.join(self._save_tmp_path, file_name)
                        # 保存
                        with open(sub_file, 'wb') as f:
                            f.write(ret.content)
                        target_sub_file = os.path.join(download_dir,
                                                       os.path.splitext(os.path.basename(sub_file))[0])
                        log.info(f"【Subtitle】转移字幕 {sub_file} 到 {target_sub_file}")
                        self.__transfer_subtitle(sub_file, target_sub_file)
                else:
                    log.error(f"【Subtitle】下载字幕文件失败：{sublink}")
                    continue
            if sublink_list:
                log.info(f"【Subtitle】{media_info.page_url} 页面字幕下载完成")
        elif res is not None:
            log.warn(f"【Subtitle】连接 {media_info.page_url} 失败，状态码：{res.status_code}")
        else:
            log.warn(f"【Subtitle】无法打开链接：{media_info.page_url}")

    @staticmethod
    def __get_url_subtitle_name(disposition, url):
        """
        从下载请求中获取字幕文件名
        """
        file_name = re.findall(r"filename=\"?(.+)\"?", disposition or "")
        if file_name:
            file_name = str(file_name[0].encode('ISO-8859-1').decode()).split(";")[0].strip()
            if file_name.endswith('"'):
                file_name = file_name[:-1]
        elif url and os.path.splitext(url)[-1] in (RMT_SUBEXT + ['.zip']):
            file_name = url.split("/")[-1]
        else:
            file_name = str(datetime.datetime.now())
        return file_name


import cadquery as cq

# Set up the length, width, and thickness
(L,w,t) = (20.0, 6.0, 3.0)
s = cq.Workplane("XY")

# Draw half the profile of the bottle, mirror it, and extrude it
p = (s.center(-L/2.0, 0).vLine(w/2.0)
    .threePointArc((L/2.0, w/2.0 + t),(L, w/2.0)).vLine(-w/2.0)
    .mirrorX().extrude(30.0,True))

# Make the neck
p = p.faces(">Z").workplane(centerOption="CenterOfMass").circle(3.0).extrude(2.0,True)

# Make the bottle a shell
result = p.faces(">Z").shell(0.3)

# Displays the result of this script
show_object(result)


import random
import tkinter
from tkinter import Tk

def zar():
    a=random.randint(1,6)
    b=random.randint(1,6)

    zar1sonuc.config(text=a)
    zar2sonuc.config(text=b)

pencere=Tk()
pencere.geometry("240x240")
pencere.title("ZAR SİMİLASYON")
pencere.config(bg="yellow")

zar1=tkinter.Label(pencere,font=("arial",18,"bold"),text="1.ZAR",fg="red",bg="black")
zar1.place(x=20,y=5)

zar1sonuc=tkinter.Label(pencere,font=("arial",48,"bold"),bg="yellow")
zar1sonuc.place(x=40,y=50)

zar2=tkinter.Label(pencere,font=("arial",18,"bold"),text="2.ZAR",fg="red",bg="black")
zar2.place(x=150,y=5)

zar2sonuc=tkinter.Label(font=("arial",48,"bold"),bg="yellow")
zar2sonuc.place(x=180,y=50)

buton=tkinter.Button(pencere,text="ZAR AT",font=("arial",20,"bold"),command=zar)
buton.place(x=60,y=180)

pencere.mainloop()


#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Problem definition:

https://www.hackerrank.com/challenges/collections-counter/problem

"""

from collections import Counter
import sys

class ProblemAttributes(object):
    number_of_shoes = 0
    shoes_sizes = list()
    number_of_customers = 0
    attribute_index = 0
    total = 0

def command_line():
    parse_first_line()
    parse_second_line()
    parse_third_line()
    for _ in range(ProblemAttributes.number_of_customers):
        size, price = tuple(map(int, input().rstrip().split()))
        if not 20 <= price <= 100:
            raise ValueError(
                "The value of a shoe must be within range 20 < price < 100")
        calculate(size, price)

def parse_first_line():
    nm = input()
    ProblemAttributes.number_of_shoes = int(nm)
    assert 0 < ProblemAttributes.number_of_shoes < 1000, \
        "Number of shoes must be within range 0 < number of shoes < 1000"

def parse_second_line():
    nm = input().strip().split()
    ProblemAttributes.shoes_sizes = Counter(map(int, nm))
    assert all([2 <= size <= 20 for size in ProblemAttributes.shoes_sizes.keys()]), \
        "All shoe sizes must be within range 2 < size < 20"

def parse_third_line():
    nm = input()
    ProblemAttributes.number_of_customers = int(nm)
    assert 0 < ProblemAttributes.number_of_customers <= 1000, \
        "Number of customers must be within range 0 < number of customers <= 1000"

def calculate(size, price):
    if size in ProblemAttributes.shoes_sizes:
        if ProblemAttributes.shoes_sizes[size] < 1:
            ProblemAttributes.shoes_sizes.pop(size)
            return
        ProblemAttributes.total += price
        ProblemAttributes.shoes_sizes[size] -= 1

def main():
    command_line()
    print(ProblemAttributes.total)

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


# pylint: disable= no-else-return

# Misc defines
MCP23017_DEFAULT_ADDR = 0x20
MCP23017_ADDR_0 = 0x20
MCP23017_ADDR_1 = 0x21

# SPI defines
SPI_MCP23S17_DEVICE = 2 # SPI1_CE2
SPI_MCP23S17_PORT = 1
SPI_SPEED = 40000  # lowered the speed for test purpose

SPI_MODE_0 = 0b00
SPI_MODE_1 = 0b01
SPI_MODE_2 = 0b10
SPI_MODE_3 = 0b11

DUMMY_BYTE = 0x00
PADDING_BYTE = 0x00

# in/out mode
IN = 1
OUT = 0

# on/off mode
OFF = 0
ON = 1

# level
HIGH = 1
LOW = 0

ERROR_MSG = 'Err: Invalid input'
MEAS_CURR = 0
MEAS_VOLT = 1

# Relay index controlled by MCP23017 (addr=0)
DC_300V = 0
AC_230V = 1
PROTECTED_EARTH = 2
p_24V = 3
p_5V = 4

# port B
S1 = 0
S2 = 1
READY = 2
SAFE =  3
RESET = 4

# Relay names controlled by MCP23017 (addr=1)
RELAY1 = 0
RELAY2 = 1
RELAY3 = 2
RELAY4 = 3
RELAY5 = 4
RELAY6 = 5
RELAY7 = 6
RELAY8 = 7
RELAY9 = 8
RELAY10 =9
RELAY11 = 10
RELAY12 = 11
RELAY13 = 12
RELAY14 = 13
RELAY15 = 14
RELAY16 = 15

# -------------------------------------------------------------
# MCP23017
# -------------------------------------------------------------
# Registers port A for MCP23017 (I2C)
I2C_IODIRA = 0x00
I2C_IOPOLA = 0x02
I2C_GPIOA = 0x12

# pin numbers for MCP23017, addr=0x20
I2C_GPA0 = 0  # 24V_on
I2C_GPA1 = 1  # Ext_pwr_on
I2C_GPA2 = 2  # 5V/3V_on
I2C_GPA3 = 3  # Shut down
I2C_GPA4 = 4  # S/W_RES
I2C_GPA5 = 5  # Detect
I2C_GPA6 = 6  # Spare0
I2C_GPA7 = 7  # Spare1

# Registers port B for MCP23017 (I2C)
I2C_IODIRB = 0x01
I2C_IOPOLB = 0x03
I2C_GPIOB = 0x13
# pin numbers
I2C_GPB0 = 0  # Spare0
I2C_GPB1 = 1  # Spare1
I2C_GPB2 = 2  # Spare2
I2C_GPB3 = 3  # Spare3
I2C_GPB4 = 4  # Spare4
I2C_GPB5 = 5  # CE_A0
I2C_GPB6 = 6  # CE_A1
I2C_GPB7 = 7  # CE_A2

# -------------------------------------------------------------
# MCP23S17
# -------------------------------------------------------------
SPI_IOCON = 0x0a
# Registers port A for MCP23S17 (SPI)
SPI_IODIRA = 0x00
SPI_IOPOLA = 0x02
SPI_GPPUA = 0x0c
SPI_GPIOA = 0x12
# pin numbers
SPI_GPA0 = 0  #
SPI_GPA1 = 1  #
SPI_GPA2 = 2  #
SPI_GPA3 = 3  #
SPI_GPA4 = 4  #
SPI_GPA5 = 5  # DigOut1
SPI_GPA6 = 6  # DigOut2
SPI_GPA7 = 7  #

# Registers port B for MCP23S17 (SPI)
SPI_IODIRB = 0x01
SPI_IOPOLB = 0x03
SPI_GPPUB = 0x0d
SPI_GPIOB = 0x13
# pin numbers
SPI_GPB0 = 0  #
SPI_GPB1 = 1  #
SPI_GPB2 = 2  #
SPI_GPB3 = 3  #
SPI_GPB4 = 4  #
SPI_GPB5 = 5  #
SPI_GPB6 = 6  #
SPI_GPB7 = 7  #

SPI_MAX_GPIO_PORT = 7

# Device parameters
DAC61408_DEVICE = 0
AD4112_DEVICE_0 = 1
AD4112_DEVICE_1 = 2
MCP23S17_DEVICE_0 = 3
MCP23S17_DEVICE_1 = 4

MCP23S17_ADDR_0 = 0
MCP23S17_ADDR_1 = 1

SPI_ADDRESS_0 = 0
SPI_ADDRESS_1 = 1

# -------------------------------------------------------------
# DAC61408
# -------------------------------------------------------------
# Register for DAC61408
DAC0 = 0x14
DAC1 = 0x15
DAC2 = 0x16
DAC3 = 0x17
DAC4 = 0x18
DAC5 = 0x19
DAC6 = 0x1a
DAC7 = 0x1b
DAC_STATUS = 0x02
SPICONFIG = 0x03
GENCONFIG = 0x04
GPIOCON = 0x06
DACPWDWN = 0x09
DACRANGE0 = 0x0b  # DAC[7:4]
DACRANGE1 = 0x0c  # DAC[3:0]

# DAC61408 parameters
DAC_RANGE_0V_p5V = 0x0  # 0 to 5V
DAC_RANGE_0V_p10V = 0x1  # 0 to 10V
DAC_RANGE_m5V_p5V = 0x9  # -5 to +5V
DAC_RANGE_m10V_p10V = 0xa  # -10 to +10V

# -------------------------------------------------------------
# AD4112
# -------------------------------------------------------------
# Register for AD4112
COMMS = 0x00  # Communication register. All access must start here. (W)
STATUS = 0x00  # Status information (R)
ADCMODE = 0x01
IFMODE = 0x02
DATA = 0x04  # The data register contains the ADC conversion result (R)
ID = 0x07

CH0 = 0x10 # Channel control register (R/W)
CH1 = 0x11
CH2 = 0x12
CH3 = 0x13
CH4 = 0x14
CH5 = 0x15
CH6 = 0x16
CH7 = 0x17
CH8 = 0x18
CH9 = 0x19
CH10 = 0x1a
CH11 = 0x1b
CH12 = 0x1c
CH13 = 0x1d
CH14 = 0x1e
CH15 = 0x1f

SETUPCON0 = 0x20  # Setup configuration register (R/W)
SETUPCON1 = 0x21
SETUPCON2 = 0x22
SETUPCON3 = 0x23
SETUPCON4 = 0x24
SETUPCON5 = 0x25
SETUPCON6 = 0x26
SETUPCON7 = 0x27

OFFSET0 = 0x30
OFFSET1 = 0x31

GAIN0 = 0x38
GAIN1 = 0x39

# AD412 parameters
RD = 0x40 # read bit in COMMS register
VIN0 = 0
VIN1 = 1
VIN2 = 2
VIN3 = 3
VIN4 = 4
VIN5 = 5
VIN6 = 6
VIN7 = 7

VIN0_VINCOM = 0x010  # Channel register CH<n>, voltage input to voltage input common
VIN1_VINCOM = 0x030
VIN2_VINCOM = 0x050
VIN3_VINCOM = 0x070
VIN4_VINCOM = 0x090
VIN5_VINCOM = 0x0b0
VIN6_VINCOM = 0x0d0
VIN6_VINCOM = 0x0f0

GP_DATA0 = 0x80  # bit 6 in GPIOCON
GP_DATA1 = 0x40  # bit 7 in GPIOCON

INT_OFFSET = 4
INT_GAIN = 5
SYSTEM_OFFSET = 6
SYSTEM_GAIN = 7

# Channel register CH0-CH7, 0x10 - 0x1f
CH_EN = 0x8000
SETUP_SEL_0 = 0x0000
SETUP_SEL_1 = 0x1000
SETUP_SEL_2 = 0x2000
SETUP_SEL_3 = 0x3000
SETUP_SEL_4 = 0x4000
SETUP_SEL_5 = 0x5000
SETUP_SEL_6 = 0x6000
SETUP_SEL_7 = 0x7000

INPUT_VIN0 = 0x0010
INPUT_VIN1 = 0x0030
INPUT_VIN2 = 0x0050
INPUT_VIN3 = 0x0070
INPUT_VIN4 = 0x0090
INPUT_VIN5 = 0x00b0
INPUT_VIN6 = 0x00d0
INPUT_VIN7 = 0x00f0

INPUT_VIN0_VIN1 = 0x0001
INPUT_VIN1_VIN0 = 0x0020
INPUT_VIN2_VIN3 = 0x0043
INPUT_VIN3_VIN2 = 0x0062
INPUT_VIN4_VIN5 = 0x0085
INPUT_VIN5_VIN4 = 0x00a4
INPUT_VIN6_VIN7 = 0x00c7
INPUT_VIN7_VIN6 = 0x00e6

IIN3 = 0x018b
IIN2 = 0x01aa
IIN2 = 0x01aa
IIN1 = 0x01c9
IIN0 = 0x01e8

# ADC mode register ADCMODE, 0x01
REF_EN = 0x8000
SING_SYNC = 0x2000
CONT_CONV = 0x0000
SING_CONV = 0x0010

# Channel register IFMODE, 0x02
CONTREAD = 0x80
DATA_STAT = 0x40

# Configuration register, SETUPCON0-7
BI_POLAR = 0x1000
REF_BUFP = 0x0800
REF_BUFM = 0x0400
INBUF_EN = 0x0300
REF_SEL_INT = 0x0020

# ------------------------------------------------------------------
# help functions
# ------------------------------------------------------------------
def ad4112_get_adc_mode_name(inp):
	if inp == CONT_CONV:
		return 'CONT_CONV'
	elif inp == SING_CONV:
		return 'SING_CONV'
	else:
		return ERROR_MSG

setup_name = {
    SETUP_SEL_0: lambda: "SETUP_SEL_0",
    SETUP_SEL_1: lambda: "SETUP_SEL_1",
    SETUP_SEL_2: lambda: "SETUP_SEL_2",
    SETUP_SEL_3: lambda: "SETUP_SEL_3",
    SETUP_SEL_4: lambda: "SETUP_SEL_4",
    SETUP_SEL_5: lambda: "SETUP_SEL_5",
    SETUP_SEL_6: lambda: "SETUP_SEL_6",
    SETUP_SEL_7: lambda: "SETUP_SEL_7",
}

def ad4112_get_setup_name(inp):
	return setup_name[inp]()

input_name = {
    INPUT_VIN0: lambda: "INPUT_VIN0",
    INPUT_VIN1: lambda: "INPUT_VIN1",
    INPUT_VIN2: lambda: "INPUT_VIN2",
    INPUT_VIN3: lambda: "INPUT_VIN3",
    INPUT_VIN4: lambda: "INPUT_VIN4",
    INPUT_VIN5: lambda: "INPUT_VIN5",
    INPUT_VIN6: lambda: "INPUT_VIN6",
    INPUT_VIN7: lambda: "INPUT_VIN7",
    INPUT_VIN0_VIN1: lambda: "INPUT_VIN0_VIN1",
    INPUT_VIN1_VIN0: lambda: "INPUT_VIN1_VIN0",
    INPUT_VIN2_VIN3: lambda: "INPUT_VIN2_VIN3",
    INPUT_VIN3_VIN2: lambda: "INPUT_VIN3_VIN2",
    INPUT_VIN4_VIN5: lambda: "INPUT_VIN4_VIN5",
    INPUT_VIN5_VIN4: lambda: "INPUT_VIN5_VIN4",
    INPUT_VIN6_VIN7: lambda: "INPUT_VIN6_VIN7",
    INPUT_VIN7_VIN6: lambda: "INPUT_VIN7_VIN6",
    IIN0: lambda: "IIN0+,IIN0-",
    IIN1: lambda: "III1+,IIN1-",
    IIN2: lambda: "III2+,IIN2-",
    IIN3: lambda: "III3+,IIN3-",
}

def ad4112_get_input_name(inp):
	return input_name[inp]()

def ad4112_get_stat_name(inp):
	if inp == DATA_STAT:
		return 'DATA_STAT'
	else:
		return ERROR_MSG

def mcp23017_get_mode_name(inp):
	if inp == OUT:
		return 'OUT'
	else:
		return 'IN'

def mcp23017_get_level_name(inp):
	if inp == ON:
		return 'ON'
	else:
		return 'OFF'

def mcp23017_get_power_name(inp):
	if inp == DC_300V:
		return 'DC_300V'
	elif inp == AC_230V:
		return 'AC_230V'
	elif inp == PROTECTED_EARTH:
		return 'PROTECTED_EARTH'
	elif inp == p_24V:
		return 'p_24V'
	elif inp == p_24V:
		return 'p_5V'
	else:
		return 'OFF'

def mcp23017_get_device_name(inp):
	if inp == 0:
		return 'AD4112 device 1'
	elif inp == 1:
		return 'AD4112 device 2'
	elif inp == 2:
		return 'DAC61408'
	elif inp == 3:
		return 'MCP23S17 device 0'
	elif inp == 4:
		return 'MCP23S17 device 1'
	else:
		return ERROR_MSG

def mcp23s17_get_device_name(inp):
	if inp == 3:
		return 'MCP23S17_DEVICE_0'
	elif inp == 4:
		return 'MCP23S17_DEVICE_1'
	else:
		return ERROR_MSG


from collections import deque
N = int(input())  # 보드의 크기
board = [[0]*N for i in range(N)]
K = int(input())  # 사과의 개수
for i in range(K):
    a, b = map(int, input().split())
    board[a-1][b-1] = 1

L = int(input())
turns = {}
for j in range(L):
    X, C = input().split()
    turns[int(X)] = C

direction = [(0, 1), (1, 0), (0, -1), (-1, 0)]  # 동 남 서 북
d_index = 0  # 처음에는 동쪽
x, y = 0, 0
board[0][0] = 2  # 출발위치
time = 1
visited = deque([[0, 0]])

while(1):
    # 해당방향으로 전진
    x = x+direction[d_index][0]
    y = y+direction[d_index][1]
    if 0 <= x < N and 0 <= y < N and board[x][y] != 2:
        if board[x][y] != 1:  # 사과가 없을 경우
            tmpx, tmpy = visited.popleft()
            board[tmpx][tmpy] = 0
        board[x][y] = 2
        visited.append([x, y])

        if time in turns.keys():
            if turns[time] == 'D':
                d_index = (d_index+1) % 4
            else:
                d_index = (d_index-1) % 4
        time += 1
    else:  # 벽에 부딪히거나 본인의 몸에 부딪힐 때
        break
print(time)


## Calculate mean squared error between source and target images.

import numpy as np

def calc_mse(source, target, color_chart_area):
  source = np.reshape(source, [-1, 1]).astype(np.float64)
  target = np.reshape(target, [-1, 1]).astype(np.float64)
  mse = sum(np.power((source - target), 2))
  return mse / ((np.shape(source)[
    0]) - color_chart_area)


# 1.
def biggie_size(arr):
    for x in range(len(arr)):
        if arr[x] > 0:
            arr[x] = "big"
    return arr

print (biggie_size([-1, 3, 5, -5]))

# 2.
def count_positives(arr):
    count = 0
    for x in range(len(arr)):
        if arr[x] > 0:
            count += 1
    arr[-1] = count
    return arr

print (count_positives([1, 6, -4, -2, -7, -2]))

# 3.
def sum_total(arr):
    sum = 0
    for x in arr:
        sum += x
    return sum

print (sum_total([6, 3, -2]))

# 4.
def average(arr):
    return sum_total(arr)/len(arr)

print (average([1, 2, 3, 4]))

# 5.
def length(arr):
    len = 0
    for x in arr:
        len += 1
    return len

print (length([37, 2, 1, -9]))

# 6.
def minimum(arr):
    if len(arr) == 0:
        return False
    else:
        min = arr[0]
        for x in arr:
            if x < min:
                min = x
        return min

print (minimum([37, 2, 1, -9]))

# 7.
def maximum(arr):
    if len(arr) == 0:
        return False
    else:
        max = arr[0]
        for x in arr:
            if x > max:
                max = x
        return max

print(maximum([37, 2, 1, -9]))

# 8.
def ultimate_analysis(arr):
    listdict = {
        "sumTotal": sum_total(arr),
        "average": average(arr),
        "minimum": minimum(arr),
        "maximum": maximum(arr),
        "length": length(arr)
    }
    return listdict

print(ultimate_analysis([37, 2, 1, -9]))

# 9.
def reverse_list(arr):
    listdict = {}
    for x in range(len(arr)):
        listdict[x] = arr[x]
    counter = -1
    for x in range(len(arr)):
        arr[counter] = listdict[x]
        counter -= 1
    return arr

print(reverse_list([37, 2, 1, -9]))


# This code is inspired by work done in the scikit-learn community
#   See PR #7990: https://github.com/scikit-learn/scikit-learn/pull/7990/

import time
import shutil
import numpy as np

from sklearn.pipeline import Pipeline, _fit_transform_one
from sklearn.base import clone
from sklearn.externals.joblib import Memory
from sklearn.externals import six

# Use global variables to calculate the number of cache hits
FIT_SINGLE_TRANSFORM_EVALUATIONS = 0
FIT_TRANSFORM_ONE_EVALUATIONS = 0

class CachedPipeline(Pipeline):

    def __init__(self, steps, cached_step_names, memory=Memory(cachedir=None, verbose=0), min_runtime_for_caching=1, run_instance=None):
        self.memory = memory
        if isinstance(memory, six.string_types):
            self.memory = Memory(cachedir=memory, verbose=0)

        self.pipeline_info = PipelineInfo(caching=True)
        global FIT_SINGLE_TRANSFORM_EVALUATIONS
        FIT_SINGLE_TRANSFORM_EVALUATIONS = 0
        global FIT_TRANSFORM_ONE_EVALUATIONS
        FIT_TRANSFORM_ONE_EVALUATIONS = 0

        self.cached_step_names = cached_step_names
        self.min_runtime_for_caching = min_runtime_for_caching

        self.run_instance = run_instance

        super(CachedPipeline, self).__init__(steps)

    def _fit(self, X, y=None, **fit_params):
        # self._validate_steps()

        fit_params_steps = dict((name, {}) for name, step in self.steps
                                if step is not None)
        for pname, pval in six.iteritems(fit_params):
            step, param = pname.split('__', 1)
            fit_params_steps[step][param] = pval
        Xt = X
        for idx_tr, (name, transform) in enumerate(self.steps[:-1]):
            start_time = time.time()
            if transform is None:
                pass
            elif name in self.cached_step_names:
                #hash_Xt = hash(str(Xt))
                #hash_Xt = 1
                previous_transformers = self.steps[:idx_tr]
                #print(previous_transformers, self.run_instance)
                cache_hits_before = self.pipeline_info.get_cache_hits()[1]
                Xt, output_dir = self._fit_single_transform_cached(transform, name, previous_transformers, self.run_instance, idx_tr, Xt,
                                                                    y, **fit_params_steps[name])
                timing = time.time() - start_time
                # TODO Timing > 1
                cache_hits_after = self.pipeline_info.get_cache_hits()[1]
                if timing > self.min_runtime_for_caching or (cache_hits_after > cache_hits_before):
                    self.pipeline_info.add_cached_preprocessor_timing(name, timing)
                    #print("Cache output directory: {}, timing: {}".format(output_dir, timing))
                else:
                    #print("Remove output directory: {}, timing: {}".format(output_dir, timing))
                    start_time = time.time()
                    shutil.rmtree(output_dir, ignore_errors=True)
                    #print("Time to remove cache: {}".format(time.time() - start_time))
            else:
                Xt = self._fit_single_transform(transform, name, None, Xt, y, **fit_params_steps[name])
            self.pipeline_info.add_preprocessor_timing(name, time.time() - start_time)

        if self._final_estimator is None:
            return Xt, {}
        return Xt, fit_params_steps[self.steps[-1][0]]

    def fit(self, X, y=None, **fit_params):
        """Fit the model

        Fit all the transforms one after the other and transform the
        data, then fit the transformed data using the final estimator.

        Parameters
        ----------
        X : iterable
            Training data. Must fulfill input requirements of first step of the
            pipeline.

        y : iterable, default=None
            Training targets. Must fulfill label requirements for all steps of
            the pipeline.

        **fit_params : dict of string -> object
            Parameters passed to the ``fit`` method of each step, where
            each parameter name is prefixed such that parameter ``p`` for step
            ``s`` has key ``s__p``.

        Returns
        -------
        self : Pipeline
            This estimator
        """
        Xt, fit_params = self._fit(X, y, **fit_params)
        if self._final_estimator is not None:
            start_time = time.time()
            self._final_estimator.fit(Xt, y, **fit_params)
            self.pipeline_info.add_estimator_timing(self.steps[-1][0], time.time() - start_time)
        return self

    def score(self, X, y, sample_weight=None):
        """Apply transforms, and score with the final estimator

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        y : iterable, default=None
            Targets used for scoring. Must fulfill label requirements for all
            steps of the pipeline.

        sample_weight : array-like, default=None
            If not None, this argument is passed as ``sample_weight`` keyword
            argument to the ``score`` method of the final estimator.

        Returns
        -------
        score : float
        """
        Xt = X
        for name, transform in self.steps[:-1]:
            if transform is not None:
                Xt = self._single_transform(transform, Xt)
        score_params = {}
        if sample_weight is not None:
            score_params['sample_weight'] = sample_weight
        return self.steps[-1][-1].score(Xt, y, **score_params)

    def _single_transform(self, transform, X):
        #print("EVALUATE _SINGLE_TRANSFORM")
        return transform.transform(X)

    def _fit_single_transform(self, transformer, name, weight, X, y, **fit_params):
        if hasattr(transformer, 'fit_transform'):
            res = transformer.fit_transform(X, y, **fit_params)
        else:
            res = transformer.fit(X, y, **fit_params).transform(X)
        # if we have a weight for this transformer, multiply output
        if weight is None:
            return res
        return res * weight

    def _fit_single_transform_cached(self, transform, name, previous_transformers, run_instance, idx_tr,  X, y, **fit_params_trans):

        #print("EVALUATE _FIT_SINGLE_TRANSFORM")
        global FIT_SINGLE_TRANSFORM_EVALUATIONS
        FIT_SINGLE_TRANSFORM_EVALUATIONS += 1

        memory = self.memory
        clone_transformer = clone(transform)
        fit_tranform_one_cached = memory.cache(_fit_transform_one, ignore=["X", "y"])
        Xt, new_transform = fit_tranform_one_cached(
            clone_transformer, name, previous_transformers, run_instance,
            None, X, y,
            **fit_params_trans)
        output_dir, _ = fit_tranform_one_cached._get_output_dir(
            transform, name, previous_transformers, run_instance,
            None, X, y,
            **fit_params_trans)
        self.steps[idx_tr] = (name, new_transform)

        #print("END EVALUATE _FIT_SINGLE_TRANSFORM")

        return Xt, output_dir

def _fit_transform_one(transformer, name, previous_transformers, run_instance, weight, X, y,
                               **fit_params):
    global FIT_TRANSFORM_ONE_EVALUATIONS
    FIT_TRANSFORM_ONE_EVALUATIONS += 1
    #print("NO CACHE HIT")
    if hasattr(transformer, 'fit_transform'):
        res = transformer.fit_transform(X, y, **fit_params)
    else:
        res = transformer.fit(X, y, **fit_params).transform(X)
    # if we have a weight for this transformer, multiply output
    res = res.astype(np.float32)
    if weight is None:
        return res, transformer
    return res * weight, transformer

class PipelineInfo(object):

    def __init__(self, caching):
        self.caching = caching
        self.timing = {
            'preprocessors': {},
            'cached_preprocessors': {},
            'estimators': {}
        }
        self.cache_hits = 0

    def add_preprocessor_timing(self, name, runtime):
        self.timing['preprocessors'][name] = runtime

    def add_cached_preprocessor_timing(self, name, runtime):
        self.timing['cached_preprocessors'][name] = runtime

    def get_preprocessor_timing(self):
        return self.timing['preprocessors']

    def get_cached_preprocessor_timing(self):
        return self.timing['cached_preprocessors']

    def add_estimator_timing(self, name, runtime):
        self.timing['estimators'][name] = runtime

    def get_estimator_timing(self):
        return self.timing['estimators']

    def get_timing(self):
        return self.timing

    def get_timing_flat(self):
        dct = self.get_preprocessor_timing().copy()
        dct.update(self.get_estimator_timing())
        return dct

    def get_cache_hits(self):
        if self.caching == True:
            global FIT_TRANSFORM_ONE_EVALUATIONS, FIT_SINGLE_TRANSFORM_EVALUATIONS
            return  (FIT_SINGLE_TRANSFORM_EVALUATIONS, FIT_SINGLE_TRANSFORM_EVALUATIONS - FIT_TRANSFORM_ONE_EVALUATIONS)
        else:
            return 0


import json
import boto3
import os
import logging
from sqlalchemy import create_engine, MetaData, Table, update

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

response_headers = {
    "Access-Control-Allow-Headers": "*",
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Methods": "DELETE, OPTIONS",
}

class ApiError(Exception):
    def __init__(self, code, message="Api Error"):
        self.code = code
        self.message = message
        super().__init__(self.message)

def create_db_engine_and_meta(db_credentials):
    engine = create_engine(
        "postgresql+psycopg2://{}:{}@{}/{}".format(
            db_credentials["username"],
            db_credentials["password"],
            db_credentials["host"],
            db_credentials["db"]
        )
    )
    meta = MetaData(engine)

    return engine, meta

def authorize(token):
    lambda_client = boto3.client("lambda")
    response = lambda_client.invoke(
        FunctionName=os.environ["GET_USER_ARN"],
        InvocationType="RequestResponse",
        Payload=json.dumps({"type": "session_token", "token": token}),
    )
    payload = json.load(response["Payload"])
    allowed_permissions = payload.get("permissions", {}).get("Allowed", [])
    is_master = payload.get("is_master", False)
    if 'error' in payload:
        raise ApiError(500, 'Error while accessing token')

    if 'user_id' not in payload:
        raise ApiError(500, str(payload["msg"]))

    if not is_master and "delete_organization" not in allowed_permissions:
        raise ApiError(401, 'Unauthorized user')

def validate_body(body):
    if 'token' not in body.keys() or not body['token']:
        raise ApiError(401, 'Token is required')

def get_organization_id(event):
    return event["pathParameters"]["id"]

def get_database_secrets():
    lambda_client = boto3.client('lambda')
    response = lambda_client.invoke(
        FunctionName=os.environ['GET_SECRET_ARN'],
        InvocationType='RequestResponse',
        Payload=json.dumps({'secret_type': 'Database Credentials'}),
    )

    payload = json.load(response['Payload'])
    if 'error' in payload:
        raise ApiError(
            500, f"accessing secrets manager got an error: {str(payload['error'])}")

    return payload['credentials']

def create_table(name, meta, engine):
    tb = Table(
        name,
        meta,
        autoload=True,
        autoload_with=engine
    )

    return tb

def get_tokens_bucket():
    s3_client = boto3.client("s3")
    bucket = os.environ["STAGE_S3_BUCKET"] if os.environ["ENVIRONMENT"] == "dev" else os.environ["PROD_S3_BUCKET"]
    return s3_client, bucket

def revoke_db_token(token_type, org_id, db_credentials):
    engine, meta = create_db_engine_and_meta(db_credentials)
    table = create_table(token_type, meta, engine)

    try:
        stmt = (
            update(table).
            where(table.columns.organization_id == org_id).
            values(archived=1)
        )
        connection = engine.connect()
        connection.execute(stmt)
    except Exception as e:
        raise ApiError(
            500, f"Faied to revoke organization's {token_type} token: {e}")

def revoke_s3_token(org_id):
    s3_client, bucket = get_tokens_bucket()
    s3_key = "System/Organizations/{}/tokens.json".format(org_id)
    token_data = {}

    try:
        s3_client.put_object(
            Body=json.dumps(token_data, sort_keys=True, indent=4),
            Bucket=bucket,
            Key=s3_key
        )
    except Exception as e:
        raise ApiError(
            500, f'Faied to revoke token for organization: {org_id} in s3: {e}')

def archive_organization(org_id, db_credentials):
    engine, meta = create_db_engine_and_meta(db_credentials)
    table = create_table("organizations", meta, engine)

    try:
        stmt = (
            update(table).
            where(table.columns.id == org_id).
            values(archived=1)
        )
        connection = engine.connect()
        connection.execute(stmt)
    except Exception as e:
        raise ApiError(
            500, f'Faied to archive for organization {org_id}: {e}')

def archive_organization_data_type(data_type, org_id, db_credentials):
    engine, meta = create_db_engine_and_meta(db_credentials)
    table = create_table(data_type, meta, engine)

    try:
        stmt = (
            update(table).
            where(table.columns.organization_id == org_id).
            values(archived=1)
        )
        connection = engine.connect()
        connection.execute(stmt)
    except Exception as e:
        raise ApiError(
            500, f'Faied to archive {data_type} for organization {org_id}: {e}')

def lambda_handler(event, context):
    if 'source' in event and event['source'] == 'aws.events':
        return {
            'msg': 'Warm up triggered..............'
        }

    try:
        body = json.loads(event['body'])
        validate_body(body)
        authorize(body['token'])

        db_credentials = get_database_secrets()
        org_id = get_organization_id(event)
        revoke_db_token("referral_tokens", org_id, db_credentials)
        revoke_db_token("documentation_tokens", org_id, db_credentials)
        revoke_s3_token(org_id)
        archive_organization_data_type(
            "organization_amd_codes", org_id, db_credentials)
        archive_organization_data_type(
            "organization_contacts", org_id, db_credentials)
        archive_organization(org_id, db_credentials)

        return {
            "statusCode": 200,
            "body": json.dumps({
                "statusCode": 200,
                "organization_id": org_id,
                "msg": "Archived successfully"
            }),
            "headers": response_headers,
        }
    except ApiError as e:
        logger.error(e)
        return {
            "statusCode": e.code,
            "headers": response_headers,
            "body": json.dumps({
                "statusCode": e.code,
                "msg": e.message,
            })
        }


# -*- coding: utf-8 -*-
"""
Created on Thu Sep 12 00:15:53 2019

@author: Sashwath
"""

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

dataset = pd.read_csv('Position_Salaries.csv')
X = dataset.iloc[:, 1:2].values
y = dataset.iloc[:, 2:3].values

"""
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test =  train_test_split(X, y, test_size = 0.2,
                                                     random_state = 0)
"""
from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
sc_y = StandardScaler()
X = sc_X.fit_transform(X)
y = sc_y.fit_transform(y)

#Fit regresion model
from sklearn.svm import SVR
regressor = SVR(kernel = 'rbf', degree=2)
regressor.fit(X,y)

#predict
y_pred = sc_y.inverse_transform(regressor.predict(sc_X.transform(np.array([[6.5]]))))

#visualize
X_grid = np.arange(min(X), max(X), 0.1)
X_grid = X_grid.reshape((len(X_grid), 1))
plt.scatter(X, y)
plt.plot(X_grid, regressor.predict(X_grid), color='red')
plt.show()

Part 2 - Regression/Section 7 - Support Vector Regression (SVR)/SVR/my_SVR.py


import gym
import numpy as np
from PIL import Image
from gym import spaces

ROWS = 6
COLUMNS = 7
ACTION_SPACE = COLUMNS
X_REWARD = 1
O_REWARD = -1
TIE_REWARD = 0
SYMBOLS_DICT = {0: '_', 1: 'X', -1: 'O'}
WIDTH = 224
HEIGHT = 192

class ConnectFourEnv(gym.Env):
    def __init__(self, representation, agent_first):
        self.name = "ConnectFour"
        self.possible_actions = list(range(7))
        self.representation = representation
        self.agent_first = agent_first
        assert self.representation in ['Tabular', 'Graphic'] and self.agent_first in [True, False, None]
        self.action_space = spaces.Discrete(ACTION_SPACE)
        if self.representation == 'Tabular':
            self.observation_space = spaces.Box(low=0., high=1., shape=(ROWS, COLUMNS, 1), dtype=np.float32)
        else:
            self.observation_space = spaces.Box(low=0., high=1., shape=(HEIGHT, WIDTH, 1), dtype=np.float32)
        self.action_space = spaces.Discrete(ACTION_SPACE)
        self.state = np.zeros((COLUMNS, ROWS))
        self.representation = representation
        self.agent_first = agent_first
        assert self.representation in ['Tabular', 'Graphic']
        self.done = False
        self.exploration_parameter = 1
        self.reset()

    def _get_observation(self):
        return self.normalize_obs(self.get_fixed_obs())

    def normalize_obs(self, obs):
        if self.representation == 'Tabular':
            return (np.array(obs, dtype=np.float32) + 1.) / 2.
        else:
            return np.expand_dims(np.asarray(self.render_board(obs), dtype=np.float32), axis=-1) / 255.

    def get_fixed_obs(self):
        obs = self.to_image(self.state)
        if not self.agent_first:
            obs = -obs
        return obs

    def to_image(self, state):
        return np.expand_dims(np.flip(state, axis=1).T, axis=-1)

    def reset(self):
        self.state = np.zeros((COLUMNS, ROWS))
        self.done = False
        return self._get_observation()

    # OpenAI Gym Environments standard function which returns next state given the action to perform, as well as the state of the game (Terminal/non Terminal), action reward and additional informations
    def step(self, action):
        invalidAction = False
        if not self.check_valid_action(self.state, action):
            invalidAction = True
        if invalidAction:
            reward = -2 * self.get_mark(self.state)
            if not self.agent_first:
                reward = -reward
            return self._get_observation(), reward, True, 'invalid_action_error'
        else:
            self.state = self.result(self.state, action)
        reward, done, info = self.goal(self.state)
        if not self.agent_first:
            reward = -reward
        return self._get_observation(), reward, done, info

    # Returns True if the action is valid, else False
    def check_valid_action(self, state, action):
        return True if state[action][ROWS - 1] == 0 else False

    # Returns all possible actions given the state
    def actions(self, state):
        return [col for col in range(COLUMNS) if self.check_valid_action(state, col)]

    def get_random_action(self, state):
        np.random.shuffle(self.possible_actions)
        for a in self.possible_actions:
            if self.check_valid_action(state, a):
                return a
        return None

    # Checks whether a final state is reached
    def goal(self, state):
        if self._check_diagonal(state) or self._check_horizontal(state) or self._check_vertical(state):
            if self.get_mark(state) == -1:
                return X_REWARD, True, "X won"
            else:
                return O_REWARD, True, "O won"
        elif len(self.actions(state)) == 0:
            return TIE_REWARD, True, "Tie"
        else:
            return 0, False, 'Game not End'

    # Returns Next state given current state and action
    def result(self, state, action):
        state_copy = state.copy()
        state_copy[action][sum(map(abs, state_copy[action])).astype('int')] = 1 if np.count_nonzero(state_copy == 1) == np.count_nonzero(state_copy == -1) else -1
        return state_copy

    # Undo the last action
    def undo(self, state, action):
        state[action][sum(map(abs, state[action])).astype('int') - 1] = 0
        return state

    # Gets current player/symbol by looking at the state of the game (Implicitly 'X' is the first player)
    def get_mark(self, state):
        return 1 if np.count_nonzero(state == 1) == np.count_nonzero(state == -1) else -1

    # Checks winning conditions -> 4 of the same symbol in a row, a column or diagonally
    def _check_horizontal(self, state):
        for i in range(ROWS - 1, -1, -1):
            for j in range(4):
                if state[j, i] != 0 and state[j, i] == state[j + 1, i] == state[j + 2, i] == state[j + 3, i]:
                    return True
        return False

    def _check_vertical(self, state):
        for i in range(COLUMNS):
            for j in range(2, -1, -1):
                if state[i, j] != 0 and state[i, j] == state[i, j + 1] == state[i, j + 2] == state[i, j + 3]:
                    return True
        return False

    def _check_diagonal(self, state):
        for i in range(4):
            for j in range(2, -1, -1):
                if state[i, j] != 0 and state[i, j] == state[i + 1, j + 1] == state[i + 2, j + 2] == state[i + 3, j + 3]:
                    return True
                if state[i + 3, j] != 0 and state[i + 3, j] == state[i + 2, j + 1] == state[i + 1, j + 2] == state[i, j + 3]:
                    return True
        return False

    ###############################################
    # Alpha Beta Pruning AI to select the best move#
    ###############################################
    def minmax(self, state, depth=6):
        alpha = float('-inf')
        beta = float('inf')
        if self.goal(state)[1]:
            return None
        else:
            if self.get_mark(state) == 1:
                value, move = self.max_value(state, alpha, beta, depth)
                return move
            else:
                value, move = self.min_value(state, alpha, beta, depth)
                return move

    def max_value(self, state, alpha, beta, depth):  # Evaluate max node values and their best moves
        if self.goal(state)[1] or depth == 0:  # If Done or maximum depth reached
            return self.goal(state)[0], None  # Return utility/reward
        v = float('-inf')  # Initialize Node value
        move = None
        for action in self.actions(
                state):  # For each possible action evaluate next state value and update node max value
            state = self.result(state, action)
            # v = max(v, min_v(next_state))
            aux, act = self.min_value(state, alpha, beta, depth - 1)
            if aux > v:
                v = aux
                move = action
            state = self.undo(state, action)
            alpha = max(alpha, aux)  # Evaluate Alpha value
            if beta <= alpha:  # Prune branch -> worst than lower bound / (worst case scenario)
                break
        return v, move

    def min_value(self, state, alpha, beta, depth):  # Evaluate min node values and their best moves
        if self.goal(state)[1] or depth == 0:
            return self.goal(state)[0], None

        v = float('inf')
        move = None
        for action in self.actions(state):
            state = self.result(state, action)
            # v = max(v, min_v(next_state))
            aux, act = self.max_value(state, alpha, beta, depth - 1)
            if aux < v:
                v = aux
                move = action
            state = self.undo(state, action)
            beta = min(beta, aux)
            if beta <= alpha:
                break
        return v, move

    def minmaxran(self, state, depth=3):
        alpha = float('-inf')
        beta = float('inf')
        if self.goal(state)[1]:
            return None
        else:
            if self.get_mark(state) == 1:
                value, moves = self.max_value_ran(state, depth, True)
                return np.random.choice(moves)
            else:
                value, moves = self.min_value_ran(state, depth, True)
                return np.random.choice(moves)

    def max_value_ran(self, state, depth, save_actions=False):
        if self.goal(state)[1] or depth == 0:
            return self.goal(state)[0], []
        v = float('-inf')
        move = None
        moves = []
        for action in self.actions(state):
            state = self.result(state, action)
            # v = max(v, min_v(next_state))
            aux, act = self.min_value_ran(state, depth - 1)
            if aux > v:
                v = aux
                move = action
                moves = []
            state = self.undo(state, action)  # Undo move
            if save_actions and aux == v:
                moves.append(action)
        return v, moves

    def min_value_ran(self, state, depth, save_actions=False):
        if self.goal(state)[1] or depth == 0:
            return self.goal(state)[0], []

        v = float('inf')
        move = None
        moves = []
        for action in self.actions(state):
            state = self.result(state, action)
            # v = max(v, min_v(next_state))
            aux, act = self.max_value_ran(state, depth - 1)
            if aux < v:
                v = aux
                move = action
                moves = []
            state = self.undo(state, action)  # Undo move
            if save_actions and aux == v:
                moves.append(action)
        return v, moves

    def render_board(self, state):
        image = Image.new('L', (WIDTH, HEIGHT), color=128)
        for i in range(ROWS):
            for j in range(COLUMNS):
                if state[i][j] != 0:
                    if state[i][j] == 1:
                        image.paste(Image.new('L', (32, 32), color=255), (32 * j, 32 * i)) #+ HEIGHT + 32
                    else:
                        image.paste(Image.new('L', (32, 32), color=0), (32 * j, 32 * i)) #+ HEIGHT + 32
        return image


from src.model import Model, BooleanModel, VectorialModel
from src.evaluation import recover_mean, precision_mean
import json

def print_recovereds(docs):
    if docs:
        print(f"\nDocumentos recuperados ({len(docs)}):\n")
        for doc in docs:
            print(f'Doc #{doc.num}: {doc.title}')

    else:
        print("No se recuperaron documentos para esa consulta\n")

try:
    with open('./Cran/dataset.json', 'r') as data:
        documents_dict = json.load(data)
except:
    print("No se encuentra el archivo 'dataset.json' en la carpeta cran")
    exit(0)

model = BooleanModel(documents_dict)

print("Recover mean:", recover_mean(model))
print("Precision mean:", precision_mean(model))

while True:
    query = input("Escribe una query y presiona enter:\n")
    recovereds = model.search(query)
    print_recovereds(recovereds)


import sqlite3

def connectDB(db):
    CricketDB = sqlite3.connect(db)
    dbCursor =CricketDB.cursor()
    return dbCursor

def selectPlayers(category,db):
    print('selectplayers')
    playerlist=[]
    try:
        cursor=connectDB(db)
        cursor.execute('Select * from stats where ctg ="'+str(category)+'"')
        record=cursor.fetchall()
        for i in record:
            print(i[0])
            playerlist.append(i[0])

    except:
            print("some problem in DB")
    return playerlist
#selectPlayers('BAT')


import os
import random

from rest_framework.test import APITestCase

from django.core.files.uploadedfile import SimpleUploadedFile
from django.urls import reverse

from hamcrest import assert_that
from hamcrest import is_in
from hamcrest import not_

from api.integration_tests.utils import Utils as TestsUtils
from api.integration_tests.matchers.blog_post_equal_to import BlogPostEqualTo
from api.integration_tests.matchers.blog_posts_equal_to import BlogPostsEqualTo

class TestBlogPost(APITestCase):

    def setUp(self):
        self.temp_images=[]

    def tearDown(self):
        for image in self.temp_images:
            path = os.path.join('photos', image)
            if os.path.exists(path):
                os.remove(path)

    def get_blog_post_list_url(self):
        return reverse('blogpost-list')

    def generate_random_blog_post_data(self):
        img_path = \
            f'{TestsUtils.random_generator.generate_string(2, 10)}.jpg'
        self.temp_images.append(img_path)
        img_content = open(os.path.join('photos', '0.jpg'), 'rb').read()
        return {
            'title': TestsUtils.random_generator.generate_string(2, 20),
            'image' : SimpleUploadedFile(name=img_path,content=img_content),
            'snippet' : TestsUtils.random_generator.generate_string(2, 10),
            'content': TestsUtils.random_generator.generate_string(10, 100)
            }

    def generate_random_blog_posts(self, number=random.randint(2,6)):
        result = {}
        for i in range(number):
            data= self.generate_random_blog_post_data()
            (response, admin_user) = TestsUtils.create_res(
                self.client, self.get_blog_post_list_url(),
                data=data, authenticate_with_admin=True)
            result[admin_user.username] = data
        return result

    def update_blog_post_with_random_data(self, blog_post_json):
        blog_post_json['title'] = \
            TestsUtils.random_generator.generate_string(2, 20)
        blog_post_json['snippet'] = \
            TestsUtils.random_generator.generate_string(2, 10)
        blog_post_json['content'] = \
            TestsUtils.random_generator.generate_string(10, 100)
        del blog_post_json['image']
        return blog_post_json

    def generate_some_posts_and_choose_one(self):
        self.generate_random_blog_posts()
        (response, admin_user) = TestsUtils.retrieve_res(
            self.client, self.get_blog_post_list_url())
        return response.json()['results'][0]

    def test_creating_blog_post_without_auth_must_be_failed(self):
        data= self.generate_random_blog_post_data()
        (response, admin_user) = TestsUtils.create_res(
            self.client, self.get_blog_post_list_url(), data=data)
        TestsUtils.assert_is_unauthorized(response)

    def test_creating_blog_post_with_auth_must_be_failed(self):
        (email_list, credentials) = TestsUtils.create_random_users_credentials(
                self.client, 1)
        data = self.generate_random_blog_post_data()
        (response, admin_user) = TestsUtils.create_res(
            self.client, self.get_blog_post_list_url(),
            data=data, token=credentials[0])
        TestsUtils.assert_is_forbidden(response)

    def test_creating_blog_post_with_admin_auth(self):
        data = self.generate_random_blog_post_data()
        (response, admin_user) = TestsUtils.create_res(
            self.client, self.get_blog_post_list_url(),
            data=data, authenticate_with_admin=True)
        TestsUtils.assert_is_created(response)
        assert_that({admin_user.username : data},
            BlogPostEqualTo(response.json(), self.client))

    def test_retrieving_blog_post_list_witout_auth_must_not_be_failed(self):
        expected = self.generate_random_blog_posts()
        (response, admin_user) = TestsUtils.retrieve_res(
            self.client, self.get_blog_post_list_url())
        TestsUtils.assert_is_ok(response)
        assert_that(expected, BlogPostsEqualTo(response, self.client))

    def test_patching_blog_post_witout_auth_must_be_failed(self):
        selected_post = self.generate_some_posts_and_choose_one()
        response = TestsUtils.patch_res(
            self.client, selected_post['url'], {})
        TestsUtils.assert_is_unauthorized(response)

    def test_patching_blog_post_with_auth_must_be_failed(self):
        selected_post = self.generate_some_posts_and_choose_one()
        (email_list, credentials) = \
            TestsUtils.create_random_users_credentials(
                self.client, 1)
        response = TestsUtils.patch_res(
            self.client,
            url=selected_post['url'],
            data={},
            token=credentials[0])
        TestsUtils.assert_is_forbidden(response)

    def test_patching_blog_post_with_admin_auth_must_not_be_failed(self):
        selected_post = self.generate_some_posts_and_choose_one()
        updated_json = self.update_blog_post_with_random_data(selected_post)
        response = TestsUtils.patch_res(
            self.client,
           url=selected_post['url'],
           data=updated_json,
           authenticate_with_admin=True)
        TestsUtils.assert_is_ok(response)
        assert_that({selected_post['owner']:updated_json},
            BlogPostEqualTo(response.json(), self.client))

    def test_deleting_blog_post_witout_auth_must_be_failed(self):
        selected_post = self.generate_some_posts_and_choose_one()
        response = TestsUtils.delete_res(
            self.client, selected_post['url'])
        TestsUtils.assert_is_unauthorized(response)

    def test_deleting_blog_post_with_auth_must_be_failed(self):
        selected_post = self.generate_some_posts_and_choose_one()
        (email_list, credentials) = \
            TestsUtils.create_random_users_credentials(
                self.client, 1)
        response = TestsUtils.delete_res(
            self.client,
            url=selected_post['url'],
            token=credentials[0])
        TestsUtils.assert_is_forbidden(response)

    def test_deleting_blog_post_with_admin_auth_must_not_be_failed(self):
        selected_post = self.generate_some_posts_and_choose_one()
        response = TestsUtils.delete_res(
            self.client,
           url=selected_post['url'],
           authenticate_with_admin=True)
        TestsUtils.assert_is_deleted(response)
        (response, admin_user) = TestsUtils.retrieve_res(
            self.client, self.get_blog_post_list_url())
        posts = response.json()['results']
        assert_that(selected_post, not_(is_in(posts)))


import tkinter
from tkinter import *

calc = Tk()
calc.geometry('320x500')
calc.resizable(0, 0)
calc.title("Calculator")

# ======================Start==========================
# ======================Functions======================

def button1():
    if not add.get():
        num1.insert(END, 1)
    else:
        num2.insert(END, 1)

def button2():
    if not add.get():
        num1.insert(END, 2)
    else:
        num2.insert(END, 2)

def button3():
    if not add.get():
        num1.insert(END, 3)
    else:
        num2.insert(END, 3)

def button4():
    if not add.get():
        num1.insert(END, 4)
    else:
        num2.insert(END, 4)

def button5():
    if not add.get():
        num1.insert(END, 5)
    else:
        num2.insert(END, 5)

def button6():
    if not add.get():
        num1.insert(END, 6)
    else:
        num2.insert(END, 6)

def button7():
    if not add.get():
        num1.insert(END, 7)
    else:
        num2.insert(END, 7)

def button8():
    if not add.get():
        num1.insert(END, 8)
    else:
        num2.insert(END, 8)

def button9():
    if not add.get():
        num1.insert(END, 9)
    else:
        num2.insert(END, 9)

def button0():
    if not add.get():
        num1.insert(END, 0)
    else:
        num2.insert(END, 0)

def adds():
    add.delete(0, END)
    add.insert(END, '+')

def mines():
    add.delete(0, END)
    add.insert(END, '-')

def multiple():
    add.delete(0, END)
    add.insert(END, '*')

def divide():
    add.delete(0, END)
    add.insert(END, '/')

def percentage():
    add.delete(0, END)
    add.insert(END, '%')

def delete():
    try:
        num1.delete(0, END)
        num2.delete(0, END)
        add.delete(0, END)
        result.delete(0, END)
    except:
        print("Deleted")

def equals():
    result.delete(0, END)
    a = num1.get()
    b = num2.get()
    if add.get() == '+':
        c = int(a) + int(b)
        result.insert(END, c)
    elif add.get() == '-':
        c = int(a) - int(b)
        result.insert(END, c)
    elif add.get() == '*':
        c = int(a) * int(b)
        result.insert(END, c)
    elif add.get() == '/':
        c = int(a) / int(b)
        result.insert(END, c)
    if add.get() == '%':
        c = int(a) * int(b) // 100
        result.insert(END, c)

#===================Front====================
calc.config(bg="white")
F1 = Frame(calc, width=350, height=50)
F1.pack()
F1.config(bg="white")

name = Label(F1, text="SULEMAN SADAT", font="Calibri 12 bold")
Python = Label(F1, text="Python Programmer", font="Calibri 12 bold")
name.config(bg="white")
Python.config(bg="white")

# ---------------------inputs--------------------------
number1Label = Label(text="Number 1: ", bg="white")
title_text = IntVar
num1 = Entry(calc, textvariable=title_text, width=45)
num1.pack()
number2Label = Label(text="Number 2: ", bg="white")
num2 = Entry(calc, width=45)
num2.pack()

resultLabel = Label(text="  Result  ", bg="red")
result = Entry(calc, width=20)
result.pack()

add = Entry(calc, width=2)
add.pack()
sulemanjan = Label(text="", bg="white")

# Img1 = PhotoImage(file="suliman.png")
# now = Label(calc, image=Img1, bg="white", ).place(x=110, y=150)

# ---------------------Buttons--------------------------
one = Button(calc, text="1", width=9, height=3, command=button1)
two = Button(calc, text="2", width=9, height=3, command=button2)
three = Button(calc, text="3", width=9, height=3, command=button3)
four = Button(calc, text="4", width=9, height=3, command=button4)
five = Button(calc, text="5", width=9, height=3, command=button5)
six = Button(calc, text="6", width=9, height=3, command=button6)
seven = Button(calc, text="7", width=9, height=3, command=button7)
eight = Button(calc, text="8", width=9, height=3, command=button8)
nine = Button(calc, text="9", width=9, height=3, command=button9)
zero = Button(calc, text="0", width=9, height=3, command=button0)
point = Button(calc, text=".", width=9, height=3,command=adds)
plusmines = Button(calc, text="+_", width=9, height=3, command=mines)
average = Button(calc, text="%", width=9, height=3, command=percentage)
backspace = Button(calc, text="backspace", width=9, height=3)
C = Button(calc, text="C", width=9, height=3, command=delete)

plus = Button(calc, text="+", width=13, height=3, command=adds)
mines = Button(calc, text="_", width=13, height=3, command=mines)
multi = Button(calc, text="X", width=13, height=3, command=multiple)
divide = Button(calc, text="/", width=13, height=3, command=divide)

equal = Button(calc, text="=", width=13, height=3, command=equals)
equal.config(bg="#EEE", activebackground="GRAY")
equal.pack()

# ---------------------location--------------------------

one.place(y=392, x=0)
two.place(y=392, x=75)
three.place(y=392, x=150)
four.place(y=342, x=0)
five.place(y=342, x=75)
six.place(y=342, x=150)
seven.place(y=292, x=0)
eight.place(y=292, x=75)
nine.place(y=292, x=150)
zero.place(y=450, x=75)
plusmines.place(y=450, x=0)
zero.place(y=450, x=75)

equal.place(y=450, x=224)
point.place(y=450, x=150)

plus.place(y=392, x=224)
mines.place(y=342, x=224)
multi.place(y=292, x=224)
divide.place(y=235, x=224)
average.place(y=235, x=0)
backspace.place(y=235, x=150)
C.place(y=235, x=75)

add.place(y=95, x=156)
number1Label.place(x=0, y=50)
number2Label.place(x=0, y=80)

num1.place(y=50, x=67)
num2.place(y=80, x=67)

resultLabel.place(x=140, y=115)

result.place(x=105, y=135)
sulemanjan.place(x=150, y=180)
F1.place()
name.place(x=100, y=0)
Python.place(x=90, y=20)
calc.mainloop()


"""Возьмите 1-3 любые задачи из прошлых семинаров (например сериализация
данных), которые вы уже решали. Превратите функции в методы класса, а
параметры в свойства. Задачи должны решаться через вызов методов экземпляра."""

from os import listdir, mkdir, makedirs, path, rename
from random import choices, randint
from string import ascii_lowercase, digits

class Files:
    def __init__(self, ext: str = 'txt', folder: str = 'files', name_len_min: int = 6, name_len_max: int = 30,
                 bytes_min: int = 256, bytes_max: int = 4096, num_files: int = 3):
        self.folder = folder
        self.ext = ext
        self.name_len_min = name_len_min
        self.name_len_max = name_len_max
        self.bytes_min = bytes_min
        self.bytes_max = bytes_max
        self.num_files = num_files

    def gen_files(self) -> None:
        """функция генерирует файлы с разными расширениями.
        Расширения и количество файлов функция принимает в качестве параметров.
        Количество переданных расширений может быть любым."""

        if not path.exists(self.folder):
            mkdir(self.folder)
        for _ in range(self.num_files):
            name = ''.join(choices(ascii_lowercase + digits + '_', k=randint(self.name_len_min, self.name_len_max)))
            data = bytes(randint(0, 255) for _ in range(randint(self.bytes_min, self.bytes_max)))
            file_name = f'{name}.{self.ext}'
            if file_name not in listdir(self.folder):
                with open(f'{self.folder}/{file_name}', 'wb') as f:
                    f.write(data)
            else:
                print(f'Файл {file_name} уже существует и не был записан!')

    def sort_files(self) -> None:
        """функция для сортировки файлов по директориям: видео, изображения, текст и т.п.
        Каждая группа включает файлы с несколькими расширениями.
        В исходной папке остаются только те файлы, которые не подошли для сортировки."""

        ext_dict = {'video': ['avi', 'mkv', 'mp4'],
                    'audio': ['wav', 'mp3'],
                    'text': ['txt', 'doc', 'rtf', 'pdf'],
                    'image': ['bmp', 'gif', 'jpg', 'jpeg', 'png'],
                    'binary': ['bin'],
                    }
        files = listdir(self.folder)

        for file in files:
            for file_type, ext in ext_dict.items():
                if file.split('.')[-1].lower() in ext:
                    makedirs(f'{self.folder}/{file_type}', exist_ok=True)
                    rename(f'{self.folder}/{file}', f'{self.folder}/{file_type}/{file}')

if __name__ == '__main__':
    new_files = {'txt': 3, 'bmp': 2}
    for extension, num in new_files.items():
        make_files = Files(ext=extension, num_files=num)
        make_files.gen_files()
        make_files.sort_files()


class Cave:
    def __init__(self, name, neighbors):
        self.name = name
        self.size = "lg" if name.isupper() else "sm"
        self.neighbors = neighbors

    def __repr__(self):
        return f"{self.name} - {self.neighbors}"

def get_input(filename):
    caves = {}
    with open(filename, "r") as f:
        for line in f.readlines():
            line = line.strip()
            cave1_name, cave2_name = line.split("-")
            if cave1_name in caves:
                caves[cave1_name].neighbors.append(cave2_name)
            else:
                caves[cave1_name] = Cave(cave1_name, [cave2_name])
            if cave2_name in caves:
                caves[cave2_name].neighbors.append(cave1_name)
            else:
                caves[cave2_name] = Cave(cave2_name, [cave1_name])
        return caves

def find_routes(caves, current_cave_name="start", visited=None, valid_paths=None, single_small_twice=False, double_visited=False):
    current_cave = caves[current_cave_name]
    if current_cave_name == "end":
        visited.append("end")
        return visited

    # if it's lowercase and we've been here before figure out what to do
    if (
            current_cave_name != "start"
            and current_cave_name in visited
            and current_cave_name.islower()
    ):
        # if it's illegal, bail
        if not single_small_twice or double_visited:
            return
        # if it's okay but only this one, make sure we don't do it again
        if single_small_twice and not double_visited:
            double_visited = True

    if visited:
        visited.append(current_cave.name)
    else:
        visited = ["start"]
    for next_cave_name in current_cave.neighbors:
        next_cave = caves[next_cave_name]
        if next_cave.name == "start":
            continue
        path = find_routes(caves, next_cave.name, visited.copy(), valid_paths, single_small_twice, double_visited)
        if path is not None:
            valid_paths.append(path)

def main():
    caves = get_input("input")
    valid_paths = []
    find_routes(caves, valid_paths=valid_paths)
    # for path in valid_paths:
    #     print(path)
    print("Part 1:")
    print(f"found {len(valid_paths)} valid paths")
    print()

    caves = get_input("input")
    valid_paths = []
    find_routes(caves, valid_paths=valid_paths, single_small_twice=True)
    print("Part 2:")
    print(f"found {len(valid_paths)} valid paths")
    print()

if __name__ == "__main__":
    main()


from project import db

class User(db.Model):

    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(128), nullable=False)
    email = db.Column(db.String(128), nullable=False)
    active = db.Column(db.Boolean(), default=True, nullable=False)

    def to_json(self):
        return {
            'id': self.id,
            'username': self.username,
            'email': self.email,
            'active': self.active
        }

    def __init__(self, username, email):
        self.username = username
        self.email = email

class Participante(db.Model):

    __tablename__ = 'participante'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    nombre = db.Column(db.String(100), nullable=False)
    apellido = db.Column(db.String(100), nullable=False)
    email = db.Column(db.String(128), nullable=True)
    celular = db.Column(db.String(9), nullable=True)
    nivel = db.Column(db.Integer, default=0, nullable=True)
    fechanacimiento = db.Column(db.String(20), nullable=True)
    estado = db.Column(db.Boolean(), default=True, nullable=True)
    sexo = db.Column(db.Integer, default=0, nullable=True)

    def to_json(self):
        return {
            'id': self.id,
            'nombre': self.nombre,
            'apellido': self.apellido,
            'email': self.email,
            'celular': self.celular,
            'nivel': self.nivel,
            'fechanacimiento': self.fechanacimiento,
            'estado': self.estado,
            'sexo': self.sexo,
        }

    def __init__(self,
                 nombre,
                 apellido,
                 email,
                 celular,
                 fechanacimiento
                 ):
        self.nombre = nombre
        self.apellido = apellido
        self.email = email
        self.celular = celular
        self.fechanacimiento = fechanacimiento

class Usuario(db.Model):

    __tablename__ = 'usuario'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    usuario = db.Column(db.String(128), nullable=False)
    clave = db.Column(db.String(128), nullable=False)
    estado = db.Column(db.Boolean(), default=True, nullable=False)
    tipocuenta = db.Column(db.Integer, default=1, nullable=False)
    idparticipante = db.Column(db.Integer, nullable=False)

    def to_json(self):
        return {
            'id': self.id,
            'usuario': self.usuario,
            'clave': self.clave,
            'estado': self.estado,
            'tipocuenta': self.tipocuenta,
            'idparticipante': self.idparticipante
            }

    def __init__(self,
                 usuario,
                 clave,
                 idparticipante
                 ):
        self.usuario = usuario
        self.clave = clave
        self.idparticipante = idparticipante


import random
import string

word_list = ['python', 'java', 'kotlin', 'javascript']
the_word = random.choice(word_list)
print('H A N G M A N')
secret_word = '-' * len(the_word)
letters = set(the_word)
attempts = 8
used_letters = []
alphabet = list(string.ascii_lowercase)
while attempts > 0 and len(letters) > 0:
    print()
    print(secret_word)
    answer = input('Input a letter:').strip()
    if len(answer) > 1:
        print("You should input a single letter")
        continue
    elif answer not in alphabet:
        print("It is not an ASCII lowercase letter")
        continue
    elif answer in used_letters:
        print("You already typed this letter")
        continue
    elif answer not in letters and answer in the_word:
        attempts -= 1
        print('No improvements')
        used_letters.append(answer)
    elif answer not in letters:
        attempts -= 1
        print('No such letter in the word')
        used_letters.append(answer)
    else:
        letters.discard(answer)
        secret_word = ''
        for i in the_word:
            if i in letters:
                secret_word += '-'
            else:
                secret_word += i
        used_letters.append(answer)
if len(letters) == 0:
    print(the_word)
    print('''You guessed the word!
    You survived!''')
else:
    print('You are hanged!')


import torch
import torch.nn as nn

class BiLinearNet(nn.Module):
  def __init__(self, num_users, num_items, num_dimensions, mean=0):
    super().__init__()

    self.user_embeddings = nn.Embedding(num_users, num_dimensions)
    self.item_embeddings = nn.Embedding(num_items, num_dimensions)

    self.user_bias = nn.Embedding(num_users, 1)
    self.item_bias = nn.Embedding(num_items, 1)

    # Gaussian initialisation of the latent factors.
    nn.init.normal_(self.user_embeddings.weight, 0, 1.0 / num_dimensions)
    nn.init.normal_(self.item_embeddings.weight, 0, 1.0 / num_dimensions)
    nn.init.zeros_(self.user_bias.weight)
    nn.init.zeros_(self.item_bias.weight)

    self.mu = mean

  def forward(self, user_id, item_id):
    u_emb = self.user_embeddings(user_id.long())#.squeeze()
    i_emb = self.item_embeddings(item_id.long())#.squeeze()

    u_bias = self.user_bias(user_id.long()).squeeze()
    i_bias = self.item_bias(item_id.long()).squeeze()

    dot_ = (u_emb * i_emb).sum(-1)

#    print(user_id.size(), item_id.size())
#    print(u_emb.size(), u_bias.size(), i_emb.size(), i_bias.size(), dot_.size())

    return dot_ + u_bias + i_bias + self.mu


import os
import datasets
import pandas as pd
from JoinQuerySampler import Table, MultiJoinQuerySampler
from baselines.encoder import MultiJoinQueryEncoder

def schema_cleaning(df_dataset_list, col_types_list, table_name_list, pk_name_list):
	pk_code_lists = []
	# map primary key column to categorical encoding
	for df, col_types, primary_key in zip(df_dataset_list, col_types_list, pk_name_list):
		if not primary_key: # empty string denotes no primary key
			pk_code_lists.append({})
			continue
		print(df.columns)
		cate = pd.Categorical(df[primary_key])
		code_dict = dict([(category, code) for code, category in enumerate(cate.categories)])
		pk_code_lists.append(code_dict)
		df[primary_key] = cate.codes
	# replace foreign key column to same categorical encoding of their primary key
	for t1_id, primary_key in enumerate(pk_name_list):
		for t2_id, df in enumerate(df_dataset_list):
			if t1_id == t2_id:
				continue
			print(t1_id, t2_id, pk_name_list[t1_id])
			if primary_key in df.columns:
				print("key value replace", t1_id, t2_id, pk_name_list[t1_id])
				df[primary_key] = df[primary_key].map(pk_code_lists[t1_id])  # map is much faster than replace
		# df[primary_key].replace(self.pk_code_lists[t1_id], inplace =True)
	# replace non-key categorical column to code
	for df, col_types in zip(df_dataset_list, col_types_list):
		for col_idx, col_name in enumerate(df.columns):
			if col_types[col_idx] == 'categorical' and col_name not in pk_name_list:
				df[col_name] = pd.Categorical(df[col_name]).codes
	schema_save_path = "/home/kfzhao/data/rdb/imdb_clean2"
	for df, table_name in zip(df_dataset_list, table_name_list):
		df.fillna(-1, inplace=True)
		df = df.astype(int) # for IMDB dataset
		df.to_csv(path_or_buf=os.path.join(schema_save_path, "{}.csv".format(table_name)), sep=';', index=False)

class DBSchema(object):
	def __init__(self, df_dataset_list, col_types_list, table_name_list, primary_key_list, chunk_size):
		self.primary_key_list = primary_key_list
		self.pk_code_lists = []
		# map primary key column to categorical encoding
		for df, col_types, primary_key in zip(df_dataset_list, col_types_list, primary_key_list):
			if not primary_key:
				self.pk_code_lists.append({})
				continue
			cate = pd.Categorical(df[primary_key])
			code_dict = dict([(category, code) for code, category in enumerate(cate.categories)])
			self.pk_code_lists.append(code_dict)
			df[primary_key] = cate.codes

		# prepare the fk categorical code for each table
		self.fk_code_dicts_list = []
		for t2_id, df in enumerate(df_dataset_list):
			fk_code_dicts = {}
			for t1_id, key in enumerate(primary_key_list):
				if t2_id == t1_id:
					continue
				if key in df.columns:
					pk_code_dict = self.pk_code_lists[t1_id]
					fk_code_dicts[key] = pk_code_dict
			self.fk_code_dicts_list.append(fk_code_dicts)
		self.tables = []
		for df, col_types, table_name, fk_code_dicts in zip(df_dataset_list, col_types_list, table_name_list, self.fk_code_dicts_list):
			table = Table(df, col_types, table_name, fk_code_dicts=fk_code_dicts, chunk_size=chunk_size)
			self.tables.append(table)

	def print_schema_info(self):
		print("<" * 80)
		for t_id, table in enumerate(self.tables):
			print("Table {}: {}".format(t_id, table.table_name))
			print("Columns", table.df.columns)
			print("PK name: {}".format(self.primary_key_list[t_id]))
			#print("FK name: {}".format(','.join(table)))
		print(">" * 80)

def load_training_schema_data(args):
	schema_name = args.schema_name
	encode = args.feat_encode
	query_path = args.query_path
	data_path = args.data_path
	chunk_size = args.chunk_size
	df_dataset_list, col_types_list, pk_name_list = [], [], []
	local_vars = locals()
	if schema_name == 'yelp':
		load_funcs = [datasets.LoadYelp_Business_raw(data_path), datasets.LoadYelp_Reviews_raw(data_path),
					  datasets.LoadYelp_Users_raw(data_path)]
		table_name_list = ['business', 'review', 'user']
	elif schema_name ==  'tpcds':
		load_funcs = [datasets.LoadTPCDS_store_sales(data_path), datasets.LoadTPCDS_store(data_path), datasets.LoadTPCDS_item(data_path),
					  datasets.LoadTPCDS_customer(data_path), datasets.LoadTPCDS_promotion(data_path)]
		table_name_list = ['store_sales', 'store', 'item', 'customer', 'promotion']
	elif schema_name == 'tpch':
		load_funcs = [datasets.LoadTPCH_lineitem(data_path), datasets.LoadTPCH_part(data_path), datasets.LoadTPCH_orders(data_path),
					  datasets.LoadTPCH_supplier(data_path)]
		table_name_list = ['lineitem', 'part', 'orders', 'supplier']
	elif schema_name == 'imdb_simple':
		load_funcs = [datasets.LoadIMDB_title(data_path), datasets.LoadIMDB_cast_info(data_path),
					  datasets.LoadIMDB_movie_info(data_path),
					  datasets.LoadIMDB_movie_companies(data_path), datasets.LoadIMDB_movie_info_idx2(data_path),
					  datasets.LoadIMDB_movie_keyword(data_path)]
		table_name_list = ['title', 'cast_info', 'movie_info', 'movie_companies', 'movie_info_idx', 'movie_keyword']
	elif schema_name == 'imdb':
		load_funcs = [datasets.LoadIMDB_title(data_path), datasets.LoadIMDB_cast_info(data_path),
					  datasets.LoadIMDB_movie_info(data_path),
					  datasets.LoadIMDB_movie_companies(data_path), datasets.LoadIMDB_movie_info_idx(data_path),
					  datasets.LoadIMDB_movie_keyword(data_path)]
		table_name_list = ['title', 'cast_info', 'movie_info', 'movie_companies', 'movie_info_idx', 'movie_keyword']
	else:
		assert False, "Unsupported Schema!"
	for load_func in load_funcs:
		local_vars['df_dataset'], local_vars['col_types'], local_vars['pk'] = load_func
		df_dataset_list.append(local_vars['df_dataset'])
		col_types_list.append(local_vars['col_types'])
		pk_name_list.append(local_vars['pk'])

	schema = DBSchema(df_dataset_list, col_types_list, table_name_list, pk_name_list, chunk_size)
	schema.print_schema_info()
	if encode == 'dnn-encoder':
		multi_join_sampler = MultiJoinQuerySampler(schema.tables)
		all_queries, all_cards, all_query_infos = multi_join_sampler.load_queries(query_path=query_path)
		X, Y = multi_join_sampler.transform_to_arrays(all_queries, all_cards)
	elif encode == 'one-hot':
		multi_join_encoder = MultiJoinQueryEncoder(schema.tables)
		all_queries, all_cards, all_query_infos = multi_join_encoder.load_queries(query_path=query_path)
		X, Y = multi_join_encoder.transform_to_arrays(all_queries, all_cards, args.model_type)
	else: assert False, "unsupported encoder type!"
	return X, Y, all_query_infos

if __name__ == "__main__":
	#data_path = "/home/kfzhao/data/rdb/TPCDS_2Gclean"
	data_path = '/home/kfzhao/data/rdb/imdb_clean'
	df_dataset_list, col_types_list, pk_name_list = [], [], []
	#load_funcs = [datasets.LoadYelp_Business_raw(), datasets.LoadYelp_Reviews_raw(), datasets.LoadYelp_Users_raw()]
	#load_funcs = [datasets.LoadTPCDS_store_sales(data_path), datasets.LoadTPCDS_store(data_path), datasets.LoadTPCDS_item(data_path),
	#			  datasets.LoadTPCDS_customer(data_path), datasets.LoadTPCDS_promotion(data_path)]
	load_funcs = [datasets.LoadIMDB_title(data_path), datasets.LoadIMDB_cast_info(data_path), datasets.LoadIMDB_movie_info(data_path),
				  datasets.LoadIMDB_movie_companies(data_path), datasets.LoadIMDB_movie_info_idx(data_path), datasets.LoadIMDB_movie_keyword(data_path)]
	#load_funcs = [datasets.LoadTPCH_lineitem(), datasets.LoadTPCH_part(), datasets.LoadTPCH_orders(), datasets.LoadTPCH_supplier()]
	#table_name_list = ['business', 'review', 'user']
	#table_name_list = ['store_sales', 'store', 'item', 'customer', 'promotion']
	#table_name_list = ['lineitem', 'part', 'orders', 'supplier']
	table_name_list = ['title', 'cast_info', 'movie_info', 'movie_companies', 'movie_info_idx', 'movie_keyword']
	local_vars = locals()
	for load_func in load_funcs:
		local_vars['df_dataset'], local_vars['col_types'], local_vars['pk'] = load_func
		df_dataset_list.append(local_vars['df_dataset'])
		col_types_list.append(local_vars['col_types'])
		pk_name_list.append(local_vars['pk'])

	#print("schema cleaning ...")
	#schema_cleaning(df_dataset_list, col_types_list, table_name_list, pk_name_list)

	schema = DBSchema(df_dataset_list, col_types_list, table_name_list, pk_name_list, chunk_size=64)

	schema.print_schema_info()

	print("build multiple join sampler")
	multi_join_sampler = MultiJoinQuerySampler(schema.tables, query_engine='clickhouse')

	multi_join_sampler.sample_batch_query(save_path='./', num_tables=2, mini_batch=100, data_centric=True, cat_size=100)
	#multi_join_sampler.parallel_sampler(mini_batch=3000, data_centric=True)

	"""
	all_queries, all_cards, all_query_infos = multi_join_sampler.load_queries(
		query_path="/home/kfzhao/PycharmProjects/NNGP/queryset/join_lineitem_part_orders_supplier_10_data_centric_427")
	X, Y = multi_join_sampler.transform_to_arrays(all_queries, all_cards)
	for query_info in all_query_infos:
		print(query_info)
	print(X.shape, Y.shape)
	print(len(all_query_infos))
	"""


import abc
from uuid import UUID

class IssueReporter:

    def __init__(self, name: str, email: str) -> None:
        self.name = name
        self.email = email

class Issue:

    def __init__(self, issue_id: UUID, reporter: IssueReporter,
                 description: str) -> None:
        self.id = issue_id
        self.description = description
        self.reporter = reporter


from fastapi import APIRouter, HTTPException

from api.exceptions import KeyExistsError
from api.payload_validators import is_empty_field, is_within_valid_battery_range
from api.registerdevice.models.device import Device, UnregisterDevice
from api.utils.response import ResponsePacket, build_response, ServiceCode
from database.shared_cache import register_device, unregister_device

router = APIRouter()

@router.post('/register', status_code=201, response_model=ResponsePacket)
def register_device_service(device: Device):
    try:
        if is_empty_field(device.device_id) or is_empty_field(device.device_name) or is_empty_field(
                device.battery_level):
            raise HTTPException(status_code=422,
                                detail=build_response(ServiceCode.FIELD_EMPTY,
                                                      'Missing Parameters!').dict())

        if not is_within_valid_battery_range(device.battery_level):
            raise HTTPException(status_code=422,
                                detail=build_response(ServiceCode.INVALID_BATTERY_RANGE,
                                                      'Invalid Battery Range!').dict())

        register_device(device)
    except KeyExistsError:
        raise HTTPException(status_code=400,
                            detail=build_response(ServiceCode.REGISTER_FAILURE,
                                                  'Device Already Exists!').dict())

    return build_response(ServiceCode.REGISTER_SUCCESS)

@router.delete('/unregister', response_model=ResponsePacket)
def unregister_device_service(device: UnregisterDevice):
    device_info = unregister_device(device)

    if device_info is None:
        raise HTTPException(status_code=400,
                            detail=build_response(ServiceCode.UNREGISTER_FAILURE,
                                                  'Device Does Not Exists!').dict())

    return build_response(ServiceCode.UNREGISTER_SUCCESS)


from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response

from quotes.models import Quote, Premium
from quotes.serializers import QuoteSerializer, PremiumSerializer

@api_view(["GET", "POST"])
def quote_list(request):
    """
    List all code quotes, or create a new snippet.
    """
    if request.method == "GET":
        quotes = Quote.objects.all()
        serializer = QuoteSerializer(quotes, many=True)
        return Response(serializer.data)

    elif request.method == "POST":
        serializer = QuoteSerializer(data=request.data)
        if serializer.is_valid():

            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(["GET"])
def premium_detail(request, quote_number: str):
    """
    Retrieve a premium quote
    """
    try:
        quote = Quote.objects.get(quote_number=quote_number)
    except Quote.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == "GET":
        premium = Premium.from_quote(quote)
        premium.save()

        serializer = PremiumSerializer(premium)
        return Response(serializer.data)


#!/usr/bin/python3
import sqlite3
from init_db import init_db

class PreciousData():
  """
  Class for data API
  """

  def __init__(self):
    self.db_path = "data.db"

    # connect to db and initialize cursor
    conn = sqlite3.connect(self.db_path)
    c = conn.cursor()

    # attempt to select from default table
    # if it fails -- create all tables for the app
    try:
      c.execute("SELECT * FROM hours")
      c.fetchall()
    except Exception as e:
      print(e)
      init_db(self.db_path)

    conn.close()

  def fetch(self, item, filters = None, one = False):
    # connect to db and initialize cursor
    conn = sqlite3.connect(self.db_path)
    c = conn.cursor()

    data = []
    if filters is not None:

      val_str = ""
      val_list = []
      for (key,val) in filters.items():
        if len(val_str) > 1:
          val_str += " AND "
        val_str += "{0}=?".format(key)
        val_list.append(val)

      c.execute("SELECT rowid,* FROM {0} WHERE {1}".format(item, val_str), tuple(val_list) )

      if one:
        data = c.fetchone() # single item, not list
      else:
        data = c.fetchall()

    else:
      c.execute("SELECT rowid,* FROM {0}".format(item))
      data = c.fetchall()

    conn.close()
    return data

  def delete_all(self, item, filters = None):
    # connect to db and initialize cursor
    conn = sqlite3.connect(self.db_path)
    c = conn.cursor()

    if filters is not None:

      val_str = ""
      val_list = []
      for (key,val) in filters.items():
        if len(val_str) > 1:
          val_str += " AND "
        val_str += "{0}=?".format(key)
        val_list.append(val)

      c.execute("DELETE FROM {0} WHERE {1}".format(item, val_str), tuple(val_list) )

    else:
      c.execute("DELETE FROM {0}".format(item))

    conn.commit()

  def insert_many(self, item, values):
    # connect to db and initialize cursor
    conn = sqlite3.connect(self.db_path)
    c = conn.cursor()
    data = []

    if(len(values) < 1):
      print("no values")
      return None

    val_str = ""
    for (i,val) in enumerate(values):
      if i > 0:
        val_str += ", "
      val_str += "(?)"

    if item == "tags":
      val_list = []
      for (i,val) in enumerate(values):
        val_list.append(val['name'])

      c.execute("INSERT INTO {0} VALUES {1}".format(item, val_str), tuple(val_list))
      data = {"id":c.lastrowid} # response
      conn.commit()

    conn.close()
    return data

  def insert(self, item, values):
    # connect to db and initialize cursor
    conn = sqlite3.connect(self.db_path)
    c = conn.cursor()
    data = []

    val_str = ""
    val_list = []
    for (i,val) in enumerate(values):
      if i > 0:
        val_str += ", "
      val_str += "?"
      val_list.append(val)

    if item == "hours" or item == "tags_hours":

      c.execute("INSERT INTO {0} VALUES ({1})".format(item, val_str), tuple(val_list))
      data = {"id":c.lastrowid} # response
      conn.commit()

    conn.close()
    return data

  def update(self, item, id, values):
    # connect to db and initialize cursor
    conn = sqlite3.connect(self.db_path)
    c = conn.cursor()

    # build update str from values dict
    val_str = ""
    val_list = []
    for (key,val) in values.items():
      val_str += key + " = ? "
      val_list.append(val)

    # id is the last in tuple for ? in db query
    val_list.append(id)

    if item == "tags":
      c.execute("UPDATE {0} SET {1} WHERE rowid=?".format(item, val_str), tuple(val_list))
      conn.commit()

    conn.close()

  def get_tags(self, item, id):
    # connect to db and initialize cursor
    conn = sqlite3.connect(self.db_path)
    c = conn.cursor()

    c.execute("SELECT tags.rowid, tags.name FROM tags INNER JOIN tags_{0}s ON tags.rowid = tags_{0}s.tag_id AND tags_{0}s.{0}_id = ?".format(item), (id,) )
    data = c.fetchall()

    conn.close()
    return data


import math

# Perform Recursive Binary Search, learned back in CMPUT 175
# Role: To search the index where the number is equal/ slightly less than the total maximum, then return the extra
def binary_search(low,high,number,extra):

    # Find the middle index of the list
    mid = (low+high)//2

    # Avoid scenario where high is less than low, when the search completes
    if high >= low:
        # Base case of recursion: if found exact number, return 0 as no surplus
        if number == n[mid]:
            return 0
        # Find surplus part
        # if the difference between list/sublist's middle elment and the number we look for is still less than extra, and not negtive
        # then total_extra will be the absolute value of the difference between the
        # use absolute function incase the difference is negative
        if (n[mid]-number) < extra and (n[mid] - number >= 0):
            extra = abs(number-n[mid])

        # Recursive part to perfrom binary search in n's sublist
        if number > n[mid]:
            # print("1")
            return binary_search(mid+1, high, number, extra)
        else:
            # print("2")
            return binary_search(low, mid-1, number, extra)
    return extra

# declare lists as global so binary search function can use
n=[]
m=[]

def main():
    # Read input and assign values from input
    first=[]
    first.append(input().split())

    for i in range (int(first[0][0])):
        n.append(int(input()))
    for i in range (int(first[0][1])):
        m.append(int(input()))

    # Sort the lists in ascending order to perfrom binary search
    n.sort() # [5,7,9]
    m.sort() # [6,8]

    total = 0
    # Get the sum the maximum values in both lists
    total_max = max(n) + max(m)

    # iterate through m, for each element perform binary search to get the surplius for each element in m
    for x in m:
        total += (binary_search(0,len(n)-1,x,total_max))
    print(total)
main()


#Exo 1 TP5 (1)

def som_div_propres(n):
    s=1
    i=2
    while i<n:
        if n%i==0 :
            s=s+i
        i=i+1
    return s
def est_parfait(n):
    if som_div_propres(n) == n:
        return True
    else :
        return False
def affiche_parfait(k):
    i=1
    while i<2**k:
        if est_parfait(i):
            print(i)
        i=i+1
def est_presque_parfait(n):
    if som_div_propres(n) == n-1:
        return True
    else:
        return False
def affiche_presque_parfait(k):
    i=1
    while i<2**k:
        if est_presque_parfait(i):
            print(i)
        i=i+1
n=int(input())
print(som_div_propres(n))
print(est_parfait(n))
k=int(input())
affiche_parfait(k)
print(est_presque_parfait(n))
affiche_presque_parfait(k)