from collections import deque

UP: list = [-1, 0]
DOWN: list = [1, 0]
LEFT: list = [0, -1]
RIGHT: list = [0, 1]

def solution(board: list) -> int:
    answer: list = []

    queue: deque = deque()
    cost: int = 100
    visited: list = [[0] * len(board[0]) for _ in range(len(board))]
    visited[0][0] = 1
    visited[0][1] = 100
    queue.append([[0, 1], RIGHT, cost])
    bfs(queue, visited, board, answer)

    queue: deque = deque()
    cost: int = 100
    visited: list = [[0] * len(board[0]) for _ in range(len(board))]
    visited[0][0] = 1
    visited[1][0] = 100
    queue.append([[1, 0], DOWN, cost])
    bfs(queue, visited, board, answer)

    return min(answer)

def bfs(queue: deque, visited: list, board: list, answer: list):
    while queue:
        cur_y: int
        cur_x: int
        direction: list
        (cur_y, cur_x), direction, cost = queue.popleft()

        if cur_y == len(board) - 1 and cur_x == len(board[0]) - 1:
            answer.append(cost)
            continue

        move_y: int
        move_x: int
        for move_y, move_x in [UP, DOWN, LEFT, RIGHT]:
            next_y: int = cur_y + move_y
            next_x: int = cur_x + move_x

            if not (0 <= next_y < len(board) and 0 <= next_x < len(board[0])):
                continue

            if board[next_y][next_x] == 0:
                next_cost: int = cal_cost(direction, [move_y, move_x], cost)
                # print(cur_y, cur_x, '->', next_y, next_x, ':', next_cost, '|',direction, [move_y, move_x])
                if visited[next_y][next_x] > next_cost or not visited[next_y][next_x]:
                    visited[next_y][next_x] = next_cost
                    # print_board(visited)
                    queue.append([[next_y, next_x], [move_y, move_x], next_cost])

def cal_cost(cur_dir: list, next_dir: list, cost) -> int:
    if (cur_dir == UP or cur_dir == DOWN) and (next_dir == UP or next_dir == DOWN):
        return cost + 100
    elif (cur_dir == UP or cur_dir == DOWN) and (next_dir == LEFT or next_dir == RIGHT):
        return cost + 600
    elif (cur_dir == LEFT or cur_dir == RIGHT) and (next_dir == LEFT or next_dir == RIGHT):
        return cost + 100
    elif (cur_dir == LEFT or cur_dir == RIGHT) and (next_dir == UP or next_dir == DOWN):
        return cost + 600

def print_board(board: list):
    for x in board:
        print(x, sep="")
    print()

if __name__ == '__main__':
    # print(solution([[0,0,0],[0,0,0],[0,0,0]]))
    print(solution([[0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0],[0,0,0,0,0,1,0,0],[0,0,0,0,1,0,0,0],[0,0,0,1,0,0,0,1],[0,0,1,0,0,0,1,0],[0,1,0,0,0,1,0,0],[1,0,0,0,0,0,0,0]]))


import json, aiohttp
from urllib.parse import urlparse

# 全局请求头
HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.50'
}

# 获取cookie
async def http_cookie(url):
    COOKIES = {'os': 'osx'}
    jar = aiohttp.CookieJar(unsafe=True)
    location = urlparse(url)
    location_orgin = f'{location.scheme}://{location.netloc}'
    async with aiohttp.ClientSession(headers=HEADERS, cookies=COOKIES, cookie_jar=jar) as session:
            async with session.get(url) as resp:
                cookies = session.cookie_jar.filter_cookies(location_orgin)
                for key, cookie in cookies.items():
                    COOKIES[key] = cookie.value
                result = await resp.json()
                return {
                    'cookie': COOKIES,
                    'data': result
                }

async def http_get(url, COOKIES={}):
    print(url)
    headers = {'Referer': url, **HEADERS}
    jar = aiohttp.CookieJar(unsafe=True)
    async with aiohttp.ClientSession(headers=headers, cookies=COOKIES, cookie_jar=jar) as session:
        async with session.get(url) as resp:
            # 喜马拉雅返回的是文本内容
            if 'https://mobile.ximalaya.com/mobile/' in url:
                result = json.loads(await resp.text())
            else:
                result = await resp.json()
            return result

async def http_code(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return response.status


# 多线程爬虫 简单实现 步骤
# 创建 存储page 页面的队列 ——》 多线程爬取不同的页面 ——》 将爬取下来的 页面存入 队列里 data_quene ——》 多线程将 data_quene 里面的队列的数据 写入磁盘

# -*- coding:utf-8 -*-
import requests
from lxml import etree
from queue import Queue
import threading
import time
import json

class crawlThreadCls(threading.Thread): # 继承 threading 里的 Thread 类
    def __init__(self, threadid, pagequeue):
        super(crawlThreadCls,self).__init__() # 先调用父类的 初始化
        self.threadid = threadid
        self.queue = pagequeue
        # url_addr = 'https://www.qiushibaike.com/8hr/page/2/'

    def run(self):
        print("开始下载数据；")
        self.spider_data()

    def spider_data(self):
        global crawl_flag
        if self.queue.empty() == True:
            crawl_flag = False
            print("网页下载队列，已空")
        else:
            crawl_flag = True
        while crawl_flag:
            if self.queue.qsize() == 0: #如果队列为空 ，退出爬取动作
                break
            else:
                pagenum = self.queue.get()
                print('当前线程为：%s, 当前页面是第 %d 页' % (self.threadid, pagenum))
                url_addr = "https://www.qiushibaike.com/8hr/page/" + str(pagenum) +'/'
                header = {
                    'User-Agent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)',
                    'Accept-Language': 'zh-CN,zh;q=0.8'
                }
                # 多次尝试失败结束、防止死循环
                timeout = 4
                while timeout > 0:
                    timeout -= 1
                    try:
                        req_info = requests.get(url_addr,headers=header)
                        #data = req_info.text.decode('utf8')
                        data_queue.put(req_info.text) # text 方法是以 文本的 方式来获取 请求的文件内容，并放入队列中
                        break
                    except Exception as e:
                        print(e)
                if timeout < 0:
                    print('request url timeout %s' % url_addr)

class parserThreadCls(threading.Thread):
    def __init__(self, parserid, data_queue, datalock, store_file):
        super(parserThreadCls, self).__init__()
        self.parserid = parserid
        self.data_q = data_queue
        self.datalock = datalock
        self.store_file = store_file

    def run(self):
        print("开始分析获取数据")
        global parser_flag
        while not parser_flag:
            try:
                # 在队列  block =  True(默认) 和 timeout 两个参数，当  block = True 时，写入和读取 是阻塞式的，阻塞时间由 timeout  确定
                # Queue.get（）默认的也是阻塞方式读取数据，队列为空时，不会抛出 except Queue.Empty ，而是进入阻塞直至超时。 加上 block=False 的参数;
                # 如果队列为空且block为False，队列将引发 Empty 异常;
                page_data = self.data_q.get(block=False)
                data_temp = page_data.encode('utf-8')
                self.parserdata(page_data)
                self.data_q.task_done()
                print('分析数据线程为：%s, 已完成工作' % self.parserid)

            except Exception as err:
                print(err)

        print('完成数据分析,线程是：%s' % self.parserid)

    def parserdata(self, htmldata):

        try:
            # htmldata_temp = htmldata.decode('utf8')
            xmldata = etree.HTML(htmldata)
            all_tiezi = xmldata.xpath('//div[contains(@id,"qiushi_tag_")]') # 获取所有的段子的 标签和内容部分
            for tiezi_detail in all_tiezi:
                try:
                    imgUrl = tiezi_detail.xpath('.//img/@src')[0]
                    title = tiezi_detail.xpath('.//h2')[0].text
                    content = tiezi_detail.xpath('.//div[@class="content"]/span')[0].text.strip()
                    vote = None
                    comments = None
                    try:
                        vote = tiezi_detail.xpath('.//i')[0].text
                        comments = tiezi_detail.xpath('.//i')[1].text
                    except:
                        pass

                    tiezi_data = {
                        'imgUrl': imgUrl,
                        'title': title,
                        'content': content,
                        'vote': vote,
                        'comments': comments,
                    }
                    #print(tiezi_data)
                    #writedate = tiezi_data
                    with self.datalock:
                        # 这里取出来的数据是 bytes 类型的，加了个换行符 \n 也需要转换成 bytes 类型的
                        self.store_file.write(json.dumps(tiezi_data,ensure_ascii=False).encode('utf-8') + "\n".encode(encoding='utf8'))
                except Exception as err:
                    print(err)

        except Exception as Err:
            print(Err)

global data_queue
data_queue = Queue() #存放数据的队列
thread_lock = threading.Lock()
global parser_flag
parser_flag = False

def main():
    output_file = open('qiushibaike.json', 'wb+')
    # 创建 页面队列 ，Queue() 没有接数字，表示没有设置队列 大小；
    page_queue = Queue()
    for num in range(1,4):
        page_queue.put(num)

    # 开始多线程 爬取页面
    # 定义 爬取的线程 存储列表， 和线程的名称
    crawl_threads = []
    crawl_list = ['crawl_thread1', 'crawl_thread2', 'crawl_thread3']

    for threadid in crawl_list:
        crawl_Thread = crawlThreadCls(threadid,page_queue)
        crawl_Thread.start()

        crawl_threads.append(crawl_Thread)

    # 初始化 分析 和 取出数据的 线程
    parser_threads = []
    parser_list = ["parser-thread1", "parser-thread2", "parser-thread3"]

    # 开始 分析 页面的 相关 数据信息的线程

    for parserid in parser_list:
        parser_thread_child = parserThreadCls(parserid, data_queue, thread_lock, output_file)
        parser_thread_child.start()
        parser_threads.append(parser_thread_child)

    # 等待队列清空 ，等待 获取页面的这个队列被清空了后再执行，分析数据的 线程；
    while not page_queue.empty():
        #print(1)
        pass
    # 添加 join 功能，防止 主进程 退出，子线程 退出；
    for crawl_thread_join in crawl_threads:
        crawl_thread_join.join()
    # print(data_queue.qsize())

    while not data_queue.empty():
        pass
    global parser_flag
    parser_flag = True
    for parser_thread_join in parser_threads:
        parser_thread_join.join()
    with thread_lock:
        output_file.close()

    # 测试 从 page_queue 队列里面去数据

    # flag = True
    # while flag:
    #     print(page_queue.get())
    #     if page_queue.qsize() == 0:
    #         flag == False

if __name__ == "__main__":
    main()


#  settings for checkerservice project.

import os
from environs import Env
import json
from halo_app.const import LOC,DEV,TST,PRD

print("== start base")

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

env = Env()

#ENV - flask environment
#ENV_TYPE - LOC,DEV,TST,PRD
#ENV_NAME - LOC or HALO_STAGE
#STAGE_URL - prefix for url

ENV = env.str('FLASK_ENV', default='production')
DEBUG = ENV == 'development'
SQLALCHEMY_DATABASE_URI = env.str('DATABASE_URL')
SECRET_KEY = env.str('SECRET_KEY')
BCRYPT_LOG_ROUNDS = env.int('BCRYPT_LOG_ROUNDS', default=13)
DEBUG_TB_ENABLED = DEBUG
DEBUG_TB_INTERCEPT_REDIRECTS = False
CACHE_TYPE = 'simple'  # Can be "memcached", "redis", etc.
SQLALCHEMY_TRACK_MODIFICATIONS = False
WEBPACK_MANIFEST_PATH = 'webpack/manifest.json'
WTF_CSRF_CHECK_DEFAULT = False

ENV_TYPE = LOC

ENV_NAME = LOC

FUNC_NAME='webfront'

APP_NAME = 'webfront_service'

from .extend import *

#@TODO load config data from env var if possible and if not from env file
#@todo add coverage to project
SERVER_LOCAL = env.bool('SERVER_LOCAL', default=False)
AWS_REGION = env.str('AWS_REGION')
DB_URL = env.str('DYNAMODB_URL')
SECRET_JWT_KEY = env.str('SECRET_JWT_KEY')
STAGE_URL=env.bool('STAGE_URL',default=True)
SITE_NAME = env.str('SITE_NAME')

# SECURITY WARNING: keep the secret key used in production secret!
# Make this unique, and don't share it with anybody.
SECRET_KEY = env.str('SECRET_KEY')

###
#Given a version number MAJOR.MINOR.PATCH, increment the:
#
#MAJOR version when you make incompatible  changes,
#MINOR version when you add functionality in a backwards-compatible manner, and
#PATCH version when you make backwards-compatible bug fixes.
###

title='webfront'
author='Author'
copyright='Copyright 2017-2018 '+ author
major='1'
minor='1'
patch='52'
version=major+'.'+minor+'.'+patch
#year.month.day.optional_revision  i.e 2016.05.03 for today
rev=1
build='2018.10.10.'+str(rev)
generate='2019.09.28.18:27:36'
print("generate="+generate)

def get_version():
    """
    Return package version as listed in  env file
    """
    if ENV_TYPE == PRD:
        return version + "/" + build
    return version + "/" + build + "/" + generate+ ' (' + ENV_NAME + ')'

VERSION = get_version()
print(VERSION)

APPEND_SLASH = True

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env.bool('DEBUG', default=False)
print("DEBUG="+str(DEBUG))

SERVER = env.str('SERVER_NAME')
HALO_HOST = None

ADMINS = (
    # ('Your Name', 'your_email@domain.com'),
)

MANAGERS = ADMINS

DB_VER = env.str('DB_VER', default='0')
PAGE_SIZE = env.int('PAGE_SIZE', default=5)
def get_db():
    return {
        'default': env.db(),
    }
#DATABASES = get_db()

def get_cache():
  return {
      'default': env.cache()
    }
#CACHES = get_cache()

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# On Unix systems, a value of None will cause  to use the same
# timezone as the operating system.
# If running in a Windows environment this must be set to the same as your
# system time zone.
USE_TZ = True
TIME_ZONE = 'America/Chicago'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LOCALE_CODE = 'en-US'
LANGUAGE_CODE = 'en'

LANGUAGES = (
    ('en', str('English')),
    #('nl', _('Dutch')),
    #('he', _('Hebrew')),
)

GET_LANGUAGE = True

LOCALE_PATHS = (
    os.path.join(BASE_DIR, '../locale'),
)

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = ''

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = ''

# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/'

ROOT_URLCONF = 'webfront_service.urls'

CORS_ORIGIN_ALLOW_ALL = True

#STATIC_URL = '/static/'
STATIC_URL = "/"+ENV_NAME+'/static/'

STATIC_ROOT = os.path.join(BASE_DIR, "api/static")

STATICFILES_DIRS = [
    #os.path.join(BASE_DIR, "api/static"),
    #'/var/www/static/',
]

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'main_formatter': {
            'format': '%(levelname)s:%(name)s: %(message)s '
                      '%(asctime)s; %(filename)s:%(lineno)d',
            'datefmt': "%Y-%m-%d %H:%M:%S",
            'class': "pythonjsonlogger.jsonlogger.JsonFormatter",
        },
        'main_formatter_old': {
            'format': '%(levelname)s:%(name)s: %(message)s '
                      '(%(asctime)s; %(filename)s:%(lineno)d)',
            'datefmt': "%Y-%m-%d %H:%M:%S",
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'main_formatter',
        },
        'console_debug_false': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'main_formatter',
        },
        'mail_admins': {
            'level': 'ERROR',
            'formatter': 'main_formatter',
            'class': 'logging.StreamHandler'
        }
    },
    'loggers': {
        'webfront_service.api.views': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'webfront_service.api.models': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'webfront_service.api.apis': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'webfront_service.api.events': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'webfront_service.handler': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'halo_app.flask.viewsx': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'halo_app.apis': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'halo_app.events': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'halo_app.flask.mixinx': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'halo_app.models': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'halo_app.flask.utilx': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'halo_app.ssm': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'halo_app.saga': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'webfront_service.api.mixin.mixin_view': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'webfront_service.api.mixin.mixin_db': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
        'webfront_service.api.mixin.mixin_handler': {
            'level': 'DEBUG',
            'handlers': ['console', 'console_debug_false', 'mail_admins']
        },
    },
}
import logging.config
logging.config.dictConfig(LOGGING)

