__all__ = ['scaffold']

from gevent import monkey

monkey.patch_all()
import csv
import gevent
from typing import List

from src.BusinessCentralLayer.setting import *

command_set = {

    # ---------------------------------------------
    # 部署接口
    # ---------------------------------------------
    'deploy': "部署项目（定时任务/Flask 开启与否取决于yaml配置文件）",
    # ---------------------------------------------
    # 调试接口
    # ---------------------------------------------
    "decouple": "立即唤醒一次subs_ddt链接解耦任务",
    "overdue": "立即执行一次过时链接清洗任务",
    "run": "立即执行一次采集任务（强制使用协程加速）",
    "force_run": "强制执行采集任务",
    "remain": "读取剩余订阅数量",
    "ping": "测试数据库连接",
    "panel": "打开桌面前端面板",
    "packer": "打包生成桌面客户端（windows可用）",
    "launcher": "返回采集器的单步启动接口",
    # ---------------------------------------------
    # 调用示例
    # ---------------------------------------------
    "example": "python main.py ping"
}

class _ConfigQuarantine(object):
    def __init__(self):

        self.root = [
            SERVER_DIR_CLIENT_DEPORT, SERVER_PATH_DEPOT_VCS,
            SERVER_DIR_DATABASE_CACHE, SERVER_DIR_CACHE_BGPIC
        ]
        self.flag = False

    def set_up_file_tree(self, root):
        """
        --/qinse/V2RaycSpider{verNum}
            --BCL
            --BLL
            --BVL
            --Database
                --client_depot
                    --vcs.csv
                --logs
                    --*error.log
                    --*runtime.log
                --temp_cache
                    --*AnyTempCacheFile...
                --*CrawlFetchHistory.txt
                --fake_useragent_0.1.11.json
            --*tests
        """

        # 检查默认下载地址是否残缺 深度优先初始化系统文件
        for child_ in root:
            if not os.path.exists(child_):
                self.flag = True
                try:
                    # 初始化文件夹
                    if os.path.isdir(child_) or not os.path.splitext(child_)[-1]:
                        os.mkdir(child_)
                        logger.success(f"系统文件链接成功->{child_}")
                    # 初始化文件
                    else:
                        if child_ == SERVER_PATH_DEPOT_VCS:
                            try:
                                with open(child_, 'w', encoding='utf-8', newline='') as fpx:
                                    csv.writer(fpx).writerow(['version', 'title'])
                                logger.success(f"系统文件链接成功->{child_}")
                            except Exception as ep:
                                logger.exception(f"Exception{child_}{ep}")
                except Exception as ep:
                    logger.exception(ep)

    @staticmethod
    def check_config():
        if not all(SMTP_ACCOUNT.values()):
            logger.warning('您未正确配置<通信邮箱>信息(SMTP_ACCOUNT)')
        if not SERVER_CHAN_SCKEY:
            logger.warning("您未正确配置<Server酱>的SCKEY")
        if not all([REDIS_SLAVER_DDT.get("host"), REDIS_SLAVER_DDT.get("password")]):
            logger.warning('您未正确配置<Redis-Slave> 本项目的部分功能将毫无意义')
        if not all([REDIS_MASTER.get("host"), REDIS_MASTER.get("password")]):
            logger.error("您未正确配置<Redis-Master> 此配置为“云彩姬”的核心组件，请配置后重启项目！")
            exit()

    def run(self):
        try:
            if [cq for cq in reversed(self.root) if not os.path.exists(cq)]:
                logger.warning('系统文件残缺！')
                logger.debug("启动<工程重构>模块...")
                self.set_up_file_tree(self.root)
            self.check_config()

        finally:
            if self.flag:
                logger.success(">>> 运行环境链接完成，请重启项目")
                logger.warning(">>> 提醒您正确配置Chrome及对应版本的ChromeDriver")
                exec("if self.flag:\n\texit()")

_ConfigQuarantine().run()

class _ScaffoldGuider(object):
    # __slots__ = list(command_set.keys())

    def __init__(self):
        # 脚手架公开接口
        self.scaffold_ruler = [i for i in self.__dir__() if i.startswith('_scaffold_')]

    @logger.catch()
    def startup(self, driver_command_set: List[str]):
        """
        仅支持单进程使用
        @param driver_command_set: 在空指令时列表仅有1个元素，表示启动路径
        @return:
        """
        # logger.info(f">>> {' '.join(driver_command_set)}")

        # -------------------------------
        # TODO 优先级0：预处理指令集
        # -------------------------------
        # CommandId or List[CommandId]
        driver_command: List[str] = []

        # 未输入任何指令 列出脚手架简介
        if len(driver_command_set) == 1:
            print("\n".join([f">>> {menu[0].ljust(20, '-')}|| {menu[-1]}" for menu in command_set.items()]))
            return True
        # 输入立即指令 转译指令
        elif len(driver_command_set) == 2:
            driver_command = [driver_command_set[-1].lower(), ]
        # 输入指令集 转译指令集
        elif len(driver_command_set) > 2:
            driver_command = list(set([command.lower() for command in driver_command_set[1:]]))

        # 捕获意料之外的情况
        if not isinstance(driver_command, list):
            return True
        # -------------------------------
        # TODO 优先级1：解析运行参数
        # -------------------------------

        # TODO --help 帮助菜单（继续完善相关功能）
        # 使用该参数时系统不解析运行指令
        if '--help' in driver_command:
            logger.info(f">>>GuiderHelp || 帮助菜单")
            driver_command.remove("--help")
            for command_ in driver_command:
                introduction = command_set.get(command_)
                if introduction:
                    print(f"> {command_.ljust(20, '-')}|| {introduction}")
                else:
                    print(f"> {command_}指令不存在")
            return True

        # -------------------------------
        # TODO 优先级2：运行单线程指令
        # -------------------------------

        # 协程任务队列
        task_list = []

        # 测试数据库连接
        while driver_command.__len__() > 0:
            _pending_command = driver_command.pop()
            try:
                task_list.append(gevent.spawn(eval(f"self._scaffold_{_pending_command}")))
            except Exception as e:
                logger.warning(f'脚手架暂未授权指令<{_pending_command}> {e}')
        else:
            # 并发执行以上指令
            gevent.joinall(task_list)

        # -------------------------------
        # TODO 优先级3：自定义参数部署（阻塞线程）
        # -------------------------------

        if 'deploy' in driver_command:
            self._scaffold_deploy()

    @staticmethod
    def _scaffold_deploy():
        logger.info(f"<ScaffoldGuider> Deploy || MainProcess")
        from src.BusinessCentralLayer.middleware.interface_io import SystemInterface as app
        app.run(deploy_=True)

    @staticmethod
    def _scaffold_decouple():
        logger.info(f"<ScaffoldGuider> Decouple || General startup")

        from src.BusinessLogicLayer.plugins.ddt_subs import SubscribesCleaner
        SubscribesCleaner(debug=True).interface()

    @staticmethod
    def _scaffold_overdue():
        logger.info(f"<ScaffoldGuider> Overdue || Redis DDT")
        from src.BusinessCentralLayer.middleware.interface_io import SystemInterface as app
        app.ddt()

    @staticmethod
    def _scaffold_run():
        if not os.path.exists(CHROMEDRIVER_PATH):
            logger.error(f"<ScaffoldGuider> ForceRun || ChromedriverNotFound ||"
                         f" 未查找到chromedriver驱动，请根据技术文档正确配置\n"
                         f">>> https://github.com/QIN2DIM/V2RayCloudSpider")
            return False

        logger.info(f"<ScaffoldGuider> Run || MainCollector")
        from src.BusinessCentralLayer.middleware.interface_io import SystemInterface as app
        app.run(deploy_=False)

    @staticmethod
    def _scaffold_force_run():

        if not os.path.exists(CHROMEDRIVER_PATH):
            logger.error(f"<ScaffoldGuider> ForceRun || ChromedriverNotFound ||"
                         f" 未查找到chromedriver驱动，请根据技术文档正确配置\n"
                         f">>> https://github.com/QIN2DIM/V2RayCloudSpider")
            return False

        logger.info(f"<ScaffoldGuider> ForceRun || MainCollector")
        from src.BusinessCentralLayer.setting import CRAWLER_SEQUENCE
        from src.BusinessLogicLayer.apis.vulcan_ash import ForceRunRelease
        ForceRunRelease(task_docker=CRAWLER_SEQUENCE).interface()

    @staticmethod
    def _scaffold_remain():
        from src.BusinessCentralLayer.middleware.redis_io import RedisClient
        logger.info(f"<ScaffoldGuider> Remain || {RedisClient().subs_info()}")

    @staticmethod
    def _scaffold_ping():
        from src.BusinessCentralLayer.middleware.redis_io import RedisClient
        logger.info(f"<ScaffoldGuider> Ping || {RedisClient().test()}")

    @staticmethod
    def _scaffold_panel():
        from src.BusinessCentralLayer.middleware.interface_io import SystemInterface
        SystemInterface.system_panel()

    @staticmethod
    def _scaffold_packer():
        pass
        # packer()

    @staticmethod
    def _scaffold_launcher(name: str = None) -> dict:
        from src.BusinessLogicLayer.cluster.slavers import actions
        from src.BusinessLogicLayer.apis.ghost_filler import gevent_ghost_filler
        response = {"entropy": actions.__entropy__, "actions": actions}
        if name is None:
            return response
        else:
            gevent_ghost_filler(docker=eval("actions.name"), silence=True)

scaffold = _ScaffoldGuider()

