# 2. Дан список:
#
# ['в', '5', 'часов', '17', 'минут', 'температура', 'воздуха', 'была', '+5', 'градусов']
# Необходимо его обработать — обособить каждое целое число кавычками и дополнить нулём до двух разрядов:
# ['в', '"', '05', '"', 'часов', '"', '17', '"', 'минут', 'температура', 'воздуха', 'была', '"', '+05', '"', 'градусов']
# Новый список не создавать! Сформировать из обработанного списка строку:
# в "05" часов "17" минут температура воздуха была "+05" градусов

# С ковычками так и не разобрался, в выведенном списке, но после просмотра варианта решения,
# понял что изначально не так начал делать. Смысла нет копипастить и поэтому сдам как есть в сыром варианте.
# С выводами промежуточных значений.

default_list = ['в', '5', 'часов', '17', 'минут', 'температура', 'воздуха', 'была', '+5', 'градусов']
new_list = []

i = 0

for i in range(len(default_list)):
    if default_list[i].isdigit() or default_list[i][1:].isdigit():
        number = int(default_list[i])
        if default_list[i][0] == '+' or default_list[i][0] == '-':
            default_list_sum = default_list[i][0]
            default_list[i] = default_list_sum + default_list[i][1:].zfill(2)
            print('Вывод с +/-: ', default_list[i])
            new_list.append(default_list[i])
        elif number > 0:
            print('default_list[i]: ', default_list[i])
            print('number: ', number)
            print('zfill: ', default_list[i].zfill(2))
            print((type(number)))
            new_list.append(default_list[i].zfill(2))
    else:
        new_list.append(default_list[i])

print('new_list: ', new_list)
new_list_sum = []

for i in range(len(new_list)):
    if new_list[i].isdigit() or new_list[i][1:].isdigit():
        new_sum = new_list[i]
        new_list_sum = ' '.join(f'"{new_sum}"' for new_sum in new_list[i])
        # new_list_sum.insert(i, '"')
        # new_list_sum.insert(i + 2, '"')
        print('new_sum: ', new_sum)
        print('new_list_sum', new_list_sum)


import os
import cv2
import numpy as np
from sklearn.cluster import KMeans  # 在sklearn.cluster库中有KMeans类可以直接使用。
import os.path
from dataloader_cluster import DataLoader
import torch
import logging
import argparse
import pandas as pd
from ast import literal_eval
import math
import joblib

# image_cluster 使用SIFT和KMEANS算法进行图像聚类，得到图像标签
def image_clusterByKMeans(cluster_num, path_filenames, img_size):
    features = []

    sift = cv2.xfeatures2d.SIFT_create()  # 使用SIFT算法提取图像特征
    # count  = 0
    files = path_filenames  # 特征检测
    bad_img = []
    for i, file in enumerate(files):
        img = cv2.imread(file)  # 读入文件
        img = cv2.resize(img, (img_size, img_size))
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 灰度化处理，加快计算速度

        kp, des = sift.detectAndCompute(gray, None)  # 调用SIFT算法检测并计算描述符

        # print(des)
        # print(des.shape)
        # 有些图片对应的feature为None，选择跳过这些图片
        if des is None:
            # path_filenames.remove(file)
            print("the feature of img{} is nonetype".format(i))
            bad_img.append(i)
            continue
        reshape_feature = des.reshape(-1, 1)
        # print(reshape_feature.shape)

        # features.append(reshape_feature[0].tolist()) #第一种取第一个元素
        reshape_feature_Mean = np.array([np.mean(reshape_feature)])  # 第二种取平均值
        features.append(reshape_feature_Mean.tolist())

    input_x = np.array(features)  # 计算关键点 因为KMeans.fix(X[,y) X是需要2D 而不是1D
    kmeans = KMeans(n_clusters=cluster_num, max_iter=200).fit(input_x)  # 关键点聚类
    return kmeans.labels_, kmeans.cluster_centers_, bad_img  # 返回标签以及聚类中心

def main(config):

    label_mapping = {'1': 'happy', '2': 'sad', '3': 'surprise', '4': 'fear', '5': 'disgust', '6': 'angry', '7': 'contempt'}

    loader = None

    img_root = os.path.join(config.dataset_root, config.imgs_folder)

    train_exp_csv_file = os.path.join(config.dataset_root, config.csv_name)

    train_dataset = DataLoader(
        img_size=config.img_size, exp_class=config.exp_label, is_transform=False
    )
    train_dataset.load_data(train_exp_csv_file, img_root)
    loader = torch.utils.data.DataLoader(
        dataset=train_dataset,
        batch_size=config.batch_size,
        shuffle=True,
        num_workers=4,
    )

    all_path = []
    for i, batch in enumerate(loader):
        if i % 5 == 0:
            print("batch {} / {}".format(i, len(loader)))

        imgs_path = batch[1]
        all_path = all_path + list(imgs_path)

    # with open("/home/users/zhiwei.huang/project_run/FER/JAAE_AU/data/list/AffectNet_{}_path.txt".format(label_mapping[str(config.exp_label)]), "w") as f:
    #     for path in all_path:
    #         f.write(path+'\n')             #记录affectNet训练集中该表情类别下所有图片的路径

    imgnum = len(all_path)  # affectNet训练集中该表情对应的图片数量
    print("img_num is", imgnum)
    # ②调用image_cluster函数实现SIFT提取特征并使用KNN聚类方法，得到图像标签
    labels, cluster_centers, bad_img = image_clusterByKMeans(config.cluster_num, all_path, config.img_size)
    print(labels.tolist())

    ###########统计结果并把图片复制到其所属聚类中心文件夹下
    res = labels.tolist()
    # print("bad_img_id is", bad_img)
    print("label_num is (filter bad_img)", len(res))

    result = [[] for i in range(config.cluster_num)]
    img_id = 0
    for i in range(len(res)):
        if img_id in bad_img:
            img_id += 1
            continue
        img_label = res[i]
        result[img_label].append(img_id)
        img_id += 1

    for i in range(config.cluster_num):
        print('第{}个聚类中心含样本{}个'.format(i + 1, res.count(i)))
        # print(len(result[i]))

    exp_type = label_mapping[str(config.exp_label)]
    output_dir = os.path.join(config.dataset_root, 'sift_exp_cluster_{}'.format(config.cluster_num), exp_type)
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    for i in range(config.cluster_num):
        save_dir = os.path.join(output_dir, 'centroid_{}'.format(i))
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)
        size = len(result[i])
        for j in range(size):
            # plt.subplot(1, size, j + 1)
            file_path = all_path[result[i][j]]
            os.system('cp {} {}'.format(file_path, save_dir))

if __name__ == "__main__":
    parser = argparse.ArgumentParser()

    # Model configuration.
    parser.add_argument(
        "--exp_label", type=int, default=1, help="the exp_label you want to cluster"
    )
    parser.add_argument("--img_size", type=int, default=128, help="image resolution")

    parser.add_argument(
        "--dataset_root",
        type=str,
        default="/mnt/data-1/zhiwei.huang/AffectNet",
        help="dataset_root",
    )
    parser.add_argument(
        "--imgs_folder", type=str, default="Manually_Annotated/Manually_Annotated_Images/"
    )
    parser.add_argument(
        "--csv_name", type=str, default="affectNet_formal_training.csv"
    )

    # Cluster configuration.
    parser.add_argument("--batch_size", type=int, default=64, help="mini-batch size")
    parser.add_argument('--cluster_num', type=int, default=12)

    config = parser.parse_args()
    print(config)
    main(config)


import scrapy
from WetBulbBackEnd.items import WeatherItem

class WeatherSpider(scrapy.Spider):
    name = 'weather'
    start_urls = [
        'https://forecast.weather.gov/MapClick.php?lat=36.2424&lon=-115.042']

    def parse(self, response):
        item = WeatherItem()
        item['temperature'] = response.css(
            'p.myforecast-current-lrg::text').get()
        weatherRows = response.css('tr')
        for row in weatherRows:
            title = row.css('b::text').get()
            if title == 'Humidity':
                item['humidity'] = row.css('td::text').get()
            if title == 'Wind Speed':
                item['windspeed'] = row.css('td::text').get()
            if title == 'Barometer':
                item['barometer'] = row.css('td::text').get()
        yield item


class Solution:
    def isValid(self, s: str) -> bool:
        stack = []
        openbrackets = ('(', '[', '{')
        matches = ('()', '[]', '{}')

        for c in s:
            if c in openbrackets:
                stack.append(c)
            else:
                if len(stack) < 1 or stack[-1] + c not in matches:
                    return False

                stack.pop()

        return len(stack) == 0


#
# @lc app=leetcode.cn id=1254 lang=python3
#
# [1254] 统计封闭岛屿的数目
#
# https://leetcode-cn.com/problems/number-of-closed-islands/description/
#
# algorithms
# Medium (58.14%)
# Likes:    50
# Dislikes: 0
# Total Accepted:    8K
# Total Submissions: 13.8K
# Testcase Example:  '[[1,1,1,1,1,1,1,0],[1,0,0,0,0,1,1,0],[1,0,1,0,1,1,1,0],
# [1,0,0,0,0,1,0,1],[1,1,1,1,1,1,1,0]]'
#
# 有一个二维矩阵 grid ，每个位置要么是陆地（记号为 0 ）要么是水域（记号为 1 ）。
#
# 我们从一块陆地出发，每次可以往上下左右 4 个方向相邻区域走，能走到的所有陆地区域，我们将其称为一座「岛屿」。
#
# 如果一座岛屿 完全 由水域包围，即陆地边缘上下左右所有相邻区域都是水域，那么我们将其称为 「封闭岛屿」。
#
# 请返回封闭岛屿的数目。
#
#
#
# 示例 1：
#
#
#
# 输入：grid =
# [[1,1,1,1,1,1,1,0],[1,0,0,0,0,1,1,0],[1,0,1,0,1,1,1,0],[1,0,0,0,0,1,0,1],[1,1,1,1,1,1,1,0]]
# 输出：2
# 解释：
# 灰色区域的岛屿是封闭岛屿，因为这座岛屿完全被水域包围（即被 1 区域包围）。
#
# 示例 2：
#
#
#
# 输入：grid = [[0,0,1,0,0],[0,1,0,1,0],[0,1,1,1,0]]
# 输出：1
#
#
# 示例 3：
#
# 输入：grid = [[1,1,1,1,1,1,1],
# [1,0,0,0,0,0,1],
# [1,0,1,1,1,0,1],
# [1,0,1,0,1,0,1],
# [1,0,1,1,1,0,1],
# [1,0,0,0,0,0,1],
#             [1,1,1,1,1,1,1]]
# 输出：2
#
#
#
#
# 提示：
#
#
# 1 <= grid.length, grid[0].length <= 100
# 0 <= grid[i][j] <=1
#
#
#

from typing import List

# @lc code=start
class Solution:
    def closedIsland(self, grid: List[List[int]]) -> int:
        res = 0
        m, n = len(grid), len(grid[0])
        fl = [[False] * n for _ in range(m)]

        def bfs(pos: (int, int)):
            x, y = pos
            fl[x][y] = True
            bl = [pos]

            f = False
            while bl:
                x, y = bl.pop(0)
                for i, j in ((x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)):
                    if not f \
                       and (i == 0 or i == m - 1 or j == 0 or j == n - 1) \
                       and not grid[i][j]:
                        f = True
                    if i > 0 and i < m - 1 and j > 0 and j < n - 1 \
                       and not grid[i][j] and not fl[i][j]:
                        fl[i][j] = True
                        bl.append((i, j))

            if not f:
                nonlocal res
                res += 1

        for i in range(1, m - 1):
            for j in range(1, n - 1):
                if not grid[i][j] and not fl[i][j]:
                    bfs((i, j))
        return res

# @lc code=end

1254.统计封闭岛屿的数目.py