USER_HEADERS = 'Mozilla/5.0'

MIXIN_HANDLER = 'webfront_service.api.mixin.mixin_handler'

SERVICE_READ_TIMEOUT_IN_SC = 3  # in seconds = 300 ms

SERVICE_CONNECT_TIMEOUT_IN_SC = 3  # in seconds = 300 ms

RECOVER_TIMEOUT_IN_SC = 0.5  # in seconds = 500 ms

MINIMUM_SERVICE_TIMEOUT_IN_SC = 0.1  # in seconds = 100 ms

HTTP_MAX_RETRY = 4

THRIFT_MAX_RETRY = 4

HTTP_RETRY_SLEEP = 10 #0.100  # in seconds = 100 ms

ERR_MSG_CLASS = 'webfront_service.api.mixin.mixin_err_msg'

#in case a web edge
FRONT_WEB = False #env.str('FRONT_API',default=False)
file_dirname = os.path.dirname(__file__)
fr_file_path = os.path.join(file_dirname, "front_web.txt")
if os.path.exists(fr_file_path):
    FRONT_WEB = True
    # for screen messages

print ("FRONT_WEB:"+str(FRONT_WEB))

#in case an api edge
FRONT_API = False #env.str('FRONT_API',default=False)
file_dirname = os.path.dirname(__file__)
fr_file_path = os.path.join(file_dirname, "front_api.txt")
if os.path.exists(fr_file_path):
    FRONT_API = True
print ("FRONT_API:"+str(FRONT_API))

import uuid
INSTANCE_ID = uuid.uuid4().__str__()[0:4]

LOG_SAMPLE_RATE = 0.05 # 5%

SSM_TYPE = env.str('SSM_TYPE',default='NONE')
print('SSM_TYPE='+SSM_TYPE)

############################################################################################

API_CONFIG = None
API_SETTINGS = ENV_NAME + '_api_settings.json'

file_dir = os.path.dirname(__file__)
file_path = os.path.join(file_dir,'..','..','env','api', API_SETTINGS)
if os.path.exists(file_path):
    with open(file_path, 'r') as fi:
        API_CONFIG = json.load(fi)
        print("api_config:" + str(API_CONFIG))
else:
    print("no api config file")

BUSINESS_EVENT_MAP = None
EVENT_SETTINGS = ENV_NAME + '_event_settings.json'
file_dir = os.path.dirname(__file__)
file_path = os.path.join(file_dir,'..','..','env','config', EVENT_SETTINGS)
if os.path.exists(file_path):
    with open(file_path, 'r') as fi:
        map = json.load(fi)
        BUSINESS_EVENT_MAP = {}
        for key in map:
            val = map[key]
            print("val:"+key+" "+str(val))
            dict = {}
            for action in val:
                item = val[action]
                file_path_data = os.path.join(file_dir,'..','..','env','config', item['url'])
                print(file_path_data)
                with open(file_path_data, 'r') as fx:
                     data = json.load(fx)
                     dict[action] = { item['type'] : data }
            BUSINESS_EVENT_MAP[key] = dict

print('== The base settings file has been loaded.')


'''A palindromic number reads the same both ways. The smallest 6 digit palindrome made from the product of two 3-digit numbers is 101101=143×707101101=143×707.

Find the largest palindrome made from the product of two 3-digit numbers which is less than NN.'''

def palindrome(string):
    ''' Indica si el string ingresado es un palindromo
    :param string:
    :return:
    '''
    return list(string) == list(reversed(string))

numeros = {i*j for i in range(100, 1000) for j in range(100, 1000) if palindrome(str(i*j))}

for _ in range(int(input())):
    n = int(input())
    print(max(filter(lambda x: x<n, numeros)))


# d= {}
# s = "my name is sanya wadhawan"
# for i in s:
#         if i in d:
#             d[i]=d[i]+1
#         else:
#             d[i]=1
# print (d)

for i in range(0, 3):
	for j in range(0, 3-i-1):
		print(end=" ")
	for j in range(0, i+1):
		print("*", end=" ")
	print()

rows= 4
for i in range(1, rows + 1):
    for j in range(1, i - 1):
        print(j, " ", end="   ")
    for j in range(i - 1, 0, -1):
        print( j," ", end="   ")
    print()

rows=5
i = 1
while i <= rows:
    j = rows
    while j > i:
        # display space
        print(' ', end=' ')
        j -= 1
    print('*', end=' ')
    k = 1
    while k < 2 * (i - 1):
        print(' ', end=' ')
        k += 1
    if i == 1:
        print()
    else:
        print('*')
    i += 1

i = rows - 1
while i >= 1:
    j = rows
    while j > i:
        print(' ', end=' ')
        j -= 1
    print('*', end=' ')
    k = 1
    while k <= 2 * (i - 1):
        print(' ', end=' ')
        k += 1
    if i == 1:
        print()
    else:
        print('*')
    i -= 1


#!/usr/bin/python -i

BASE2_LETTERS = '01'
BASE8_LETTERS = '01234567'
BASE10_LETTERS = '0123456789'
BASE16_LETTERS = '0123456789ABCDEF'
BASE32_LETTERS = (
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "234567")
BASE64_LETTERS = (
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz"
    "0123456789+/")
BASE58_LETTERS = (
    "  1 2 3 4 5 6 7 8 9"
    "A B C D E F G H   J K L M N   P Q R S T U V W X Y Z"
    "a b c d e f g h i j k   m n o p q r s t u v w x y z").replace(" ", "")

def gcd(a, b):
    '''Returns Greatest Common Divisor of `a` and `b`'''
    while b:
        q = a // b
        (a, b) = (b, a - q * b)
    return abs(a)