def packer(ico_path: str = None, output_dir=None, py_panel=None):
    """
    打包panel
    :param ico_path:
    :param output_dir:
    :param py_panel:
    :return:
    """
    # ----------------------------
    # 参数整理
    # ----------------------------
    if ico_path is None:
        ico_path = join(PANEL_DIR_ROOT, 'logo.ico')
    if output_dir is None:
        output_dir = join(PANEL_DIR_ROOT, 'bin')
        if not os.path.exists(output_dir):
            os.mkdir(output_dir)
    if py_panel is None:
        py_panel = join(PANEL_DIR_ROOT, 'panel.py')
    # ----------------------------
    # 根据不同的操作系统选择不同的打包方案
    # > Windows:Pyinstaller
    # https://pyinstaller.readthedocs.io/en/stable/usage.html#options
    # ----------------------------

    if platform.startswith('win'):
        pass
    elif platform.startswith('linux'):
        pass
    elif platform.startswith('darwin'):
        pass

if __name__ == '__main__':
    packer()


#!/usr/bin/env python
import logging
import unittest
import docker
import time
import os

import kuberay_utils.utils as utils

logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)

# Image version
ray_version = '1.9.0'

# Docker images
ray_image = 'rayproject/ray:1.9.0'
kuberay_operator_image = 'kuberay/operator:nightly'
kuberay_apiserver_image = 'kuberay/apiserver:nightly'

class BasicRayTestCase(unittest.TestCase):
    cluster_template_file = 'tests/config/ray-cluster.mini.yaml.template'

    @classmethod
    def setUpClass(cls):
        # Ray cluster is running inside a local Kind environment.
        # We use port mapping to connect to the Kind environment
        # from another local ray container. The local ray container
        # outside Kind environment has the same ray version as the
        # ray cluster running inside Kind environment.
        utils.delete_cluster()
        utils.create_cluster()
        images = [ray_image, kuberay_operator_image, kuberay_apiserver_image]
        utils.download_images(images)
        utils.apply_kuberay_resources(images, kuberay_operator_image, kuberay_apiserver_image)
        utils.create_kuberay_cluster(BasicRayTestCase.cluster_template_file,
                                     ray_version, ray_image)

    def test_simple_code(self):
        # connect from a ray container client to ray cluster
        # inside a local Kind environment and run a simple test
        client = docker.from_env()
        container = client.containers.run(ray_image,
                                          remove=True,
                                          detach=True,
                                          tty=True,
                                          network_mode='host')
        rtn_code, output = container.exec_run(['python',
                                               '-c', '''
import ray
ray.init(address='ray://127.0.0.1:10001')

def retry_with_timeout(func, count=90):
    tmp = 0
    err = None
    while tmp < count:
        try:
            return func()
        except Exception as e:
            err = e
            tmp += 1
    assert err is not None
    raise err

@ray.remote
def f(x):
    return x * x

def get_result():
    futures = [f.remote(i) for i in range(4)]
    print(ray.get(futures))
    return 0
rtn = retry_with_timeout(get_result)
assert rtn == 0
'''],
                                              demux=True)
        stdout_str, stderr_str = output

        container.stop()

        if stdout_str != b'[0, 1, 4, 9]\n':
            logger.error('test_simple_code returns {}'.format(output))
            raise Exception(('test_simple_code returns invalid result. ' +
                             'Expected: {} Actual: {} Stderr: {}').format(
                b'[0, 1, 4, 9]', stdout_str, stderr_str))
        if rtn_code != 0:
            msg = 'invalid return code {}'.format(rtn_code)
            logger.error(msg)
            raise Exception(msg)

        client.close()

    def test_cluster_info(self):
        # connect from a ray container client to ray cluster
        # inside a local Kind environment and run a test that
        # gets the amount of nodes in the ray cluster.
        client = docker.from_env()
        container = client.containers.run(ray_image,
                                          remove=True,
                                          detach=True,
                                          tty=True,
                                          network_mode='host')
        rtn_code, output = container.exec_run(['python',
                                               '-c', '''
import ray
ray.init(address='ray://127.0.0.1:10001')

print(len(ray.nodes()))
'''],
                                              demux=True)
        stdout_str, _ = output

        container.stop()

        if stdout_str != b'2\n':
            logger.error('test_cluster_info returns {}'.format(output))
            raise Exception(('test_cluster_info returns invalid result. ' +
                             'Expected: {} Actual: {}').format(b'2',
                                                               stdout_str))
        if rtn_code != 0:
            msg = 'invalid return code {}'.format(rtn_code)
            logger.error(msg)
            raise Exception(msg)

        client.close()

class RayFTTestCase(unittest.TestCase):
    cluster_template_file = 'tests/config/ray-cluster.ray-ft.yaml.template'

    @classmethod
    def setUpClass(cls):
        if not utils.ray_ft_supported(ray_version):
            raise unittest.SkipTest("ray ft is not supported")
        utils.delete_cluster()
        utils.create_cluster()
        images = [ray_image, kuberay_operator_image, kuberay_apiserver_image]
        utils.download_images(images)
        utils.apply_kuberay_resources(images, kuberay_operator_image, kuberay_apiserver_image)
        utils.create_kuberay_cluster(RayFTTestCase.cluster_template_file,
                                     ray_version, ray_image)

    def test_kill_head(self):
        # This test will delete head node and wait for a new replacement to
        # come up.
        utils.shell_assert_success(
            'kubectl delete pod $(kubectl get pods -A | grep -e "-head" | awk "{print \$2}")')

        # wait for new head node to start
        time.sleep(80)
        utils.shell_assert_success('kubectl get pods -A')

        # make sure the new head is ready
        # shell_assert_success('kubectl wait --for=condition=Ready pod/$(kubectl get pods -A | grep -e "-head" | awk "{print \$2}") --timeout=900s')
        # make sure both head and worker pods are ready
        rtn = utils.shell_run(
            'kubectl wait --for=condition=ready pod -l rayCluster=raycluster-compatibility-test --all --timeout=900s')
        if rtn != 0:
            utils.shell_run('kubectl get pods -A')
            utils.shell_run(
                'kubectl describe pod $(kubectl get pods | grep -e "-head" | awk "{print \$1}")')
            utils.shell_run(
                'kubectl logs $(kubectl get pods | grep -e "-head" | awk "{print \$1}")')
            utils.shell_run(
                'kubectl logs -n $(kubectl get pods -A | grep -e "-operator" | awk \'{print $1 "  " $2}\')')
        assert rtn == 0

    def test_ray_serve(self):
        client = docker.from_env()
        container = client.containers.run(ray_image, remove=True, detach=True, stdin_open=True, tty=True,
                                          network_mode='host', command=["/bin/sh", "-c", "python"])
        s = container.attach_socket(
            params={'stdin': 1, 'stream': 1, 'stdout': 1, 'stderr': 1})
        s._sock.setblocking(0)
        s._sock.sendall(b'''
import ray
import time
import ray.serve as serve
import os
import requests
from ray._private.test_utils import wait_for_condition

def retry_with_timeout(func, count=90):
    tmp = 0
    err = None
    while tmp < count:
        try:
            return func()
        except Exception as e:
            err = e
            tmp += 1
    assert err is not None
    raise err

ray.init(address='ray://127.0.0.1:10001')

@serve.deployment
def d(*args):
    return f"{os.getpid()}"

d.deploy()
pid1 = ray.get(d.get_handle().remote())

print('ready')
        ''')

        count = 0
        while count < 90:
            try:
                buf = s._sock.recv(4096)
                logger.info(buf.decode())
                if buf.decode().find('ready') != -1:
                    break
            except Exception as e:
                pass
            time.sleep(1)
            count += 1
        if count >= 90:
            raise Exception('failed to run script')

        # kill the gcs on head node. If fate sharing is enabled
        # the whole head node pod will terminate.
        utils.shell_assert_success(
            'kubectl exec -it $(kubectl get pods -A| grep -e "-head" | awk "{print \\$2}") -- /bin/bash -c "ps aux | grep gcs_server | grep -v grep | awk \'{print \$2}\' | xargs kill"')
        # wait for new head node getting created
        time.sleep(10)
        # make sure the new head is ready
        utils.shell_assert_success(
            'kubectl wait --for=condition=Ready pod/$(kubectl get pods -A | grep -e "-head" | awk "{print \$2}") --timeout=900s')

        s._sock.sendall(b'''
def get_new_value():
    return ray.get(d.get_handle().remote())
pid2 = retry_with_timeout(get_new_value)

if pid1 == pid2:
    print('successful: {} {}'.format(pid1, pid2))
    sys.exit(0)
else:
    print('failed: {} {}'.format(pid1, pid2))
    raise Exception('failed')
        ''')

        count = 0
        while count < 90:
            try:
                buf = s._sock.recv(4096)
                logger.info(buf.decode())
                if buf.decode().find('successful') != -1:
                    break
                if buf.decode().find('failed') != -1:
                    raise Exception('test failed {}'.format(buf.decode()))
            except Exception as e:
                pass
            time.sleep(1)
            count += 1
        if count >= 90:
            raise Exception('failed to run script')

        container.stop()
        client.close()

    def test_detached_actor(self):
        # This test will run a ray client and start a detached actor at first.
        # Then we will kill the head node and kuberay will start a new head node
        # replacement. Finally, we will try to connect to the detached actor again.
        client = docker.from_env()
        container = client.containers.run(ray_image, remove=True, detach=True, stdin_open=True, tty=True,
                                          network_mode='host', command=["/bin/sh", "-c", "python"])
        s = container.attach_socket(
            params={'stdin': 1, 'stream': 1, 'stdout': 1, 'stderr': 1})
        s._sock.setblocking(0)
        s._sock.sendall(b'''
import ray
import time

def retry_with_timeout(func, count=90):
    tmp = 0
    err = None
    while tmp < count:
        try:
            return func()
        except Exception as e:
            err = e
            tmp += 1
    assert err is not None
    raise err

ray.init(address='ray://127.0.0.1:10001')

@ray.remote
class A:
    def ready(self):
        import os
        return os.getpid()

a = A.options(name="a", lifetime="detached", max_restarts=-1).remote()
res1 = ray.get(a.ready.remote())
print('ready')

        ''')

        count = 0
        while count < 90:
            try:
                buf = s._sock.recv(4096)
                logger.info(buf.decode())
                if buf.decode().find('ready') != -1:
                    break
            except Exception as e:
                pass
            time.sleep(1)
            count += 1
        if count >= 90:
            raise Exception('failed to run script')

        # kill the gcs on head node. If fate sharing is enabled
        # the whole head node pod will terminate.
        utils.shell_assert_success(
            'kubectl exec -it $(kubectl get pods -A| grep -e "-head" | awk "{print \\$2}") -- /bin/bash -c "ps aux | grep gcs_server | grep -v grep | awk \'{print \$2}\' | xargs kill"')
        # wait for new head node getting created
        time.sleep(10)
        # make sure the new head is ready
        utils.shell_assert_success(
            'kubectl wait --for=condition=Ready pod/$(kubectl get pods -A | grep -e "-head" | awk "{print \$2}") --timeout=900s')

        s._sock.sendall(b'''
def get_detached_actor():
    return ray.get_actor("a")
a = retry_with_timeout(get_detached_actor)

def get_new_value():
    return ray.get(a.ready.remote())
res2 = retry_with_timeout(get_new_value)

if res1 != res2:
    print('successful: {} {}'.format(res1, res2))
    sys.exit(0)
else:
    print('failed: {} {}'.format(res1, res2))
    raise Exception('failed')
        ''')

        count = 0
        while count < 90:
            try:
                buf = s._sock.recv(4096)
                logger.info(buf.decode())
                if buf.decode().find('successful') != -1:
                    break
                if buf.decode().find('failed') != -1:
                    raise Exception('test failed {}'.format(buf.decode()))
            except Exception as e:
                pass
            time.sleep(1)
            count += 1
        if count >= 90:
            raise Exception('failed to run script')

        container.stop()
        client.close()