from contextlib import suppress
from functools import lru_cache
from getpass import getuser
import grp
from typing import List, Dict, Optional, Union, Any, Sequence, Set, Tuple
from inspect import iscoroutinefunction
import os
import re

import graphene
from jupyter_server.auth import Authorizer
from tornado import web
from traitlets.config.loader import LazyConfigValue

from cylc.uiserver.schema import UISMutations

class CylcAuthorizer(Authorizer):
    """Defines a safe default authorization policy for Jupyter Server.

    `Jupyter Server`_ provides an authorisation layer which gives full
    permissions to any user who has been granted permission to the Jupyter Hub
    ``access:servers`` scope
    (see :ref:`JupyterHub scopes reference <jupyterhub-scopes>`). This allows
    the execution of arbitrary code under another user account.

    To prevent this you must define an authorisation policy using
    :py:attr:`c.ServerApp.authorizer_class
    <jupyter_server.serverapp.ServerApp.authorizer_class>`.

    This class defines a policy which blocks all API calls to another user's
    server, apart from calls to Cylc interfaces explicitly defined in the
    :ref:`Cylc authorisation configuration <cylc.uiserver.user_authorization>`.

    This class is configured as the default authoriser for all Jupyter Server
    instances spawned via the ``cylc hubapp`` command. This is the default if
    you started `Jupyter Hub`_ using the ``cylc hub`` command. To see where
    this default is set, see this file for the appropriate release of
    cylc-uiserver:
    https://github.com/cylc/cylc-uiserver/blob/master/cylc/uiserver/jupyter_config.py

    If you are launching Jupyter Hub via another command (e.g. ``jupyterhub``)
    or are overriding :py:attr:`jupyterhub.app.JupyterHub.spawner_class`, then
    you will need to configure a safe authorisation policy e.g:

    .. code-block:: python

       from cylc.uiserver.authorise import CylcAuthorizer
       c.ServerApp.authorizer_class = CylcAuthorizer

    .. note::

       It is possible to provide read-only access to Jupyter Server extensions
       such as Jupyter Lab, however, this isn't advisable as Jupyter Lab does
       not apply file-system permissions to what another user is allowed to
       see.

       If you wish to grant users access to other user's Jupyter Lab servers,
       override this configuration with due care over what you choose to
       expose.

    """

    def is_authorized(self, handler, user, action, resource) -> bool:
        """Allow a user to access their own server.

        Note that Cylc uses its own authorization system (which is locked-down
        by default) and is not affected by this policy.
        """
        # the username of the user running this server
        # (used for authorzation purposes)
        me = getuser()

        if user.username == me:
            # give the user full permissions to their own server
            return True

        # block access to everyone else
        return False

def constant(func):
    """Decorator preventing reassignment"""

    def fset(self, value):
        raise TypeError

    def fget():
        return func()

    return property(fget, fset)

class Authorization:
    """Authorization Information Class
    One instance for the life of the UI Server. If authorization settings
    change they will need to re-start the UI Server.
    Authorization has access groups: `READ`, `CONTROL`, `ALL` - along with
    their negations, `!READ`, `!CONTROL` and `!ALL` which indicate removal of
    the permission groups.

    """

    # config literals
    DEFAULT = "default"
    LIMIT = "limit"
    GRP_IDENTIFIER = "group:"

    # Operations

    ##########################################################################
    #                               !WARNING!                                #
    #                                                                        #
    #   Beware of changing these permission groups. Users may be relying on  #
    #   these settings. Changes should be widely publicised to users.        #
    #                                                                        #
    #   If adding/removing operations, ensure documentation is updated.      #
    #                                                                        #
    ##########################################################################

    READ_OPERATION = "read"

    # Access group identifiers (used in config)

    READ = "READ"
    CONTROL = "CONTROL"
    ALL = "ALL"
    NOT_READ = "!READ"
    NOT_CONTROL = "!CONTROL"
    NOT_ALL = "!ALL"

    # Access Groups

    READ_OPS = {READ_OPERATION}
    ASYNC_OPS = {"query", "mutation"}
    READ_AUTH_OPS = {"query", "subscription"}

    @staticmethod
    @constant
    def ALL_OPS() -> List[str]:
        """ALL OPS constant, returns list of all mutations."""
        return get_list_of_mutations()

    @staticmethod
    @constant
    def CONTROL_OPS() -> List[str]:
        """CONTROL OPS constant, returns list of all control mutations."""
        return get_list_of_mutations(control=True)

    def __init__(self, owner, owner_auth_conf, site_auth_conf, log) -> None:
        self.owner = owner
        self.log = log
        self.owner_auth_conf = self.set_auth_conf(owner_auth_conf)
        self.site_auth_config = self.set_auth_conf(site_auth_conf)
        self.owner_user_info = {
            "user": self.owner,
            "user_groups": self._get_groups(self.owner),
        }
        self.owner_dict = self.build_owner_site_auth_conf()

        # lru_cache this method - see flake8-bugbear B019
        self.get_permitted_operations = lru_cache(maxsize=128)(
            self._get_permitted_operations
        )

    @staticmethod
    def expand_and_process_access_groups(permission_set: set) -> set:
        """Process a permission set.

        Takes a permission set, e.g. limits, defaults.
        Expands the access groups and removes negated operations.

        Args:
            permission_set: set of permissions

        Returns:
            permission_set: processed permission set.
        """
        for action_group, expansion in {
            Authorization.CONTROL: Authorization.CONTROL_OPS.fget(),
            Authorization.ALL: Authorization.ALL_OPS.fget(),
            Authorization.READ: Authorization.READ_OPS,
        }.items():
            if action_group in permission_set:
                permission_set.remove(action_group)
                permission_set.update(expansion)
        # Expand negated permissions
        for action_group, expansion in {
                Authorization.NOT_CONTROL: [
                    f"!{x}" for x in Authorization.CONTROL_OPS.fget()],
                Authorization.NOT_ALL: [
                    f"!{x}" for x in Authorization.ALL_OPS.fget()],
                Authorization.NOT_READ: [
                    f"!{x}" for x in Authorization.READ_OPS]}.items():
            if action_group in permission_set:
                permission_set.remove(action_group)
                permission_set.update(expansion)
        # Remove negated permissions
        remove = set()

        for perm in permission_set:
            if perm.startswith("!"):
                remove.add(perm.lstrip("!"))
                remove.add(perm)
        permission_set.difference_update(remove)
        permission_set.discard("")
        return permission_set

    @staticmethod
    def set_auth_conf(auth_conf: Union[LazyConfigValue, dict]) -> dict:
        """Resolve lazy config where empty

        Args:
            auth_conf: Authorization configuration from a jupyter_config.py

        Returns:
            Valid configuration dictionary
        """
        if isinstance(auth_conf, LazyConfigValue):
            return auth_conf.to_dict()
        return auth_conf

    def get_owner_site_limits_for_access_user(
        self, access_user: Dict[str, Union[str, Sequence[Any]]]
    ) -> Set:
        """Returns limits owner can give to given access_user

        Args:
            access_user: Dictionary containing info about access user and their
            membership of system groups.

        Returns:
            Set of limits that the uiserver owner is allowed to give away
            for given access user.
        """
        limits: Set[str] = set()
        if not self.owner_dict:
            return limits
        items_to_check = ["*", access_user["access_username"]]
        items_to_check.extend(access_user["access_user_groups"])
        for item in items_to_check:
            permission: Union[str, List] = ""
            default = ""
            with suppress(KeyError):
                default = self.owner_dict[item].get(Authorization.DEFAULT, "")
            with suppress(KeyError):
                permission = self.owner_dict[item].get(
                    Authorization.LIMIT, default)
            if permission == []:
                raise_auth_config_exception("site")
            if isinstance(permission, str):
                limits.add(permission)
            else:
                limits.update(permission)
        limits.discard("")
        return limits

    def get_access_user_permissions_from_owner_conf(
        self, access_user: Dict[str, Union[str, Sequence[Any]]]
    ) -> set:
        """
        Returns set of operations specific to access user from owner user conf.

        Args:
            access_user: Dictionary containing info about access user and their
            membership of system groups. Defaults to None.
        """
        items_to_check = ["*", access_user["access_username"]]
        items_to_check.extend(access_user["access_user_groups"])
        allowed_operations = set()
        for item in items_to_check:
            permission = self.owner_auth_conf.get(item, "")
            # Specifiying empty list equates to removing of all permissions.
            if permission == []:
                raise_auth_config_exception("user")
            if isinstance(permission, str):
                allowed_operations.add(permission)
            else:
                allowed_operations.update(permission)
        allowed_operations.discard("")
        return allowed_operations

    # lru_cached - see __init__()
    def _get_permitted_operations(self, access_user: str):
        """Return permitted operations for given access_user.

        Cached for efficiency.
        Checks:
        - site config to ensure owner is permitted to give away permissions
        - user config for authorised operations related to access_user and
          their groups
        - if user not in user config, then returns defaults from site config.

        Args:
            access_user: username to check for permitted operations

        Returns:
            Set of operations permitted by given access user for this UI Server
        """
        # For use in the ui, owner permissions (ALL operations) are set
        if access_user == self.owner:
            return set(Authorization.ALL_OPS.fget())
        # Otherwise process permissions for (non-uiserver owner) access_user

        access_user_dict = {
            "access_username": access_user,
            "access_user_groups": self._get_groups(access_user),
        }
        limits_owner_can_give = self.get_owner_site_limits_for_access_user(
            access_user=access_user_dict)
        user_conf_permitted_ops = (
            self.get_access_user_permissions_from_owner_conf(
                access_user=access_user_dict)
        )
        # If not explicit permissions for access user in owner conf then revert
        # to site defaults
        if len(user_conf_permitted_ops) == 0:
            user_conf_permitted_ops = (
                self.return_site_auth_defaults_for_access_user(
                    access_user=access_user_dict
                )
            )
        user_conf_permitted_ops = self.expand_and_process_access_groups(
            user_conf_permitted_ops
        )
        limits_owner_can_give = self.expand_and_process_access_groups(
            limits_owner_can_give
        )
        allowed_operations = limits_owner_can_give.intersection(
            user_conf_permitted_ops
        )
        self.log.info(
            f"User {access_user} authorized permissions: "
            f"{sorted(allowed_operations)}"
        )
        return allowed_operations

    def is_permitted(self, access_user: str, operation: str) -> bool:
        """Checks if user is permitted to action operation.

        Args:
            access_user: User attempting to action given operation.
            operation: operation name

        Returns:
            True if access_user permitted to action operation, otherwise,
            False.
        """
        if access_user == self.owner_user_info["user"]:
            return True
        # re.sub needed for snake/camel case
        if re.sub(
            r'(?<!^)(?=[A-Z])', '_', operation
        ).lower() in self.get_permitted_operations(access_user):
            self.log.info(f"{access_user}: authorized to {operation}")
            return True
        self.log.info(f"{access_user}: not authorized to {operation}")

        return False

    def build_owner_site_auth_conf(self):
        """Build UI Server owner permissions dictionary.
        Creates a reduced site auth dictionary for the ui-server owner.

        """
        owner_dict = {}
        items_to_check = ["*", self.owner_user_info["user"]]
        items_to_check.extend(self.owner_user_info["user_groups"])

        # dict containing user info applying to the current ui_server owner
        for uis_owner_conf, access_user_dict in self.site_auth_config.items():
            if uis_owner_conf in items_to_check:
                # acc_user = access_user
                for acc_user_conf, acc_user_perms in access_user_dict.items():
                    existing_user_conf = owner_dict.get(acc_user_conf)
                    if existing_user_conf:
                        # process limits and defaults and update dictionary
                        existing_default = existing_user_conf.get(
                            Authorization.DEFAULT, '')
                        existing_limit = existing_user_conf.get(
                            Authorization.LIMIT, existing_default)
                        new_default = acc_user_perms.get(
                            Authorization.DEFAULT, '')
                        new_limit = acc_user_perms.get(
                            Authorization.LIMIT, new_default)
                        set_defs = set()
                        for conf in [existing_default, new_default]:
                            if isinstance(conf, list):
                                set_defs.update(conf)
                            else:
                                set_defs.add(conf)
                        set_lims = set()
                        for conf in [existing_limit, new_limit]:
                            if isinstance(conf, list):
                                set_lims.update(conf)
                            else:
                                set_lims.add(conf)
                        # update and continue
                        owner_dict[
                            acc_user_conf][Authorization.LIMIT] = list(
                            set_lims)
                        owner_dict[
                            acc_user_conf][Authorization.DEFAULT] = list(
                            set_defs)
                        continue
                    owner_dict.update(access_user_dict)
        # Now we have a reduced site auth dictionary for the current owner
        return owner_dict

    def return_site_auth_defaults_for_access_user(
        self, access_user: Dict[str, Union[str, Sequence[Any]]]
    ) -> Set:
        """Return site authorization defaults for given access user.
        Args:
            access_user: access_user dictionary, in the form
                        {'access_username': username
                         'access_user_group: [group1, group2,...]'
                        }
        Returns:
            Set of default operations permitted

        """
        defaults: Set[str] = set()
        if not self.owner_dict:
            return defaults
        items_to_check = ["*", access_user["access_username"]]
        items_to_check.extend(access_user["access_user_groups"])
        for item in items_to_check:
            permission: Union[str, List] = ""
            with suppress(KeyError):
                permission = self.owner_dict[item].get(
                    Authorization.DEFAULT, ""
                )
            if permission == []:
                raise_auth_config_exception("site")
            if isinstance(permission, str):
                defaults.add(permission)
            else:
                defaults.update(permission)
        defaults.discard("")
        return defaults

    def _get_groups(self, user: str) -> List:
        """Allows get groups to use self.logger if something goes wrong.

        Added to provide a single interface for get_groups to this class, to
        avoid having to pass the logger to get_groups (and methods it calls).
        """
        good_groups, bad_groups = get_groups(user)
        if bad_groups:
            self.log.warning(
                f'{user} has the following invalid groups in their profile '
                f'{bad_groups} - these groups will be ignored.'
            )
        return good_groups