def lcm(a, b):
    '''Returns Least Common Multiple of `a` and `b`'''
    return abs(a) * (abs(b) // gcd(a, b))

def extended_gcd(a, b):
    (s, old_s) = (0, 1)
    (t, old_t) = (1, 0)
    (r, old_r) = (b, a)
    while r:
        q = old_r // r
        (old_r, r) = (r, old_r - q * r)
        (old_s, s) = (s, old_s - q * s)
        (old_t, t) = (t, old_t - q * t)
    return (old_r, (old_s, old_t), (t, s))

def inverse_mod(a, p):
    '''Returns `(1/a) mod p`'''
    return extended_gcd(a, p)[1][0] % p

def to_iterable(seq):
    if hasattr(seq, '__next__'): return seq
    return iter(seq)

def continuant_generator(terms, init=(0, 1)):
    terms = to_iterable(terms)
    (v_2, v_1) = init
    while True:
        x = next(terms)
        (v_2, v_1) = (v_1, v_1 * x + v_2)
        yield v_1

def continuant(terms, init=(0, 1), n=None):
    cg = continuant_generator(terms, init=init)
    v = init[1]
    i = -1
    try:
        while (n is None) or (i < n):
            v = next(cg)
            i += 1
    except StopIteration:
        pass
    if (n is not None) and (i < n):
        raise Exception("not enough elements in terms: n={}, terms produced only {}".format(n, i))
    return (v, i)

def const_generator(x):
    while True:
        yield x

def prefixed_generator(prefix_seq, general_seq):
    prefix_seq = to_iterable(prefix_seq)
    try:
        while True:
            yield next(prefix_seq)
    except StopIteration:
        pass
    while True:
        yield next(general_seq)

def prefixed_const_generator(prefix_seq, x):
    return prefixed_generator(prefix_seq, const_generator(x))

def sequential_generator(func, init=1):
    while True:
        yield func(init)
        init += 1

def prefixed_sequential_generator(prefix_seq, func, init=1):
    return prefixed_generator(prefix_seq, sequential_generator(func, init=init))

def repeating_generator(seq):
    seq = to_iterable(seq)
    v = []
    try:
        while True:
            x = next(seq)
            v.append(x)
            yield x
    except StopIteration:
        pass
    if not v: raise StopIteration()
    i = 0
    while True:
        yield v[i]
        i = (i + 1) % len(v)

def prefixed_repeating_generator(prefix_seq, general_seq):
    return prefixed_generator(prefix_seq, repeating_generator(general_seq))

def scf_convergent_generator(terms):
    '''
    Returns a generator that produces successive convergents of a simple continued fraction
      formed by applying the fundamental recurrence formulas:
        * P(n) = P(n-1)*a(n) + P(n-2); P(-2) = 0, P(-1) = 1; [P(0) = a0]
        * Q(n) = Q(n-1)*a(n) + Q(n-2); Q(-2) = 1, Q(-1) = 0; [Q(0) = 1]
      where P(n)/Q(n) is a n-th convergent and equals to the simple continued fraction:
        P(n)/Q(n) = a0 + 1/(a1 + 1/(a2 + 1/(a3 + ...)))

    The `terms` parameter is a sequence (generator or any iterable object) of a(n) values.

    NOTE:
      * `n` starts from 0
      * a0 (first element from the `terms`) is an integer part [i. e. floor(P(n)/Q(n))]
      * `terms` is usually written as: [a0; a1, a2, ...]

    Returned value is a tuple: (P(n), Q(n)).
    '''
    terms = to_iterable(terms)
    (p_2, p_1) = (0, 1)
    (q_2, q_1) = (1, 0)
    while True:
        a = next(terms)
        (p_2, p_1) = (p_1, p_1 * a + p_2)
        (q_2, q_1) = (q_1, q_1 * a + q_2)
        yield (p_1, q_1)

def scf_convergent(terms, n=None):
    '''
    Returns a n-th convergent produced by the `scf_convergent_generator(terms)`.
    :param: x xyu
    * If the `terms` parameter has less that `n` elements, the Exception will be thrown.
    * If the `n` parameter is None and `terms` is an endless sequence, the stack will be
      overflowed and a corresponding exception will be thrown.

    Returned value is a tuple: (P(n), Q(n), n).
    '''
    cg = scf_convergent_generator(terms)
    (p, q) = (1, 0)
    i = -1
    try:
        while (n is None) or (i < n):
            (p, q) = next(cg)
            i += 1
    except StopIteration:
        pass
    if (n is not None) and (i < n):
        raise Exception("not enough elements in terms: n={}, terms produced only {}".format(n, i))
    return (p, q, i)

def gcf_convergent_generator(denom_terms, num_terms):
    '''
    Returns a generator that produces successive convergents of a generalized continued fraction
      formed by applying the fundamental recurrence formulas:
        * P(n) = P(n-1)*a(n) + P(n-2)*b(n); P(-2) = 0, P(-1) = 1; [P(0) = a(0)]
        * Q(n) = Q(n-1)*a(n) + Q(n-2)*b(n); Q(-2) = 1, Q(-1) = 0; [Q(0) = b(0) = 1]
      where P(n)/Q(n) is a n-th convergent and equals to the generalized continued fraction:
        P(n)/Q(n) = a0 + b1/(a1 + b2/(a2 + b3/(a3 + ... + b(n)/a(n))))

    The `demon_terms` parameter is a sequence (generator or any iterable object)
      of a(n) values [n = 0, 1, 2, ...] (so called `partial denominators`).
    The `num_terms` parameter is a sequence (generator or any iterable object)
      of b(n) values [n = 1, 2, 3, ...] (so called `partial numerators`).

    NOTE:
      * `n` starts from 0 for denominators
      * `n` starts from 1 for numerators, so b0 = 1 and
         should not be produced by the `denom_terms`

    Returned value is a tuple: (P(n), Q(n)).
    '''
    denom_terms = to_iterable(denom_terms)
    num_terms = to_iterable(num_terms)
    a = next(denom_terms)
    b = 1
    (p_2, p_1) = (1, a)
    (q_2, q_1) = (0, b)
    yield (p_1, q_1)
    while True:
        a = next(denom_terms)
        b = next(num_terms)
        (p_2, p_1) = (p_1, p_1 * a + p_2 * b)
        (q_2, q_1) = (q_1, q_1 * a + q_2 * b)
        yield (p_1, q_1)

class Quotient:
    def __init__(self, p, q=1):
        if type(p) != int:
            raise ValueError('p is not integer')
        if type(q) != int:
            raise ValueError('q is not integer')
        if q < 1:
            raise ValueError('q is not natural')
        self.p = p
        self.q = q
        self.canonize()
    def canonize(self):
        d = gcd(abs(self.p), self.q)
        if d > 1:
            self.p //= d
            self.q //= d
        return self
    def __repr__(self):
        return "Quotient({}/{})".format(self.p, self.q)
    @staticmethod
    def toQTuple(that):
        if isinstance(that, Quotient):
            return (that.p, that.q)
        elif type(that) == int:
            return (that, 1)
        else:
            raise ValueError('unsupported type: "{}" (value: {})'.format(type(that), that))
    def __iadd0__(self, xp, xq):
        if self.q != xq:
            self.p = (self.p * xq) + (xp * self.q)
            self.q *= xq
        else:
            self.p += xp
        return self.canonize()
    def __iadd__(self, that):
        (xp, xq) = Quotient.toQTuple(that)
        return self.__iadd0__(xp, xq)
    def __add__(self, that):
        return Quotient(self.p, self.q).__iadd__(that)
    def __isub__(self, that):
        (xp, xq) = Quotient.toQTuple(that)
        self.__iadd0__(-xp, xq)
        return self
    def __sub__(self, that):
        return Quotient(self.p, self.q).__isub__(that)
    def __imul0__(self, xp, xq):
        self.p *= xp
        self.q *= xq
        return self.canonize()
    def __imul__(self, that):
        (xp, xq) = Quotient.toQTuple(that)
        return self.__imul0__(xp, xq)
    def __mul__(self, that):
        return Quotient(self.p, self.q).__imul__(that)
    def __itruediv__(self, that):
        (ixq, ixp) = Quotient.toQTuple(that)
        if (ixq == 0): raise ZeroDivisionError("denominator is zero for inverted quotient: {}".format(that))
        if (ixq < 0): (ixp, ixq) = (-ixp, -ixq)
        return self.__imul0__(ixp, ixq) # invert quotien & mul instead of div: x / (a/b) => x * (b/a)
    def __truediv__(self, that):
        return Quotient(self.p, self.q).__itruediv__(that)
    def __abs__(self):
        return Quotient(abs(self.p), self.q)
    def __lt__(self, that):
        if id(self) == id(that): return False
        (xp, xq) = Quotient.toQTuple(that)
        return self.p*xq < xp*self.q
    def __le__(self, that):
        if id(self) == id(that): return True
        (xp, xq) = Quotient.toQTuple(that)
        return self.p*xq <= xp*self.q
    def __eq__(self, that):
        if id(self) == id(that): return True
        (xp, xq) = Quotient.toQTuple(that)
        return (self.p == xp) and (self.q == xq)
    def __ne__(self, that):
        return not self.__eq__(that)
    def __gt__(self, that):
        if id(self) == id(that): return False
        (xp, xq) = Quotient.toQTuple(that)
        return self.p*xq > xp*self.q
    def __ge__(self, that):
        if id(self) == id(that): return True
        (xp, xq) = Quotient.toQTuple(that)
        return self.p*xq >= xp*self.q
    def __pow__(self, n):
        if type(n) != int:
            raise ValueError('n is not integer')
        return Quotient(self.p**n, self.q**n)
    def toPositionalFractionGenerator(self, radix=10):
        (p, q) = (abs(self.p), self.q)
        x = p // q
        p -= q * x

        # 0. produce sign part as None if value is negative
        if self.p < 0:
            yield None

        # 1. produce integer part as: a(m), a(m-1), a(m-2), ..., a(0)
        m = 0
        while x >= (radix**(m+1)):
            m += 1
        while m >= 0:
            y, x = divmod(x, (radix**m))
            m -= 1
            yield y

        # 2. produce radix point as None
        yield None

        # 3. produce fraction part as: b(0), b(1), ...
        while True:
            p *= radix
            x = p // q
            p -= q * x
            yield x
    def toPositionalFraction(self, radixLetters, fractionPrecision=12):
        g = self.toPositionalFractionGenerator(radix=len(radixLetters))
        v = []
        i = next(g)
        if i is None:
            v.append('-')
            i = next(g)
        while i is not None:
            v.append(radixLetters[i])
            i = next(g)
        if fractionPrecision > 0:
            v.append('.')
            while fractionPrecision > 0:
                v.append(radixLetters[next(g)])
                fractionPrecision -= 1
        return ''.join(v)
    def toDecimalFraction(self, fractionPrecision=12):
        return self.toPositionalFraction(BASE10_LETTERS, fractionPrecision=fractionPrecision)
    def toHexadecimalFraction(self, fractionPrecision=12):
        return self.toPositionalFraction(BASE16_LETTERS, fractionPrecision=fractionPrecision)
    def toBase58Fraction(self, fractionPrecision=12):
        return self.toPositionalFraction(BASE58_LETTERS, fractionPrecision=fractionPrecision)
    @staticmethod
    def fromScfConvergent(terms, n=None):
        v = scf_convergent(terms, n)
        return Quotient(v[0], v[1])
    @staticmethod
    def fromScfConvergentWithPrecision(terms, precisionDenominator):
        cg = scf_convergent_generator(terms)
        (p, q) = (1, 0)
        i = -1
        try:
            while precisionDenominator > q*q:
                (p, q) = next(cg)
                i += 1
        except StopIteration:
            pass
        return (Quotient(p, q), i)


from os import environ, getcwd, chdir
from os.path import join, dirname, abspath
from subprocess import call
from pathlib import Path

import pandas as pd
from django.conf import settings

# static paths
_R_PATH = join(dirname(abspath(__file__)), 'r')
_HORIZON_R_SCRIPT = join(_R_PATH, 'horizon.r')

def generate_image(df: pd.DataFrame, uid: str, width: int, height: int) -> None:
    """
    Generate a horizon plot of taxonomy abundances.
    Check static paths for file locations.

    WARNING: - Local files are being created to pass data
             - Files that should be static are created dynamically
             - Scripts are being called in subprocesses
             - Environment variables are being passed between processes

    Future considerations:
             - Find a way to integrate the R script into Python
             - Find a Python-native method to generate horizon plots
             - Find a way to generate horizon plots in Plotly
    """

    image_dir = join(settings.STATICFILES_DIRS[0], 'dashboard', uid)
    Path(image_dir).mkdir(parents=True, exist_ok=True)
    image_path = join(image_dir, 'horizon.png')
    csv_file = join(_R_PATH, uid + '_abundances.csv')

    horizon_scale = _write_csv(df, csv_file)
    _export_env_vars(image_path, width, height, csv_file, horizon_scale)
    _call_r_script()

def _write_csv(df: pd.DataFrame, csv_file: str) -> int:
    """
    Transpose mmonitor db to a Dataframe with only taxonomies and their abundances.
    """

    # calculate the width of bands for the horizon plot assuming 6 bands
    horizon_scale = (df['abundance'].max() - df['abundance'].min()) // 6

    # scale the abundances so that 0 is the origin for a better y axis label
    def shift(x):
        return x - horizon_scale * 3

    df['abundance'] = df['abundance'].apply(shift)

    # target df
    csv_df = pd.DataFrame()

    # create column in target df for each unique taxonomy
    taxonomies = df['taxonomy'].unique()

    # extract a taxonomy's abundances as series and
    # append it to the target df as new column
    for t in taxonomies:
        f = df['taxonomy'] == t
        csv_df[t] = pd.Series(df[f]['abundance']).reset_index(drop=True)

    # write file
    csv_df.to_csv(csv_file, index=False)

    return horizon_scale

def _export_env_vars(image_path: str, width: int, height: int, csv_file: str, horizon_scale: int) -> None:
    """
    Export necessary variables to environment
    so that the R script can read them from the environment.
    """

    environ['HORI_WIDTH'] = str(width)
    environ['HORI_HEIGHT'] = str(height)
    environ['HORI_BANDWIDTH'] = str(horizon_scale)
    environ['HORI_CSV'] = csv_file
    environ['HORI_IMAGE'] = image_path

def _call_r_script() -> None:
    """
    Execute the R script that generates a horizon plot.
    """

    cwd = getcwd()
    chdir(_R_PATH)
    call([settings.RSCRIPT, '--no-save', _HORIZON_R_SCRIPT])
    chdir(cwd)


from datetime import datetime
from sqlalchemy import (
    Column, Integer, String,
    ForeignKey, Text, Date
)
from EnGo.models import db, MyModel

class Activity(db.Model, MyModel):
    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('user.id'), nullable=False)
    title = Column(String(200), nullable=False)
    description = Column(Text, nullable=True)
    due_date = Column(Date, nullable=False, default=datetime.today)

    @property
    def validation(self):
        from .validation import ActivityValidation
        return ActivityValidation(self)