class RayServiceTestCase(unittest.TestCase):
    service_template_file = 'tests/config/ray-service.yaml.template'
    service_serve_update_template_file = 'tests/config/ray-service-serve-update.yaml.template'
    service_cluster_update_template_file = 'tests/config/ray-service-cluster-update.yaml.template'

    @classmethod
    def setUpClass(cls):
        if not utils.ray_service_supported(ray_version):
            raise unittest.SkipTest("ray service is not supported")
        # Ray Service is running inside a local Kind environment.
        # We use the Ray nightly version now.
        # We wait for the serve service ready.
        # The test will check the successful response from serve service.
        utils.delete_cluster()
        utils.create_cluster()
        images = [ray_image, kuberay_operator_image, kuberay_apiserver_image]
        utils.download_images(images)
        utils.apply_kuberay_resources(images, kuberay_operator_image, kuberay_apiserver_image)
        utils.create_kuberay_service(
            RayServiceTestCase.service_template_file, ray_version, ray_image)

    def test_ray_serve_work(self):
        time.sleep(5)
        curl_cmd = 'curl  -X POST -H \'Content-Type: application/json\' localhost:8000 -d \'["MANGO", 2]\''
        utils.wait_for_condition(
            lambda: utils.shell_run(curl_cmd) == 0,
            timeout=15,
        )
        utils.create_kuberay_service(
            RayServiceTestCase.service_serve_update_template_file,
            ray_version, ray_image)
        curl_cmd = 'curl  -X POST -H \'Content-Type: application/json\' localhost:8000 -d \'["MANGO", 2]\''
        time.sleep(5)
        utils.wait_for_condition(
            lambda: utils.shell_run(curl_cmd) == 0,
            timeout=60,
        )
        utils.create_kuberay_service(
            RayServiceTestCase.service_cluster_update_template_file,
            ray_version, ray_image)
        time.sleep(5)
        curl_cmd = 'curl  -X POST -H \'Content-Type: application/json\' localhost:8000 -d \'["MANGO", 2]\''
        utils.wait_for_condition(
            lambda: utils.shell_run(curl_cmd) == 0,
            timeout=180,
        )

def parse_environment():
    global ray_version, ray_image, kuberay_operator_image, kuberay_apiserver_image
    for k, v in os.environ.items():
        if k == 'RAY_IMAGE':
            ray_image = v
            ray_version = ray_image.split(':')[-1]
        elif k == 'OPERATOR_IMAGE':
            kuberay_operator_image = v
        elif k == 'APISERVER_IMAGE':
            kuberay_apiserver_image = v

if __name__ == '__main__':
    parse_environment()
    logger.info('Setting Ray image to: {}'.format(ray_image))
    logger.info('Setting Ray version to: {}'.format(ray_version))
    logger.info('Setting KubeRay operator image to: {}'.format(kuberay_operator_image))
    logger.info('Setting KubeRay apiserver image to: {}'.format(kuberay_apiserver_image))
    unittest.main(verbosity=2)


import numpy as np
import torch
from torch.autograd import Variable

dtype = torch.FloatTensor

def pull_arm(bandit):
      result = np.random.randn(1)
      if result > bandit:
          return 1
      else:
          return -1

bandits = [0.1, 1, -0.4, -5]
num_bandits = len(bandits)

w = Variable(torch.ones(num_bandits).type(dtype), requires_grad=True)
rewards = np.zeros(num_bandits)

lr = 0.001

for t in range(1000):
  if np.random.rand(1) < 0.1:
    action = np.random.randint(0, num_bandits)
  else:
    action = np.argmax(w.data)
  reward = pull_arm(bandits[action])
  loss = -torch.log(w[action]) * reward
  rewards[action] += reward
  loss.backward()
  w.data -=  lr* w.grad.data
  w.grad.data.zero_()

print(rewards)


import numpy as np

class PCA(object):

    def __init__(self):
        self.U = None
        self.S = None
        self.V = None

    def fit(self, X):
        """
        Decompose dataset into principal components.
        You may use your SVD function from the previous part in your implementation or numpy.linalg.svd function.

        Don't return anything. You can directly set self.U, self.S and self.V declared in __init__ with
        corresponding values from PCA.

        Args:
            X: N*D array corresponding to a dataset
        Return:
            None
        """
        X_hat = X - np.mean(X, axis=0).reshape(1, X.shape[1])
        self.U, self.S, self.V = np.linalg.svd(X_hat, full_matrices=False)

    def transform(self, data, K=2):
        """
        Transform data to reduce the number of features such that final data has given number of columns

        Utilize self.U, self.S and self.V that were set in fit() method.

        Args:
            data: N*D array corresponding to a dataset
            K: Int value for number of columns to be kept
        Return:
            X_new: N*K array corresponding to data obtained by applying PCA on data
        """
        n = data.shape[0]
        s = np.dot(self.S, self.S) / n
        # print("k: ", K, " data :", data.shape, " self.V.T: ", self.V.T.shape)
        v = np.matmul(data, self.V.T)[..., :K]
        return v

    def transform_rv(self, data, retained_variance=0.99):  # 3 pts
        """
        Transform data to reduce the number of features such that a given variance is retained

        Utilize self.U, self.S and self.V that were set in fit() method.

        Args:
            data: N*D array corresponding to a dataset
            retained_variance: Float value for amount of variance to be retained
        Return:
            X_new: N*K array corresponding to data obtained by applying PCA on data
        """

        s_sqr = np.dot(self.S, self.S)
        s_i = self.S * self.S
        s_i_cum = np.cumsum(s_i)
        s_var = s_i_cum / s_sqr
        k = np.where(s_var == retained_variance)[0]
        if (len(k) == 0):
            k = np.argmin(s_var - retained_variance * ((s_var - retained_variance) > 0))
        else:
            k = k[0]
        k += 1
        # print(k)
        return self.transform(data, k)

    def get_V(self):
        """ Getter function for value of V """

        return self.V

    def get_V(self):
        """ Getter function for value of V """

        return self.V


import meep as mp
import numpy as np