# GraphQL middleware
class AuthorizationMiddleware:
    """Authorization Middleware for authorization checking GraphQL.

    Mutations are checked against permissions from config files.

    Raises:
        web.HTTPError: Unauthorized requests.
    """

    auth = None

    def resolve(self, next_, root, info, **args):
        current_user = info.context["current_user"]
        # We won't be re-checking auth for return variables
        if len(info.path) > 1:
            return next_(root, info, **args)
        op_name = self.get_op_name(info.field_name, info.operation.operation)
        # It shouldn't get here but worth checking for zero trust
        if not op_name:
            self.auth_failed(
                current_user, op_name, http_code=400,
                msg="Operation not in schema."
            )
        try:
            authorised = self.auth.is_permitted(current_user, op_name)
        except Exception:
            # Fail secure
            authorised = False
        if not authorised:
            self.auth_failed(current_user, op_name, http_code=403)
        if (info.operation.operation in Authorization.ASYNC_OPS
                or iscoroutinefunction(next_)):
            return self.async_resolve(next_, root, info, **args)
        return next_(root, info, **args)

    def auth_failed(self, current_user: str, op_name: str,
                    http_code: int, message: Optional[str] = None):
        """
        Raise authorization error
        Args:
            current_user: username accessing operation
            op_name: operation name
            http_code: http error code to raise
            message: Message to log Defaults to None.

        Raises:
            web.HTTPError
        """
        log_message = (f"Authorization failed for {current_user}"
                       f":requested to {op_name}.")
        if message:
            log_message = log_message + " " + message
        raise web.HTTPError(http_code, reason=message)

    def get_op_name(self, field_name: str, operation: str) -> Optional[str]:
        """
        Returns operation name required for authorization.
        Converts queries and subscriptions to read operations.
        Args:
            field_name: Field name e.g. play
            operation: operation type

        Returns:
            operation name
        """
        if operation in Authorization.READ_AUTH_OPS:
            return Authorization.READ_OPERATION
        else:
            # Check it is a mutation in our schema
            if self.auth and re.sub(
                r'(?<!^)(?=[A-Z])', '_', field_name
            ).lower() in Authorization.ALL_OPS.fget():
                return field_name
        return None

    async def async_resolve(self, next_, root, info, **args):
        """Return awaited coroutine"""
        return await next_(root, info, **args)

def get_groups(username: str) -> Tuple[List[str], List[str]]:
    """Return list of system groups for given user.

    Uses ``os.getgrouplist`` and ``os.NGROUPS_MAX`` to get system groups for a
    given user. ``grp.getgrgid`` then parses these to return a list of group
    names.

    Args:
        username: username used to check system groups.

    Returns:
        list: system groups for username given
    """
    groupmax = os.NGROUPS_MAX  # type: ignore
    group_ids = os.getgrouplist(username, groupmax)
    group_ids.remove(groupmax)
    # turn list of group_ids into group names with group identifier prepended
    return parse_group_ids(group_ids)

def parse_group_ids(group_ids: List) -> Tuple[List[str], List[str]]:
    """Returns list of groups in the correct format for authorisation.

    Args:
        group_ids: List of users groups, in number format

    Returns:
        List: List of users groups, in id format with group identifier
        prepended.
    """
    group_list = []
    bad_group_list = []
    for x in group_ids:
        try:
            group_list.append(
                f"{Authorization.GRP_IDENTIFIER}{grp.getgrgid(x).gr_name}"
            )
        except OverflowError:
            continue
        except KeyError:
            bad_group_list.append(x)
    return group_list, bad_group_list

def get_list_of_mutations(control: bool = False) -> List[str]:
    """Gets list of mutations"""
    list_of_mutations = [
        attr for attr in dir(UISMutations)
        if isinstance(getattr(UISMutations, attr), graphene.Field)
    ]
    if control:
        # Broadcast is an ALL mutation
        list_of_mutations.remove("broadcast")
    else:
        # 'read' is used soley for authorization and is not a UISMutation
        list_of_mutations.append(Authorization.READ_OPERATION)
    return list_of_mutations

def raise_auth_config_exception(config_type: str):
    """Error raise for empty list in auth config.

    Args:
        config_type: Either site or user.
    """
    raise Exception(
        f'Error in {config_type} config: '
        f'`c.CylcUIServer.{config_type}_authorization`. '
        f'"[]" is not supported. Use "{Authorization.NOT_ALL}" to remove all'
        ' permissions.'
    )


from __future__ import absolute_import
from __future__ import print_function

import abc
import functools
import sys
import typing

PY34 = sys.version_info[:2] > (3, 3)

class BaseDecorator(typing.Callable):
    """Base class for decorators.

    Implements wrapping and __call__, wrapper getter is abstract.

    Note:
        wrapper getter is called only on function call,
        if decorator used without braces.

    Usage example:

    >>> class TestDecorator(BaseDecorator):
    ...     def _get_function_wrapper(self, func):
    ...         print('Wrapping: {}'.format(func.__name__))
    ...         @functools.wraps(func)
    ...         def wrapper(*args, **kwargs):
    ...             print('call_function: {}'.format(func.__name__))
    ...             return func(*args, **kwargs)
    ...         return wrapper

    >>> @TestDecorator
    ... def func_no_init():
    ...     pass
    >>> func_no_init()
    Wrapping: func_no_init
    call_function: func_no_init
    >>> isinstance(func_no_init, TestDecorator)
    True
    >>> func_no_init._func is func_no_init.__wrapped__
    True

    >>> @TestDecorator()
    ... def func_init():
    ...     pass
    Wrapping: func_init
    >>> func_init()
    call_function: func_init
    >>> isinstance(func_init, TestDecorator)
    False
    """

    def __init__(self, func=None):
        """Decorator.

        :param func: function to wrap
        :type func: typing.Optional[typing.Callable]
        """
        # pylint: disable=assigning-non-slot
        self.__func = func
        if self.__func is not None:
            functools.update_wrapper(self, self.__func)
            if not PY34:  # pragma: no cover
                self.__wrapped__ = self.__func
        # pylint: enable=assigning-non-slot
        # noinspection PyArgumentList
        super(BaseDecorator, self).__init__()

    @property
    def _func(self):
        """Get wrapped function.

        :rtype: typing.Optional[typing.Callable]
        """
        return self.__func  # pragma: no cover

    @abc.abstractmethod
    def _get_function_wrapper(self, func):
        """Here should be constructed and returned real decorator.

        :param func: Wrapped function
        :type func: typing.Callable
        :rtype: typing.Callable
        """
        raise NotImplementedError()  # pragma: no cover

    def __call__(self, *args, **kwargs):
        """Main decorator getter."""
        args = list(args)
        wrapped = self.__func or args.pop(0)
        wrapper = self._get_function_wrapper(wrapped)
        if self.__func:
            return wrapper(*args, **kwargs)
        return wrapper

    def __repr__(self):
        """For debug purposes."""
        return "<{cls}({func!r}) at 0x{id:X}>".format(
            cls=self.__class__.__name__,
            func=self.__func,
            id=id(self)
        )  # pragma: no cover

# 8<----------------------------------------------------------------------------

if __name__ == '__main__':
    import doctest  # pragma: no cover
    doctest.testmod(verbose=2)  # pragma: no cover


from django.urls import path, include
from django.contrib import admin
from . import views

urlpatterns = [
    path('', views.home,name="home"),
    path('query_builder/ ', views.query_builder,name="query_builder"),
    path('api/', views.apiOverview, name="api_overview"),
    path('field_list/',views.FieldList,name="field_list"),
    path('test_db/',views.TestDb_view,name="test_db"),
    path('ukb_test/',views.OHE_Test2,name="ukb_test"),

]


from random import Random

class Person:
    def __init__(self, date_of_birth, date_of_death):
        self.birth = date_of_birth
        self.death = date_of_death

    def __str__(self):
        return f"Person({birth}, {death})"

if __name__ == '__main__':
    people = []
    rand = Random()
    for i in range(0, 10):
        birth = rand.randint(1900, 2000)
        death = 2000 if birth == 2000 else rand.randint(birth, 2000)
        person = Person(birth, death)
        people.append(person)
        print(person)

    birth_years = sorted(list(map(lambda x: x.birth, people)))
    death_years = sorted(list(map(lambda x: x.death, people)))
    print(birth_years)
    print(death_years)
    death_count = 0
    birth_count = 0

    max_alive = (1900, 0)

    number_of_alive = 0
    birth_year_index = 0
    death_years_index = 0

    while birth_year_index < len(people):
        if birth_years[birth_year_index] < death_years[death_years_index]:
            number_of_alive += 1
            if number_of_alive > max_alive[1]:
                max_alive = (birth_years[birth_year_index], number_of_alive)
            birth_year_index += 1
        else:
            number_of_alive -= 1
            death_years_index += 1

    print(max_alive)


#
# @lc app=leetcode id=77 lang=python3
#
# [77] Combinations
#

# @lc code=start
class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        # sample = [i for i in range(1, n+1)]
        # result = []
        # def helper(sample, temp):
        #     if len(temp) == k:
        #         result.append(temp[:])
        #     elif len(temp) <= k:
        #         for i in range(len(sample)):
        #             temp.append(sample[i])
        #             helper(sample[i+1:],temp)
        #             temp.pop()
        # helper(sample, [])
        # return result
        sample = [i for i in range(1, n+1)]
        result = []
        def helper(sample, temp):
            if len(temp) == k:
                result.append(temp[:])
            for i in range(len(sample)):
                temp.append(sample[i])
                helper(sample[i+1:], temp)
                temp.remove(sample[i])
        helper(sample, [])
        return result