"""Explorer module handles launch and exit of the File Explorer."""

# Used to get path to desktop directory
from os import path
# Opens File Explorer as a process
from subprocess import Popen

# Inherited by class Explorer
from unison.classes.module import Module

class FileExplorer(Module):

    def __init__(self):
        """Set required inherited parameters."""
        super().__init__(name=FileExplorer.__name__,
                         verbs=["explorer"])

    def launch_explorer(self, filepath):
        """Launch an instance of File Explorer with Popen.

        Args:
            filepath (str): Path to file to be opened.
        """
        self.process = Popen([r'explorer', "{}".format(filepath)])

    def exit_explorer(self):
        """Terminates self.process."""
        # Not working!
        # Each time an instance of File Explorer is called, it is
        # replaced by another instance of File Explorer by the OS.
        self.process.kill()

    def run(self, **kwargs):
        """Run module by set kwargs and verb switch statement.

        Set using the instructions outlined in the inherited Module class.

        Args:
            **kwargs:
                settings (dict): All program settings.
                verb (str): Action word to match with module.
                noun (str): Item to be acted upon.
        """
        settings = kwargs["settings"]
        verb = kwargs["verb"]
        noun = kwargs["noun"]

        filepath = path.join(settings["desktop"],
                             settings["desktop_dir"])

        if self.process:
            self.exit_explorer()
        else:
            self.launch_explorer(filepath)


"""
A universal directory tree widget for Textual.
"""

from __future__ import annotations

from typing import ClassVar, Iterable, List, Optional, Type

from textual.binding import BindingType
from textual.widgets._directory_tree import DirEntry
from textual.widgets._tree import TreeNode
from textual_universal_directorytree import UniversalDirectoryTree
from upath import UPath as Path

from browsr._base import BrowsrPath, vim_cursor_bindings

class BrowsrDirectoryTree(UniversalDirectoryTree):
    """
    A DirectoryTree that can handle any filesystem.
    """

    PATH: Type[BrowsrPath] = BrowsrPath

    BINDINGS: ClassVar[List[BindingType]] = [
        *UniversalDirectoryTree.BINDINGS,
        *vim_cursor_bindings,
    ]

    @classmethod
    def _handle_top_level_bucket(cls, dir_path: Path) -> Optional[Iterable[Path]]:
        """
        Handle scenarios when someone wants to browse all of s3

        This is because S3FS handles the root directory differently than other filesystems
        """
        if str(dir_path) == "s3:/":
            sub_buckets = sorted(
                Path(f"s3://{bucket.name}") for bucket in dir_path.iterdir()
            )
            return sub_buckets
        return None

    def _populate_node(self, node: TreeNode[DirEntry], content: Iterable[Path]) -> None:  # type: ignore[override]
        """
        Populate the given tree node with the given directory content.

        This function overrides the original textual method to handle root level
        cloud buckets.
        """
        top_level_buckets = self._handle_top_level_bucket(dir_path=node.data.path)  # type: ignore[union-attr, arg-type]
        if top_level_buckets is not None:
            content = top_level_buckets
        node.remove_children()
        for path in content:
            if top_level_buckets is not None:
                path_name = str(path).replace("s3://", "").rstrip("/")
            else:
                path_name = path.name
            node.add(
                path_name,
                data=DirEntry(path),
                allow_expand=self._safe_is_dir(path),
            )
        node.expand()


#!/usr/bin/python

# Standard imports
import cv2
import numpy as np
import time

# Read image
im = cv2.imread("blob.jpg", cv2.IMREAD_GRAYSCALE)
cap = cv2.VideoCapture(0)
i = 0

# Setup SimpleBlobDetector parameters.
params = cv2.SimpleBlobDetector_Params()

# Change thresholds
params.minThreshold = 10
params.maxThreshold = 400

# Filter by Area.
params.filterByArea = True
params.minArea = 100
params.maxArea=4000

# Filter by Circularity
params.filterByCircularity = False
params.minCircularity = 0.001

# Filter by Convexity
params.filterByConvexity = True
params.minConvexity = 0.87

# Filter by Inertia
params.filterByInertia = True
params.minInertiaRatio = 0.0001

# Grouping
params.minDistBetweenBlobs = 20

params.filterByColor = False
params.blobColor = 225

# Create a detector with the parameters
ver = (cv2.__version__).split('.')
if int(ver[0]) < 3 :
	detector = cv2.SimpleBlobDetector(params)
else :
	detector = cv2.SimpleBlobDetector_create(params)

while(True):
# Detect blobs.
	#keypoints = detector.detect(im)
	ret, frame = cap.read()
	keypoints = detector.detect(frame)

# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures
# the size of the circle corresponds to the size of blob

	#im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
	cap_w_keypoints = cv2.drawKeypoints(frame, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

# Show blobs
	#cv2.imshow("Keypoints", im_with_keypoints)
	cv2.imshow('frame',cap_w_keypoints)
	#cv2.waitKey(0)

	pts = cv2.KeyPoint_convert(keypoints)
	print("keypoints: ", pts)
#-----------------------------------------------------------------------

# Text Box
	#img = np.zeros((500,800,3),np.uint8)
	#response= str(pts)

#	cv2.putText(img, response,(0, 50),
 #              cv2.FONT_HERSHEY_SIMPLEX,
  #             1,(0, 0, 255),
   #            lineType=cv2.LINE_AA)

#	cv2.imshow('frame2', img)
#-----------------------------------------------------------------------

	if cv2.waitKey(1) & 0xFF == ord('q'):
		break

cap.release()
cv2.destroyAllWindows()


# 입력 순서 학생 수, 체육복을 잃어버린 학생번호, 여벌 체육복이 있는 학생번호.
# 체육복은 자기 번호 -1 / +1 인 학생들한테만 빌려줄수 있고 인당 여벌 체육복은 1벌씩이라고 가정한다.

def take_a_class(n, lost, reserve):
    students = [i for i in range(1, n + 1)]

    for student in lost:
        if student in reserve:
            reserve.remove(student)
            lost.remove(student)

    for student in lost:
        if student - 1 in reserve:
            reserve.remove(student - 1)
        elif student + 1 in reserve:
            reserve.remove(student + 1)
        else:
            students.remove(student)

    return len(students)

def main():
    students_count = int(input())
    lost_students = sorted(list(map(int, input().split())))
    reserve_students = sorted(list(map(int, input().split())))

    print(take_a_class(students_count, lost_students, reserve_students))

if __name__ == "__main__":
    main()


from sklearn.datasets import load_files
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.pipeline import Pipeline
from sklearn.model_selection import cross_val_score
from sklearn.naive_bayes import MultinomialNB
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import SGDClassifier
from sklearn.svm import LinearSVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier

def output(x, y):
    print('Accuracy =', accuracy_score(x, y),
          '\nPrecision =', precision_score(x, y),
          '\nRecall =', recall_score(x, y),
          '\nF1-score =', f1_score(x, y),
          '\nError rate =', (1 - accuracy_score(x, y)))

import seaborn
import matplotlib.pyplot as plt

def plot_confusion_matrix(data, labels, output_filename):
    seaborn.set(color_codes=True)
    plt.figure(1, figsize=(9, 6))

    plt.title("Confusion Matrix")

    seaborn.set(font_scale=1.4)
    ax = seaborn.heatmap(data, annot=True, fmt='g', cbar_kws={'label': 'Scale'})

    ax.set_xticklabels(labels)
    ax.set_yticklabels(labels)

    ax.set(ylabel="Predicted class", xlabel="Actual class")

    plt.savefig(output_filename, bbox_inches='tight', dpi=300)
    plt.close()

doc_data = load_files("./train/", encoding="utf-8", decode_error="replace")
X_train, y_train = doc_data.data, doc_data.target

doc_data = load_files("./test/", encoding="utf-8", decode_error="replace")
X_test, y_test = doc_data.data, doc_data.target

# создание конвейеров обучения для моделей
bayes = Pipeline([
    ("count vectorizer", CountVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("bayes", MultinomialNB())
])
bayes_tfidf = Pipeline([
    ("count vectorizer", TfidfVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("bayes", MultinomialNB())
])
destree = Pipeline([
    ("count vectorizer", CountVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("destree", DecisionTreeClassifier())
])
destree_tfidf = Pipeline([
    ("count vectorizer", TfidfVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("destree", DecisionTreeClassifier())
])
sgd = Pipeline([
    ("count vectorizer", CountVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("sgd", SGDClassifier(loss="modified_huber"))
])
sgd_tfidf = Pipeline([
    ("tfidf_vectorizer", TfidfVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("sgd", SGDClassifier())
])
svc = Pipeline([
    ("count_vectorizer", CountVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("linear svc", LinearSVC())
])
svc_tfidf = Pipeline([
    ("tfidf_vectorizer", TfidfVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("linear svc", LinearSVC())
])
ranfor = Pipeline([
    ("count_vectorizer", CountVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("ranfor", RandomForestClassifier())
])
ranfor_tfidf = Pipeline([
    ("tfidf_vectorizer", TfidfVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("ranfor", RandomForestClassifier())
])
logreg = Pipeline([
    ("count_vectorizer", CountVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("logreg", LogisticRegression())
])
logreg_tfidf = Pipeline([
    ("tfidf_vectorizer", TfidfVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("logreg", LogisticRegression())
])
knn = Pipeline([
    ("count_vectorizer", CountVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("knn", KNeighborsClassifier())
])
knn_tfidf = Pipeline([
    ("tfidf_vectorizer", TfidfVectorizer(stop_words="english", max_features=5000, decode_error="ignore")),
    ("knn", KNeighborsClassifier())
])

all_models = [
    ("bayes", bayes),
    ("bayes_tfidf", bayes_tfidf),
    ("destree", destree),
    ("destree_tfidf", destree_tfidf),
    ("sgd", sgd),
    ("sgd_tfidf", sgd_tfidf),
    ("svc", svc),
    ("svc_tfidf", svc_tfidf),
    ("ranfor", ranfor),
    ("ranfor_tfidf", ranfor_tfidf),
    ("logreg", logreg),
    ("logreg_tfidf", logreg_tfidf),
    ("knn", knn),
    ("knn_tfidf", knn)
]

# нахождение самой производительной модели
unsorted_scores = [(name, cross_val_score(model, X_train, y_train, cv=None).mean()) for name, model in all_models]
scores = sorted(unsorted_scores, key=lambda x: -x[1])
print(scores)

model = svc_tfidf
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
output(y_test, y_pred)

tn, fp, fn, tp = confusion_matrix(list(y_test), list(y_pred), labels=[0, 1]).ravel()

data = [[tp, fp],
        [fn, tn]]
labels = ["private", "public"]

# создание матрицы несоответствий
plot_confusion_matrix(data, labels, "confusion_matrix3.png")

research stages/model training and selection.py


import time
import pyautogui
import pyperclip
from selenium.webdriver import Remote
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.common.action_chains import ActionChains

TIME_OUT = 5
INTERVAL = .5

class Driver:
    host = ''

    def __init__(self, driver: Remote):
        self.driver = driver

    def goto(self, url:str):
        if url.startswith(('http://', 'https://')):
            return self.driver.get(url)
        if not url.startswith('/'):
            return ValueError('url must start with slash /.')
        url = self.host + url
        return self.driver.get(url)

    def click(self, locator):
        el = self.wait_clickable(locator)
        el.click()
        return self

    def type(self, locator, words):
        el = self.wait_element(locator)
        el.send_keys(words)
        return self

    def double_click(self, locator):
        ac = ActionChains(self.driver)
        el = self.wait_clickable(locator)
        ac.double_click(el).perform()
        return self

    def right_click(self, locator):
        ac = ActionChains(self.driver)
        el = self.wait_clickable(locator)
        ac.context_click(el).perform()
        return self

    def drag(self, start_locator, end_locator):
        ac = ActionChains(self.driver)
        el_start = self.wait_element(start_locator)
        el_end = self.wait_element(end_locator)
        ac.drag_and_drop(el_start, el_end).perform()
        return self

    def move_to(self, locator):
        ac = ActionChains(self.driver)
        el = self.wait_clickable(locator)
        ac.move_to_element(el).perform()
        return self

    def switch_to_window(self, window_name):
        self.driver.switch_to.window(window_name=window_name)
        return self

    def switch_to_frame(self, locator, timeout=TIME_OUT, interval=INTERVAL):
        wait = WebDriverWait(self.driver, timeout=timeout, poll_frequency=interval)
        wait.until(expected_conditions.frame_to_be_available_and_switch_to_it(locator))
        return self

    def switch_to_alert(self, locator, timeout=TIME_OUT, interval=INTERVAL):
        wait = WebDriverWait(self.driver, timeout=timeout, poll_frequency=interval)
        el = wait.until(expected_conditions.alert_is_present)
        return el

    def scroll_to_bottom(self):
        self.driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
        return self

    def scroll_to(self, width, height):
        self.driver.execute_script(f'window.scrollTo({width}, {height})')
        return self

    def upload(self, locator, file):
        el = self.wait_element(locator)
        if el.tag_name == 'input':
            el.send_keys(file)
            return self
        el.click()
        pyperclip.copy(file)
        time.sleep(.2)
        pyautogui.hotkey('ctrl', 'v')
        pyautogui.press('enter', presses=2)
        return self

    def find(self, locator):
        return self.driver.find_element(*locator)

    def wait_element(self, locator, timeout=TIME_OUT, interval=INTERVAL) -> WebElement:
        used_time = 0
        while used_time < timeout:
            try:
                el = self.driver.find_element(*locator)
                return el
            except NoSuchElementException:
                time.sleep(interval)
                used_time += interval
        raise NoSuchElementException(f"can not find the element by locator:{locator}")

    def wait_visible(self, locator, timeout=TIME_OUT, interval=INTERVAL):
        wait = WebDriverWait(self.driver, timeout=timeout, poll_frequency=interval)
        el = wait.until(expected_conditions.visibility_of_element_located(locator))
        return el

    def wait_presence(self, locator, timeout=TIME_OUT, interval=INTERVAL):
        wait = WebDriverWait(self.driver, timeout=timeout, poll_frequency=interval)
        el = wait.until(expected_conditions.presence_of_element_located(locator))
        return el

    def wait_clickable(self, locator, timeout=TIME_OUT, interval=INTERVAL):
        wait = WebDriverWait(self.driver, timeout=timeout, poll_frequency=interval)
        el = wait.until(expected_conditions.element_to_be_clickable(locator))
        return el

    def quit(self):
        self.driver.quit()

    def screenshot(self):
        self.driver.save_screenshot('demo.png')

def screenshot_required(f):
    def decorator(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except Exception as e:
            for i in args:
                if isinstance(i, Driver):
                    i.screenshot()
            raise e
    return decorator


"""MangaBuddy site downloader"""

import re
from typing import Iterable, Set

from bs4 import BeautifulSoup

from .base import Chapter, ChapterImage, Language, Manga, Site

class MangaBuddy(Site):
    @property
    def name(self) -> str:
        return "MangaBuddy"

    @property
    def url(self) -> str:
        return "https://mangabuddy.com"

    @property
    def supported_languages(self) -> Set[Language]:
        return {Language.en}

    def search(self, query: str, lang: Language = None) -> Iterable[Manga]:
        with self.session.get(f"{self.url}/search", params={"q": query}) as resp:
            resp.raise_for_status()
            soup = BeautifulSoup(resp.text, "html.parser")
        for card in soup("div", {"class": "book-item"}):
            anchor = card.a
            if anchor is None:
                continue
            yield Manga(
                url=f'{self.url}{anchor["href"].strip()}',
                name=anchor["title"].strip(),
                cover=card.findNext("img")["data-src"].strip(),
            )

    def get_chapters(self, manga: Manga) -> Iterable[Chapter]:
        url = f"https://mangabuddy.com/api/manga{manga.url[len(self.url):]}/chapters?source=detail"
        with self.session.get(url) as resp:
            resp.raise_for_status()
            soup = BeautifulSoup(resp.text, "html.parser")
        soup = soup.find("ul", {"id": "chapter-list"})
        for item in soup("li"):
            item = item.find("a")
            name = item.findNext("strong", {"class": "chapter-title"}).text.strip()
            yield Chapter(name=name, url=f'{self.url}{item["href"]}')

    def get_images(self, chapter: Chapter) -> Iterable[ChapterImage]:
        with self.session.get(chapter.url) as resp:
            resp.raise_for_status()
            imgs = re.findall(r"var chapImages = '(.*)'", resp.text)[0].split(",")
        for img in imgs:
            if not img.startswith(("https://", "http://")):
                img = f"https://s1.mbcdnv1.xyz/file/img-mbuddy/manga/{img}"
            yield ChapterImage(url=img)

    def download_image(self, image: ChapterImage) -> bytes:
        with self.session.get(image.url, headers={"referer": self.url}) as resp:
            resp.raise_for_status()
            return resp.content

    def download_cover(self, manga: Manga) -> bytes:
        assert manga.cover
        with self.session.get(manga.cover, headers={"referer": self.url}) as resp:
            resp.raise_for_status()
            return resp.content


# -*- coding: utf-8 -*-
"""
Created on Fri May 15 00:05:13 2020

@author: user
"""

#Scenario
#A junior magician has picked a secret number. He has hidden it in a variable named secret_number.
#He wants everyone who run his program to play the Guess the secret number game,
#and guess what number he has picked for them.
#Those who don't guess the number will be stuck in an endless loop forever!

secret_number = 777

print(
"""
+================================+
| Welcome to my game, muggle!    |
| Enter an integer number        |
| and guess what number I've     |
| picked for you.                |
| So, what is the secret number? |
+================================+
""")

number = int(input("guess the secret number: "))

while number != secret_number:
    print("ha ha! You're stuck in my loop!")
    number = int(input("guess the secret number: "))

print("Well done, muggle! You are free now.")


class Graf():
    def __init__(self):
        self.slownikSasiedztwa = dict()

    def dodajWierzcholek(self, wierzcholek):
        if wierzcholek in self.slownikSasiedztwa:
            print('Już dodany')
        else:
            self.slownikSasiedztwa[wierzcholek] = []

    def dodajKrawedz(self, start, koniec):
        if start in self.slownikSasiedztwa and koniec in self.slownikSasiedztwa:
            self.slownikSasiedztwa[start] += [koniec]

    def wypisz(self):
        for wierzcholek in self.slownikSasiedztwa:
            print(wierzcholek, ' : ', end='')
            for sasiedzi in self.slownikSasiedztwa[wierzcholek]:
                print(sasiedzi, ' , ', end='')
            print('')

    def znajdzSciezke(self, start, koniec):
        def znajdz(self, start, koniec, odwiedzone = set()):
            if start in self.slownikSasiedztwa and koniec in self.slownikSasiedztwa:
                if start == koniec:
                    return [koniec]
                for sasiad in self.slownikSasiedztwa[start]:
                    odwiedzone.add(sasiad)
                    sciezka = znajdz(self, sasiad, koniec, odwiedzone)
                    if sciezka:
                        return [sasiad] + sciezka
        if znajdz(self, start,koniec):
            return [start] + znajdz(self, start,koniec)[:-1]

    def znajdzWszystkieSciezki(self, start, koniec, sciezki = []):
        def znajdz(self, start, koniec, odwiedzone = set()):
            if start in self.slownikSasiedztwa and koniec in self.slownikSasiedztwa:
                if start == koniec:
                    return [koniec]
                for sasiad in self.slownikSasiedztwa[start]:
                    odwiedzone.add(sasiad)
                    sciezka = znajdz(self, sasiad, koniec, odwiedzone)
                    if sciezka:
                        return [sasiad] + sciezka

        for sasiad in self.slownikSasiedztwa[start]:
            if znajdz(self, sasiad, koniec):
                nowa = [start] + [sasiad] + znajdz(self, sasiad,koniec)[:-1]
                sciezki.append(nowa)
                #sciezki.append(self.znajdzWszystkieSciezki(sasiad, koniec, sciezki))
        return sciezki

    def najkrotszaSciezka(self, start, koniec):
        najkrotsza = self.znajdzWszystkieSciezki(start, koniec)[0]
        for x in self.znajdzWszystkieSciezki(start, koniec):
            if len(x) < len(najkrotsza):
                najkrotsza = x
        return najkrotsza

    def czyPetla(self,wierzcholek):
        for sasiad in self.slownikSasiedztwa[wierzcholek]:
            if sasiad == wierzcholek:
                return True
        return False

    def stopien(self, wierzcholek):
        if wierzcholek in self.slownikSasiedztwa:
            return len(self.slownikSasiedztwa[wierzcholek])

    def znajdzIzolowaneWierzcholki(self):
        izolowane = []
        for wierzcholek in self.slownikSasiedztwa:
            falga = 1
            for sasiad in self.slownikSasiedztwa[wierzcholek]:
                if sasiad != wierzcholek:
                    flaga = 0
            if flaga:
                izolowane.append(wierzcholek)
        return izolowane

    def czySpojny(self):
        if self.znajdzIzolowaneWierzcholki():
                return False
        return True

g = Graf()
g.dodajWierzcholek('A')
g.dodajWierzcholek('B')
g.dodajWierzcholek('C')
g.dodajWierzcholek('D')
g.dodajWierzcholek('E')
g.dodajWierzcholek('F')
g.dodajWierzcholek('G')
g.dodajWierzcholek('H')

g.dodajKrawedz('A', 'D')
g.dodajKrawedz('A', 'C')
g.dodajKrawedz('A', 'E')
g.dodajKrawedz('B', 'D')
g.dodajKrawedz('C', 'F')
g.dodajKrawedz('E', 'B')
g.dodajKrawedz('F', 'E')
g.dodajKrawedz('D', 'G')
g.dodajKrawedz('D', 'F')
g.dodajKrawedz('G', 'F')
g.dodajKrawedz('H', 'H')

g.wypisz()
print(g.znajdzWszystkieSciezki('A','F'))
print(g.najkrotszaSciezka('A','F'))
print('Czy graf jest spojny?', g.czySpojny())
print('Czy petla dla wierzcholka H', g.czyPetla('H'))
print('Czy petla dla wierzcholka A', g.czyPetla('A'))


# coding:utf-8
import MySQLdb
from eleme import settings
from sqlalchemy import Column, String, Integer, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from eleme.items import RestaurantItem

# 创建对象的基类
Base = declarative_base()

class Restaurant(Base):
    __tablename__ = 'eleme_restaurants'

    id = Column(Integer, primary_key=True)
    name = Column(String(521))
    recent_order_num = Column(Integer)
    average_cost = Column(String(521))
    address = Column(String(1024))
    distance = Column(Integer)

class ElemePipeline(object):
    def open_spider(self, spider):
        engine = create_engine(
            'mysql+mysqldb://%s:%s@%s:3306/%s?charset=utf8' % (
                settings.MYSQL_USER, settings.MYSQL_PASSWORD, settings.MYSQL_HOST,
                settings.MYSQL_DB))
        self.sessionDB = sessionmaker(bind=engine)
        self.session = self.sessionDB()

    def close_spider(self, spider):
        try:
            self.session.commit()
        except:
            self.session.rollback()
            raise
        finally:
            self.session.close()

    def process_item(self, item, spider):
        if isinstance(item, RestaurantItem):
            r = {
                'id': item['restaurant']['id'],
                'name': item['restaurant']['name'],
                'recent_order_num': item['restaurant']['recent_order_num'],
                'average_cost': item['restaurant']['average_cost'],
                'address': item['restaurant']['address'],
                'distance': item['restaurant']['distance'],
            }
            new_r = Restaurant(**r)
            self.session.merge(new_r)
        return item


import numpy as np
import matplotlib.pyplot as plt

# Función de Rosenbrock
def rosenbrock(x, y, a=1, b=100):
    return (a - x) ** 2 + b * (y - x**2) ** 2

# Función para generar una nueva solución vecina (Simulated Annealing)
def neighbor_solution(point, step_size):
    return point + np.random.uniform(-step_size, step_size, point.shape)

# Criterio de Boltzmann para aceptar una nueva solución
def accept_solution(delta, temperature):
    if delta < 0:
        return True
    else:
        return np.random.rand() < np.exp(-delta / temperature)

# Parámetros iniciales
np.random.seed(0)
initial_point = np.random.rand(2) * 2 - 1  # Punto inicial aleatorio (en [-1, 1])
initial_temperature = 1.0  # Temperatura inicial
cooling_rate = 0.99  # Tasa de enfriamiento
step_size = 0.05  # Tamaño de cada paso para generar vecinos
max_iterations = 10000  # Número máximo de iteraciones
min_temperature = 1e-3  # Temperatura mínima para detener el algoritmo

# Simulated Annealing
current_point = initial_point
current_value = rosenbrock(current_point[0], current_point[1])
temperature = initial_temperature
points_history = [current_point]

for iteration in range(max_iterations):
    new_point = neighbor_solution(current_point, step_size)
    new_value = rosenbrock(new_point[0], new_point[1])

    # Se acepta la nueva solución si es mejor
    if accept_solution(new_value - current_value, temperature):
        current_point, current_value = new_point, new_value
        points_history.append(current_point)

    # Se reduce la temperatura
    temperature *= cooling_rate

    # Condición de finalización por temperatura mínima
    if temperature < min_temperature:
        break

# Grafica función de Rosenbrock y el punto mínimo
x = np.linspace(-2, 2, 400)
y = np.linspace(-1, 3, 400)
X, Y = np.meshgrid(x, y)
Z = rosenbrock(X, Y)

plt.figure(figsize=(8, 6))
plt.contour(X, Y, Z, levels=np.logspace(-0.5, 3.5, 20), cmap="viridis")
plt.plot(
    *zip(*points_history),
    marker="o",
    color="r",
    markersize=3,
    linestyle="-",
    linewidth=1,
    label="Camino al mínimo",
)
plt.plot(
    current_point[0],
    current_point[1],
    "bo",
    label=f"Punto mínimo: ({current_point[0]:.4f}, {current_point[1]:.4f})",
)
plt.title("Camino al mínimo de la función de Rosenbrock")
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
plt.show()

# Resultados
print("Punto final:", current_point)
print("Valor en el punto final:", current_value)


# Chapter 8
# 8.7 Exercises
# 10.

from string import punctuation

def n(x=0):
    print("\n" * x)

def dlm(x=0):
    print("-" * x)

def name():
    n(1)

    sen = input(
        "please enter a sentence. \n we encourage you to keep your language appropriate: "
    )

    for c in punctuation:
        sen = sen.replace(c, "")
    ssen = sen.split()

    swords = ["darn", "dang", "freakin", "heck", "shoot"]

    count = 0
    print("ssen:", ssen)
    for x in ssen:
        print("word:", x, swords)
        if x in swords:
            print("issword:", ssen[count])
            ssen[count] = "*" * len(ssen[count])
        count += 1

    ssen = " ".join(ssen)

    sen_f = ""
    for x in ssen:
        sen_f += x
    sen_f += "."
    n(2)
    print(sen_f)

    n(2)

name()


import git, os, hashlib, logging, io, tempfile, shutil
from django.conf import settings
from django.http import Http404, HttpResponse
from corere.main import models as m
from django.db.models import Max

logger = logging.getLogger(__name__)

# What actually makes something a "helper" here?

def create_manuscript_repo(manuscript):
    repo_path = get_manuscript_repo_path(manuscript)
    repo = git.Repo.init(repo_path, mkdir=True)
    files_path = get_manuscript_files_path(manuscript)
    os.makedirs(files_path, exist_ok=True)
    repo.index.commit("initial commit")

def create_submission_repo(manuscript):
    repo_path = get_submission_repo_path(manuscript)
    repo = git.Repo.init(repo_path, mkdir=True)
    files_path = get_submission_files_path(manuscript)
    os.makedirs(files_path, exist_ok=True)
    repo.index.commit("initial commit")
    # repo.create_head("master")

# #Maybe unused
# def get_manuscript_files_list(manuscript):
#     return _get_files_list(manuscript, get_manuscript_files_path(manuscript))

# #Only used for submission deleteallfiles
# def get_submission_files_list(manuscript):
#     print(get_submission_files_path(manuscript))
#     return _get_files_list(manuscript, get_submission_files_path(manuscript))

# #Only used for get_submission_files_list which is only used for deleteallfiles
# def _get_files_list(manuscript, path):
#     try:
#         print("huh")
#         repo = git.Repo(path+"..")
#         print(repo.__dict__)
#         if 'head' in repo.__dict__: #TODO: This doesn't work currently on the 1st submission because there is no head because we did not make a branch
#             return helper_list_paths(repo.head.commit.tree[0], path, path)
#         else:
#             print("NO COMMITS")
#             yield from () #If no head (e.g. no commits) return empty list
#         #TODO: We may want to handle having a head but no files
#     except git.exc.NoSuchPathError:
#         raise Http404()

# returns md5 of file
def store_manuscript_file(manuscript, file, subdir):
    repo_path = get_manuscript_repo_path(manuscript)
    files_folder = get_manuscript_files_path(manuscript, relative=True)
    return _store_file(repo_path, files_folder + subdir, file)

# returns md5 of file
def store_submission_file(manuscript, file, subdir):
    repo_path = get_submission_repo_path(manuscript)
    files_folder = get_submission_files_path(manuscript, relative=True)
    return _store_file(repo_path, files_folder + subdir, file)

# TODO-REPO: repo_path variable name here is incorrect. Probably other places too

# store file to filesystem, create commit for file
# returns md5 of file
def _store_file(repo_path, subdir, file):
    repo = git.Repo(repo_path)
    full_path = repo_path + subdir

    os.makedirs(full_path, exist_ok=True)
    hash_md5 = hashlib.md5()
    with open(full_path + file.name, "wb+") as destination:
        for chunk in file.chunks():
            destination.write(chunk)
            hash_md5.update(chunk)
    repo.index.add(full_path + file.name)
    repo.index.commit("store file: " + full_path + file.name)
    return hash_md5.hexdigest()

def rename_manuscript_files(manuscript, files_dict_list):
    repo_path = get_manuscript_repo_path(manuscript)
    files_folder = get_manuscript_files_path(manuscript, relative=True)
    return _rename_files(repo_path, files_folder, files_dict_list)

def rename_submission_files(manuscript, files_dict_list):
    repo_path = get_submission_repo_path(manuscript)
    files_folder = get_submission_files_path(manuscript, relative=True)
    return _rename_files(repo_path, files_folder, files_dict_list)

def _rename_files(repo_path, files_folder, files_dict_list):
    repo = git.Repo(repo_path)

    for d in files_dict_list:
        old_path = files_folder + d.get("old")
        new_path = files_folder + d.get("new")

        if os.path.exists(repo_path + new_path):
            logger.warning(
                "Error renaming files, new path already exists. Repo path: "
                + repo_path
                + " . Current file old path: "
                + old_path
                + " . New path: "
                + new_path
                + " ."
            )
            return False
        try:
            os.renames(repo_path + old_path, repo_path + new_path)
            repo.index.add(repo_path + new_path)
            repo.index.remove(repo_path + old_path)
            repo.index.commit("File " + repo_path + old_path + " renamed to " + repo_path + new_path)
        except Exception as e:
            logger.error(
                "Error renaming files. Cause uncertain. Repo path: "
                + repo_path
                + " . Current file old path: "
                + old_path
                + " . New path: "
                + new_path
                + " . Error "
                + str(e)
            )
            return False

        return True

def delete_manuscript_file(manuscript, file_path):
    repo_path = get_manuscript_repo_path(manuscript)
    files_folder = get_manuscript_files_path(manuscript, relative=True)
    # if(not file_path == '/.git'):
    _delete_file(repo_path, repo_path + files_folder + file_path)

    # We recreate our "inside the repo" directory incase our delete recursively deleted it
    files_path = get_manuscript_files_path(manuscript)
    os.makedirs(files_path, exist_ok=True)

def delete_submission_file(manuscript, file_path):
    repo_path = get_submission_repo_path(manuscript)
    files_folder = get_submission_files_path(manuscript, relative=True)
    # if(not file_path == '/.git'):
    _delete_file(repo_path, repo_path + files_folder + file_path)

    # We recreate our "inside the repo" directory incase our delete recursively deleted it
    # TODO: This is likely slow when called many times (e.g. old delete all). If we have performance issues we should only call it once at the end of many deletes
    files_path = get_submission_files_path(manuscript)
    os.makedirs(files_path, exist_ok=True)

def delete_all_submission_files(manuscript):
    submission_files_path = get_submission_files_path(manuscript)
    shutil.rmtree(submission_files_path)
    os.makedirs(submission_files_path)
    repo = git.Repo(get_submission_repo_path(manuscript))
    try:
        repo.index.remove(submission_files_path, r=True)
    except Exception as e:
        if not str(e).endswith("did not match any files'"):
            # We catch the error of there being no files to delete
            raise e
    repo.index.commit("delete all submission files")

# delete file from filesystem, create commit for file
# TODO: This currently will delete the
def _delete_file(repo_path, file_full_path):
    repo = git.Repo(repo_path)
    if repo_path in os.path.realpath(file_full_path):
        if os.path.exists(file_full_path):
            os.remove(file_full_path)
            file_full_folder = file_full_path.rsplit("/", 1)[0]
            try:
                os.removedirs(file_full_folder)  # deletes empty folders recursively. Will never delete repo_path as there is a git folder
            except OSError:
                pass  # If file_full_folder has other files, removedirs will error and fail, as expected
        else:
            logger.error("Attempted to delete file where path did not exist. Path provided: " + file_full_path)
            raise Http404()
    else:
        logger.error("Attempted to delete file above the repo path. Possibly a hack attempt. Path: " + file_full_path)
        raise Http404()

    repo.index.remove(file_full_path)
    repo.index.commit("delete file: " + file_full_path)

def get_manuscript_file(manuscript, file_path, response=False):
    repo_path = get_manuscript_repo_path(manuscript)
    files_folder = get_manuscript_files_path(manuscript, relative=True)
    return _get_file(repo_path, files_folder, file_path, "master", response)

def get_submission_file(submission, file_path, response=False):
    repo_path = get_submission_repo_path(submission.manuscript)
    files_folder = get_submission_files_path(submission.manuscript, relative=True)

    # We have to check whether our submission is the latest submission. If its latest, use master, otherwise use branch name
    max_version_id = submission.manuscript.get_max_submission_version_id()
    if submission.version_id == max_version_id:
        branch_name = "master"
    else:
        branch_name = helper_get_submission_branch_name(submission)
    return _get_file(repo_path, files_folder, file_path, branch_name, response)

def _get_file(repo_path, files_folder, file_path, branch_name, response):
    repo = git.Repo(repo_path)
    branch_commit = repo.commit(branch_name)
    if file_path[0] == "/":
        file_path = file_path[1:]  # [1:] removes leading slash. Could be made more robust
    file_path = files_folder + file_path
    file = branch_commit.tree / file_path

    if response:
        with io.BytesIO(file.data_stream.read()) as f:
            response = HttpResponse(f.read(), content_type=file.mime_type)
            response["Content-Disposition"] = 'attachment; filename="' + file.name + '"'
            return response
    else:
        return file

def download_all_submission_files(submission):
    max_version_id = submission.manuscript.get_max_submission_version_id()
    if submission.version_id == max_version_id:
        branch_name = "master"
    else:
        branch_name = helper_get_submission_branch_name(submission)

    repo_path = get_submission_repo_path(submission.manuscript)
    repo = git.Repo(repo_path)

    tempf = tempfile.TemporaryFile()
    repo.archive(tempf, treeish=branch_name)
    tempf.seek(0)  # you have to return to the start of the temporaryfile after writing to it

    response = HttpResponse(tempf.read(), content_type="application/zip")  # temp.mime_type)
    response["Content-Disposition"] = 'attachment; filename="' + submission.manuscript.slug + "_-_submission_" + str(submission.version_id) + '.zip"'
    return response

def download_all_manuscript_files(manuscript):
    branch_name = "master"
    repo_path = get_manuscript_repo_path(manuscript)
    repo = git.Repo(repo_path)

    tempf = tempfile.TemporaryFile()
    repo.archive(tempf, treeish=branch_name)
    tempf.seek(0)  # you have to return to the start of the temporaryfile after writing to it

    response = HttpResponse(tempf.read(), content_type="application/zip")  # temp.mime_type)
    response["Content-Disposition"] = 'attachment; filename="' + manuscript.slug + '_-_manuscript.zip"'
    return response

# def get_manuscript_repo_name(manuscript):
#     return str(manuscript.id) + "_-_manuscript_-_" + manuscript.slug

# def get_submission_repo_name(manuscript):
#     return str(manuscript.id) + "_-_submission_-_" + manuscript.slug

### The repo contains a sub-folder containing all the files. This is half to support downloading zips with a root folder

#TODO: Maybe rename these path endpoints to communicate they are getting the system path not the relative path in the code folder
def get_manuscript_repo_path(manuscript):
    return settings.GIT_ROOT + "/" + str(manuscript.id) + "_-_manuscript_-_" + manuscript.slug + "/"

def get_manuscript_files_path(manuscript, relative=False):
    rel_path = manuscript.slug + "_-_manuscript/"
    if relative:
        return rel_path
    else:
        return get_manuscript_repo_path(manuscript) + rel_path

def get_submission_repo_path(manuscript):
    return settings.GIT_ROOT + "/" + str(manuscript.id) + "_-_submission_-_" + manuscript.slug + "/"

def get_submission_files_path(manuscript, relative=False):
    rel_path = manuscript.slug + "_-_submission/"
    if relative:
        return rel_path
    else:
        return get_submission_repo_path(manuscript) + rel_path

def create_submission_branch(submission):
    repo = git.Repo(get_submission_repo_path(submission.manuscript))
    repo.create_head(helper_get_submission_branch_name(submission))

# Lists the paths of all the files. Used only to delete_all currently
# When initially called, repo_path and rel_path should be the same.
# TODO: This actually returns a generator, we should probably name it differently or switch it to a list
# def helper_list_paths(root_tree, repo_path, rel_path):
#     for blob in root_tree.blobs:
#         #Split off the system path from the return.
#         yield (rel_path.split(repo_path, 1)[1] + '/' + blob.name)#[1:] #commented code would remove leading slash
#     for tree in root_tree.trees:
#         yield from (helper_list_paths(tree, repo_path, rel_path + '/' + tree.name)) #recursive

# Note: Submission branches are only created when the submission is completed. This will not tell you whether your submission has been completed.
def helper_get_submission_branch_name(submission):
    return "Submission_" + str(submission.version_id)


import pandas as pd
from tqdm import tqdm as tqdm
import requests
import json
import csv

df_CO = pd.read_csv("to_publish.csv",sep=',')
df_CO=df_CO[:17]

intCodeLst=[]
singularities_10={}
singularities_2={}
singularities_5={}

for i in df_CO['Geographic Regions']:
    singularities_2[i]=[]
for i in df_CO['Geographic Regions']:
    singularities_5[i]=[]
for i in df_CO['Geographic Regions']:
    singularities_10[i]=[]

for i in tqdm(df_CO.iloc[:,1:].columns):
    if df_CO[i].max()>df_CO[df_CO[i]!=df_CO[i].max()][i].max()*10:
        singularities_10[df_CO[df_CO[i]==df_CO[i].max()]['Geographic Regions'].values[0]].append([i,df_CO[i].max()])
        if i not in intCodeLst:
            intCodeLst.append(i)
    if df_CO[i].max()>df_CO[df_CO[i]!=df_CO[i].max()][i].max()*2:
        singularities_2[df_CO[df_CO[i]==df_CO[i].max()]['Geographic Regions'].values[0]].append([i,df_CO[i].max()])
        if i not in intCodeLst:
            intCodeLst.append(i)
    if df_CO[i].max()>df_CO[df_CO[i]!=df_CO[i].max()][i].max()*2:
        singularities_5[df_CO[df_CO[i]==df_CO[i].max()]['Geographic Regions'].values[0]].append([i,df_CO[i].max()])
        if i not in intCodeLst:
            intCodeLst.append(i)

int_dict={}
no_name=[]
for i in tqdm(intCodeLst):
    try:
        link='https://graph.facebook.com/v5.0/search?access_token=<TOKEN>&locale=en_US&interest_fbid_list=["'+str(i)+'"]&type=adinterestvalid'
        r=requests.get(link)
        response = json.loads(r.text)
        int_dict[i]=response["data"][0]['name']
    except:
        print(i)
        no_name.append(i)

nm_sin_10={}
for key in singularities_10:
    sing_lst=[]
    for i in singularities_10[key]:
        sing_lst.append([int_dict[i[0]],i[1]])
    nm_sin_10[key]=sing_lst
nm_sin_2={}
for key in singularities_2:
    sing_lst=[]
    for i in singularities_2[key]:
        sing_lst.append([int_dict[i[0]],i[1]])
    nm_sin_2[key]=sing_lst
nm_sin_5={}
for key in singularities_5:
    sing_lst=[]
    for i in singularities_5[key]:
        sing_lst.append([int_dict[i[0]],i[1]])
    nm_sin_5[key]=sing_lst

with open('int_dict.txt', 'w') as csv_file:
        writer = csv.writer(csv_file)
        for key, value in int_dict.items():
            writer.writerow([key, value])

with open('nm_sin_10.txt', 'w') as csv_file:
        writer = csv.writer(csv_file)
        for key, value in nm_sin_10.items():
            writer.writerow([key, value])
with open('nm_sin_2.txt', 'w') as csv_file:
        writer = csv.writer(csv_file)
        for key, value in nm_sin_2.items():
            writer.writerow([key, value])
import csv
with open('nm_sin_5.txt', 'w') as csv_file:
        writer = csv.writer(csv_file)
        for key, value in nm_sin_5.items():
            writer.writerow([key, value])


from django.db.models import Q
from django.shortcuts import get_object_or_404
import os

from numpy import append

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')

import django
django.setup()
from pybo.models import Similar,Maincont

class Similar_query:
    def __init__(self, user):
        self.user=user

    def my_similar(self):

        similar2 = Similar.objects.values_list('maincont').distinct()
        similar3 = similar2.filter(author__username__icontains=self.user).order_by('-similar')

        lists=list(similar3)

        similar_list= []

        for v in lists:
            similar_list.append(v[0])

        query = Maincont.objects.filter(id=similar_list[0])

        for i in similar_list:
            query = query | Maincont.objects.filter(id=i)
            #query.save()

        return query


from models import MineField

def find_big_bangs(mines):
    if not mines:
        return []

    mine_field = MineField(mines)

    bangs = []
    for mine in mines:
        bangs += mine_field.get_bang_progression(mine)

    sorted_bangs = sorted(bangs,
                          key=lambda b: (-b.mine_count, b.starter.x_coord, b.starter.y_coord))
    max_explosion_count = sorted_bangs[0].mine_count

    big_bangs = []
    for bang in sorted_bangs:
        if bang.mine_count < max_explosion_count:
            break
        big_bangs.append(bang)

    return big_bangs


import yaml
import argparse
import os
import sys
from os import path

root_folder = path.dirname(path.abspath(__file__))
sys.path.insert(0, path.join(root_folder, "../../../"))
print(sys.path)

from vision_wl import train_vision_wl, run_inference, collect_class_labels, load_model, run_inference_per_patient

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--config_file", type=str, required=True)
    args = parser.parse_args()

    with open(args.config_file, "r") as f:
        config = yaml.safe_load(f)

    dataset_dir = config['args']['dataset_dir']
    train_dataset_dir = os.path.join(dataset_dir, "train")
    test_dataset_dir = os.path.join(dataset_dir, "test")
    # output_dir = config['args']['output_dir']
    output_dir = config['training_args']['output_dir']
    batch_size = config['training_args']['batch_size']
    epochs = config['training_args']['epochs']
    bf16 = config['training_args']['bf16']
    model_name = config['args']['model']

    # do_predict = config['training_args']['do_predict']
    do_predict = config['args']['inference']
    do_predict_per_patient = config['args']['inference_per_patient']
    # do_train = config['training_args']['do_train']
    do_train = config['args']['finetune']

    saved_model_dir = config['args']['saved_model_dir']

    # output_file_test = config['args']['output_file_test_dir']
    output_file_test = config['args']['inference_output']

    # output_file_train = config['args']['output_file_train_dir']
    output_file_train = config['args']['finetune_output']

    # this is one is used for place holder
    vision_int8_inference = 'vision_int_8.yaml' # config['inference_args']['int8_inference']
    class_labels = collect_class_labels(train_dataset_dir)
    if (do_train):
        model, history, dict_metrics = train_vision_wl(train_dataset_dir,
                                                       output_dir, model_name,
                                                       batch_size, epochs, bf16=bf16)
        run_inference(train_dataset_dir, saved_model_dir, class_labels,
                      model_name, vision_int8_inference, output_file_train)

    if (do_predict):
        run_inference(test_dataset_dir, saved_model_dir, class_labels,
                      model_name, vision_int8_inference, output_file_test)
    if (do_predict_per_patient):
        model = load_model(model_name,saved_model_dir)
        # Sample dict
        patient_dict = {'106L':[os.path.join(train_dataset_dir,"Malignant/P106_L_CM_MLO1.jpg")],\
                        '106R':[os.path.join(train_dataset_dir,"Benign/P106_R_CM_CC1.jpg"),\
                                os.path.join(train_dataset_dir,"Benign/P106_R_CM_CC2.jpg")]}
        results = run_inference_per_patient(model, patient_dict,class_labels)

if __name__ == "__main__":
    main()


# 2017.08.29 21:49:22 Støední Evropa (letní èas)
# Embedded file name: scripts/client/gui/server_events/events_helpers.py
import time
import BigWorld
from gui import makeHtmlString
from gui.Scaleform.locale.MENU import MENU
from gui.Scaleform.locale.QUESTS import QUESTS
from gui.server_events import formatters
from helpers import time_utils, i18n
from shared_utils import CONST_CONTAINER
FINISH_TIME_LEFT_TO_SHOW = time_utils.ONE_DAY
START_TIME_LIMIT = 5 * time_utils.ONE_DAY
AWARDS_PER_PAGE = 3
AWARDS_PER_SINGLE_PAGE = 4

class EventInfoModel(object):
    NO_BONUS_COUNT = -1

    def __init__(self, event):
        self.event = event

    def getTimerMsg(self, key = None):
        startTimeLeft = self.event.getStartTimeLeft()
        if startTimeLeft > 0:
            if startTimeLeft > START_TIME_LIMIT:
                fmt = self._getDateTimeString(self.event.getStartTime())
            else:
                fmt = self._getTillTimeString(startTimeLeft)
            return makeHtmlString('html_templates:lobby/quests', 'timerTillStart', {'time': fmt})
        if FINISH_TIME_LEFT_TO_SHOW > self.event.getFinishTimeLeft() > 0:
            gmtime = time.gmtime(self.event.getFinishTimeLeft())
            if gmtime.tm_hour > 0:
                fmt = i18n.makeString('#quests:item/timer/tillFinish/onlyHours')
            else:
                fmt = i18n.makeString('#quests:item/timer/tillFinish/lessThanHour')
            fmt %= {'hours': time.strftime('%H', gmtime),
             'min': time.strftime('%M', gmtime),
             'days': str(gmtime.tm_mday)}
            return makeHtmlString('html_templates:lobby/quests', 'timerTillFinish', {'time': fmt})
        return ''

    def _getStatus(self, pCur = None):
        return (EVENT_STATUS.NONE, '')

    @classmethod
    def _getTillTimeString(cls, timeValue):
        return time_utils.getTillTimeString(timeValue, MENU.TIME_TIMEVALUE)

    @classmethod
    def _getDailyProgressResetTimeOffset(cls):
        regionalSettings = BigWorld.player().serverSettings['regional_settings']
        if 'starting_time_of_a_new_game_day' in regionalSettings:
            newDayOffset = regionalSettings['starting_time_of_a_new_game_day']
        elif 'starting_time_of_a_new_day' in regionalSettings:
            newDayOffset = regionalSettings['starting_time_of_a_new_day']
        else:
            newDayOffset = 0
        return newDayOffset

    def _getActiveDateTimeString(self):
        i18nKey, args = None, {}
        if self.event.getFinishTimeLeft() <= time_utils.ONE_DAY:
            gmtime = time.gmtime(self.event.getFinishTimeLeft())
            if gmtime.tm_hour > 0:
                fmt = i18n.makeString(QUESTS.ITEM_TIMER_TILLFINISH_LONGFULLFORMAT)
            else:
                fmt = i18n.makeString(QUESTS.ITEM_TIMER_TILLFINISH_SHORTFULLFORMAT)
            fmt %= {'hours': time.strftime('%H', gmtime)}
            return fmt
        if self.event.getStartTimeLeft() > 0:
            i18nKey = '#quests:details/header/activeDuration'
            args = {'startTime': self._getDateTimeString(self.event.getStartTime()),
             'finishTime': self._getDateTimeString(self.event.getFinishTime())}
        elif self.event.getFinishTimeLeft() <= time_utils.HALF_YEAR:
            i18nKey = '#quests:details/header/tillDate'
            args = {'finishTime': self._getDateTimeString(self.event.getFinishTime())}
        weekDays = self.event.getWeekDays()
        intervals = self.event.getActiveTimeIntervals()
        if len(weekDays) or len(intervals):
            if i18nKey is None:
                i18nKey = '#quests:details/header/schedule'
            if len(weekDays):
                days = ', '.join([ i18n.makeString('#menu:dateTime/weekDays/full/%d' % idx) for idx in self.event.getWeekDays() ])
                i18nKey += 'Days'
                args['days'] = days
            if len(intervals):
                times = []
                for low, high in intervals:
                    times.append('%s - %s' % (BigWorld.wg_getShortTimeFormat(low), BigWorld.wg_getShortTimeFormat(high)))

                i18nKey += 'Times'
                times = ', '.join(times)
                args['times'] = times
        if i18nKey is None:
            return
        else:
            return i18n.makeString(i18nKey, **args)

    @classmethod
    def _getDateTimeString(cls, timeValue):
        return '{0:>s} {1:>s}'.format(BigWorld.wg_getLongDateFormat(timeValue), BigWorld.wg_getShortTimeFormat(timeValue))

class QuestInfoModel(EventInfoModel):

    def _getActiveDateTimeString(self):
        timeLeft = self.event.getFinishTimeLeft()
        if timeLeft <= time_utils.THREE_QUARTER_HOUR:
            return formatters.formatYellow(QUESTS.DETAILS_HEADER_COMETOENDINMINUTES, minutes=getMinutesRoundByTime(timeLeft))
        return super(QuestInfoModel, self)._getActiveDateTimeString()

    def getTimerMsg(self, key = 'comeToEndInMinutes'):
        timeLeft = self.event.getFinishTimeLeft()
        if timeLeft <= time_utils.THREE_QUARTER_HOUR:
            return makeHtmlString('html_templates:lobby/quests/', key, {'minutes': getMinutesRoundByTime(timeLeft)})
        return super(QuestInfoModel, self).getTimerMsg()

    def _getDailyResetStatus(self, resetLabelKey, labeFormatter):
        if self.event.bonusCond.isDaily():
            resetHourOffset = (time_utils.ONE_DAY - self._getDailyProgressResetTimeOffset()) / time_utils.ONE_HOUR
            if resetHourOffset >= 0:
                return labeFormatter(resetLabelKey) % {'time': time.strftime(i18n.makeString('#quests:details/conditions/postBattle/dailyReset/timeFmt'), time_utils.getTimeStructInLocal(time_utils.getTimeTodayForUTC(hour=resetHourOffset)))}
        return ''

    def _getCompleteDailyStatus(self, completeKey):
        return i18n.makeString(completeKey, time=self._getTillTimeString(time_utils.ONE_DAY - time_utils.getServerRegionalTimeCurrentDay()))

def getCarouselAwardVO(bonuses, isReceived = False):
    """ Generate award VOs for carousel.

    :param bonuses: list of bonuses (instances of gui.server_events.SimpleBonus).
    :param isReceived: flag describing whether this is 'already received' context.
    """
    result = []
    for bonus in bonuses:
        if not bonus.isShowInGUI():
            continue
        result.extend(bonus.getCarouselList(isReceived))

    while len(result) % AWARDS_PER_PAGE != 0 and len(result) > AWARDS_PER_SINGLE_PAGE:
        result.append({})

    return result

class EVENT_STATUS(CONST_CONTAINER):
    COMPLETED = 'done'
    NOT_AVAILABLE = 'notAvailable'
    WRONG_TIME = 'wrongTime'
    NONE = ''

def getMinutesRoundByTime(timeLeft):
    timeLeft = int(timeLeft)
    return (timeLeft / time_utils.QUARTER_HOUR + cmp(timeLeft % time_utils.QUARTER_HOUR, 0)) * time_utils.QUARTER

def missionsSortFunc(a, b):
    """ Sort function for common quests (all except potapov and motive).
    """
    res = cmp(a.isAvailable()[0] and not a.isCompleted(), b.isAvailable()[0] and not b.isCompleted())
    if res:
        return res
    res = cmp(a.getPriority(), b.getPriority())
    if res:
        return res
    res = cmp(a.isAvailable()[1] == 'requirement', b.isAvailable()[1] == 'requirement')
    if res:
        return res
    res = cmp(bool(a.isAvailable()[1]), bool(b.isAvailable()[1]))
    if res:
        return res
    res = cmp(a.isCompleted(), b.isCompleted())
    if res:
        return res
    return cmp(a.getUserName(), b.getUserName())
# okay decompyling c:\Users\PC\wotmods\files\originals\res\packages\scripts\scripts\client\gui\server_events\events_helpers.pyc
# decompiled 1 files: 1 okay, 0 failed, 0 verify failed
# 2017.08.29 21:49:22 Støední Evropa (letní èas)