class MVSim:
    def __init__(self, params, geom, src):
        self.params = params
        self.geom = geom
        self.src = src

        self.empty = mp.Simulation(
            resolution=params.res,
            cell_size=geom.cell_size,
            boundary_layers=geom.pml,
            geometry=geom.empty_geom,
            sources=src.sources,
            k_point=mp.Vector3(),
            force_complex_fields=True,
        )
        self.sim = mp.Simulation(
            resolution=params.res,
            cell_size=geom.cell_size,
            boundary_layers=geom.pml,
            geometry=geom.geom,
            sources=src.sources,
            k_point=mp.Vector3(),
            force_complex_fields=True,
        )

    def set_monitors(self, nperiods=100, df=0, nfreqs=1):
        mon_pt = self.params.mon_pt
        mon_size = mp.Vector3(self.params.sx, self.params.sy)
        comps = [mp.Ex, mp.Ey, mp.Ez, mp.Hx, mp.Hy, mp.Hz]
        directions = [mp.X, mp.Y, mp.Z]
        empty = self.empty
        sim = self.sim
        fcen = self.params.fcen

        nf_inc = empty.add_dft_fields(comps, fcen, df, nfreqs, center=-1 * mon_pt, size=mon_size)
        nf_ref = sim.add_dft_fields(comps, fcen, df, nfreqs, center=-1 * mon_pt, size=mon_size)
        nf_trm = sim.add_dft_fields(comps, fcen, df, nfreqs, center=mon_pt, size=mon_size)

        fr_plus = mp.FluxRegion(center=mon_pt, size=mon_size)
        fr_minus = mp.FluxRegion(center=-1 * mon_pt, size=mon_size)
        flux_inc = empty.add_flux(fcen, df, nfreqs, fr_minus)
        flux_rec = sim.add_flux(fcen, df, nfreqs, fr_minus)
        flux_trm = sim.add_flux(fcen, df, nfreqs, fr_plus)

        n2f_inc = empty.add_near2far(fcen, df, nfreqs, fr_minus, nperiods=nperiods)
        n2f_ref = sim.add_near2far(fcen, df, nfreqs, fr_minus, nperiods=nperiods)
        n2f_trm = sim.add_near2far(fcen, df, nfreqs, fr_plus, nperiods=nperiods)

        force_field_x = sim.add_force(fcen, df, nfreqs,
                                      *[mp.ForceRegion(w * mon_pt, size=mon_size, direction=mp.X, weight=w) for w in
                                        [+1, -1]])
        force_field_y = sim.add_force(fcen, df, nfreqs,
                                      *[mp.ForceRegion(w * mon_pt, size=mon_size, direction=mp.Y, weight=w) for w in
                                        [+1, -1]])
        force_field_z = sim.add_force(fcen, df, nfreqs,
                                      *[mp.ForceRegion(w * mon_pt, size=mon_size, direction=mp.Z, weight=w) for w in
                                        [+1, -1]])
        force_fields = [force_field_x, force_field_y, force_field_z]
        # force_fields = []
        # for d in directions:
        #     force_regions = []
        #     for w in [+1, -1]:
        #         region = mp.ForceRegion(center=mon_pt, size=mon_size, direction=d, weight=w)
        #         force_regions.append(region)
        #     field = sim.add_force(fcen, 0, 1, *force_regions)
        #     force_fields.append(field)

        self.near_fields = [nf_inc, nf_ref, nf_trm]
        self.flux_fields = [flux_inc, flux_rec, flux_trm]
        self.n2f_fields = [n2f_inc, n2f_ref, n2f_trm]
        self.force_fields = force_fields

    def run(self, tol=1e-6):
        if isinstance(self.src.src, mp.GaussianSource):
            self._run_peak(tol=tol)
        elif isinstance(self.src.src, mp.ContinuousSource):
            self._run_pw()
        else:
            raise TypeError("Unknown source type!")

    def _run_peak(self, tol=1e-6):
        self.empty.run(until_after_sources=mp.stop_when_fields_decayed(.5, mp.Hy, self.params.mon_pt, tol))
        self._load_minus()
        self.sim.run(until_after_sources=mp.stop_when_fields_decayed(.5, mp.Hy, self.params.mon_pt, tol))

    def _run_pw(self):
        pass

    def _load_minus(self):
        flux_data = self.empty.get_flux_data(self.flux_fields[0])
        n2f_data = self.empty.get_near2far_data(self.n2f_fields[0])
        self.sim.load_minus_flux_data(self.flux_fields[1], flux_data)
        self.sim.load_minus_near2far_data(self.n2f_fields[1], n2f_data)

    def get_eigenmode_force(self, nbands=5, flux=1.):
        try:
            ref = self.flux_fields[1]
            trm = self.flux_fields[2]
            res_ref = self.sim.get_eigenmode_coefficients(ref, range(1, nbands+1))
            res_trm = self.sim.get_eigenmode_coefficients(trm, range(1, nbands+1))
            alpha_ref = res_ref.alpha[:,:, 1]
            knorm_ref = np.asarray([np.asarray(kdom)/self.params.fcen/self.params.n0 for kdom in res_ref.kdom])
            alpha_trm = res_trm.alpha[:,:, 0]
            knorm_trm = np.asarray([np.asarray(kdom)/self.params.fcen/self.params.n0 for kdom in res_trm.kdom])
            f_ref = np.sum(knorm_ref * np.abs(alpha_ref)**2 * np.array([-1,-1,2]), axis=0)
            f_trm = np.sum(knorm_trm * np.abs(alpha_trm)**2 * np.array([1,1,0]), axis=0)
            return res_ref, res_trm, (f_ref + f_trm)/flux
        except Exception:
            print(res_ref.kdom)
            print(res_trm.kdom)

    def get_flux(self):
        fluxes = [mp.get_fluxes(flux) for flux in self.flux_fields]
        return np.array(fluxes)


import pandas as pd
from scipy.sparse import coo_matrix
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from movie_stream.models import Rating, Movie, LightFMModel
import pickle
from movie_stream.users.models import User

def get_recommendations(userid):
    """Get movie and follow recommendations for a user.

    Args:
        userid (int): id of a user in database
    """
    ratings_df = pd.DataFrame.from_records(
        Rating.objects.all().values('movie_id', 'rating', 'user_id'))
    movies_df = pd.DataFrame.from_records(
        Movie.objects.all().values('id', 'title'))
    ratings_df = ratings_df.pivot(
        index='user_id', columns='movie_id', values='rating')
    train_sparse = coo_matrix(ratings_df)

    model = pickle.loads(
        LightFMModel.objects.all().last().pickle_model)  # get last model
    # should really just store n_users and n_tems in database
    # so we don't have to load the whold database everytime
    n_users, n_items = train_sparse.shape

    user_row = ratings_df.index.tolist().index(userid)
    # This will fail unless model has run at least once for user
    scores = model.predict(user_row, np.arange(n_items))
    # rank them in order of most liked to least
    top_items = movies_df['id'].values[np.argsort(-scores)]

    # Now we can use the feature vectors of each user to find who
    # is the most similar to them. (Likes the same type of movies)
    similarities = cosine_similarity(model.user_embeddings)
    ind = np.argpartition(similarities[user_row], -6)[-6:]

    to_follow_ids = ratings_df.index[ind].tolist()
    # don't want to recomend to follow user self
    to_follow_ids.remove(userid)
    return top_items[:10], to_follow_ids


#User function Template for python3
from collections import defaultdict ,deque
class Solution:
    def findOrder(self,alien_dict, N, K):
    # code here
        graph = defaultdict(list)
        degree = defaultdict(int)

        for i in range(len(alien_dict) -1 ):

            edges = self.comper(alien_dict[i] ,alien_dict[i+1])

            if edges:

                graph[edges[0]].append(edges[1])
                degree[edges[0]] = 0 if  edges[0] not in degree else degree[edges[0]]
                degree[edges[1]] += 1

        que = deque()

        for i in range(k):
            if not degree[chr(97+i)]:
                que.append(chr(97+i))
        order = []

        while que:
            curNode = que.popleft()
            order.append(curNode)
            for nbr in graph[curNode]:
                degree[nbr] -=1
                if not degree[nbr]:
                    que.append(nbr)

        return "".join(order)

    def comper(self , str1 , str2 ):
        i = j = 0
        while i < len(str1) and j < len(str2):
            if str1[i] != str2[j]:
                return (str1[i] ,str2[j])
            i += 1
            j += 1


from mode_switcher.modes import Mode
import json
import os.path

def main():
    mode = Mode()
    mode_path = './input/scenario_2/mode.json'
    mode_type = None

    if os.path.isfile(mode_path):
        with open(mode_path) as f:
            mode_type = json.load(f)

    if mode_type:
        mode.run(mode_type['mode'])
    else:
        mode.run('normal')

if __name__ == '__main__':
    main()


# Optical Flow
import cv2
import numpy as np
from matplotlib import pyplot as plt

# Load the images "OF1.jpg" and "OF2.jpg" and change them to grayscale.
img1 = cv2.imread('OF1.jpg')
img2 = cv2.imread('OF2.jpg')

b,g,r = cv2.split(img1) # Changing the order from bgr to rgb so that matplotlib can show it
img1 = cv2.merge([r,g,b])
b,g,r = cv2.split(img2) # Changing the order from bgr to rgb so that matplotlib can show it
img2 = cv2.merge([r,g,b])

gray1 = cv2.cvtColor(img1, cv2.COLOR_RGB2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_RGB2GRAY)

# plt.figure(figsize = (18,18))
# plt.subplot(1,2,1)
# plt.imshow(gray1, cmap = 'gray')
# plt.subplot(1,2,2)
# plt.imshow(gray2, cmap = 'gray')

# They look pretty much the same. We can now use optical flow to find out how the objects
# in the picutures have moved. We do this by first using [cv2.goodFeaturesToTrack]
# (https://docs.opencv.org/3.4/dd/d1a/group__imgproc__feature.html#ga1d6bb77486c8f92d79c8793ad995d541)
# to find features in the first image. You can play around with the parameters to see the difference.
feat1 = cv2.goodFeaturesToTrack(gray1, maxCorners=100, qualityLevel=0.4, minDistance=7)
# The function finds the most prominent corners in the image or in the specified image region

# Next we use the function [cv2.calcOpticalFlowPyrLK]
# (https://docs.opencv.org/3.4/dc/d6b/group__video__track.html#ga473e4b886d0bcc6b65831eb88ed93323)
# to track the features in the next image.
feat2, status, error = cv2.calcOpticalFlowPyrLK(gray1, gray2, feat1, None)

# We now have the location of the features from the first image in the second image. To find the movement we can draw a line between the keypoints.
# for i in range(len(feat1)):
#     cv2.line(img2, (feat1[i][0][0], feat1[i][0][1]), (feat2[i][0][0], feat2[i][0][1]), (0, 255, 0), 2)
#     cv2.circle(img2, (feat1[i][0][0], feat1[i][0][1]), 5, (0, 255, 0), -1)

# plt.figure(figsize=(15,15))
# plt.imshow(img2)

# ## 4a) Change the code such that only the keypoints that have moved will be showed in the image.

# # feat1 = cv2.goodFeaturesToTrack(gray1, maxCorners=100, qualityLevel=0.4, minDistance=7)
# # feat2 = cv2.goodFeaturesToTrack(gray2, maxCorners=100, qualityLevel=0.4, minDistance=7)
# # for i in range(len(feat1)):
# #     if feat1[i][0][0] != feat2[i][0][0] and feat1[i][0][1] != feat2[i][0][1]:
# #         cv2.line(img2, (feat1[i][0][0], feat1[i][0][1]), (feat2[i][0][0], feat2[i][0][1]), (0, 255, 0), 2)
# #         cv2.circle(img2, (feat1[i][0][0], feat1[i][0][1]), 5, (0, 255, 0), -1)
# # plt.figure(figsize=(15,15))
# # plt.imshow(img2)

# plt.show()