# @lc code=end


#!/usr/bin/env python3

import argparse
import logging
import os
import re
import socket
import subprocess
import sys

from abc import ABC, abstractmethod
from pathlib import Path
from typing import Dict, Optional, List, Tuple

import requests
import yaml

DEFAULT_VG_NAME = "libvirt"
DEFAULT_VOL_SIZE_G = 20
KNOWN_DATACENTERS = ["dd", "ez", "pt", "rs"]

subcommands = {
    "sync": "sync",
    "create": "create"
}

def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="manage libvirt lvm volumes")
    group = parser.add_mutually_exclusive_group()
    group.add_argument("--force-recreate", "-f", type=bool, default=False, action=argparse.BooleanOptionalAction, help="Delete and re-create existing volumes")
    group.add_argument("--interactive", "-i", type=bool, default=None, action=argparse.BooleanOptionalAction, help="Interactively prompt for confirmation")
    parser.add_argument("--dry-run", "-n", type=bool, default=None, action=argparse.BooleanOptionalAction, help="Delete and re-create existing volumes")

    subparsers = parser.add_subparsers(title='Subcommands', dest='subcommand')
    sync = subparsers.add_parser(subcommands["sync"], help='Read information from hosts file and (re-)create volumes')
    sync.add_argument("--hosts-file", type=str, required=True, help="File or http link to hosts definition file")
    sync.add_argument("--base-image-dir", "-b", required=True, type=str, default=None, help="Dir containing base images")
    sync.add_argument("--vm-host", type=str, default=None, help="The host name of the host the VMs should be scheduled. Usually this is auto detected.")

    cmd_create_volume = subparsers.add_parser(subcommands["create"], help='Create a new volume on-the-fly')
    cmd_create_volume.add_argument("--vg-name", "-v", type=str, default=None, help="Name of the volume group")
    cmd_create_volume.add_argument("--vol-size", "-s", type=int, default=None, help="Size of the volume in GiB")
    cmd_create_volume.add_argument("--vol-name", "-n", required=True, type=str, default=None, help="Name of the volume")
    cmd_create_volume.add_argument("--base-image", "-b", required=True, type=str, default=None, help="Base image to use")
    cmd_create_volume.add_argument("--domain-name", "-d", type=str, default=None, help="Name of the domain (virtual machine)")

    # Parse the command-line arguments
    args = parser.parse_args()

    if args.subcommand not in subcommands.values():
        parser.print_help()
        print()
        print(f"No subcommand given, expected one of {subcommands.values()}")
        sys.exit(1)

    if args.subcommand == subcommands["create"]:
        # Assign the parsed values to the variables
        if not args.vg_name:
            args.vg_name = DEFAULT_VG_NAME

        if not args.domain_name:
            args.domain_name = args.vol_name

        if not args.vol_size:
            args.vol_size = DEFAULT_VOL_SIZE_G

    return args

# Is used when a choice is to be made, for example when a volume needs to be recreated
class UserInteraction(ABC):  # pylint: disable=too-few-public-methods
    def proceed(self) -> bool:
        pass

# Always answer with a preconfigured answer.
class NonInteractive(UserInteraction):  # pylint: disable=too-few-public-methods
    def __init__(self, proceed: bool):
        self._proceed = proceed

    def proceed(self) -> bool:
        return self._proceed

# Let the user interactively decide.
class Interactive(UserInteraction):  # pylint: disable=too-few-public-methods
    def proceed(self) -> bool:
        while True:
            user_input = input("Do you want to proceed (y/n): ").strip().lower()
            if user_input in ['y', 'yes']:
                return True
            if user_input in ['n', 'no']:
                return False
            print("Invalid input. Please enter 'y' or 'n'.")

class Calls(ABC):
    @abstractmethod
    def vg_exists(self, vg_name: str) -> bool:
        pass

    @abstractmethod
    def volume_exists(self, vg_name: str, vol_name: str) -> bool:
        pass

    @abstractmethod
    def create_volume(self, vg_name: str, vol_name: str, base_image: Path, vol_size: int) -> None:
        pass

    @abstractmethod
    def remove_volume(self, vg_name: str, volume_name: str):
        pass

    @abstractmethod
    def is_domain_running(self, vm_name: str) -> bool:
        return False

    @abstractmethod
    def shutdown_domain(self, domain_name: str):
        pass

    @abstractmethod
    def start_domain(self, domain_name):
        pass

class NoopCalls(Calls):
    def vg_exists(self, vg_name: str) -> bool:
        return True

    def volume_exists(self, vg_name: str, vol_name: str) -> bool:
        return False

    def create_volume(self, vg_name: str, vol_name: str, base_image: Path, vol_size: int) -> None:
        print(f"create volume for {vg_name}/{vol_name} using {base_image} ({vol_size}GiB)")

    def remove_volume(self, vg_name: str, volume_name: str):
        print(f"remove volume for {vg_name}/{volume_name}")

    def shutdown_domain(self, domain_name: str):
        print(f"shutdown domain {domain_name}")

    def start_domain(self, domain_name):
        print(f"start domain {domain_name}")

    def is_domain_running(self, vm_name: str) -> bool:
        return False

class NativeBinaries(Calls):
    def vg_exists(self, vg_name: str) -> bool:
        try:
            subprocess.run(["lvdisplay", "-C", "--select", f"vg_name={vg_name}"], capture_output=True, check=True)
            return True
        except subprocess.CalledProcessError:
            return False

    def volume_exists(self, vg_name: str, vol_name: str) -> bool:
        if not self.vg_exists(vg_name):
            return False

        result = subprocess.run(["lvdisplay", "-C", "--select", f"vg_name={vg_name}"], capture_output=True, text=True, check=True)
        output = result.stdout
        existing_vms = [line.split()[0] for line in output.splitlines()[1:]]
        return vol_name in existing_vms

    def create_volume(self, vg_name: str, vol_name: str, base_image: Path, vol_size: int = None):
        if not vol_size:
            vol_size = DEFAULT_VOL_SIZE_G

        subprocess.run(["lvcreate", "-L", f"{vol_size}G", "-n", vol_name, vg_name], check=True)
        dst = f"/dev/mapper/{vg_name}-{vol_name}"
        subprocess.run(["qemu-img", "convert", base_image, "-O", "raw", dst], check=True)
        #subprocess.run(["lvresize", "-L", f"{vol_size}G", f"{vg_name}/{vol_name}"], check=True)

    def remove_volume(self, vg_name: str, volume_name: str):
        lv_name = f"{vg_name}/{volume_name}"
        command = ["lvremove", "-f", lv_name]
        subprocess.run(command, check=True)

    def is_domain_running(self, vm_name: str) -> bool:
        try:
            result = subprocess.run(['virsh', 'list', '--name'], capture_output=True, text=True, check=True)
            output = result.stdout
            return vm_name in output.splitlines()
        except subprocess.CalledProcessError as err:
            logging.error("Error talking to libvirt: %s", err)
            return False

    def shutdown_domain(self, domain_name: str):
        # todo: check if actually running and add error handling
        command = ["virsh", "destroy", domain_name]
        subprocess.run(command, check=True)

    def start_domain(self, domain_name: str):
        command = ["virsh", "start", domain_name]
        subprocess.run(command, check=True)

def find_baseimage(base_dir: str, file_name: str) -> Optional[str]:
    matching_files = []

    file_name = file_name.lower()

    for root, _, files in os.walk(base_dir):
        for file in files:
            if file_name in str(file).lower():
                matching_files.append(os.path.join(root, file))

    return _filter_images(matching_files)

def _filter_images(matching_files: List[str]) -> Optional[str]:
    if not matching_files:
        return None

    sorted_files = sorted(matching_files, key=_extract_date_from_filename, reverse=True)
    return sorted_files[0]

def _extract_date_from_filename(filename: str) -> str:
    pattern = r'\d{8}'
    match = re.search(pattern, filename)
    if match:
        return match.group(0)
    return ""

def _hostname_without_domain(hostname: str) -> str:
    parts = hostname.split('.')
    if len(parts) > 1:
        return parts[0]
    return hostname

def iterate_vms(datacenter: str, vm_host: str, hosts_data: Dict[str, any], args: argparse.Namespace, impl: Calls, prompt: UserInteraction) -> None:
    if datacenter not in hosts_data['local_hosts']:
        return

    simple_hostname = _hostname_without_domain(vm_host)
    for host in hosts_data["local_hosts"][datacenter]:
        if "vm_config" not in host or host["vm_config"]["host"] not in [simple_hostname, vm_host]:
            continue

        wanted_os = host["vm_config"]["os"]
        base_image = find_baseimage(args.base_image_dir, wanted_os)
        if not base_image:
            logging.error("could not find any images for '%s' in dir '%s'", wanted_os, args.base_image_dir)
            continue

        block_devices = host["vm_config"]["block_devices"]
        if not block_devices:
            logging.error("no block devices configured, skipping")
            continue

        vg_name, vol_name = find_lvm_info(block_devices)
        if not vg_name or not vol_name:
            logging.error("no vg_name / vol_name found, skipping")
            continue

        vm_name = host["host"]
        disk_size = host["vm_config"]["disk_size_b"] / (1024 ** 3)

        create_volume(vg_name=vg_name, vol_name=vol_name, base_image=base_image, vol_size=disk_size, domain_name=vm_name, force_recreate=args.force_recreate, impl=impl, prompt=prompt)

def _detect_datacenter(hostname: str) -> Optional[str]:
    pattern = r'\.([^.\s]+)\.[^.]+\.[^.]+$'
    match = re.search(pattern, hostname)

    if match and  match.group(1) in KNOWN_DATACENTERS:
        return match.group(1)

    return None

def _get_hosts_data(hosts_file: str) -> Dict[str, any]:
    if hosts_file.startswith("http://") or hosts_file.startswith("https://"):
        data = requests.get(hosts_file, timeout=5)
        return yaml.safe_load(data)

    with open(hosts_file, 'r', encoding="utf8") as file:
        return yaml.safe_load(file)

def find_lvm_info(block_devices: List[str]) -> Optional[Tuple[str, str]]:
    for device in block_devices:
        if is_dm_device(device):
            return _parse_volgroup_volname(device)
    return None

def is_dm_device(name: str) -> bool:
    pattern = r'^/dev/mapper/[a-zA-Z0-9_-]+-[a-zA-Z0-9_-]+$'
    return bool(re.match(pattern, name))

def _parse_volgroup_volname(name: str) -> Tuple[str, str]:
    if not name.startswith("/dev/mapper/"):
        raise ValueError(f"{name} is not a valid dm device")

    parts = name.replace("/dev/mapper/", "", 1).split('-')
    if len(parts) != 2:
        raise ValueError(f"{name} is not a valid dm device")

    return parts[0], parts[1]

def create_volume(vg_name: str, vol_name: str, base_image: str, impl: Calls, vol_size: int = None, prompt = UserInteraction, domain_name: str = None, force_recreate: bool = False):
    if not domain_name:
        domain_name = vol_name

    if not vol_size:
        vol_size = DEFAULT_VOL_SIZE_G

    logging.info("Creating volume for %s/%s", vg_name, vol_name)
    if impl.volume_exists(vg_name=vg_name, vol_name=vol_name):
        logging.warning("volume '%s' already exists", vol_name)
        if not prompt.proceed() and not force_recreate:
            logging.error("Not forcing re-creation of volume, exiting.")
            return

        power_cycle_domain = impl.is_domain_running(domain_name)
        if power_cycle_domain:
            impl.shutdown_domain(domain_name)

        impl.remove_volume(vg_name=vg_name, volume_name=vol_name)

        if power_cycle_domain:
            impl.start_domain(domain_name)

    try:
        impl.create_volume(vg_name=vg_name, vol_name=vol_name, base_image=base_image, vol_size=vol_size)
    except subprocess.CalledProcessError as err:
        logging.error("creating volume failed: %s", err)

def main():
    logging.basicConfig(format='%(levelname)-8s %(message)s')
    logging.getLogger().setLevel(logging.INFO)
    args = parse_args()

    impl = NoopCalls() if args.dry_run else NativeBinaries()
    prompt = Interactive() if args.force_recreate is None else NonInteractive(proceed=args.force_recreate)

    if args.subcommand == subcommands["sync"]:
        vm_host = args.vm_host if args.vm_host else socket.gethostname()
        datacenter = _detect_datacenter(vm_host)
        if not datacenter:
            logging.error("could not detect datacenter from hostname %s", vm_host)
            sys.exit(1)
        else:
            logging.info("Detected datacenter '%s' from hostname '%s'", datacenter, vm_host)

        hosts_data = _get_hosts_data(args.hosts_file)
        logging.info("Loaded hosts_data with %d entries for dc %s", len(hosts_data["local_hosts"][datacenter]), datacenter)
        iterate_vms(datacenter=datacenter, vm_host=vm_host, hosts_data=hosts_data, args=args, impl=impl, prompt=prompt)
    elif args.subcommand == subcommands["create"]:
        if not impl.vg_exists(args.vg_name):
            logging.error("volume group '%s' does not exist", args.vg_name)
            sys.exit(1)
        base_image = Path(args.base_image)
        if not base_image.is_file() or not base_image.exists():
            raise ValueError(f"base image '{base_image}' must be a file and must exist")

        create_volume(vg_name=args.vg_name, vol_name=args.vol_name, base_image=args.base_image, impl=impl, prompt=prompt, vol_size=args.vol_size, domain_name=args.domain_name, force_recreate=args.force_recreate)

if __name__ == "__main__":
    main()


import httplib2
from bs4 import BeautifulSoup
from argparse import ArgumentParser

http = httplib2.Http()

def copy_content(uri, out):
    status, response = http.request(uri, "GET")
    soup = BeautifulSoup(response, 'html.parser')
    with open(out, 'a') as fp:
        fp.write(soup.prettify())

def find_links(uri, out):
    status, response = http.request(uri, "GET")
    soup = BeautifulSoup(response, 'html.parser')
    with open(out, 'a') as fp:
        for link in soup.find_all('a', href=True):
            fp.write(link['href'] + '\n')

def find_img(uri, out):
    status, response = http.request(uri, "GET")
    soup = BeautifulSoup(response, 'html.parser')
    with open(out, 'a') as fp:
        for img in soup.find_all('img'):
            fp.write(img['src'] + '\n')

parser = ArgumentParser()
subparser = parser.add_subparsers(required=True)

parser_html = subparser.add_parser('html', help="Writes the html document into result.html")
parser_html.add_argument('-l', type=str, dest="url", help="Specify the link")
parser_html.add_argument('-o', type=str, dest="output_file", help="Name of the output file")
parser_html.set_defaults(func=copy_content)

parser_links = subparser.add_parser('links', help="Extracts links from the documents and writes them into result.txt")
parser_links.add_argument('-l', type=str, dest="url", help="Specify the link")
parser_links.add_argument('-o', type=str, dest="output_file", help="Name of the output file")
parser_links.set_defaults(func=find_links)

parser_images = subparser.add_parser('images', help="Extracts links from the documents and writes them into result.txt")
parser_images.add_argument('-l', type=str, dest="url", help="Specify the link")
parser_images.add_argument('-o', type=str, dest="output_file", help="Name of the output file")
parser_images.set_defaults(func=find_img)

if __name__ == '__main__':
    args = parser.parse_args()
    args.func(args.url, args.output_file)


import subprocess
import pathlib
import tempfile

from . import misc

def create_config(configpath, args):
    with open(configpath, "wt") as f:
        print("workdir: '" + str(args.workdir) + "'", file=f)
        print("metafile: '" + str(args.metafile) + "'", file=f)
        print("coverages: '" + str(args.coverages) + "'", file=f)
        print("cov_dir: '" + str(args.cov_dir) + "'", file=f)
        print("bedfile: '" + str(args.bedfile) + "'", file=f)
        print("bamsfile: '" + str(args.bamsfile) + "'", file=f)
        print("reference: '" + str(args.reference) + "'", file=f)

def workflow_reassignment(args):
    args.bamsfile = (pathlib.Path(args.workdir) / "allbams.txt").absolute()
    args.cov_dir = (pathlib.Path(args.workdir) / "covs").absolute()
    args.bedfile = pathlib.Path(args.bedfile).absolute()
    args.coverages = pathlib.Path(args.coverages).absolute()
    args.metafile = pathlib.Path(args.metafile).absolute()
    args.reference = pathlib.Path(args.reference).absolute()

    misc.prepare_reassignment(args)

    configpath = (
        pathlib.Path(__file__).absolute().parent
        / pathlib.Path("workflow")
        / pathlib.Path("config_reassignment.yml")
    )
    configpath.parent.mkdir(parents=True, exist_ok=True)
    create_config(configpath, args)
    arguments = [
        "snakemake",
        "--snakefile",
        str(
            pathlib.Path(__file__).absolute().parent
            / pathlib.Path("workflow")
            / pathlib.Path("Snakefile_reassignment")
        ),
        "--configfile",
        str(configpath),
        "--cores",
        str(args.cores),
    ]
    if args.cluster_configfile:
        arguments.append("--cluster-config")
        arguments.append(args.cluster_configfile)
    if args.drmaa_mem and args.drmaa_time and args.drmaa_jobs:
        arguments.append("-p")
        arguments.append("--drmaa")
        workdir_full_path = str(pathlib.Path(args.workdir).absolute())

        drmaa_string = f" --mem={args.drmaa_mem} --time={args.drmaa_time} --output={workdir_full_path}/sge_log/%x-%j.log "
        arguments.append(drmaa_string)
        arguments.append("-j")
        arguments.append(str(args.drmaa_jobs))
    # How to create the dir the best way?
    subprocess.check_call(["mkdir", "-p", f"{args.workdir}sge_log"])
    subprocess.check_call(["mkdir", "-p", f"{args.workdir}covs"])

    subprocess.check_call(arguments)


from pymongo import MongoClient
from flask import Flask, render_template, jsonify, request

app = Flask(__name__)

client = MongoClient('mongodb://localhost:27017/')
db = client.dbsparta

@app.route('/')
def home():
    return render_template('index.html')

# 주문 정보 DB에 저장하기
@app.route('/order', methods=['POST'])
def write_order():
    # 주문 정보 변수 생성
    name = request.form['name']
    qty = request.form['qty']
    address = request.form['address']
    phone = request.form['phone']

    # db에 저장하기
    db.myshoporder.insert_one({
        'name': name,
        'qty': qty,
        'address': address,
        'phone': phone
    })

    return jsonify({'result': 'success'})

# 주문자 리스트 화면에 보여주기
@app.route('/order', methods=['GET'])
def read_order():
    orders = list(db.myshoporder.find({}, {'_id': False}))
    return jsonify({'result': 'success', 'orders': orders})

if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)


# coding=utf-8
import turtle
import random

t = turtle.screensize() #返回默认大小(400, 300)
t = turtle.screensize(800, 600, "green")

turtle.down() #落下画笔,进行绘制
turtle.up() #抬起画笔,不进行绘制
turtle.pensize(12) #绘制时的宽度
turtle.color('red') #绘制时的颜色
turtle.fillcolor('red') #绘制的填充颜色
turtle.fill(t)
turtle.fill(t)
degree = 22
speed = 10
turtle.forward(degree) #向前移动距离degree代表距离
turtle.backward(degree) #向后移动距离degree代表距离
turtle.right(degree) #向右移动多少度
turtle.left(degree) #向左移动多少度
turtle.goto(20,40) #将画笔移动到坐标为x,y的位置
turtle.stamp() #复制当前图形
turtle.speed(speed) #画笔绘制的速度范围[0,10]整数
turtle.clear() #清空turtle画的笔迹
turtle.reset() #清空窗口，重置turtle状态为起始状态
turtle.undo()#撤销上一个turtle动作
turtle.isvisible()#返回当前turtle是否可见
turtle.stamp() #复制当前图形
turtle.write('string') #写字符串'string'

turtle.circle(10) #画一个R为10的圆形
turtle.circle(30, 270) #圆弧为270度
turtle.circle(20, steps=3) #画一个R为20的圆内切多边形

# line = 50
# for x in range(25):
#     if x % 5 ==0:
#         line += 20
#     turtle.forward(line)
#     turtle.right(144)
# turtle.exitonclick()


"""

"""
from __future__ import division, print_function, absolute_import

import networkx as nx
import numpy as np

from numpy.testing import assert_equal, assert_array_less, assert_raises

import npmctree
from npmctree.cyfels import assert_csr_tree

def _check_csr_non_path_tree(G, root):
    # For this test require at least two nodes.
    assert_array_less(1, len(G))
    nodes = nx.topological_sort(G, [root])

def _graph_to_csr(G, nodes):
    m = nx.to_scipy_sparse_matrix(G, nodes)
    return m.indices, m.indptr

def test_csr_tree_path():

    # Make a directed path which is a kind of tree.
    G = nx.DiGraph()
    root = 'x'
    G.add_edges_from([('x', 'y'), ('y', 'z'), ('z', 'w')])

    # Check a directed path which is a kind of tree.
    nodes = nx.topological_sort(G, [root])
    indices, indptr = _graph_to_csr(G, nodes)
    assert_csr_tree(indices, indptr, len(G))

    # The reversed toposort order should not work.
    nodes = nx.topological_sort(G, [root], reverse=True)
    indices, indptr = _graph_to_csr(G, nodes)
    assert_raises(AssertionError, assert_csr_tree, indices, indptr, len(G))

def test_csr_tree_not_path():

    # Make a tree that branches.
    x, y, z, w = 'xyzw'
    root = 'x'
    G = nx.DiGraph()
    G.add_edges_from([(x, y), (x, z), (x, w)])

    # The toposort order should work.
    nodes = nx.topological_sort(G, [root])
    indices, indptr = _graph_to_csr(G, nodes)
    assert_csr_tree(indices, indptr, len(G))

    # The reversed toposort order should not work.
    nodes = nx.topological_sort(G, [root], reverse=True)
    indices, indptr = _graph_to_csr(G, nodes)
    assert_raises(AssertionError, assert_csr_tree, indices, indptr, len(G))

def test_csr_tree_disconnected():
    # This disconnected graph has the correct number of edges
    # relative to the number of nodes, but it is not a tree.
    x, y, z, u, v = 'xyzuv'
    root = 'x'
    G = nx.DiGraph()
    G.add_edges_from([(x, y), (y, z), (x, z), (u, v)])
    nodes = (x, y, z, u, v)
    indices, indptr = _graph_to_csr(G, nodes)
    assert_raises(AssertionError, assert_csr_tree, indices, indptr, len(G))


import tty
import sys
import termios
import matplotlib.pyplot as plt
from IPython import display

class Getch:
    def __init__(self):
        pass

    def __call__(self):

        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSAFLUSH, old_settings)
        return ch

getch = Getch()

plt.ion()

def plot_progress(scores, mean_scores):
    display.clear_output(wait=True)
    display.display(plt.gcf())
    plt.clf()
    plt.title('Training...')
    plt.xlabel('Number of Games')
    plt.ylabel('Score')
    plt.scatter([i for i in range(len(scores))], scores, c='r')
    plt.plot(mean_scores)
    plt.ylim(ymin=0)
    plt.text(len(scores)-1, scores[-1], str(scores[-1]))
    plt.text(len(mean_scores)-1, mean_scores[-1], str(mean_scores[-1]))
    plt.show(block=False)
    plt.pause(.1);