### Dense Optical Flow
# The sparse optical flow finds the flow of the detected keypoints.
#  We will now try to use dense optical flow which, finds the flow of all the points in the picture.
# For this example we use the same two images, so we don't have to load them again.
# To find the optical flow we use the function [cv2.calcOpticalFlowFarneback]
# (https://docs.opencv.org/3.4/dc/d6b/group__video__track.html#ga5d10ebbd59fe09c5f650289ec0ece5af).
# Check out the description to see what all the different parameters does, and try to change them to see the difference.
flow = cv2.calcOpticalFlowFarneback(gray1, gray2, None, 0.5, 3, 15, 3, 5, 1.5, 0)
# The function returns an array containing the flow vector for every pixel.
# This can be changed to a magnitude and an angle using the function cv2.cartToPolar.

# Find a way to represent the flow in the image. For example by drawing vectors the relevant places
# or by making a new image with colors representing the flow of every pixel.
# An example of retrieving the magnitude and angle is shown below, which you can use if you like.
mag, ang = cv2.cartToPolar(flow[:,:,0], flow[:,:,1]) # Retrieving the magnitude and angle of every pixel

### Fill in some code to represent the flow here ###
old_shape = img1.shape
prev_img_gray = gray1
current_img = img2
current_img_gray= gray2
assert current_img.shape == old_shape # assert: return TRUE if the conditions is true
hsv = np.zeros_like(img1)
hsv[...,1] = 255 # all the element of the first column set to 255
flow = None
flow = cv2.calcOpticalFlowFarneback(prev=prev_img_gray,
                                      next=current_img_gray, flow=flow,
                                      pyr_scale=0.8, levels=15, winsize=5,
                                      iterations=10, poly_n=5, poly_sigma=0,
                                      flags=10)
mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1])
hsv[..., 0] = ang*180/np.pi/2
hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)
rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
cv2.imshow(img2,rgb)
plt.show()


def fib(n, d):
    if n in d:
        return d[n]
    else:
        ans = fib(n-1, d) + fib(n-2, d)
        d[n] = ans
        return ans
d = {0:0, 1:1, 2:1}
for t in range(int(input())):
    n = int(input())
    print(str(n) + " = " + str(fib(n-1, d)))


from apscheduler.schedulers.background import BackgroundScheduler
from lib.providers import wrapper
from lib.mongo import timeseries
from lib import tools
from datetime import datetime
import time
import json

providers = tools.read_json('static/providers.json')
centers = tools.read_json('static/centers.json')
predictions = tools.read_json('static/predictions.json')

def update(provider, city, predict):
    # Get the information for the city
    try:
        stations = wrapper.collect(provider, city)
    except:
        return
    # Update the database
    if predict == 'Yes':
        timeseries.update_city(stations, city)
    # Save the data for the map
    geojson = tools.json_to_geojson(stations)
    with open('static/geojson/{0}.geojson'.format(city), 'w') as outfile:
        json.dump(geojson, outfile)
    # Tell the server the city's data was updated
    with open('static/updates/{0}.txt'.format(city), 'w') as outfile:
        outfile.write(datetime.now().isoformat())

if __name__ == '__main__':
    scheduler = BackgroundScheduler()
    for provider, cities in providers.items():
        for city in cities:
            time.sleep(3)
            update(provider, city, predictions[city])
            scheduler.add_job(update, 'interval', seconds=60,
                              args=[provider, city, predictions[city]],
                              misfire_grace_time=50, coalesce=True)
    scheduler.start()
    while True:
        time.sleep(10e-1000000)


# -*- coding: utf-8 -*-
"""
Created on Thu May 19 09:37:43 2022

@author: cvskf
"""

import os
import importlib
import inspect

for file in os.listdir():
    print(file)
    if file.startswith('gbElements'):

        version_=file[-7:-3]
        print(version_)
        version=version_.replace('_','.')
        print(version)

        with open(os.path.join(os.pardir,
                               os.pardir,
                               'docs',
                               'auto_auto_methods_pages',
                               f'{version}_index.rst'),
                  'w') as f:

            f.write(f'Schema Version {version}\n')
            f.write('===================\n\n')
            f.write('.. toctree::\n\n')

            my_module = importlib.import_module(f'xgbxml.auto.gbElements_{version_}')

            print(my_module)

            for kls_name,kls in inspect.getmembers(my_module, inspect.isclass):

                f.write(f'   {version}/{kls_name}\n')

                continue  # to avoid recreating the large set of files below each time.

                with open(os.path.join(os.pardir,
                                       os.pardir,
                                       'docs',
                                       'auto_auto_methods_pages',
                                       f'{version}',
                                       f'{kls_name}.rst'),
                          'w') as f1:

                    f1.write(f'{kls_name}\n')
                    x='='*len(kls_name)
                    f1.write(f'{x}\n\n')
                    f1.write(f'.. autoclass:: xgbxml.auto.gbElements_{version_}.{kls_name}\n')
                    f1.write('   :members:\n')
                    f1.write('   :undoc-members:\n\n')

    #break


with open('input.txt') as f:
    data = f.read()

def resolve(name, nodes):
    if name not in nodes:
        return int(name)

    c = nodes[name]

    if len(c) == 1:
        return resolve(c[0], nodes)

    r1 = resolve(c[0], nodes)
    r2 = resolve(c[2], nodes)

    op = c[1]

    if op == '+':
        return r1 + r2
    elif op == '-':
        return r1 - r2
    elif op == '*':
        return r1 * r2
    elif op == '/':
        return r1 / r2

    else:
        raise ValueError('Invalid input!')

def sign(x):
    return x // abs(x)

def binary_search(f, lower, upper):
    l_value = f(lower)
    u_value = f(upper)

    if sign(l_value) == sign(u_value):
        raise ValueError(f"The range [{lower}, {upper}] does not contain zero")

    if l_value > u_value:
        ff = lambda x: -f(x)
    else:
        ff = f

    while lower <= upper:
        mid = (lower + upper) // 2
        m_value = ff(mid)

        if m_value == 0:
            return mid

        elif m_value < 0:
            lower = mid + 1

        else:
            upper = mid

    return lower

def find_root_equality(nodes):
    left = nodes['root'][0]
    right = nodes['root'][2]

    def goal_seek_function(human_input):
        nodes['humn'] = [str(human_input)]
        return resolve(left, nodes) - resolve(right, nodes)

    return binary_search(goal_seek_function, 1, int(1e15))

nodes = {}

for line in data.splitlines():
    name, op = line.split(': ')
    nodes[name] = op.split()

print("Part 1:", int(resolve('root', nodes)))
print("Part 2:", find_root_equality(nodes))

import time
print(time.process_time()) # <0.1s


from secml.core import CCreator
from secml.data import CDataset
from secml.data.loader import CDLRandomBlobs
from secml.data.splitter import CDataSplitterShuffle
from secml.figure import CFigure
from secml.ml.features.normalization import CNormalizerMinMax
from secml.ml.peval.metrics import CMetric
from secml.optim.constraints import CConstraintBox
from secml.optim.function import CFunction
from secml.testing import CUnitTest

class _CAttackPoisoningLinTest(CCreator):
    """
    Debugging class for poisoning against linear classifiers.

    This class implement different functions which are useful to test
    the poisoning gradients of a linear classifier.
    """

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

    def w1(self, xc):
        """
        Parameters
        ----------
        xc: poisoning point

        Returns
        -------
        f_obj: values of objective function (average hinge loss) at x
        """
        idx, clf, tr = self._clf_poisoning(xc)

        return clf.w.ravel()[0]

    def w2(self, xc):
        """
        Parameters
        ----------
        xc: poisoning point

        Returns
        -------
        f_obj: values of objective function (average hinge loss) at x
        """

        idx, clf, tr = self._clf_poisoning(xc)

        return clf.w.ravel()[1]

    def b(self, xc):
        """
        Parameters
        ----------
        xc: poisoning point

        Returns
        -------
        f_obj: values of objective function (average hinge loss) at x
        """

        idx, clf, tr = self._clf_poisoning(xc)

        return clf.b

    def _clf_poisoning(self, xc):

        xc = xc.atleast_2d()
        n_samples = xc.shape[0]

        if n_samples > 1:
            raise TypeError("x is not a single sample!")

        # index of poisoning point within xc.
        # This will be replaced by the input parameter xc
        if self.pois_obj._idx is None:
            idx = 0
        else:
            idx = self.pois_obj._idx

        self.pois_obj._xc[idx, :] = xc
        clf, tr = self.pois_obj._update_poisoned_clf()

        return idx, clf, tr

    def _preparation_for_grad_computation(self, xc):

        idx, clf, tr = self._clf_poisoning(xc)

        y_ts = self.pois_obj._y_target if self.pois_obj._y_target is not \
                                          None else self.pois_obj.val.Y

        # computing gradient of loss(y, f(x)) w.r.t. f
        score = clf.decision_function(self.pois_obj.val.X)
        loss_grad = self.pois_obj._attacker_loss.dloss(y_ts, score)

        return idx, clf, loss_grad, tr

    def _grads_computation(self, xc):
        """
        Compute the derivative of the classifier parameters w.r.t. the
        poisoning points xc.

        The result is a CArray of dimension d * (d+1) where d is equal to the
        number of features

        """
        idx, clf, loss_grad, tr = self._preparation_for_grad_computation(xc)
        self.pois_obj._gradient_fk_xc(self.pois_obj._xc[idx, :],
                                      self.pois_obj._yc[idx],
                                      clf, loss_grad, tr)
        grads = self.pois_obj._d_params_xc
        return grads

    def gradient_w1_xc(self, xc):

        grad = self._grads_computation(xc)

        norm = grad.norm_2d()
        grad = grad / norm if norm > 0 else grad

        return grad[:, 0].ravel()

    def gradient_w2_xc(self, xc):

        grad = self._grads_computation(xc)

        norm = grad.norm_2d()
        grad = grad / norm if norm > 0 else grad

        return grad[:, 1].ravel()

    def gradient_b_xc(self, xc):

        grad = self._grads_computation(xc)

        norm = grad.norm_2d()
        grad = grad / norm if norm > 0 else grad

        return grad[:, 2].ravel()