from .settings import *

DEBUG = True

#variable added here to permit any IP address computer to run this file
ALLOWED_HOSTS = []

# Crie a secret key para seu ambiente de desenvolvimento
SECRET_KEY = 'ixb62ha#ts=ab4t2u%p1_62-!5w2j==j6d^3-j$!z(@*m+-h'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3')}
}


from matplotlib import pyplot as plt
import numpy as np

class Records:
    def __init__(self, n_labels):
        #         self.train_losses = np.array([])
        #         self.holdout_losses = np.array([])
        #         self.test_accuracies = np.array([])

        self.train_losses = []
        self.holdout_losses = []
        self.test_accuracies = []
        self.test_confusion = np.zeros((n_labels, n_labels))

    def record(self, train_los, holdout_los, test_acc):

        #         np.append(self.train_losses, train_los)
        #         np.append(self.holdout_losses, holdout_los)
        #         np.append(self.test_accuracies, test_acc)

        self.train_losses.append(train_los)
        self.holdout_losses.append(holdout_los)
        self.test_accuracies.append(test_acc)

    # def plt_losses(self, n_components, lr, n_epoches, train=True, holdout=True):
    #     assert len(self.train_losses) == len(self.holdout_losses)
    #     plt.figure()
    #     if train:
    #         plt.errorbar(range(n_epoches), np.mean(self.train_losses, axis=0), yerr=np.std(self.train_losses, axis=0))
    #     if holdout:
    #         plt.errorbar(range(n_epoches), np.mean(self.holdout_losses, axis=0),
    #                      yerr=np.std(self.holdout_losses, axis=0))
    #     plt.title("n_components={}, learning_rates={}, n_epoches={}".format(n_components, lr, n_epoches))
    #     plt.show()
    def plt_losses(self, n_components, lr, n_epoches, std_idx, train=True, holdout=True):
        assert len(self.train_losses) == len(self.holdout_losses)
        images_dir = "../Report/Images/"
        plt.figure()
        mask = np.zeros(n_epoches)
        std_idx = [i - 1 for i in std_idx]
        mask[std_idx] = 1
        if train:
            train_yerror = np.std(self.train_losses, axis=0) * mask
            plt.errorbar(range(n_epoches), np.mean(self.train_losses, axis=0), yerr=train_yerror, label='train')
        if holdout:
            holdout_yerror = np.std(self.train_losses, axis=0) * mask
            plt.errorbar(range(n_epoches), np.mean(self.holdout_losses, axis=0), yerr=holdout_yerror,
                         label='holdout')
        plt.title("n_components={}, learning_rates={}, n_epoches={}".format(n_components, lr, n_epoches))
        plt.xlabel("Epoches")
        plt.ylabel("Cross Entropy Loss")
        plt.legend()
        #         plt.show()
        plt.savefig(images_dir + "{} losses, n_components={}, learning_rates={}, n_epoches={}.png".format(
            'softmax', n_components, lr, n_epoches),
                    bbox_inches='tight')

    def show_accuracies(self):
        print("The accuracy is {}".format(np.mean(self.test_accuracies)))

    def plt_confusion(self):
        plt.matshow(self.test_confusion)

    def print_confusion(self, classifier_type, n_components, lr, n_epoches, n_labels): #, confusion_matrix):
        print(
            "{} confusion, n_components={}, learning_rates={}, n_epoches={}".format(classifier_type, n_components,
                                                                                lr, n_epoches))
        emotion_dict = {"h": "happy", "ht": "happy with teeth", "m": "maudlin",
            "s": "surprise", "f": "fear", "a": "anger", "d": "disgust", "n": "neutral"}
        # expressions = ["disgust", "anger", "surprise","happy", "fear", "maudlin"]
        expressions = [emotion_dict[label] for label in n_labels]
        table_str = ""
        for i, line in enumerate(self.test_confusion):
            table_str += "\\hline\n" + expressions[i] + " & " + " & ".join([str(num) for num in line]) + "\\\\\n"
        return table_str


def sort(my_data):
    for i, _ in enumerate(my_data):
        min_el = i
        for j in range(i + 1, len(my_data)):
            if my_data[j] < my_data[min_el]:
                min_el = j
        my_data[i], my_data[min_el] = my_data[min_el], my_data[i]

import random
import time

if __name__ == "__main__":
    i = 10
    data = []
    while i < 100000000:
        for j in range(i):
            data.append(random.randint(1, 100000))
        start_time = time.time()
        sort(data)
        print(i, ": %s seconds ---" % (time.time() - start_time))
        i = i + 100
        data.clear()


import re
from django.forms import ModelForm, Textarea

from django import forms

from .models import Event, Meeting

class EventForm(ModelForm):
    # date = forms.DateTimeField(input_formats=['%d/%m/%Y %H:%M'])

    class Meta:
        model = Event

        fields = '__all__'

        widgets = {
            'description': Textarea(attrs={'rows': 15}),
        }

    def clean(self):
        cleaned_data = super(EventForm, self).clean()
        start = cleaned_data.get("start")
        stop = cleaned_data.get("stop")
        status = cleaned_data.get("status")
        content = cleaned_data.get("description")

        if start and stop:
            if stop < start:
                raise forms.ValidationError(
                    "La date de fin ne peut être avant la date de début"
                )

        if (not stop) and start:
            cleaned_data['stop'] = start

        if status == "r" and not start:
            raise forms.ValidationError(
                "Un événement prêt doit avoir une date de début"
            )

        expr = re.compile(r"!\[.+\]\(http:\/\/.+\)")
        matches = expr.findall(content)

        if len(matches) > 0:
            self.add_error(
                "description",
                f"La description de l'évènement contient des images en http non sécurisé ({' - '.join(matches)})"
            )

class MeetingForm(ModelForm):
    class Meta:
        model = Meeting
        fields = ('OJ', 'PV')


json = {
    "_id": "5eca0224bbf81beccba525d5",
    "index": 0,
    "guid": "7c53ffb4-5152-4e58-bfd7-49c7b00a92d2",
    "isActive": False,
    "balance": "$1,905.45",
    "picture": "http://placehold.it/32x32",
    "age": 23,
    "eyeColor": "blue",
    "name": "Mendez Love",
    "gender": "male",
    "company": "NIQUENT",
    "email": "mendezlove@niquent.com",
    "phone": "+1 (803) 421-3635",
    "address": "883 Garnet Street, Roy, Federated States Of Micronesia, 288",
    "about": "Magna do sunt id mollit non nulla est. Dolor ea occaecat minim veniam sit in Lorem excepteur et sint minim ea esse. Consequat incididunt tempor labore proident exercitation dolor quis Lorem. Veniam ipsum pariatur pariatur id officia.\r\n",
    "registered": "2015-07-21T07:09:56 -03:00",
    "latitude": -85.74001,
    "longitude": -36.020207,
    "tags": [
        "ipsum",
        "pariatur",
        "officia",
        "incididunt",
        "labore",
        "exercitation",
        "occaecat"
    ],
    "friends": [
        {
            "id": 0,
            "name": "Gardner Quinn"
        },
        {
            "id": 1,
            "name": "Antonia Mercer",
            "Waldo": "Я здесь!",
        },
        {
            "id": 2,
            "name": "Allie Sharp"
        }
    ],
    "greeting": "Hello, Mendez Love! You have 6 unread messages.",
    "asA": "banana"
}


# Read sysfs entry related to the discovery test code
# and display a circular counter (0-9) or enable LEDs

import sys
import time
from sense_hat import SenseHat

sense = SenseHat()

def read_discovery():
        # fp1 = open("/sys/soo/soolink/discovery/stream_count", "r")
        fp1 = open("/sys/soo/soolink/discovery/neighbours", "r")
        #value = [fp1.read(), fp2.read()]

        value = [fp1.read()]

        # fp2.close()
        fp1.close()
        return value

on = 1;

while True:
        if on == 1:
            sense.set_pixel(7, 7, (0, 0, 255))
            on = 0
        else:
            sense.set_pixel(7, 7, (0, 0, 0))
            on = 1

        val = read_discovery()
        # print("value " + val[0] + " neigh " + val[1])
        # count = int(val[0]) % 10

        # Display the number of successful downloads
        # sense.show_letter(str(count))

        # Display the number of neighbours
        for pix in range(0, 7):
            sense.set_pixel(0, pix, (0, 0, 0))

        for pix in range (0, int(val[0])):
            sense.set_pixel(0, pix, (0, 255, 0))

        time.sleep(1)


def diff(x, y, z):
    """Return whether one argument is the difference between the other two.

    x, y, and z are all integers.

    >>> diff(5, 3, 2) # 5 - 3 is 2
    True
    >>> diff(2, 3, 5) # 5 - 3 is 2
    True
    >>> diff(2, 5, 3) # 5 - 3 is 2
    True
    >>> diff(-2, 3, 5) # 3 - 5 is -2
    True
    >>> diff(-5, -3, -2) # -5 - -2 is -3
    True
    >>> diff(-2, 3, -5) # -2 - 3 is -5
    True
    >>> diff(2, 3, -5)
    False
    >>> diff(10, 6, 4)
    True
    >>> diff(10, 6, 3)
    False
    """
    if x - y == z:
    	return True
    elif y - x == z:
    	return True
    elif x - z == y:
    	return True
    elif z - x == y:
    	return True
    elif y - z == x:
    	return True
    elif z - y == x:
    	return True
    else:
    	return False

def abundant(n):
    """Print all ways of forming positive integer n by multiplying two positive
    integers together, ordered by the first term. Then, return whether the sum
    of the proper divisors of n is greater than n.

    A proper divisor of n evenly divides n but is less than n.

    >>> abundant(12) # 1 + 2 + 3 + 4 + 6 is 16, which is larger than 12
    1 * 12
    2 * 6
    3 * 4
    True
    >>> abundant(14) # 1 + 2 + 7 is 10, which is not larger than 14
    1 * 14
    2 * 7
    False
    >>> abundant(16)
    1 * 16
    2 * 8
    4 * 4
    False
    >>> abundant(20)
    1 * 20
    2 * 10
    4 * 5
    True
    >>> abundant(22)
    1 * 22
    2 * 11
    False
    >>> r = abundant(24)
    1 * 24
    2 * 12
    3 * 8
    4 * 6
    >>> r
    True
    """
    fac = [1]
    count = 0
    for i in range(2,n//2):
    	if n % i == 0:
    		for o in fac:
    			if i * o != n:
    				count += 1
    		if count == len(fac):
    			fac.append(i)
    			count = 0
    for i in range(len(fac)):
    	print(fac[i], '*', int(n / fac[i]))
    s = 0
    for i in range(1,n):
    	if n % i == 0:
    		s += i
    if s > n:
    	return True
    else:
    	return False

def sumdiv(n):
	sum = 1
	for i in range(2,n):
		if n % i == 0:
			sum += i
	return sum

def amicable(n):
    """Return the smallest amicable number greater than positive integer n.

    Every amicable number x has a buddy y different from x, such that
    the sum of the proper divisors of x equals y, and
    the sum of the proper divisors of y equals x.

    For example, 220 and 284 are both amicable because
    1 + 2 + 4 + 5 + 10 + 11 + 20 + 22 + 44 + 55 + 110 is 284, and
    1 + 2 + 4 + 71 + 142 is 220

    >>> amicable(5)
    220
    >>> amicable(220)
    284
    >>> amicable(284)
    1184
    >>> r = amicable(5000)
    >>> r
    5020
    """
    guess = n + 1
    a = False
    while a == False:
    	ami1 = int(sumdiv(sumdiv(guess)))
    	if ami1 == guess and sumdiv(guess) != guess:
    		return guess
    		a = True

    	else:
    		guess += 1


################################################################################
#      pyCosPath: A Python Library for Locating Optimal Reaction Pathways      #
#                 in Simulations with Chain-of-States Methods                  #
#                                                                              #
#                     Copyright (c) 2022 the Authors                           #
#                                                                              #
################################################################################
#                                                                              #
# Authors: Zilin Song                                                          #
# Contributors:                                                                #
#                                                                              #
################################################################################

import numpy
from typing import List, Tuple, Union

from pycospath.chain        import ChainBase
from pycospath.comms.twodim import Rep2D
from pycospath.utils        import rms

class Chain2D(ChainBase):
    """The chain of 2D replicas."""

    def __init__(self,
                 replicas: List[Rep2D]):
        """Create a chain of 2D replicas.

        Parameter
        ---------
        replicas: List[Rep2D]
            A list of 2D replica objects that makes up the chain.
        """
        ChainBase.__init__(self, replicas)

        # Fill the chain_vec with the rep_vec from each replica.
        chain_vec = numpy.zeros((self._n_reps, self._n_dofs))

        for i_rep in range(self._n_reps):
            if not isinstance(self._rep_list[i_rep], Rep2D):
                raise TypeError("Chain2D must be initialized with List[Rep2D].")

            rep: Rep2D = self._rep_list[i_rep]
            chain_vec[i_rep, :] = rep.get_rep_vec()

        self._chain_vec = chain_vec

    def get_wscale_vec(self) -> numpy.ndarray:
        """Get the copy of the weighting scaling vector (self._wscale_vec.copy()
        ) for the scaling of the rows of the chain vector (self._chain_vec)
        degrees-of-freedoms.

        Raises a NotImplementedError if called.
        """
        raise NotImplementedError("No weight-scaling in Chain2D objects.")

    def get_chain_vec(self) -> numpy.ndarray:
        """Get a copy of the chain vector (self._chain_vec.copy()).

        Returns
        -------
        chain_vec: numpy.ndarray of shape (n_reps, n_dofs)
            A copy of the chain vector (self._chain_vec.copy()).
        """
        return self._chain_vec.copy()

    def set_chain_vec(self,
                      chain_vec: numpy.ndarray
                      ) -> None:
        """Set the value of the chain vector (self._chain_vec) with a copy of
        chain_vec (chain_vec.copy()).

        Also update the replica vector (rep_vec) for all replica objects on this
        chain.

        Parameters
        ----------
        chain_vec: numpy.ndarray of shape (n_reps, n_dofs)
            The vector used to set the value of chain vector (self._chain_vec).
        """
        self._chain_vec = chain_vec.copy()

        # Also update the rep_vec for each Rep2D.
        c_vec_val = self._chain_vec.copy() # such that the mem alloc differs.

        for r in range(self._n_reps):
            self._rep_list[r].set_rep_vec(c_vec_val[r, :])

    def get_eners_grads(self) -> Tuple[numpy.ndarray, numpy.ndarray]:
        """Get the energies vector and the gradients vector of the chain vector
        (self._chain_vec).

        Returns
        -------
        (eners_vec, grads_vec): (numpy.ndarray of shape (n_reps, ),
                                 numpy.ndarray of shape (n_reps, n_dofs))
            eners_vec: The energies  vector of the chain vector;
            grads_vec: The gradients vector of the chain vector.
        """
        eners_vec = numpy.zeros(shape=(self._n_reps, ))
        grads_vec = numpy.zeros(shape=(self._n_reps, self._n_dofs))

        for r in range(self._n_reps):
            eners_vec[r], grads_vec[r, :] = self._rep_list[r].get_ener_grad()

        return eners_vec, grads_vec

    def get_rms(self,
                chain_vec: numpy.ndarray,
                return_grads: bool = False
                ) -> Union[numpy.ndarray, Tuple[numpy.ndarray, numpy.ndarray]]:
        """Computes the mass-weighted root-mean-square (RMS) distances b/w the
        adjacent rows of the chain vector (self._chain_Vec):
            ||r_{i} - r_{i+1}||_{2} ;
        and the gradients of RMS distances:
            ||r_{i} - r_{i+1}||_{2} w.r.t. r_{i}, if return_grads is true.

        Parameters
        ----------
        chain_vec: numpy.ndarray of shape (n_reps, n_dofs)
            The chain vector along which the RMS b/w adjacent replica vectors is
            to be computed.

        return_grads: bool
            If the gradients of RMS distances should also be returned.

        Returns
        -------
        rms: numpy.ndarray of shape (n_reps-1, )
            The RMS distances b/w adjacent rows of the chain vector.

        (rms, rms_grad): (numpy.ndarray of shape (n_reps-1, ),
                          numpy.ndarray of shape (n_reps-1, n_dofs))
            The RMS distances b/w adjacent rows of the chain vector and their
            gradients w.r.t. r_{i}. Returns only if return_grads = True.
        """
        wscale = numpy.ones((2, ))
        redund = 2      # 2 dof weights per 2D atom/replica.

        return rms(chain_vec, wscale, redund, return_grads)


# how to create
def func_name(name:str):
    """Document lines
    Describes the function behaviour, could be seen when run help
    """
    print ("Hello, "+name)
    print ("How are you?")
    answer = input ("Please enter fine / not fine: ")
    if answer=="fine":
        print("Glad to see you are fine, "+name)
    elif answer=="not fine":
       print( "Oh, I'm sorry")
    else:
        print("Sorry, I didn't get it")
name = input ("What's your name? ")
func_name(name)

#finction wih 2 parameters
def summa (x,y):
    print ("Summa:" + str(x+y))

summa (9,11)

#return
def diff (x,y):
    return x-y

print("Difference is: "+str(diff(10,3)))

#factorial function
def factor(n):
    """Calculate factor of n"""
    i=1
    result=1
    #while i<=n:
    while i in range (1,n+1):
        result = i*result
        i=i+1
    print("Factor of " + str(n)+" is "+ str(result))

factor (3)
factor (4)
factor (5)

#create dictionary in function
def create_user (name, phone, address):
    record = {
        'name':name,
        'phone':phone,
        'address':address
    }
    return record

user1 = create_user("User name 1", "+9712787868", "Dallas, TX")
user2 = create_user ("Iser name 2", "212134343", "Raleigh, NC")

print(user1)
print(user2)

def hello_sep (name = 'World', sep = '-'):
    print("Hello", name, sep=sep)
def hello (name='Karl'):
    print("Hello", name)
hello_sep()
hello_sep("John")
hello()


import math as mt
import random

class sudoku:
    def __init__(self, n, elems):
        self._n = n
        self._elems = elems
        # atributes for Search
        self._chmove = None
        self._posMoves = None
        self._tm = None
        self._parent = None

        # atributes for GA and HC
        self._zeropos = None  # the free positions, that will be the genes of chromosome for GA
        self._remNumbers = []
        self._fitness = None
        self._remNumbersPos = None

    def getFitness(self):
        return self._fitness

    def getChmove(self):
        return self._chmove

    #referinta
    def getPosMove(self):
        return self._posMoves

    def getThisMove(self):
        return self._tm

    #referinta
    def getZeroPos(self, remnum=False):
        if self._zeropos is None:
            self.blanksAndRemNumbers(False)
        return self._zeropos

    #referinta
    def getRemnumbers(self):
        return self._remNumbers

    #referinta
    def getElems(self):
        return self._elems

    def getNr(self):
        return self._n

    def setChmove(self, new):
        self._chmove = new

    # referinta
    def setPosMove(self, new):
        self._posMoves = new

    def setThisMove(self, new):
        self._tm = new

    # referinta
    def setZeroPos(self, new):
        self._zeropos = new

    # referinta
    def setRemnumbers(self, new):
        self._remNumbers = new

    # referinta
    def setElems(self, new):
        self._elems = new

    def setParrent(self, new):
        self._parent = new

    def copyElems(self):
        nelems = []
        for i in self._elems:
            nelems.append(i[:])
        return nelems

    # copy the sudoku and initialize the zeropos and remNumbers if they are not initialized
    def copy(self, randomize=False):
        # ret = sudoku(self._n, self.copyElems())
        ret = sudoku(self._n, self._elems)
        if self._zeropos is None or self._remNumbers is None:
            self.blanksAndRemNumbers(False)

        if self._remNumbersPos is None:
            self._remNumbersPos = []
            for zp in self._zeropos:
                self._remNumbersPos.append(self.posMove(zp[0], zp[1]))

        ret._zeropos = self._zeropos
        ret._remNumbers = self._remNumbers[:]
        ret._remNumbersPos = self._remNumbersPos

        if randomize:
            ret.randomizeGenes()

        return ret

    # cut point crossover
    def crossover(self, ot):
        p1 = random.randint(0, len(self._zeropos))
        off = sudoku(self._n, self._elems)
        off._zeropos = self._zeropos
        off._remNumbersPos = self._remNumbersPos
        off._remNumbers = []

        for i in range(len(self._zeropos)):
            if i <= p1:
                off._remNumbers.append(self._remNumbers[i])
            else:
                off._remNumbers.append(ot._remNumbers[i])

        return off

    # random gene crossover
    def crossover2(self, ot):
        off = sudoku(self._n, self._elems)
        off._zeropos = self._zeropos
        off._remNumbersPos = self._remNumbersPos
        off._remNumbers = []

        for i in range(len(self._zeropos)):
            if random.random() < 0.5:
                off._remNumbers.append(self._remNumbers[i])
            else:
                off._remNumbers.append(ot._remNumbers[i])

        return off

    # random initialization for population of genetical algorithm
    def randomizeGenes(self):
        self._remNumbers = [self._remNumbersPos[i][random.randint(0, len(self._remNumbersPos[i]) - 1)] for i in
                            range(len(self._zeropos))]
        # self._remNumbers = [random.randint(1, self._n) for i in range(len(self._zeropos))]

    # for GA and HC
    # mutation can modify the current chromosome(inplace) or return a modified copy
    def mutate(self, mutRate, inplace=True):
        if inplace:
            for i in range(len(self._zeropos)):
                if random.random() < mutRate:
                    self._remNumbers[i] = self._remNumbersPos[i][random.randint(0, len(self._remNumbersPos[i]) - 1)]
                    # self._remNumbers[i] = random.randint(1, self._n)
        else:
            ret = self.copy()
            for i in range(len(ret._zeropos)):
                if random.random() < mutRate:
                    ret._remNumbers[i] = self._remNumbersPos[i][random.randint(0, len(self._remNumbersPos[i]) - 1)]
                    # ret._remNumbers[i] = random.randint(1, self._n)
            return ret

    # the fitness is the numbers of wrong numbers
    def calcFitness(self):
        errors = 0
        self.placeNumbers()
        for i in range(len(self._zeropos)):
            aux = self._remNumbers[i]
            self._elems[self._zeropos[i][0]][self._zeropos[i][1]] = 0
            if not self._isValid(self._zeropos[i][0], self._zeropos[i][1], self._remNumbers[i]):
                errors += 1
            self._elems[self._zeropos[i][0]][self._zeropos[i][1]] = self._remNumbers[i]
        self._fitness = errors

    # place numbers in the empty places
    def placeNumbers(self):
        for i in range(len(self._remNumbers)):
            self._elems[self._zeropos[i][0]][self._zeropos[i][1]] = self._remNumbers[i]

    # calculate all posible numbers to put in one square
    def _isValid(self, line, col, elem):
        ssq = int(mt.sqrt(self._n))
        bigsql, bigsqc = line // ssq, col // ssq
        for i in range(self._n):
            if i != col and self._elems[line][i] == elem:
                return False
            if i != line and self._elems[i][col] == elem:
                return False
            l, c = (bigsql * ssq) + i // ssq, (bigsqc * ssq) + i % ssq
            if line != l and col != c and self._elems[l][c] == elem:
                return False
        return True

    #insertion sort (dubios) of frequency
    def _sortPosG(self,pos,fr):
        for i in range(1,len(pos)):
            p = i
            for j in range(i, 0, -1):
                if fr[pos[p]-1] < fr[pos[j]-1]:
                    aux = pos[p]
                    pos[p] = pos[j]
                    pos[j] = aux
                    p = j
        return pos

    # calculate all posible numbers to put in one square
    def posMove(self, line, col):
        ssq = int(mt.sqrt(self._n))
        pos = [x+1 for x in range(self._n)]
        bigsql, bigsqc = line // ssq, col // ssq
        for i in range(self._n):
            if i != col and self._elems[line][i] != 0:
                try:
                    pos.remove(self._elems[line][i])
                except Exception:
                    pass
            if i != line and self._elems[i][col] != 0:
                try:
                    pos.remove(self._elems[i][col])
                except Exception:
                    pass
            l, c = (bigsql*ssq)+i//ssq, (bigsqc*ssq)+i%ssq
            if line != l and col != c and self._elems[l][c] != 0:
                try:
                    pos.remove(self._elems[l][c])
                except Exception:
                    pass
        return pos

    # calculate all posible numbers to put in one square
    # and remove those moves that make others invalid
    def posValMoves(self, line, col):
        ssq = int(mt.sqrt(self._n))
        pos = self.posMove(line, col)
        bigsql, bigsqc = line // ssq, col // ssq
        if len(pos) == 1:
            return pos
        # frequency of other moves
        elems = [0 for i in range(self._n)]
        for i in pos:
            elems[i-1] += 1
        # calculate valid moves for all other position that conflicts with the curent one
        for i in range(self._n):
            if i >= 3 and i != col and self._elems[line][i] == 0:
                p = self.posMove(line, i)
                for elm in p:
                    elems[i-1] += 1
            if i >= 3 and i != line and self._elems[i][col] == 0:
                p = self.posMove(i, col)
                for elm in p:
                    elems[i-1] += 1
            l, c = (bigsql * ssq) + i // ssq, (bigsqc * ssq) + i % ssq
            if line != l and col != c and self._elems[l][c] == 0:
                p = self.posMove(l, c)
                for elm in p:
                    elems[i-1] += 1
        return self._sortPosG(pos, elems)

    # check if some numbers are in conflict
    def valid(self):
        for i in range(self._n):
            for j in range(self._n):
                if self._elems[i][j] != 0:

                    aux = self._elems[i][j]
                    self._elems[i][j] = 0
                    all = self.posMove(i, j)
                    try:
                        all.remove(aux)
                    except ValueError:
                        return i, j

                    self._elems[i][j] = aux
        return None

    # check if sudoku is finished
    def finished(self):
        if self._zeropos is not None:
            self.blanksAndRemNumbers(False)
        return len(self._zeropos) == 0

    # compute all blanks spaces and all remaining numbers
    # rem numbers is for GA and HC
    def blanksAndRemNumbers(self, remnr=True):
        if remnr:
            self._remNumbers = [i+1 for j in range(self._n) for i in range(self._n)]
        self._zeropos = []
        for i in range(self._n):
            for j in range(self._n):
                if self._elems[i][j] == 0:
                    self._zeropos.append((i, j))
                elif remnr:
                    self._remNumbers.remove(self._elems[i][j])

    # get first empty space
    def firstBlank(self):
        if self._zeropos is None:
            self.blanksAndRemNumbers(False)
        if len(self._zeropos) != 0:
            ret = self._zeropos[0]
            self._zeropos.remove(ret)
            return ret
        return None

    # get the empty space with fewest possible numbers to fill
    def getBestBlank(self):
        if self._zeropos is None:
            self.blanksAndRemNumbers(False)
        try:
            minp = self._zeropos[0]
        except IndexError:
            return None
        min = len(self.posMove(self._zeropos[0][0], self._zeropos[0][1]))
        for i in self._zeropos:
            current = len(self.posMove(i[0], i[1]))
            if current < min:
                minp = i
                min = current
            if min == 1:
                self._zeropos.remove(minp)
                return minp[0], minp[1]
        self._zeropos.remove(minp)
        return minp[0], minp[1]

    # get the children (complete the first blank with a number)
    def getChildren(self):
        if self._chmove is None:
            self._chmove = self.firstBlank()
        if self._chmove is None:
            return None
        if self._posMoves is None:
            self._posMoves = self.posMove(self._chmove[0],self._chmove[1])
        if len(self._posMoves) == 0:
            return None
        elem = self._posMoves[0]
        self._posMoves.remove(elem)
        self._elems[self._chmove[0]][self._chmove[1]] = elem
        sp = sudoku(self._n, self._elems)
        sp._tm = self._chmove
        sp._parent = self
        sp._zeropos = self._zeropos
        return sp

    # get the children for Greedy completion ( fill the blank with the fewest possible number of moves )
    def getChildrenGreedy(self):
        if self._chmove is None:
            self._chmove = self.getBestBlank()
        if self._chmove is None:
            return None
        if self._posMoves is None:
            self._posMoves = self.posValMoves(self._chmove[0], self._chmove[1])
        if len(self._posMoves) == 0:
            return None
        elem = self._posMoves[0]
        self._posMoves.remove(elem)
        self._elems[self._chmove[0]][self._chmove[1]] = elem
        sp = sudoku(self._n, self._elems)
        sp._tm = self._chmove
        sp._parent = self
        sp._zeropos = self._zeropos
        return sp

    # remove the last number added
    # None if no number added previously
    def getParent(self):
        if self._parent is not None:
            if self._tm is not None:
                self._zeropos.append((self._tm[0], self._tm[1]))
                self._elems[self._tm[0]][self._tm[1]] = 0
            self._parent._zeropos = self._zeropos
        return self._parent

    def __str__(self):
        stri = ""
        for i in range(self._n):
            stri += str(self._elems[i])+"\n"
        return stri


import theano
import theano.tensor as T
import numpy as np

epsilon=1e-16
dtype=theano.config.floatX

def euclidean_dist(X):
    """
    Compute squared distance map.

    Parameters
    ----------
    X : matrix
        A tensor matrix with dimension (number of samples, number of features)

    Return
    ------
    A tensor matrix for squared distance map.
    """
    N = X.shape[0]
    ss = (X ** 2).sum(axis=1)
    return ss.reshape((N, 1)) + ss.reshape((1, N)) - \
           2*X.dot(X.T)

def euclidean_dist2(X, X_new):
    """
    compute cross distance.

    returns
    -------
        square distance map with dim(X_new, X).
    """
    N0 = X_new.shape[0]
    N1 = X.shape[0]

    ss0 = (X_new ** 2).sum(axis=1)
    ss1 = (X ** 2).sum(axis=1)
    return ss0.reshape((N0, 1)) + ss1.reshape((1, N1)) - \
           2*X_new.dot(X.T)

def density_est(X_t, W_t, sigma, X_s):
    """
    Density estimator.

    Parameters
    ----------
    X_t : A tensor matrix
        sample features.
    W_t : A tensor vector
        sample weights.
    sigma : A tensor scalar
        standard deviation for gaussian kernel.
    X_s : A tensor matrix
        input sample features.

    Return
    ------
    density estimation at input sample points.
    """
    N0 = X_s.shape[0]
    N1 = X_t.shape[0]

    sqdist = euclidean_dist2(X_t, X_s)
    #k = T.exp(-sqdist/(2*sigma**2)) * (1./np.sqrt(2*sigma**2*np.pi)) * W_t.reshape((1, N1))
    # Prefactor of Gaussians will cancel
    k = T.exp(-sqdist/(2*sigma**2))* W_t.reshape((1, N1))
    return k.sum(axis=1) * (1./W_t.sum())

def transition_matrix(d_s, X_s, sigma):
    """
    Compute diffusion matrix.

    Parameters
    ----------
    d_s : A tensor vector
        density estimation at input points.
    X_s : A tensor matrix
        input sample features.
    sigma : A tensor scalar
        standard deviation for diffusion distance measure.

    Return
    ------
    diffusion matrix, row major.
    """
    N = d_s.shape[0]
    sqdist = euclidean_dist(X_s)
    dr_s = T.sqrt(d_s).reshape((1, N))
    #L = T.exp(-sqdist/(2*sigma**2)) * (1./np.sqrt(2*sigma**2*np.pi)) * (1./dr_s)
    #L = T.exp(-sqdist/(2*sigma**2)) * (1./np.sqrt(2*sigma**2*np.pi)) * dr_s
    # Prefactor of Gaussians will cancel
    L = T.exp(-sqdist/(2*sigma**2)) * dr_s

    row_sum = T.sum(L, axis=1).reshape((N,1))
    return L/row_sum

def transition_student_matrix(d_s, X_s):
    N = d_s.shape[0]
    sqdist = euclidean_dist(X_s)
    dr_s = T.sqrt(d_s).reshape((1, N))
    L = 1./np.pi * 1./(1. + sqdist) * (1./dr_s)  # student-t

    row_sum = T.sum(L, axis=1).reshape((N,1))
    return L/row_sum

def cost_var(X_t, Y_t, W_t, sigma_den, sigma_trans):
    """
    KL divergence estimator.

    Parameters
    ----------
    X_t : A tensor matrix
        high-dimension input features.
    Y_t : A tensor matrix
        low-dimension input features.
    W_t : A tensor vecotr
        sample weights.
    sigma_den : A tensor scalar
        standard deviation for density estimator.
    sigma_trans : A tensor scalar
        standard deviation for diffusion distance measure.

    Return
    ------
    cost value based on KL divergence.
    """

    DX = density_est(X_t, W_t, sigma_den, X_t)
    PX = transition_matrix(DX, X_t, sigma_trans)
    DY = density_est(Y_t, W_t, sigma_den, Y_t)
    PY = transition_matrix(DY, Y_t, sigma_trans)

    PXc = T.maximum(PX, epsilon)
    PYc = T.maximum(PY, epsilon)
    cost = T.sum(PX * T.log(PXc / PYc))/X_t.shape[0]
    cost_ref = T.sum(PX * T.log(PXc / PXc))/X_t.shape[0]
    return cost, cost_ref

def init_glorot(shape):
    """
    Weight initializor.
    """
    if len(shape) < 2:
        raise RuntimeError("shape should be at least 2D")

    n1, n2 = shape[:2]
    field_size = np.prod(shape[2:])
    std = np.sqrt(2.0 / ((n1 + n2) * field_size))
    return np.asarray(np.random.normal(size=shape, loc=0., scale=std),
                      dtype=dtype)

def init_constant(shape, value=0.):
    """
    Constant initializor.
    """
    return np.ones(shape=shape, dtype=dtype) * value

def tanh(x):
    """
    tanh function.
    """
    return theano.tensor.tanh(x)

def rectify(x):
    """
    Rectify Linear Unit.
    """
    return theano.tensor.nnet.relu(x)

def identity(x):
    """
    identity function.
    """
    return x

def dense_layer(X_t, w_shape, name, b_v=None, nonlinearity=tanh):
    """
    Dense Layer.

    Parameters
    ----------
    X_t : A tensor matrix.
        input tensor matrix.
    w_shape : 2 dim list.
        weight shape, (number of input units, number of output units).
    name : string.
        layer name, which is passed to tensor.
    b_v : float.
        bias initital value.
    nonlinearity : method
        non-linear activation function.

    Return
    ------
    A list of (output tensor, (weight tensor, bias tensor)).
    """
    if len(w_shape) != 2:
        raise RuntimeError("w_shape should be 2 dim")

    W_value = init_glorot(w_shape)
    W_s = theano.shared(W_value, name="%s:W"%name)

    if b_v is not None:
        b_value = init_constant(w_shape[1], b_v)
        b_s = theano.shared(b_value, name="%s:b"%name)
    else:
        b_s = None

    act = T.dot(X_t, W_s)
    if b_s is not None:
        act = act + b_s
    return nonlinearity(act), [W_s, b_s]