class CAttackPoisoningTestCases(CUnitTest):
    def _dataset_creation(self):
        """Creates a blob dataset. """
        self.n_features = 2  # Number of dataset features

        self.seed = 42

        self.n_tr = 50
        self.n_ts = 100
        self.n_classes = 2

        loader = CDLRandomBlobs(
            n_samples=self.n_tr + self.n_ts,
            n_features=self.n_features,
            centers=[(-1, -1), (+1, +1)],
            center_box=(-2, 2),
            cluster_std=0.8,
            random_state=self.seed)

        self.logger.info(
            "Loading `random_blobs` with seed: {:}".format(self.seed))

        dataset = loader.load()
        splitter = CDataSplitterShuffle(num_folds=1, train_size=self.n_tr,
                                        random_state=3)
        splitter.compute_indices(dataset)
        self.tr = dataset[splitter.tr_idx[0], :]
        self.ts = dataset[splitter.ts_idx[0], :]

        normalizer = CNormalizerMinMax(feature_range=(-1, 1))
        self.tr.X = normalizer.fit_transform(self.tr.X)
        self.ts.X = normalizer.transform(self.ts.X)

        self.lb = -1
        self.ub = 1

        self.grid_limits = [(self.lb - 0.1, self.ub + 0.1),
                            (self.lb - 0.1, self.ub + 0.1)]

    def _create_poisoning_object(self):
        self.solver_type = 'pgd-ls'
        self.solver_params = {'eta': 0.05, 'eta_min': 0.05, 'eps': 1e-9}

        self._poisoning_params = {
            "classifier": self.classifier,
            "training_data": self.tr,
            "val": self.ts,
            "lb": self.lb,
            "ub": self.ub,
            "solver_type": self.solver_type,
            "solver_params": self.solver_params,
            'random_seed': self.seed
        }

        self.poisoning = self.pois_class(**self._poisoning_params)
        self.poisoning.verbose = 2  # enables print on terminal
        self.poisoning.n_points = 1  # 1
        self.xc, self.yc = self.poisoning._rnd_init_poisoning_points()

        self.logger.info('yc: ' + str(self.yc))

    def _set_up(self, poisoning_class, clf_idx, clf_class, clf_params):

        self.plot_creation = False

        self.clf_idx = clf_idx
        self.pois_class = poisoning_class
        self.clf_class = clf_class
        self.clf_params = clf_params

    def _test_init(self, normalizer=None):
        """Creates the classifier and fit it. """

        self._dataset_creation()

        # create the classifier
        self.classifier = self.clf_class(preprocess=normalizer,
                                         **self.clf_params)
        # fit the classifier
        self.classifier.fit(self.tr.X, self.tr.Y)

    def _clf_poisoning(self):
        """
        Computes a poisoning point considering as source the sample {xc, yc}.
        """
        xc = self.poisoning._run(self.xc, self.yc)

        self.logger.info("Starting score: " + str(self.poisoning.f_seq[0]))
        self.logger.info("Final score: " + str(self.poisoning.f_seq[-1]))
        self.logger.info("x*: " + str(xc))
        self.logger.info("Point sequence: " + str(self.poisoning.x_seq))
        self.logger.info("Score sequence: : " + str(self.poisoning.f_seq))
        self.logger.info("Fun Eval: " + str(self.poisoning.f_eval))
        self.logger.info("Grad Eval: " + str(self.poisoning.grad_eval))

        metric = CMetric.create('accuracy')
        y_pred, scores = self.classifier.predict(self.ts.X,
                                                 return_decision_function=True)
        orig_acc = metric.performance_score(y_true=self.ts.Y,
                                            y_pred=y_pred)
        self.logger.info("Error on testing data: " + str(1 - orig_acc))

        tr = self.tr.append(CDataset(xc, self.yc))

        pois_clf = self.classifier.deepcopy()

        pois_clf.fit(tr.X, tr.Y)
        y_pred, scores = pois_clf.predict(self.ts.X,
                                          return_decision_function=True)
        pois_acc = metric.performance_score(y_true=self.ts.Y,
                                            y_pred=y_pred)
        self.logger.info(
            "Error on testing data (poisoned): " + str(1 - pois_acc))

        return pois_clf, xc

    def _test_attack_effectiveness(self, normalizer):
        """
        This function, firsly, computes a poisoning point. Than, it compares
        the value of the attacker objective function on that point before and
        after the attack. Finally, raises an error if the one computed on
        the poisoning point is not the highest.
        """
        self.logger.info("Test if the value of the attacker objective "
                         "function increases after the attack")

        self._test_init(normalizer)
        self._create_poisoning_object()

        x0 = self.xc  # starting poisoning point
        xc = self._clf_poisoning()[1]

        fobj_x0 = self.poisoning.objective_function(xc=x0)
        fobj_xc = self.poisoning.objective_function(xc=xc)

        self.logger.info(
            "Objective function before the attack {:}".format(fobj_x0))
        self.logger.info(
            "Objective function after the attack {:}".format(fobj_xc))

        self.assertLess(fobj_x0, fobj_xc,
                        "The attack does not increase the objective "
                        "function of the attacker. The fobj on the "
                        "original poisoning point is {:} while "
                        "on the optimized poisoning point is {:}.".format(
                            fobj_x0, fobj_xc))

        if self.plot_creation:
            self._create_2D_plots(normalizer)

    def _test_clf_accuracy(self, normalizer):
        """Checks the accuracy of the classifier considered into the
        test. """

        self._test_init(normalizer)

        metric = CMetric.create('accuracy')
        y_pred, scores = self.classifier.predict(self.ts.X,
                                                 return_decision_function=True)
        acc = metric.performance_score(y_true=self.ts.Y, y_pred=y_pred)
        self.logger.info("Error on testing data: " + str(1 - acc))
        self.assertGreater(
            acc, 0.70, "The trained classifier have an accuracy that "
                       "is too low to evaluate if the poisoning against "
                       "this classifier works")

    #####################################################################
    #                        PLOT FUNCTIONALITIES
    #####################################################################

    def _create_box(self):
        """Create a box constraint"""
        if self.lb == "x0":
            self.lb = self.x0
        if self.ub == "x0":
            self.ub = self.x0
        box = CConstraintBox(lb=self.lb, ub=self.ub)
        return box

    def _plot_func(self, fig, func, **func_kwargs):
        """Plot poisoning objective function"""
        fig.sp.plot_fun(
            func=func,
            grid_limits=self.grid_limits, plot_levels=False,
            n_grid_points=10, colorbar=True, **func_kwargs)

    def _plot_obj_grads(self, fig, func, **func_kwargs):
        """Plot poisoning attacker objective function gradient"""
        fig.sp.plot_fgrads(
            func,
            grid_limits=self.grid_limits,
            n_grid_points=20, **func_kwargs)

    def _create_2D_plots(self, normalizer):

        self._test_init(normalizer)

        self.logger.info("Create 2-dimensional plot")

        self.clf_orig = self.classifier.deepcopy()
        pois_clf = self._clf_poisoning()[0]

        fig = CFigure(height=4, width=10, title=self.clf_idx)
        n_rows = 1
        n_cols = 2

        box = self._create_box()

        fig.subplot(n_rows, n_cols, grid_slot=1)
        fig.sp.title('Attacker objective and gradients')
        self._plot_func(fig, self.poisoning.objective_function)
        self._plot_obj_grads(
            fig, self.poisoning.objective_function_gradient)
        fig.sp.plot_ds(self.tr)
        fig.sp.plot_decision_regions(self.clf_orig, plot_background=False,
                                     grid_limits=self.grid_limits,
                                     n_grid_points=10, )

        fig.sp.plot_constraint(box, grid_limits=self.grid_limits,
                               n_grid_points=10)
        fig.sp.plot_path(self.poisoning.x_seq,
                         start_facecolor='r' if self.yc == 1 else 'b')

        fig.subplot(n_rows, n_cols, grid_slot=2)
        fig.sp.title('Classification error on val')
        self._plot_func(fig, self.poisoning.objective_function,
                        acc=True)
        fig.sp.plot_ds(self.tr)
        fig.sp.plot_decision_regions(pois_clf, plot_background=False,
                                     grid_limits=self.grid_limits,
                                     n_grid_points=10, )

        fig.sp.plot_constraint(box, grid_limits=self.grid_limits,
                               n_grid_points=10)
        fig.sp.plot_path(self.poisoning.x_seq,
                         start_facecolor='r' if self.yc == 1 else 'b')

        fig.tight_layout()
        exp_idx = "2d_pois_"
        exp_idx += self.clf_idx
        if self.classifier.class_type == 'svm':
            if self.classifier.kernel.preprocess is not None:
                exp_idx += "_norm"
        else:
            if self.classifier.preprocess is not None:
                exp_idx += "_norm"
        fig.savefig(exp_idx + '.pdf', file_format='pdf')

    #####################################################################
    # FUNCTIONS TO CHECK THE POISONING GRADIENT OF CLASSIFIERS
    # LEARNED IN THE PRIMAL
    #####################################################################

    def _plot_param_sub(self, fig, param_fun, grad_fun, clf):

        box = self._create_box()

        self._plot_func(fig, param_fun)
        self._plot_obj_grads(
            fig, grad_fun)

        fig.sp.plot_ds(self.tr)
        fig.sp.plot_decision_regions(clf, plot_background=False,
                                     grid_limits=self.grid_limits,
                                     n_grid_points=10, )
        fig.sp.plot_constraint(box, grid_limits=self.grid_limits,
                               n_grid_points=10)

    def _create_params_grad_plot(self, normalizer):
        """
        Show the gradient of the classifier parameters w.r.t the poisoning
        point
        """
        self.logger.info("Create 2-dimensional plot of the poisoning "
                         "gradient")

        self._test_init(normalizer)

        pois_clf = self._clf_poisoning()[0]

        if self.n_features == 2:
            debug_pois_obj = _CAttackPoisoningLinTest(self.poisoning)

            fig = CFigure(height=8, width=10)
            n_rows = 2
            n_cols = 2

            fig.title(self.clf_idx)

            fig.subplot(n_rows, n_cols, grid_slot=1)
            fig.sp.title('w1 wrt xc')
            self._plot_param_sub(fig, debug_pois_obj.w1,
                                 debug_pois_obj.gradient_w1_xc,
                                 pois_clf)

            fig.subplot(n_rows, n_cols, grid_slot=2)
            fig.sp.title('w2 wrt xc')
            self._plot_param_sub(fig, debug_pois_obj.w2,
                                 debug_pois_obj.gradient_w2_xc,
                                 pois_clf)

            fig.subplot(n_rows, n_cols, grid_slot=3)
            fig.sp.title('b wrt xc')
            self._plot_param_sub(fig, debug_pois_obj.b,
                                 debug_pois_obj.gradient_b_xc,
                                 pois_clf)

            fig.tight_layout()
            exp_idx = "2d_grad_pois_"
            exp_idx += self.clf_idx
            if self.classifier.preprocess is not None:
                exp_idx += "_norm"
            fig.savefig(exp_idx + '.pdf', file_format='pdf')

    def _single_param_grad_check(self, xc, f_param, df_param, param_name):
        """

        Parameters
        ----------
        xc CArray
            poisoning point
        f_param function
            the function that update the parameter value
        df_param function
            the function that compute the gradient value
        param_name the parameter name
        """

        # Compare analytical gradient with its numerical approximation
        check_grad_val = CFunction(
            f_param, df_param).check_grad(xc, epsilon=100)
        self.logger.info("Gradient difference between analytical {:} "
                         "gradient and numerical gradient: %s".format(
            param_name),
            str(check_grad_val))
        self.assertLess(check_grad_val, 1,
                        "poisoning gradient is wrong {:}".format(
                            check_grad_val))

    def _test_single_poisoning_grad_check(self, normalizer):

        self._test_init(normalizer)

        pois_clf = self._clf_poisoning()[0]

        xc = self.xc

        debug_pois_obj = _CAttackPoisoningLinTest(self.poisoning)

        self._single_param_grad_check(xc, debug_pois_obj.w1,
                                      debug_pois_obj.gradient_w1_xc,
                                      param_name='w1')
        self._single_param_grad_check(xc, debug_pois_obj.w2,
                                      debug_pois_obj.gradient_w2_xc,
                                      param_name='w2')
        self._single_param_grad_check(xc, debug_pois_obj.b,
                                      debug_pois_obj.gradient_b_xc,
                                      param_name='b')

        if self.plot_creation is True:
            self._create_params_grad_plot(normalizer)

if __name__ == '__main__':
    CUnitTest.main()


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

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from mtcnn.model import PNet,RNet,ONet,load_weight
from mtcnn.run import run_pnet,run_rnet,run_onet
from mtcnn.utils import show_bboxes
from mtcnn.bboxUtils import nms,calibrate_box,convert_to_square,get_image_crop,correct_bboxes

import torch
from torch.autograd import Variable

def build_pyramid(image,min_face_size=20.0):
    width,height = image.size
    min_length = min(width,height)

    min_detection_size = 12
    factor = 0.707

    scales = []

    m = min_detection_size / min_face_size
    min_length *= m

    factor_count = 0
    while min_length > min_detection_size:
        scales.append(m * factor **factor_count)
        min_length *= factor
        factor_count += 1

    return scales

pnet_weight = "weights/pnet.npy"
p_net = PNet()
load_weight(p_net,pnet_weight)

file = "1.jpg"
image = Image.open(file)

scales = build_pyramid(image)

bounding_boxes = []
for s in scales:
    boxes = run_pnet(image,p_net,s,0.6)
    bounding_boxes.append(boxes)

# 经过P-Net 后，所有可能包含人脸的box
bounding_boxes = [i for i in bounding_boxes if i is not None]
bounding_boxes = np.vstack(bounding_boxes)

print("经过P-Net 后，所有可能包含人脸的box个数:{}".format(bounding_boxes.shape[0]))

img1 = show_bboxes(image,bounding_boxes[:,0:4])

keep = nms(bounding_boxes,0.7)
bounding_boxes = bounding_boxes[keep]
print("NMS删除重叠较多的box后，box个数:{}".format(bounding_boxes.shape[0]))

img2 = show_bboxes(image,bounding_boxes[:,0:5])

bounding_boxes = calibrate_box(bounding_boxes,bounding_boxes[:,5:])

img3 = show_bboxes(image,bounding_boxes[:,0:4])

plt.figure()
plt.subplot(221)
plt.imshow(img1)

plt.subplot(222)
plt.imshow(img2)

plt.subplot(223)
plt.imshow(img3)

#####
###　STAGE 2
####
rnet = RNet()
load_weight(rnet,"weights/rnet.npy")
bounding_boxes = run_rnet(image,bounding_boxes,rnet,0.7)

onet = ONet()
load_weight(onet,"weights/onet.npy")
bounding_boxes,landmarks = run_onet(image,bounding_boxes,onet,0.8)

img4 = show_bboxes(image,bounding_boxes,landmarks)

plt.subplot(224)
plt.imshow(img4)
plt.show()


import dolfin as df
import surfaise as sf
import os
import ufl

parameters = dict(
    R=30.,  # Radius
    r=10.,
    res=100,  # Resolution
    dt=2e-1,
    rho=.01,
    eta=.1,
    tau=0.2,
    M=1.0,
    restart_folder=None,
    folder="results_nspfc_torus",
    t_0=0.0,
    tstep=0,
    T=2000,
    dump_intv=5,
    stats_intv=1,
    checkpoint_intv=50,
    verbose=True,
    init_mode="random",
    alpha=0.0,
)
cmd_kwargs = sf.cmd.parse_command_line()
parameters.update(**cmd_kwargs)
if parameters["restart_folder"]:
    sf.io.load_parameters(parameters, os.path.join(
        parameters["restart_folder"], "parameters.dat"))
    parameters.update(**cmd_kwargs)

R = parameters["R"]
r = parameters["r"]
res = parameters["res"]
dt = sf.TimeStepSelector(parameters["dt"])
rho = df.Constant(parameters["rho"])
eta = df.Constant(parameters["eta"])
tau = df.Constant(parameters["tau"])
M = df.Constant(parameters["M"])

# geo_map = TorusMap(R, r)
geo_map = sf.EllipsoidMap(R, R, R, verbose=True, eps=1e-1)
geo_map.initialize(res, restart_folder=parameters["restart_folder"])

W = geo_map.mixed_space((geo_map.ref_el, geo_map.ref_el, geo_map.ref_el,
                         geo_map.ref_vel, geo_map.ref_el))
field_names = ("psi", "mu", "nu", "u", "p")
# W = geo_map.mixed_space((geo_map.ref_el, geo_map.ref_el, geo_map.ref_el))
# field_names = ("psi", "mu", "nu")

# Define trial and test functions
chi, xi, beta, v, q = df.TestFunctions(W)
# chi, xi, beta = df.TestFunctions(W)

# Define functions
w = df.TrialFunction(W)
w_ = df.Function(W, name="u_")  # current solution
w_1 = df.Function(W, name="u_1")  # solution from previous converged step

# Split mixed functions
psi, mu, nu, u,  p = df.split(w)
psi_, mu_, nu_, u_, p_ = df.split(w_)
psi_1, mu_1, nu_1, u_1, p_1 = df.split(w_1)

# psi, mu, nu = df.split(w)
# psi_, mu_, nu_ = df.split(w_)
# psi_1, mu_1, nu_1 = df.split(w_1)

# Create intial conditions
if parameters["restart_folder"] is None:
    init_mode = parameters["init_mode"]
    if init_mode == "random":
        w_init = sf.ics.RandomIC(w_, degree=1)
    else:
        exit("Unknown IC")
    w_1.interpolate(w_init)
    w_.assign(w_1)
else:
    sf.io.load_checkpoint(parameters["restart_folder"], w_, w_1)

w_pot = sf.QuarticPotential()

dw_stab = w_pot.derivative_stab(psi_, psi_1, tau)

f = df.Constant((0., 0.))

# Define some UFL indices:
i, j, k, l = ufl.Index(), ufl.Index(), ufl.Index(), ufl.Index()

# Brazovskii-Swift (conserved PFC with dc/dt = grad^2 delta F/delta c)
m_NL = dw_stab * xi
m_0 = 4 * nu_ * xi - 4 * geo_map.gab[i, j]*nu_.dx(i)*xi.dx(j)
m = m_NL + m_0
m_NS = (rho / dt * geo_map.g_ab[i, j] * (u_[i]-u_1[i]) * v[j]
        + rho * geo_map.g_ab[i, j] * u_[k] *
        geo_map.CovD10(u_)[k, i] * v[j]
        + eta * geo_map.g_ab[i, k] * geo_map.gab[j, l] *
        geo_map.CovD10(u_)[i, j] * geo_map.CovD10(v)[k, l]
        + eta * geo_map.K * geo_map.g_ab[i, j] * u_[i] * v[j]
        - p_ * geo_map.CovD10(v)[i, i]
        - q * geo_map.CovD10(u_)[i, i]
        + psi_ * mu_.dx(i) * v[i]
        - f[i]*v[i])

F_psi = geo_map.form(1/dt * (psi_ - psi_1) * chi
                     - psi_ * u_[i] * chi.dx(i)
                     + M * geo_map.gab[i, j]*mu_.dx(i)*chi.dx(j))
F_mu = geo_map.form(mu_*xi - m)
F_nu = geo_map.form(nu_*beta + geo_map.gab[i, j]*psi_.dx(i)*beta.dx(j))
F_PFC = F_psi + F_mu + F_nu
F_NS = geo_map.form(m_NS)
F = F_PFC + F_NS

J = df.derivative(F, w_, du=w)

x = geo_map.ref_mesh.coordinates()
s_max = sf.cmd.mpi_max(x[:, 1])
s_min = sf.cmd.mpi_min(x[:, 1])
t_min = sf.cmd.mpi_min(x[:, 0])

def poles(x, on_boundary):
    return on_boundary and bool(x[1] <= s_min+df.DOLFIN_EPS_LARGE
                                or x[1] >= s_max-df.DOLFIN_EPS_LARGE)

u_bc = df.DirichletBC(W.sub(3).sub(1), df.Constant(0.),
                      poles)
# p_bc = df.DirichletBC(W.sub(1), df.Constant(0.),
#                       "x[0] < {t_min} && x[1] < {s_min}".format(
#                            t_min=t_min, s_min=s_min),
#                       "pointwise")

problem = df.NonlinearVariationalProblem(F, w_, J=J, bcs=[u_bc])
solver = df.NonlinearVariationalSolver(problem)
solver.parameters["newton_solver"]["absolute_tolerance"] = 1e-8
solver.parameters["newton_solver"]["relative_tolerance"] = 1e-5
solver.parameters["newton_solver"]["maximum_iterations"] = 16
#solver.parameters["newton_solver"]["linear_solver"] = "gmres"
#solver.parameters["newton_solver"]["preconditioner"] = "default"
# solver.parameters["newton_solver"]["krylov_solver"]["nonzero_initial_guess"] = True
# solver.parameters["newton_solver"]["krylov_solver"]["absolute_tolerance"] = 1e-8
# solver.parameters["newton_solver"]["krylov_solver"]["monitor_convergence"] = False
#solver.parameters["newton_solver"]["krylov_solver"]["maximum_iterations"] = 1000

# solver.parameters["linear_solver"] = "gmres"
# solver.parameters["preconditioner"] = "jacobi"

df.parameters["form_compiler"]["optimize"] = True
df.parameters["form_compiler"]["cpp_optimize"] = True

#
t = parameters["t_0"]
tstep = parameters["tstep"]
T = parameters["T"]

# Output file
ts = sf.io.Timeseries(parameters["folder"], w_,
                      field_names, geo_map, tstep,
                      parameters=parameters,
                      restart_folder=parameters["restart_folder"])

E_kin = 0.5*rho*geo_map.g_ab[i, j]*u_[i]*u_[j]
divu = geo_map.CovD10(u_)[i, i]
U = [sum([geo_map.get_function(xi + "_," + vj)*u_[dj]
          for dj, vj in enumerate(geo_map.AXIS_REF)])
     for xi in geo_map.AXIS]
GradMu = [sum([geo_map.get_function(xi + "_," + vj)
               * geo_map.gab[i, dj]*mu_.dx(i)
               for dj, vj in enumerate(geo_map.AXIS_REF)])
          for xi in geo_map.AXIS]

E_psi = (2*nu_**2 - 2 * geo_map.gab[i, j]*psi_.dx(i)*psi_.dx(j)
         + w_pot(psi_, tau))
grad_mu_ufl = df.sqrt(geo_map.gab[i, j]*mu_.dx(i)*mu_.dx(j))
u_norm_ufl = df.sqrt(geo_map.g_ab[i, j]*u_[i]*u_[j])

ts.add_field(E_psi, "E_psi")
ts.add_field(GradMu, "GradMu")
ts.add_field(grad_mu_ufl,
             "abs_grad_mu")

ts.add_field(E_kin, "E_kin")
ts.add_field(divu, "divu")
ts.add_field(U, "U")
ts.add_field(u_norm_ufl, "u_norm")

# Step in time
ts.dump(tstep)

while t < T:
    tstep += 1
    sf.cmd.info_cyan("tstep = {}, time = {}".format(tstep, t))

    w_1.assign(w_)

    converged = False
    while not converged:
        try:
            solver.solve()
            converged = True
        except:
            sf.cmd.info_blue("Did not converge. Chopping timestep.")
            dt.chop()
            sf.cmd.info_blue("New timestep is: dt = {}".format(dt.get()))
            w_.assign(w_1)

    # Update time with final dt value
    t += dt.get()

    if tstep % parameters["dump_intv"] == 0:
        ts.dump(t)

    # Assigning timestep size according to grad_mu_max:
    grad_mu = df.project(grad_mu_ufl, geo_map.S_ref)
    grad_mu_max = sf.cmd.mpi_max(grad_mu.vector().get_local())
    u_norm = df.project(u_norm_ufl, geo_map.S_ref)
    u_norm_max = sf.cmd.mpi_max(u_norm.vector().get_local())

    vel_max = max(u_norm_max, grad_mu_max)

    dt_prev = dt.get()
    dt.set(min(0.2/vel_max, T-t))

    sf.cmd.info_blue("dt = {}".format(dt.get()))
    if tstep % parameters["stats_intv"] == 0 or t >= T:
        E_kin_out = df.assemble(geo_map.form(E_kin))
        E_psi_out = df.assemble(geo_map.form(E_psi))
        divu_out = df.assemble(geo_map.form(divu))

        ts.dump_stats(t, [E_kin_out, E_psi_out, divu_out, grad_mu_max,
                          u_norm_max],
                      "data")

    if tstep % parameters["checkpoint_intv"] == 0 or t >= T:
        sf.io.save_checkpoint(tstep, t, geo_map.ref_mesh,
                              w_, w_1, ts.folder, parameters)


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

image = plt.imread('animation.jpg')
grayscale = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)

g_width = grayscale.shape[0]
g_height = grayscale.shape[1]

kernel1 = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, -1]])

pad_quantity = int((len(kernel1) - 1) / 2)

padded_g = pad_arr = np.pad(grayscale, pad_quantity)

processed_img1 = cv2.filter2D(padded_g, -1, kernel1, cv2.BORDER_CONSTANT)
processed_img1 = processed_img1[pad_quantity:g_width+pad_quantity, pad_quantity:g_height+pad_quantity]

print(padded_g[0:5,padded_g.shape[1]-5:])
print(processed_img1)

m, n = kernel1.shape

y, x = padded_g.shape

processed_img2 = np.zeros((g_width, g_height))

for i in range(g_width):
    for j in range(g_height):
        processed_img2[i][j] = int(np.sum(padded_g[i:i+m, j:j+n]*kernel1))

        if(processed_img2[i][j] > 255):
            processed_img2[i][j] = 255
        if(processed_img2[i][j] < 0):
            processed_img2[i][j] = 0

img_set = [image,grayscale,processed_img1, processed_img2]
title_set = ['RGB','Grayscale','Neighborhood', 'BuiltIn']
cmap_set = ['','gray','gray','gray']

n = len(img_set)
plt.figure(figsize=(15,15))

for i in range (n):
    img = img_set[i]
    plt.subplot(2,3,i+1)
    plt.title(title_set[i])
    ch = len(img_set[i].shape)
    if ch == 3:
        plt.imshow(img_set[i])
    else:
        plt.imshow(img_set[i],cmap=cmap_set[i])

    plt.savefig('Neighborhood_BuiltIn_Comparision.jpg')
plt.show()


# django imports
from django.conf import settings

# sendgrid imports
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import (
    Mail,
    Attachment,
    FileContent,
    FileName,
    FileType,
    Disposition,
    Content,
)

# additional imports
from typing import Tuple
import os

class SendGrid:
    SENDGRID_USE = settings.SENDGRID_USE
    SENDGRID_API_KEY = os.environ.get('SENDGRID_API_KEY', '')
    SENDGRID_TEMPLATE_ID = os.environ.get('SENDGRID_TEMPLATE_ID', '')
    SENDGRID_SENDER_EMAIL = os.environ.get('SENDGRID_SENDER_EMAIL', '')

    def __init__(self) -> None:

        '''
        This is the constructor for SendGrid class.
        In future a logger will also be initialized here.
        '''

        if self.SENDGRID_USE:
            self.sendgrid_client = SendGridAPIClient(self.SENDGRID_API_KEY)

    def mail_object(self, to_email: str, verification_link: str) -> Mail:

        '''
        This method will create a Mail object which will be sent by the email,
        Mail object consists of from_email, to_emails, subject, template_id and dynamic_template_data
        '''

        mail = Mail(
            from_email=self.SENDGRID_SENDER_EMAIL,
            to_emails=to_email,
            subject='SSM Forgot Password hero',
        )
        mail.template_id = self.SENDGRID_TEMPLATE_ID
        mail.dynamic_template_data = {'verification_link': verification_link}

        return mail

    def send_email(self, to_email: str, verification_link: str) -> Tuple[bool, str]:

        '''
        This method will send the mail and returns a tuple of bool and str,
        corresponding to success and success message or error and error message(in case of failure)
        '''

        if not self.SENDGRID_USE:
            return True, 'Mail was not sent because sendgrid use is set to false'
        try:
            mail = self.mail_object(to_email, verification_link)
            sendgrid_response = self.sendgrid_client.send(mail)
            return True, str(sendgrid_response.headers)
        except Exception as e:
            return False, str(e)


'''
Autor: Alexandre Borgmann
Data: 11/04/2020
URI Online Judge | 1065 Pares entre Cinco Números

Faça um programa que leia 5 valores inteiros.
Conte quantos destes valores digitados são pares e mostre esta informação.
Entrada
O arquivo de entrada contém 5 valores inteiros quaisquer.
Saída
Imprima a mensagem conforme o exemplo fornecido, indicando a quantidade de valores pares lidos.

Exemplo de Entrada
Exemplo de Saída
7
-5
6
-4
12
3 valores pares

'''
pares=0
for i in range(5):
    a = int(input())
    if(a%2==0):
        pares+=1
print(pares,'valores pares')


from voice_input import VoiceInput
# right now, there are some issues/warnings with microphone integration

def main():
    vinput = VoiceInput(
        whisper_model='small',
        non_english=False,
        energy_treshold=1000,
        default_mic='pulse'
        # default_mic='Blue Snowball: USB Audio (hw:1,0)',
        # record_timeout=2,
        # phrase_timeout=3
    )
    print("Voice input ready")

    i = 0
    while True:
        i += 1
        transcription = vinput.get_phrase()
        print(f"{i}: {transcription}")
        holder = input()

if __name__ == "__main__":
    main()