from typing import Any, Callable, Dict, List, Optional, Set, Union

import pyarrow as pa

from deltacat.storage import (
    Delta,
    DeltaLocator,
    DeltaType,
    DistributedDataset,
    LifecycleState,
    ListResult,
    LocalDataset,
    LocalTable,
    Manifest,
    ManifestAuthor,
    Namespace,
    Partition,
    SchemaConsistencyType,
    Stream,
    StreamLocator,
    Table,
    TableVersion,
    SortKey,
    PartitionLocator,
)
from deltacat.types.media import ContentType, StorageType, TableType
from deltacat.utils.common import ReadKwargsProvider

def list_namespaces(*args, **kwargs) -> ListResult[Namespace]:
    """
    Lists a page of table namespaces. Namespaces are returned as list result
    items.
    """
    raise NotImplementedError("list_namespaces not implemented")

def list_tables(namespace: str, *args, **kwargs) -> ListResult[Table]:
    """
    Lists a page of tables for the given table namespace. Tables are returned as
    list result items. Raises an error if the given namespace does not exist.
    """
    raise NotImplementedError("list_tables not implemented")

def list_table_versions(
    namespace: str, table_name: str, *args, **kwargs
) -> ListResult[TableVersion]:
    """
    Lists a page of table versions for the given table. Table versions are
    returned as list result items. Raises an error if the given table does not
    exist.
    """
    raise NotImplementedError("list_table_versions not implemented")

def list_partitions(
    namespace: str,
    table_name: str,
    table_version: Optional[str] = None,
    *args,
    **kwargs
) -> ListResult[Partition]:
    """
    Lists a page of partitions for the given table version. Partitions are
    returned as list result items. Table version resolves to the latest active
    table version if not specified. Raises an error if the table version does
    not exist.
    """
    raise NotImplementedError("list_partitions not implemented")

def list_stream_partitions(stream: Stream, *args, **kwargs) -> ListResult[Partition]:
    """
    Lists all partitions committed to the given stream.
    """
    raise NotImplementedError("list_stream_partitions not implemented")

def list_deltas(
    namespace: str,
    table_name: str,
    partition_values: Optional[List[Any]] = None,
    table_version: Optional[str] = None,
    first_stream_position: Optional[int] = None,
    last_stream_position: Optional[int] = None,
    ascending_order: Optional[bool] = None,
    include_manifest: bool = False,
    *args,
    **kwargs
) -> ListResult[Delta]:
    """
    Lists a page of deltas for the given table version and committed partition.
    Deltas are returned as list result items. Deltas returned can optionally be
    limited to inclusive first and last stream positions. Deltas are returned by
    descending stream position by default. Table version resolves to the latest
    active table version if not specified. Partition values should not be
    specified for unpartitioned tables. Raises an error if the given table
    version or partition does not exist.

    To conserve memory, the deltas returned do not include manifests by
    default. The manifests can either be optionally retrieved as part of this
    call or lazily loaded via subsequent calls to `get_delta_manifest`.
    """
    raise NotImplementedError("list_deltas not implemented")

def list_partition_deltas(
    partition_like: Union[Partition, PartitionLocator],
    first_stream_position: Optional[int] = None,
    last_stream_position: Optional[int] = None,
    ascending_order: bool = False,
    include_manifest: bool = False,
    *args,
    **kwargs
) -> ListResult[Delta]:
    """
    Lists a page of deltas committed to the given partition.

    To conserve memory, the deltas returned do not include manifests by
    default. The manifests can either be optionally retrieved as part of this
    call or lazily loaded via subsequent calls to `get_delta_manifest`.
    """
    raise NotImplementedError("list_partition_deltas not implemented")

def get_delta(
    namespace: str,
    table_name: str,
    stream_position: int,
    partition_values: Optional[List[Any]] = None,
    table_version: Optional[str] = None,
    include_manifest: bool = False,
    *args,
    **kwargs
) -> Optional[Delta]:
    """
    Gets the delta for the given table version, partition, and stream position.
    Table version resolves to the latest active table version if not specified.
    Partition values should not be specified for unpartitioned tables. Raises
    an error if the given table version or partition does not exist.

    To conserve memory, the delta returned does not include a manifest by
    default. The manifest can either be optionally retrieved as part of this
    call or lazily loaded via a subsequent call to `get_delta_manifest`.
    """
    raise NotImplementedError("get_delta not implemented")

def get_latest_delta(
    namespace: str,
    table_name: str,
    partition_values: Optional[List[Any]] = None,
    table_version: Optional[str] = None,
    include_manifest: bool = False,
    *args,
    **kwargs
) -> Optional[Delta]:
    """
    Gets the latest delta (i.e. the delta with the greatest stream position) for
    the given table version and partition. Table version resolves to the latest
    active table version if not specified. Partition values should not be
    specified for unpartitioned tables. Raises an error if the given table
    version or partition does not exist.

    To conserve memory, the delta returned does not include a manifest by
    default. The manifest can either be optionally retrieved as part of this
    call or lazily loaded via a subsequent call to `get_delta_manifest`.
    """
    raise NotImplementedError("get_latest_delta not implemented")

def download_delta(
    delta_like: Union[Delta, DeltaLocator],
    table_type: TableType = TableType.PYARROW,
    storage_type: StorageType = StorageType.DISTRIBUTED,
    max_parallelism: Optional[int] = None,
    columns: Optional[List[str]] = None,
    file_reader_kwargs_provider: Optional[ReadKwargsProvider] = None,
    ray_options_provider: Callable[[int, Any], Dict[str, Any]] = None,
    *args,
    **kwargs
) -> Union[LocalDataset, DistributedDataset]:
    """
    Download the given delta or delta locator into either a list of
    tables resident in the local node's memory, or into a dataset distributed
    across this Ray cluster's object store memory. Ordered table N of a local
    table list, or ordered block N of a distributed dataset, always contain
    the contents of ordered delta manifest entry N.
    """
    raise NotImplementedError("download_delta not implemented")

def download_delta_manifest_entry(
    delta_like: Union[Delta, DeltaLocator],
    entry_index: int,
    table_type: TableType = TableType.PYARROW,
    columns: Optional[List[str]] = None,
    file_reader_kwargs_provider: Optional[ReadKwargsProvider] = None,
    *args,
    **kwargs
) -> LocalTable:
    """
    Downloads a single manifest entry into the specified table type for the
    given delta or delta locator. If a delta is provided with a non-empty
    manifest, then the entry is downloaded from this manifest. Otherwise, the
    manifest is first retrieved then the given entry index downloaded.
    """
    raise NotImplementedError("download_delta_manifest_entry not implemented")

def get_delta_manifest(
    delta_like: Union[Delta, DeltaLocator], *args, **kwargs
) -> Manifest:
    """
    Get the manifest associated with the given delta or delta locator. This
    always retrieves the authoritative remote copy of the delta manifest, and
    never the local manifest defined for any input delta.
    """
    raise NotImplementedError("get_delta_manifest not implemented")

def create_namespace(
    namespace: str, permissions: Dict[str, Any], *args, **kwargs
) -> Namespace:
    """
    Creates a table namespace with the given name and permissions. Returns
    the created namespace.
    """
    raise NotImplementedError("create_namespace not implemented")

def update_namespace(
    namespace: str,
    permissions: Optional[Dict[str, Any]] = None,
    new_namespace: Optional[str] = None,
    *args,
    **kwargs
) -> None:
    """
    Updates a table namespace's name and/or permissions. Raises an error if the
    given namespace does not exist.
    """
    raise NotImplementedError("update_namespace not implemented")

def create_table_version(
    namespace: str,
    table_name: str,
    table_version: Optional[str] = None,
    schema: Optional[Union[pa.Schema, str, bytes]] = None,
    schema_consistency: Optional[Dict[str, SchemaConsistencyType]] = None,
    partition_keys: Optional[List[Dict[str, Any]]] = None,
    primary_key_column_names: Optional[Set[str]] = None,
    sort_keys: Optional[List[SortKey]] = None,
    table_version_description: Optional[str] = None,
    table_version_properties: Optional[Dict[str, str]] = None,
    table_permissions: Optional[Dict[str, Any]] = None,
    table_description: Optional[str] = None,
    table_properties: Optional[Dict[str, str]] = None,
    supported_content_types: Optional[List[ContentType]] = None,
    *args,
    **kwargs
) -> Stream:
    """
    Create a table version with an unreleased lifecycle state and an empty delta
    stream. Table versions may be schemaless and unpartitioned, or partitioned
    according to a list of partition key names and types. Note that partition
    keys are not required to exist in the table's schema, and can thus still be
    used with schemaless tables. This can be useful for creating logical shards
    of a delta stream where partition keys are known but not projected onto each
    row of the table (e.g. all rows of a customer orders table are known to
    correspond to a given order day, even if this column doesn't exist in the
    table). Primary and sort keys must exist within the table's schema.
    Permissions specified at the table level override any conflicting
    permissions specified at the table namespace level. Returns the stream
    for the created table version. Raises an error if the given namespace does
    not exist.

    Schemas are optional for DeltaCAT tables and can be used to inform the data
    consistency checks run for each field. If a schema is present, it can be
    used to enforce the following column-level data consistency policies at
    table load time:

    None: No consistency checks are run. May be mixed with the below two
    policies by specifying column names to pass through together with
    column names to coerce/validate.

    Coerce: Coerce fields to fit the schema whenever possible. An explicit
    subset of column names to coerce may optionally be specified.

    Validate: Raise an error for any fields that don't fit the schema. An
    explicit subset of column names to validate may optionally be specified.
    """
    raise NotImplementedError("create_table_version not implemented")

def update_table(
    namespace: str,
    table_name: str,
    permissions: Optional[Dict[str, Any]] = None,
    description: Optional[str] = None,
    properties: Optional[Dict[str, str]] = None,
    new_table_name: Optional[str] = None,
    *args,
    **kwargs
) -> None:
    """
    Update table metadata describing the table versions it contains. By default,
    a table's properties are empty, and its description and permissions are
    equal to those given when its first table version was created. Raises an
    error if the given table does not exist.
    """
    raise NotImplementedError("update_table not implemented")

def update_table_version(
    namespace: str,
    table_name: str,
    table_version: str,
    lifecycle_state: Optional[LifecycleState] = None,
    schema: Optional[Union[pa.Schema, str, bytes]] = None,
    schema_consistency: Optional[Dict[str, SchemaConsistencyType]] = None,
    description: Optional[str] = None,
    properties: Optional[Dict[str, str]] = None,
    *args,
    **kwargs
) -> None:
    """
    Update a table version. Notably, updating an unreleased table version's
    lifecycle state to 'active' telegraphs that it is ready for external
    consumption, and causes all calls made to consume/produce streams,
    partitions, or deltas from/to its parent table to automatically resolve to
    this table version by default (i.e. when the client does not explicitly
    specify a different table version). Raises an error if the given table
    version does not exist.
    """
    raise NotImplementedError("update_table_version not implemented")

def stage_stream(
    namespace: str,
    table_name: str,
    table_version: Optional[str] = None,
    *args,
    **kwargs
) -> Stream:
    """
    Stages a new delta stream for the given table version. Resolves to the
    latest active table version if no table version is given. Returns the
    staged stream. Raises an error if the table version does not exist.
    """
    raise NotImplementedError("stage_stream not implemented")

def commit_stream(stream: Stream, *args, **kwargs) -> Stream:
    """
    Registers a delta stream with a target table version, replacing any
    previous stream registered for the same table version. Returns the
    committed stream.
    """
    raise NotImplementedError("commit_stream not implemented")

def delete_stream(
    namespace: str,
    table_name: str,
    table_version: Optional[str] = None,
    *args,
    **kwargs
) -> None:
    """
    Deletes the delta stream currently registered with the given table version.
    Resolves to the latest active table version if no table version is given.
    Raises an error if the table version does not exist.
    """
    raise NotImplementedError("delete_stream not implemented")

def get_stream(
    namespace: str,
    table_name: str,
    table_version: Optional[str] = None,
    *args,
    **kwargs
) -> Optional[Stream]:
    """
    Gets the most recently committed stream for the given table version and
    partition key values. Resolves to the latest active table version if no
    table version is given. Returns None if the table version does not exist.
    """
    raise NotImplementedError("get_stream not implemented")

def stage_partition(
    stream: Stream, partition_values: Optional[List[Any]] = None, *args, **kwargs
) -> Partition:
    """
    Stages a new partition for the given stream and partition values. Returns
    the staged partition. If this partition will replace another partition
    with the same partition values, then it will have its previous partition ID
    set to the ID of the partition being replaced. Partition keys should not be
    specified for unpartitioned tables.
    """
    raise NotImplementedError("stage_partition not implemented")

def commit_partition(partition: Partition, *args, **kwargs) -> Partition:
    """
    Commits the given partition to its associated table version stream,
    replacing any previous partition registered for the same stream and
    partition values. Returns the registered partition. If the partition's
    previous delta stream position is specified, then the commit will
    be rejected if it does not match the actual previous stream position of
    the partition being replaced. If the partition's previous partition ID is
    specified, then the commit will be rejected if it does not match the actual
    ID of the partition being replaced.
    """
    raise NotImplementedError("commit_partition not implemented")

def delete_partition(
    namespace: str,
    table_name: str,
    table_version: Optional[str] = None,
    partition_values: Optional[List[Any]] = None,
    *args,
    **kwargs
) -> None:
    """
    Deletes the given partition from the specified table version. Resolves to
    the latest active table version if no table version is given. Partition
    values should not be specified for unpartitioned tables. Raises an error
    if the table version or partition does not exist.
    """
    raise NotImplementedError("delete_partition not implemented")

def get_partition(
    stream_locator: StreamLocator,
    partition_values: Optional[List[Any]] = None,
    *args,
    **kwargs
) -> Optional[Partition]:
    """
    Gets the most recently committed partition for the given stream locator and
    partition key values. Returns None if no partition has been committed for
    the given table version and/or partition key values. Partition values
    should not be specified for unpartitioned tables.
    """
    raise NotImplementedError("get_partition not implemented")

def stage_delta(
    data: Union[LocalTable, LocalDataset, DistributedDataset, Manifest],
    partition: Partition,
    delta_type: DeltaType = DeltaType.UPSERT,
    max_records_per_entry: Optional[int] = None,
    author: Optional[ManifestAuthor] = None,
    properties: Optional[Dict[str, str]] = None,
    s3_table_writer_kwargs: Optional[Dict[str, Any]] = None,
    content_type: ContentType = ContentType.PARQUET,
    *args,
    **kwargs
) -> Delta:
    """
    Writes the given table to 1 or more S3 files. Returns an unregistered
    delta whose manifest entries point to the uploaded files. Applies any
    schema consistency policies configured for the parent table version.
    """
    raise NotImplementedError("stage_delta not implemented")

def commit_delta(delta: Delta, *args, **kwargs) -> Delta:
    """
    Registers a new delta with its associated target table version and
    partition. Returns the registered delta. If the delta's previous stream
    position is specified, then the commit will be rejected if it does not match
    the target partition's actual previous stream position. If the delta's
    stream position is specified, it must be greater than the latest stream
    position in the target partition.
    """
    raise NotImplementedError("commit_delta not implemented")

def get_namespace(namespace: str, *args, **kwargs) -> Optional[Namespace]:
    """
    Gets table namespace metadata for the specified table namespace. Returns
    None if the given namespace does not exist.
    """
    raise NotImplementedError("get_namespace not implemented")

def namespace_exists(namespace: str, *args, **kwargs) -> bool:
    """
    Returns True if the given table namespace exists, False if not.
    """
    raise NotImplementedError("namespace_exists not implemented")

def get_table(namespace: str, table_name: str, *args, **kwargs) -> Optional[Table]:
    """
    Gets table metadata for the specified table. Returns None if the given
    table does not exist.
    """
    raise NotImplementedError("get_table not implemented")

def table_exists(namespace: str, table_name: str, *args, **kwargs) -> bool:
    """
    Returns True if the given table exists, False if not.
    """
    raise NotImplementedError("table_exists not implemented")

def get_table_version(
    namespace: str, table_name: str, table_version: str, *args, **kwargs
) -> Optional[TableVersion]:
    """
    Gets table version metadata for the specified table version. Returns None
    if the given table version does not exist.
    """
    raise NotImplementedError("get_table_version not implemented")

def get_latest_table_version(
    namespace: str, table_name: str, *args, **kwargs
) -> Optional[TableVersion]:
    """
    Gets table version metadata for the latest version of the specified table.
    Returns None if no table version exists for the given table.
    """
    raise NotImplementedError("get_latest_table_version not implemented")

def get_latest_active_table_version(
    namespace: str, table_name: str, *args, **kwargs
) -> Optional[TableVersion]:
    """
    Gets table version metadata for the latest active version of the specified
    table. Returns None if no active table version exists for the given table.
    """
    raise NotImplementedError("get_latest_active_table_version not implemented")

def get_table_version_column_names(
    namespace: str,
    table_name: str,
    table_version: Optional[str] = None,
    *args,
    **kwargs
) -> Optional[List[str]]:
    """
    Gets a list of column names for the specified table version, or for the
    latest active table version if none is specified. The index of each
    column name returned represents its ordinal position in a delimited text
    file or other row-oriented content type files appended to the table.
    Returns None for schemaless tables. Raises an error if the table version
    does not exist.
    """
    raise NotImplementedError("get_table_version_column_names not implemented")

def get_table_version_schema(
    namespace: str,
    table_name: str,
    table_version: Optional[str] = None,
    *args,
    **kwargs
) -> Optional[Union[pa.Schema, str, bytes]]:
    """
    Gets the schema for the specified table version, or for the latest active
    table version if none is specified. Returns None if the table version is
    schemaless. Raises an error if the table version does not exist.
    """
    raise NotImplementedError("get_table_version_schema not implemented")

def table_version_exists(
    namespace: str, table_name: str, table_version: str, *args, **kwargs
) -> bool:
    """
    Returns True if the given table version exists, False if not.
    """
    raise NotImplementedError("table_version_exists not implemented")


#1.求两数之和
def qiuhe(a,b):
    sum=a+b
    return sum
print(qiuhe(3,4))
#2.求数字的阶乘
def jiecheng(number):
    result=1
    while number>0:
        result*=number
        number-=1
    return result
print(jiecheng(6))
#3.计算圆的面积
import math
def yuanmianji(r):
    s=math.pi*pow(r,2)
    return s
print(round(yuanmianji(1),2))
#4.计算区间内所有的素数
def issushu(number):
    if number in(1,2):
        return True
    else:
        for i in range(2,number):
            if number%i==0:
                return False
    return True
def sushu(begin,end):
    for number in range(1,end+1):
        if issushu(number):
            print(f'{number}is prime')
print(sushu(1,6))
#5求前n个数字的平方和
def pingfanghe(n):
    result=0
    while n>0:
        result+=pow(n,2)
        n-=1
    return result
print(pingfanghe(3))
#6.计算列表数字的和
def liebiaohe(list):
    result=0
    for i in list:
        result+=i
    return result
list1=[1,2,3,4]
print(liebiaohe(list1))
#7.数字范围内所有的偶数
def oushu(n):
    result=[]
    for i in range(1,n+1):
        if i%2==0:
            result.append(i)
    return result
print(oushu(7))
#8.从列表中移除多个元素
def yichuduoge(list1,list2):
    for i in list2:
        if i in list1:
            list1.remove(i)
    return list1
list1=[1,2,3,4,5,6]
list2=[1,2]
print(yichuduoge(list1,list2))
#列表推导式的使用
date=[i for i in list1 if i not in list2]
print(date)
#9对列表进行去重
#运用集合对其进行去重
a=[1,2,3,1,1,1]
b=set(a)
print(list(b))
#正常函数方法
def quchong(list):
    result=[]
    for i in list:
        if i not in result:
            result.append(i)
    return result
print(quchong(a))
#10.对简单列表进行排序sort,sorted,reverse=Ture从大到小进行排序
def paixu(list):
    listb=sorted(list,reverse=True)#这样写并没有改变原列表的顺序,只是又新建了一个列表
    return listb
list3=[2,1,4,3,5,7,6]
print(paixu(list3))
#11.python实现对学生成绩的排序lambda
students=[
    {'name':'小王','chengji':'99'},
    {'name':'小赵','chengji':'77'},
    {'name':'小李','chengji':'88'},
    {'name':'小芳','chengji':'66'}
]
paixu=sorted(students,key=lambda x:x['chengji'],reverse=True)
print(paixu)#key是键
#12.python读取成绩文件实现排序
def readfile():
    result=[]
    with open('./chengjiwenjian.txt') as fin:
        for line in fin:
            line=line[:-1]
            result.append(line.split(','))
    return result
def sortgrade(dates):
    return sorted(dates,
                  key=lambda x:int(x[2]),
                  reverse=True)
dates=readfile()
print(dates)
b=sortgrade(dates)
print(b)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
@Author: Youshumin
@Date: 2019-08-26 10:26:19
@LastEditors: Please set LastEditors
@LastEditTime: 2019-12-03 17:21:45
@desc: 管理定时任务 添加post, 修改状态patch, 删除delete,  修改内容put, 获取任务get
'''

import json
import logging

import apscheduler
from oslo.form.form import form_error
from oslo.web.requesthandler import MixinRequestHandler
from oslo.web.route import route
from tornado import gen
from forms.cron import (CronDeleteForm, CronGetForm, CronPatchForm,
                        CronPostFrom, CronPutForm)
from utils.cron import register_task, scheduler

LOG = logging.getLogger(__name__)

@route("/cron/")
class CronTaskHandler(MixinRequestHandler):
    def post(self):
        """
            添加定时任务
        """
        form = CronPostFrom(self)
        if form.is_valid():
            cron_id = form.value_dict["cron_id"]
            cron_type = form.value_dict["cron_type"]
            cron_body = form.value_dict["cron_body"]
            cron_time_trigger = form.value_dict["cron_time_trigger"]
            cron_time_body = form.value_dict["cron_time_body"]
        else:
            form_error(self, form)
            return

        return_id = register_task(cron_id, cron_type, cron_body,
                                  cron_time_trigger, cron_time_body)
        if return_id:
            self.send_ok(data="")
        else:
            self.send_fail(msg="添加任务失败")
        return

    def put(self):
        """
            修改定时任务
        """
        form = CronPutForm(self)
        if form.is_valid():
            cron_id = form.value_dict["cron_id"]
            cron_type = form.value_dict["cron_type"]
            cron_body = form.value_dict["cron_body"]
            cron_time_trigger = form.value_dict["cron_time_trigger"]
            cron_time_body = form.value_dict["cron_time_body"]
        else:
            form_error(self, form)
            return

        old_cron = scheduler.get_job(cron_id)
        if old_cron:
            return_id = register_task(cron_id, cron_type, cron_body,
                                      cron_time_trigger, cron_time_body)
            if return_id:
                self.send_ok(data="")
                return
        else:
            self.send_fail(msg="修改任务失败")
            return

    def delete(self):
        """
            删除定时任务
        """
        form = CronDeleteForm(self)
        if form.is_valid():
            cron_id = form.value_dict["cron_id"]
        else:
            form_error(self, form)
            return
        try:
            scheduler.remove_job(cron_id)
            self.send_ok(data="")
        except Exception:
            self.send_fail(msg="删除任务失败")
        return

    def get(self):
        """
            获取定时任务
        """
        form = CronGetForm(self)
        if form.is_valid():
            pageIndex = form.value_dict["pageIndex"]
            pageLimit = form.value_dict["pageLimit"]
            cron_id = form.value_dict["cron_id"]
        else:
            form_error(self, form)
            return

        start = (int(pageIndex) - 1) * int(pageLimit)
        end = int(pageIndex) * int(pageLimit)
        reps_list = []

        try:
            if not cron_id:
                cron_list = scheduler.get_jobs()
            else:
                cron_list = [scheduler.get_jobs(cron_id)]
                start = 0

            for cron in cron_list:
                if isinstance(cron.trigger,
                              apscheduler.triggers.interval.IntervalTrigger):
                    # 解析 interval 触发器时间
                    cron_task = dict(
                        cron_body=cron.kwargs.get('data'),
                        status='0' if cron.next_run_time else '1',
                        next_run_time=str(cron.next_run_time),
                        tigger="interval",
                        cron_time=cron.trigger.interval.total_seconds(),
                        cron_id=cron.id)
                    reps_list.append(cron_task)
                elif isinstance(cron.trigger,
                                apscheduler.triggers.cron.CronTrigger):
                    # 解析cron 时间触发器
                    start_date = cron.trigger.start_date
                    end_date = cron.trigger.end_date
                    fields = cron.trigger.fields

                    cron_time = {}
                    for item in fields:
                        cron_time.setdefault(item.name, str(item))

                    cron_task = dict(cron_body=cron.kwargs.get('data'),
                                     status='0' if cron.next_run_time else '1',
                                     trigger="cron",
                                     cron_time=cron_time,
                                     next_run_time=str(cron.next_run_time),
                                     cron_id=cron.id)
                    reps_list.append(cron_task)
                elif isinstance(cron.trigger,
                                apscheduler.triggers.date.DateTrigger):
                    # 解析 date时间触发器
                    cron_task = dict(cron_body=cron.kwargs.get('data'),
                                     status='0' if cron.next_run_time else '1',
                                     trigger="date",
                                     cron_time=str(cron.trigger.run_date),
                                     next_run_time=str(cron.next_run_time),
                                     cron_id=cron.id)
                    reps_list.append(cron_task)
                else:
                    print(cron.trigger)
                    print(type(cron.trigger))
                LOG.debug(reps_list)

            retList = reps_list[start:end]
            totalCount = len(reps_list)
        except Exception as e:
            retList = []
            totalCount = 0
            LOG.debug(str(e))
        return self.send_ok(data={"rows": retList, "totalCount": totalCount})

    def patch(self):
        """
            暂停或者恢复任务
        """
        form = CronPatchForm(self)
        if form.is_valid():
            cron_id = form.value_dict["cron_id"]
        else:
            form_error(self, form)
            return

        if scheduler.get_job(cron_id).next_run_time:
            option = "pause"
        else:
            option = "resume"

        if option == "pause":
            try:
                scheduler.pause_job(cron_id)
                self.send_ok(data="")
            except Exception as e:
                self.send_fail(msg=str(e))
        elif option == "resume":
            try:
                scheduler.resume_job(cron_id)
                self.send_ok(data="")
            except Exception as e:
                self.send_fail(msg=str(e))
        else:
            self.send_fail(nsg="未知错误")
        return

@route("/test/mq/")
class TestHandler(MixinRequestHandler):
    @gen.coroutine
    def get(self):
        hostinfo = [
            dict(host="192.168.2.132",
                 port=22051,
                 user="root",
                 password="",
                 ansible_ssh_private_key_file="~/.ssh/youshumin"),
        ]
        mq_server = self.application.mq_server

        data = dict(msg_id="2019-12-15",
                    msg_task="setup",
                    msg_data=hostinfo,
                    msg_return=True)
        from configs.setting import MQ_ANSIBLE_EXCHANGE, MQ_ANSIBLE_ROUTING_KEY
        yield mq_server.send_msg(json.dumps(data), MQ_ANSIBLE_EXCHANGE,
                                 MQ_ANSIBLE_ROUTING_KEY)
        return self.send_ok(data="")


'''Provide services of infra module.'''
from django.utils.timezone import now
from django.contrib.auth import get_user_model

from infra.models import Notification
from infra.utils import prod_logger

User = get_user_model()

class NotificationService:  # pylint: disable=R0903
    '''Provide services for Notification.'''
    @classmethod
    def _get_notification_robot(cls):
        robot = User.objects.get(username='notification-robot')
        return robot

    @staticmethod
    def mark_user_notifications_as_read(user):
        '''Mark all notifications for user as read.'''
        notifications = (
            Notification.objects
            .filter(recipient=user)  # Notifications for current user
            .filter(read_time=None)  # All unread notifications
        )
        return notifications.update(read_time=now())

    @staticmethod
    def delete_user_notifications(user):
        '''Delete all notifications the current user received.'''
        msg = f'正在删除用户 {user.first_name}(工号: {user.username}) 的所有通知'
        prod_logger.info(msg)
        return Notification.objects.filter(recipient=user).delete()

    @staticmethod
    def send_system_notification(recipient, content):
        '''Send system notification.

        Parameters
        ------------
        recipient: User or int,
            The user or the id of the user to receive the notification.
        content: str
            The content of the notification.
        '''
        if isinstance(recipient, int):
            recipient = User.objects.get(id=recipient)
        elif not isinstance(recipient, User):
            raise ValueError('Only User instance or int id is supported')
        notification = Notification.objects.create(
            sender=NotificationService._get_notification_robot(),
            recipient=recipient,
            content=content
        )
        from auth.services import PermissionService
        PermissionService.assign_object_permissions(recipient, notification)


from src.algorithm.Activity.top_users_activity import TopUsersActivity
import argparse
import time
from src.algorithm.top_users.parser.parse_config import parse_from_file
from src.shared.utils import get_project_root

DEFAULT_PATH = str(get_project_root()) + "/src/algorithm/top_users/config/rank_users.yaml"
DEFAULT_METHOD = "Label Propagation"

def top_users(cluster_num: int, base_user: str, cluster_type: str, path=DEFAULT_PATH):
    config = parse_from_file(path)

    activity = TopUsersActivity(config)
    activity.find_top_users(cluster_num, base_user, cluster_type)

if __name__ == "__main__":
    """
    Clean inactive users in the friends list.
    """
    parser = argparse.ArgumentParser(description='Get rid of inactive users')
    parser.add_argument('-c', '--cluster number', dest='cluster_num', required=True,
        help='which cluster to find top words', type=int)
    parser.add_argument('-u', '--user', dest='base_user', required=True,
        help='The target user', type=str)
    parser.add_argument('-t', '--clustering type', dest='cluster_type', required=False,
        default=DEFAULT_METHOD, help='Label Propagation / Max Modularity', type=str)
    parser.add_argument('-p', '--path', dest='path', required=False,
        default=DEFAULT_PATH, help='The path of the config file', type=str)

    args = parser.parse_args()

    top_users(args.cluster_num, args.base_user, args.cluster_type,args.path)


import http
import os
import ssl
import threading
import time
import socket

import jni_test
from framework.lwm2m.messages import *
from framework.test_utils import *
from framework.lwm2m_test import *
from framework.coap_file_server import CoapFileServerThread, CoapFileServer

UPDATE_STATE_IDLE = 0
UPDATE_STATE_DOWNLOADING = 1
UPDATE_STATE_DOWNLOADED = 2
UPDATE_STATE_UPDATING = 3

UPDATE_RESULT_INITIAL = 0
UPDATE_RESULT_SUCCESS = 1
UPDATE_RESULT_NOT_ENOUGH_SPACE = 2
UPDATE_RESULT_OUT_OF_MEMORY = 3
UPDATE_RESULT_CONNECTION_LOST = 4
UPDATE_RESULT_INTEGRITY_FAILURE = 5
UPDATE_RESULT_UNSUPPORTED_PACKAGE_TYPE = 6
UPDATE_RESULT_INVALID_URI = 7
UPDATE_RESULT_FAILED = 8
UPDATE_RESULT_UNSUPPORTED_PROTOCOL = 9

FIRMWARE_PATH = '/firmware'

class FirmwareUpdate:
    class Test(jni_test.LocalSingleServerTest):
        def set_expect_send_after_state_machine_reset(self, expect_send_after_state_machine_reset):
            self.expect_send_after_state_machine_reset = expect_send_after_state_machine_reset

        def setUp(self, garbage=0, *args, **kwargs):
            garbage_lines = ''
            while garbage > 0:
                garbage_line = '#' * (min(garbage, 80) - 1) + '\n'
                garbage_lines += garbage_line
                garbage -= len(garbage_line)
            self.FIRMWARE_SCRIPT_CONTENT = garbage_lines.encode('ascii')
            super().setUp(*args, **kwargs)

        def tearDown(self):
            try:
                super().tearDown()
            finally:
                try:
                    os.unlink('downloaded_firmware')
                except FileNotFoundError:
                    pass

        def read_update_result(self):
            req = Lwm2mRead(ResPath.FirmwareUpdate.UpdateResult)
            self.serv.send(req)
            res = self.serv.recv()
            self.assertMsgEqual(Lwm2mContent.matching(req)(), res)
            return int(res.content)

        def read_state(self):
            req = Lwm2mRead(ResPath.FirmwareUpdate.State)
            self.serv.send(req)
            res = self.serv.recv()
            self.assertMsgEqual(Lwm2mContent.matching(req)(), res)
            return int(res.content)

        def write_firmware_and_wait_for_download(self, firmware_uri: str,
                                                 download_timeout_s=20):
            # Write /5/0/1 (Firmware URI)
            req = Lwm2mWrite(ResPath.FirmwareUpdate.PackageURI, firmware_uri)
            self.serv.send(req)
            self.assertMsgEqual(Lwm2mChanged.matching(req)(),
                                self.serv.recv())

            # wait until client downloads the firmware
            deadline = time.time() + download_timeout_s
            while time.time() < deadline:
                time.sleep(0.5)

                if self.read_state() == UPDATE_STATE_DOWNLOADED:
                    return

            self.fail('firmware still not downloaded')

    class TestWithHttpServer(Test):
        RESPONSE_DELAY = 0
        CHUNK_SIZE = sys.maxsize
        ETAGS = False

        def get_firmware_uri(self):
            return 'http://127.0.0.1:%d%s' % (self.http_server.server_address[1], FIRMWARE_PATH)

        def provide_response(self, use_real_app=False):
            with self._response_cv:
                self.assertIsNone(self._response_content)
                if use_real_app:
                    with open(os.path.join(self.config.demo_path, self.config.demo_cmd), 'rb') as f:
                        firmware = f.read()
                        self._response_content = make_firmware_package(
                            firmware)
                else:
                    self._response_content = make_firmware_package(
                        self.FIRMWARE_SCRIPT_CONTENT)
                self._response_cv.notify()

        def _create_server(self):
            test_case = self

            class FirmwareRequestHandler(http.server.BaseHTTPRequestHandler):
                def do_GET(self):
                    self.send_response(http.HTTPStatus.OK)
                    self.send_header('Content-type', 'text/plain')
                    if test_case.ETAGS:
                        self.send_header('ETag', '"some_etag"')
                    self.end_headers()

                    # This condition variable makes it possible to defer sending the response.
                    # FirmwareUpdateStateChangeTest uses it to ensure demo has enough time
                    # to send the interim "Downloading" state notification.
                    with test_case._response_cv:
                        while test_case._response_content is None:
                            test_case._response_cv.wait()
                        response_content = test_case._response_content
                        test_case.requests.append(self.path)
                        test_case._response_content = None

                    def chunks(data):
                        for i in range(0, len(response_content), test_case.CHUNK_SIZE):
                            yield response_content[i:i + test_case.CHUNK_SIZE]

                    for chunk in chunks(response_content):
                        time.sleep(test_case.RESPONSE_DELAY)
                        self.wfile.write(chunk)
                        self.wfile.flush()

                def log_request(self, code='-', size='-'):
                    # don't display logs on successful request
                    pass

            return http.server.HTTPServer(('', 0), FirmwareRequestHandler)

        def write_firmware_and_wait_for_download(self, *args, **kwargs):
            requests = list(self.requests)
            super().write_firmware_and_wait_for_download(*args, **kwargs)
            self.assertEqual(requests + ['/firmware'], self.requests)

        def setUp(self, *args, **kwargs):
            self.requests = []
            self._response_content = None
            self._response_cv = threading.Condition()

            self.http_server = self._create_server()

            super().setUp(*args, **kwargs)

            self.server_thread = threading.Thread(
                target=lambda: self.http_server.serve_forever())
            self.server_thread.start()

        def tearDown(self):
            try:
                super().tearDown()
            finally:
                self.http_server.shutdown()
                self.server_thread.join()

    class TestWithTlsServer(Test):
        @staticmethod
        def _generate_pem_cert_and_key(cn='127.0.0.1', alt_ip='127.0.0.1'):
            import datetime
            import ipaddress
            from cryptography import x509
            from cryptography.x509.oid import NameOID
            from cryptography.hazmat.backends import default_backend
            from cryptography.hazmat.primitives import hashes, serialization
            from cryptography.hazmat.primitives.asymmetric import rsa

            key = rsa.generate_private_key(public_exponent=65537, key_size=2048,
                                           backend=default_backend())
            name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, cn)])
            now = datetime.datetime.utcnow()
            cert_builder = (x509.CertificateBuilder().
                            subject_name(name).
                            issuer_name(name).
                            public_key(key.public_key()).
                            serial_number(1000).
                            not_valid_before(now).
                            not_valid_after(now + datetime.timedelta(days=1)))
            if alt_ip is not None:
                cert_builder = cert_builder.add_extension(x509.SubjectAlternativeName(
                    [x509.DNSName(cn), x509.IPAddress(ipaddress.IPv4Address(alt_ip))]),
                    critical=False)
            cert = cert_builder.sign(key, hashes.SHA256(), default_backend())
            cert_pem = cert.public_bytes(encoding=serialization.Encoding.PEM)
            key_pem = key.private_bytes(encoding=serialization.Encoding.PEM,
                                        format=serialization.PrivateFormat.TraditionalOpenSSL,
                                        encryption_algorithm=serialization.NoEncryption())
            return cert_pem, key_pem

        def setUp(self, pass_cert_to_demo=True):
            cert_pem, key_pem = self._generate_pem_cert_and_key()

            with tempfile.NamedTemporaryFile(delete=False) as cert_file, \
                    tempfile.NamedTemporaryFile(delete=False) as key_file:
                cert_file.write(cert_pem)
                cert_file.flush()

                key_file.write(key_pem)
                key_file.flush()

                self._cert_file = cert_file.name
                self._key_file = key_file.name

            extra_cmdline_args = []
            if pass_cert_to_demo:
                extra_cmdline_args += ['--fw-cert-file', self._cert_file]
            super().setUp(extra_cmdline_args=extra_cmdline_args)

        def tearDown(self):
            def unlink_without_err(fname):
                try:
                    os.unlink(fname)
                except:
                    print('unlink(%r) failed' % (fname,))
                    sys.excepthook(*sys.exc_info())

            try:
                super().tearDown()
            finally:
                unlink_without_err(self._cert_file)
                unlink_without_err(self._key_file)

    class TestWithHttpsServer(TestWithTlsServer, TestWithHttpServer):
        def get_firmware_uri(self):
            http_uri = super().get_firmware_uri()
            assert http_uri[:5] == 'http:'
            return 'https:' + http_uri[5:]

        def _create_server(self):
            http_server = super()._create_server()
            http_server.socket = ssl.wrap_socket(http_server.socket, certfile=self._cert_file,
                                                 keyfile=self._key_file,
                                                 server_side=True)
            return http_server

class FirmwareUpdateHttpsTest(FirmwareUpdate.TestWithHttpsServer):
    def runTest(self):
        self.provide_response()
        self.write_firmware_and_wait_for_download(
            self.get_firmware_uri(), download_timeout_s=20)

        # Execute /5/0/2 (Update)
        req = Lwm2mExecute(ResPath.FirmwareUpdate.Update)
        self.serv.send(req)
        self.assertMsgEqual(Lwm2mChanged.matching(req)(),
                            self.serv.recv())

class FirmwareUpdateUnconfiguredHttpsTest(FirmwareUpdate.TestWithHttpsServer):
    def setUp(self):
        super().setUp(pass_cert_to_demo=False)

    def runTest(self):
        # disable minimum notification period
        write_attrs_req = Lwm2mWriteAttributes(ResPath.FirmwareUpdate.UpdateResult,
                                               query=['pmin=0'])
        self.serv.send(write_attrs_req)
        self.assertMsgEqual(Lwm2mChanged.matching(
            write_attrs_req)(), self.serv.recv())

        # initial result should be 0
        observe_req = Lwm2mObserve(ResPath.FirmwareUpdate.UpdateResult)
        self.serv.send(observe_req)
        self.assertMsgEqual(Lwm2mContent.matching(
            observe_req)(content=b'0'), self.serv.recv())

        # Write /5/0/1 (Firmware URI)
        req = Lwm2mWrite(ResPath.FirmwareUpdate.PackageURI,
                         self.get_firmware_uri())
        self.serv.send(req)
        self.assertMsgEqual(Lwm2mChanged.matching(req)(),
                            self.serv.recv())

        # even before reaching the server, we should get an error
        notify_msg = self.serv.recv()
        # no security information => "Unsupported protocol"
        self.assertMsgEqual(Lwm2mNotify(observe_req.token,
                                        str(UPDATE_RESULT_UNSUPPORTED_PROTOCOL).encode()),
                            notify_msg)
        self.serv.send(Lwm2mReset(msg_id=notify_msg.msg_id))
        self.assertEqual(0, self.read_state())


from collections import Counter
import math
def minWindow_alt(s,  t): # easier to follow
    res = math.inf
    l, r = 0, 0
    d = Counter(t)
    l_d = 0
    while r < len(s):
        d[s[r]] -= 1
        if d[s[r]] >= 0:
            l_d += 1
        while l_d == len(t):
            # curr_l = r - l + 1
            # if curr_l < glob_l:
            #     glob_l = curr_l
                # glob_ans = s[l: r + 1]
            res = min(res, r - l + 1)
            d[s[l]] += 1
            if d[s[l]] > 0:
                l_d -= 1
            l += 1
        r += 1
    return res if res != math.inf else -1

def minWindow_repurpose(s, t):
    """
    Take the exact solution from 076 but return the length of the resulting string instead of the string itself
    """
    l, r, curr_l, glob_ans, glob_l = 0, 0, 0, '', math.inf
    d = Counter(t)
    l_d = 0
    while r < len(s):
        d[s[r]] -= 1
        if d[s[r]] >= 0:
            l_d += 1
        while l_d == len(t):
            curr_l = r - l + 1
            if curr_l < glob_l:
                glob_l = curr_l
                glob_ans = s[l: r + 1]
            d[s[l]] += 1
            if d[s[l]] > 0:
                l_d -= 1
            l += 1
        r += 1
    return len(glob_ans) if len(glob_ans) != 0 else -1

if __name__ == '__main__':
    print(minWindow_alt("dcbefebce", "fd"))
    print(minWindow_alt("bfbeadbcbcbfeaaeefcddcccbbbfaaafdbebedddf", "cbccfafebccdccebdd"))
    print(minWindow_repurpose("dcbefebce", "fd"))
    print(minWindow_repurpose("bfbeadbcbcbfeaaeefcddcccbbbfaaafdbebedddf", "cbccfafebccdccebdd"))


# Do not modify these lines
__winc_id__ = '7b9401ad7f544be2a23321292dd61cb6'
__human_name__ = 'arguments'

# Add your code after this line
# Part 1
def greet(name, template='Hello, <name>!'):
    template = template.replace('<name>', name)
    return (f'{template}')

print(greet('Doc'))

#Part 2
def force(mass, body='earth'):
    bodies = {'mercury': 3.7,
              'venus': 8.9,
              'earth': 9.8,
              'moon': 1.6,
              'mars': 3.7,
              'jupiter': 23.1,
              'saturn': 9.0,
              'uranus': 8.7,
              'neptune': 11.0,
              'pluto': 0.7}
    gravity = bodies.get(body)
    force_n = gravity * mass

    #f = m * g

    return force_n

print(force(3,'uranus'))

# Part 3
def pull(m1, m2, d):
    # F = G * ((m1 * m2) / (d**2))
    pull = (6.674 * (10**-11))
    print(pull)
    pull_n = pull * ((m1 * m2) / (d**2))
    return pull_n

print(pull(800, 1500, 3))


import argparse
import configparser
import os

import tomli

from .vendored.flake8 import parse_files_to_codes_mapping
from .zimports import run_with_options

def _load_config(config_file="setup.cfg"):
    config = configparser.ConfigParser()
    config["flake8"] = {
        "application-import-names": "",
        "application-package-names": "",
        "import-order-style": "google",
    }
    config.read(config_file)
    return config

def _load_toml(config_file="pyproject.toml"):

    if os.path.exists(config_file):
        with open(config_file, "rb") as f:
            toml_dict = tomli.load(f)  # type: ignore
    else:
        toml_dict = {}

    return toml_dict.get("tool", {}).get("zimports", {})

def main(argv=None):
    parser = argparse.ArgumentParser(prog="zimports")

    config = _load_config()

    NOT_SET = object()

    parser.add_argument(
        "--toml-config",
        type=str,
        default="pyproject.toml",
        help="name / path of pyproject.toml file",
    )
    parser.add_argument(
        "-m",
        "--application-import-names",
        type=str,
        default=config["flake8"]["application-import-names"],
        help="comma separated list of names that should be considered local "
        "to the application.  reads from [flake8] application-import-names "
        "by default.",
    )
    parser.add_argument(
        "-p",
        "--application-package-names",
        type=str,
        default=config["flake8"]["application-package-names"],
        help="comma separated list of names that should be considered local "
        "to the organization.  reads from [flake8] application-package-names "
        "by default.",
    )
    parser.add_argument(
        "--style",
        type=str,
        default=config["flake8"]["import-order-style"],
        help="import order styling, reads from "
        "[flake8] import-order-style by default, or defaults to 'google'",
    )
    parser.add_argument(
        "--black-line-length",
        type=int,
        default=NOT_SET,
        help="Format long imports past given line length using Black-style "
        "formatting",
    )
    parser.add_argument(
        "--multi-imports",
        action="store_true",
        default=NOT_SET,
        help="If set, multiple imports can exist on one line",
    )
    parser.add_argument(
        "-k",
        "--keep-unused",
        action="store_true",
        default=NOT_SET,
        help="keep unused imports even though detected as unused. "
        "Implies keep-unused-type-checking",
    )
    parser.add_argument(
        "-kt",
        "--keep-unused-type-checking",
        action="store_true",
        default=NOT_SET,
        help="keep unused imports even though detected as unused "
        "in type checking blocks. zimports does not detect type usage "
        "in comments or when used as string",
    )
    parser.add_argument(
        "--heuristic-unused",
        type=int,
        default=NOT_SET,
        help="Remove unused imports only if number of imports is "
        "less than <HEURISTIC_UNUSED> percent of the total lines of code. "
        "Ignored in type checking blocks",
    )
    parser.add_argument(
        "--statsonly",
        action="store_true",
        help="don't write or display anything except the file stats",
    )
    parser.add_argument(
        "-e",
        "--expand-stars",
        action="store_true",
        help="Expand star imports into the names in the actual module, which "
        "can then have unused names removed.  Requires modules can be "
        "imported",
    )
    parser.add_argument(
        "--diff",
        action="store_true",
        help="don't modify files, just dump out diffs",
    )
    parser.add_argument(
        "--stdout", action="store_true", help="dump file output to stdout"
    )
    parser.add_argument(
        "filename", nargs="+", help="Python filename(s) or directories"
    )
    cpu = os.cpu_count()
    parser.add_argument(
        "-W",
        "--workers",
        type=int,
        default=cpu,
        help=f"Number of parallel workers  [default: {cpu};x>=1]",
    )

    options = parser.parse_args(argv)

    toml = _load_toml(options.toml_config)
    if options.black_line_length is NOT_SET:
        options.black_line_length = toml.get("black-line-length", None)
    if options.multi_imports is NOT_SET:
        options.multi_imports = toml.get("multi-imports", False)
    if options.keep_unused is NOT_SET:
        options.keep_unused = toml.get("keep-unused", False)
    if options.keep_unused_type_checking is NOT_SET:
        options.keep_unused_type_checking = toml.get(
            "keep-unused-type-checking", False
        )
    if options.heuristic_unused is NOT_SET:
        options.heuristic_unused = toml.get("heuristic-unused", None)

    if "per-file-ignores" in config["flake8"]:
        options.per_file_ignores = parse_files_to_codes_mapping(
            config["flake8"]["per-file-ignores"]
        )
    else:
        options.per_file_ignores = []

    run_with_options(options)


#Bhavani

print("Bhavani".center(100,'*'))
def tuple_values(start, end):
    t_result = ()
    while start !=end:
        t_result += start,
        start+=1
    return t_result

print(tuple_values(1, 11))

print("Rimjhim".center(100,'*'))
#Rimjhim
def getlist(start,end):
    t = ()
    i=start
    while i<= end:
       t = t + (i,)
       i += 1
    print(t)
    return t

print(getlist(1,10))

print("Ismail".center(100,'*'))
def tuple_values(start, end):
    return tuple(range(start,end))

print(tuple_values(1,20))


import numpy as np
depth = 0 # depth of tree

class AIPlayer:
    def __init__(self, player_number):
        self.player_number = player_number
        self.type = 'ai'
        self.player_string = 'Player {}:ai'.format(player_number)

    # calcs number of possible col wins
    def col_wins(self, board, col, p_num):
        # if empty col
        if not np.any(board[:, col]):
            num_col_wins = 3
        # if not empty col
        else:
            for i in range(len(board[:, col])):
                if board[:, col][i] != 0:
                    # print(board[:i+1, col])
                    # when the last token is player's
                    if board[:, col][i] == p_num:
                        if len(board[:i + 1, col]) >= 4:
                            num_col_wins = len(board[:i + 1, col]) - 3
                        else:
                            num_col_wins = 0
                    # when the last token is not player's
                    else:
                        if len(board[:i + 1, col]) - 1 >= 4:
                            num_col_wins = len(board[:i + 1, col]) - 1 - 3
                        else:
                            num_col_wins = 0
                    # print(num_col_wins)
                    break
        return num_col_wins

    # calcs number of possible row wins
    def row_wins(self, board, col, p_num):
        if not np.any(board[:, col]):
            row = board[5]
            # print(row)
        else:
            for i in range(len(board[:, col])):
                if board[:, col][i] != 0:
                    row = board[i - 1]
                    # print(row)
                    break
        temp_row = []
        for i in range(len(row)):
            # print(row[i])
            if row[i] == 0:
                temp_row.append(p_num)
            else:
                temp_row.append(row[i])
        # print(temp_row)
        in_row = 0
        store_in_row = []
        for i in temp_row:
            if i == p_num:
                in_row += 1
            else:
                store_in_row.append(in_row)
                in_row = 0
        store_in_row.append(in_row)
        # print(store_in_row)
        num_row_wins = 0
        for val in store_in_row:
            if val - 3 > 0:
                num_row_wins += val - 3
        # print(num_row_wins)
        return num_row_wins

    # calcs number of possible diag wins
    def diag_wins(self, board, col, p_num):
        if not np.any(board[:, col]):
            diag_row_start = 5
        else:
            for i in range(len(board[:, col])):
                if board[:, col][i] != 0:
                    diag_row_start = i - 1
                    break
        # print("Start: (", diag_row_start, ", ", col, ")")
        # print(board)
        # print(np.diag(board, k= col-diag_row_start))
        temp_diag = []
        for i in np.diag(board, k=col - diag_row_start):
            if i != 0:
                temp_diag.append(p_num)
            else:
                temp_diag.append(i)
        in_diag = 0
        store_in_diag = []
        for i in temp_diag:
            if i == p_num:
                in_diag += 1
            else:
                store_in_diag.append(in_diag)
                in_diag = 0
        store_in_diag.append(in_diag)
        # print(store_in_row)
        num_diag_wins = 0
        for val in store_in_diag:
            if val - 3 > 0:
                num_diag_wins += val - 3
        return num_diag_wins
    """
    def update_board(self, board, move, player_num):
        # print(self.board)
        temp_board = board
        if 0 in temp_board[:, move]:
            update_row = -1
            for row in range(1, temp_board.shape[0]):
                update_row = -1
                if temp_board[row, move] > 0 and temp_board[row - 1, move] == 0:
                    update_row = row - 1
                elif row == temp_board.shape[0] - 1 and temp_board[row, move] == 0:
                    update_row = row

                if update_row >= 0:
                    temp_board[update_row, move] = player_num

        return temp_board
        """

    # gets max's best move
    def get_max(self, board):
        global depth
        alpha = -np.inf
        next_states = self.evaluation_function(board)
        for i in range(len(next_states)):
            if next_states[i] > alpha:
                alpha = next_states[i]
                choice = i
        if depth < 2:
            depth += 1
            return self.get_min(board)
        else:
            depth = 0
            return choice

    # gets min's best move
    def get_min(self, board):
        global depth
        beta = np.inf
        next_states = self.evaluation_function(board)
        for i in range(len(next_states)):
            if next_states[i] < beta:
                beta = next_states[i]
                choice = i
        if depth <2 :
            depth += 1
            return self.get_max(board)
        else:
            flag = 0
            return choice

    # for expectimax random portion
    def get_min_expect(self, board):
        choice = np.random.randint(7) #https://www.javatpoint.com/numpy-random
        if depth <2 :
            depth += 1
            return self.get_max(board)
        else:
            flag = 0
            return choice

    def get_alpha_beta_move(self, board):
        """
        Given the current state of the board, return the next move based on
        the alpha-beta pruning algorithm

        This will play against either itself or a human player

        INPUTS:
        board - a numpy array containing the state of the board using the
                following encoding:
                - the board maintains its same two dimensions
                    - row 0 is the top of the board and so is
                      the last row filled
                - spaces that are unoccupied are marked as 0
                - spaces that are occupied by player 1 have a 1 in them
                - spaces that are occupied by player 2 have a 2 in them

        RETURNS:
        The 0 based index of the column that represents the next move
        """

        if (np.count_nonzero(board == 1) <= np.count_nonzero(board == 2)):
            choice = self.get_max(board)
        else:
            choice = self.get_min(board)

        return choice

    def get_expectimax_move(self, board):
        """
        Given the current state of the board, return the next move based on
        the expectimax algorithm.

        This will play against the random player, who chooses any valid move
        with equal probability

        INPUTS:
        board - a numpy array containing the state of the board using the
                following encoding:
                - the board maintains its same two dimensions
                    - row 0 is the top of the board and so is
                      the last row filled
                - spaces that are unoccupied are marked as 0
                - spaces that are occupied by player 1 have a 1 in them
                - spaces that are occupied by player 2 have a 2 in them

        RETURNS:
        The 0 based index of the column that represents the next move
        """
        if (np.count_nonzero(board == 1) <= np.count_nonzero(board == 2)):
            choice = self.get_max(board)
        else:
            choice = self.get_min_expect(board)

        # raise NotImplementedError('Whoops I don\'t know what to do')
        return choice

    def evaluation_function(self, board):
        """
        Given the current stat of the board, return the scalar value that
        represents the evaluation function for the current player

        INPUTS:
        board - a numpy array containing the state of the board using the
                following encoding:
                - the board maintains its same two dimensions
                    - row 0 is the top of the board and so is
                      the last row filled
                - spaces that are unoccupied are marked as 0
                - spaces that are occupied by player 1 have a 1 in them
                - spaces that are occupied by player 2 have a 2 in them

        RETURNS:
        The utility value for the current board
        """
        evals = [] # array of values for next states

        for i in range(7):
            evals.append(2*self.col_wins(board, i, 1) + 2*self.row_wins(board, i, 1) + self.diag_wins(board, i, 1) - (
                            2*self.col_wins(board, i, 2) + 2*self.row_wins(board, i, 2) + self.diag_wins(board, i, 2)))
        if not np.any(board[:, 3]):
            evals[3] = evals[3]+100
        print(evals)

        return evals

class RandomPlayer:
    def __init__(self, player_number):
        self.player_number = player_number
        self.type = 'random'
        self.player_string = 'Player {}:random'.format(player_number)

    def get_move(self, board):
        """
        Given the current board state select a random column from the available
        valid moves.

        INPUTS:
        board - a numpy array containing the state of the board using the
                following encoding:
                - the board maintains its same two dimensions
                    - row 0 is the top of the board and so is
                      the last row filled
                - spaces that are unoccupied are marked as 0
                - spaces that are occupied by player 1 have a 1 in them
                - spaces that are occupied by player 2 have a 2 in them

        RETURNS:
        The 0 based index of the column that represents the next move
        """
        valid_cols = []
        for col in range(board.shape[1]):
            if 0 in board[:, col]:
                valid_cols.append(col)

        return np.random.choice(valid_cols)

class HumanPlayer:
    def __init__(self, player_number):
        self.player_number = player_number
        self.type = 'human'
        self.player_string = 'Player {}:human'.format(player_number)

    def get_move(self, board):
        """
        Given the current board state returns the human input for next move

        INPUTS:
        board - a numpy array containing the state of the board using the
                following encoding:
                - the board maintains its same two dimensions
                    - row 0 is the top of the board and so is
                      the last row filled
                - spaces that are unoccupied are marked as 0
                - spaces that are occupied by player 1 have a 1 in them
                - spaces that are occupied by player 2 have a 2 in them

        RETURNS:
        The 0 based index of the column that represents the next move
        """

        valid_cols = []
        for i, col in enumerate(board.T):
            if 0 in col:
                valid_cols.append(i)

        move = int(input('Enter your move: '))

        while move not in valid_cols:
            print('Column full, choose from:{}'.format(valid_cols))
            move = int(input('Enter your move: '))

        return move


import numpy as np

if __name__ == '__main__':

    with open('day10.txt') as f:
        lines = f.read().splitlines()

    dict_paren = {'(':')','[':']','{':'}','<':'>'}
    bad_chars = []
    bad_chars_dict = {')':3,']':57,'}':1197,'>':25137}
    bad_chars_count = 0

    for line in lines:

        queue = []

        for i in line:

            if i in dict_paren:
                queue.append(dict_paren[i])

            else:
                if i != queue[-1]:
                    bad_chars.append(i)
                    bad_chars_count += bad_chars_dict[i]
                    break

                else:
                    queue.pop(len(queue)-1)

    print(bad_chars_count)

    scores = []
    missing_score = {')':1,']':2,'}':3,'>':4}

    for line in lines:

        queue = []
        line_score = 0

        for i in line:

            if i in dict_paren:
                queue.append(dict_paren[i])

            else:
                if i != queue[-1]:
                    break

                else:
                    queue.pop(-1)

        else:
            for qi in range(len(queue),0,-1):
                line_score = line_score*5 + missing_score[queue[qi-1]]

            scores.append(line_score)

    print(np.median(scores))


#
# @lc app=leetcode id=73 lang=python3
#
# [73] Set Matrix Zeroes
#

# @lc code=start
class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        m, n = len(matrix[0]), len(matrix)
        r1 = any(matrix[0][j] == 0 for j in range(m))
        c1 = any(matrix[i][0] == 0 for i in range(n))

        for i in range(1, n):
            for j in range(1, m):
                if matrix[i][j] == 0:
                    matrix[i][0] = matrix[0][j] = 0

        for i in range(1, n):
            for j in range(1, m):
                if matrix[i][0] * matrix[0][j] == 0:
                    matrix[i][j] = 0
        if r1:
            for i in range(m):
                matrix[0][i] = 0
        if c1:
            for j in range(n):
                matrix[j][0] = 0
# @lc code=end


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

#b
def N(x1, x2, mu1, mu2, sigma1, sigma2, rho):
    '''
    Implementation of a bivariate Gaussian distrobution
    '''
    result = 1/(2 * math.pi * sigma1 * sigma2 * math.sqrt(1 - rho**2)) #Normalisation term
    xmmu = np.array([x1 - mu1, x2 - mu2], dtype = float) #x - mu
    epsilon = np.matrix([[sigma1**2, rho * sigma1 * sigma2], [rho * sigma1 * sigma2, sigma2**2]], dtype=float) #Cov matrix
    result *= math.exp(- 1/2 * xmmu @ epsilon.I @ xmmu) #Exponential term
    return result

#c
X1, X2 = np.meshgrid(np.linspace(-3, 3, 30), np.linspace(-3, 3, 100))
fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6)) = plt.subplots(3, 2, sharex = 'col', sharey = 'row')

pltList = [ax1, ax2, ax3, ax4, ax5, ax6]
mu1s = [0, 1, 0, 0, 0,       0]
mu2s = [0, 1, 0, 0, 0,       0]
s1s =  [1, 1, 1, 2, 1,       1]
s2s =  [1, 1, 2, 1, 1,       1]
rhos = [0, 0, 0, 0, 0.5,    -0.75]

for i in range(6):
    f = np.vectorize(lambda x1, x2: N(x1, x2, mu1s[i], mu2s[i], s1s[i], s2s[i], rhos[i])    )
    Z = f(X1, X2)
    pltList[i].set_title("(\u03BC\u2081, \u03BC\u2082, \u03C3\u2081, \u03C3\u2082, \u03C1) = ({}, {}, {}, {}, {})".format(mu1s[i], mu2s[i], s1s[i], s2s[i], rhos[i]))
    pltList[i].contour(X1, X2, Z)

plt.subplots_adjust(hspace = 0.35, wspace = 0.45)
plt.show()

#d
#mu 1 and 2:
#Center of distro in x1 and x2
#sigma 1 and 2:
#"Stretch" in  x1 and x2
#rho
#Rotation


# tkinter import
from tkinter import *

# some constants
reps = 0
PAUSE = False
TIME  = ''
tick = '✔'
num = 0

#-----------------------------------------------------(GUI SETUP)-------------------------------------------------------#
# tkinter screen setup
screen = Tk()
screen.minsize(width=360 , height=450)
screen.title("POMODORO")
screen.config(padx= 0 , pady= 0)

# Canvas setup with background image
canvas = Canvas(width=360 , height=450 , bg='white')
tomato_img = PhotoImage(file='Pomodoro_tomato.png')
image = canvas.create_image(180 ,225 , image= tomato_img)
canvas.place(x=0 , y=0)

#-----------------------------------------------------(WIDGET SETUP)-------------------------------------------------------#
# LABEL text on canvas
heading = canvas.create_text(185,398,text='TIMER' , fill='black', font=('impact',20,'normal'))
# Ticks on canvas
ticks = canvas.create_text(185,363.5,text= ' ' , fill='green', font=('impact',13,'normal'))
# timer text
timer = canvas.create_text(185 , 197.5 ,text=f'00:00' ,fill='black', font=('impact',32,'normal'))

#-----------------------------------------------------(TIMER SETUP)-------------------------------------------------------#

# starts the timer upon access
def start_timer():
    global reps , num
    reps += 1

    start_button.config(command=UNpause)

    if reps % 6 == 0  :
        num = num + 1
        canvas.itemconfig(ticks , text= tick * num)
        countdown(20 * 60)
        canvas.itemconfig(heading , text= 'REST')

    elif reps % 2 != 0:
        countdown(25 * 60)
        canvas.itemconfig(heading , text= 'WORK')

    elif reps % 2 == 0:
        num = num + 1
        canvas.itemconfig(ticks , text= tick * num)
        countdown(5 * 60)
        canvas.itemconfig(heading , text= 'BREAK')

# Countdown function
def countdown(time):
    """Countdowns given interval of time
    time must be in seconds"""
    min = time // 60
    sec = time % 60
    min1 = ''
    sec1 = ''

    if min < 10:
        min1 = 0
    if sec < 10:
        sec1 = 0

    if time >= 0:

        if PAUSE == False:
            canvas.itemconfig(timer , text= f'{min1}{min}:{sec1}{sec}')
            screen.after(10 , countdown ,time - 1 )

        elif PAUSE == True:
            global TIME
            TIME = time
            canvas.itemconfig(heading , text= 'PAUSED')

    else :
        start_timer()

# pauses the timer
def pause():
    global PAUSE
    PAUSE = True

# resumes the timer
def UNpause():
    global PAUSE  , TIME
    PAUSE = False
    countdown(TIME)
    global reps
    if reps % 6 == 0  :
        canvas.itemconfig(heading , text= 'REST')

    elif reps % 2 != 0:
        canvas.itemconfig(heading , text= 'WORK')

    elif reps % 2 == 0:
        canvas.itemconfig(heading , text= 'BREAK')

#-----------------------------------------------------(BUTTONS)-------------------------------------------------------#

# buttons
start_png = PhotoImage(file='Start.png')
start_button = Button( text='START' ,image=start_png ,height=36 , width=80 ,command=start_timer, border=0,background='yellow')
start_button.place(x=60,y=373 , anchor='center')

stop_png = PhotoImage(file='Stop.png')
stop_button = Button( text='STOP' ,image=stop_png ,height=36 , width=80 , background='yellow', border=0 , command=pause)
stop_button.place(x=260,y=355)

screen.mainloop()


#!/usr/bin/python-dsu3

from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
import os

#import Pymoult
from pymoult.highlevel.listener import Listener
from pymoult.threads import DSU_Thread

#Initialize a simple ftp server
authorizer = DummyAuthorizer()
authorizer.add_anonymous(os.path.abspath("data"))

handler = FTPHandler
handler.authorizer = authorizer
handler.banner = "Bruce"

address = ('127.0.0.1',2121)
server = FTPServer(address,handler)

server.max_cons = 256
server.max_cons_per_ip = 5

#Start Pymoult Listener
listener = Listener()
listener.start()

def main():
    server.serve_forever(timeout=0.5)

mainThread = DSU_Thread(target=main,name="mainThread")
mainThread.start()


from typing import Tuple

import torch
from torch import Tensor, nn
from torch.nn.functional import softmax

from model_base import BaseModel
from modules import GatedAttention

class ABMIL(BaseModel):
    def __init__(
            self,
            in_channels: int,
            intermediate_dim: int,
            n_classes: int,
            stain_info: bool,
            dropout: bool
    ) -> None:
        super().__init__()

        # Mini-encoder for pretrained features
        if stain_info:
            in_channels += 2

        self.projector = nn.Sequential(
            nn.Linear(in_channels, intermediate_dim),
            nn.ReLU(),
        )
        # Attention mechanism
        self.attn = GatedAttention(
            in_dim=intermediate_dim,
            intermediate_dim=int(intermediate_dim//2),
            out_dim=1,
            dropout=dropout
        )

        # Classifier for final bag logits
        self.final_classifier = nn.Sequential(
            nn.Linear(intermediate_dim, n_classes),
            nn.Sigmoid()
        )

        # Parameters
        self.stain_info = stain_info

        self.apply(self._init_weights)

    def forward(self,
                x: Tensor,
                fname: str,
                ) -> Tuple[Tensor]:
        N = x.size(0)

        # Add a stain_info indicator vector

        if self.stain_info:
            is_img_diffquick = self.diffquick_or_papsmear(
                fname, keywords=['DQ']
            )
            if is_img_diffquick:
                stain = torch.tensor([1., 0.])
            else:
                stain = torch.tensor([0., 1.])
            stain = stain.repeat(N, 1)
            stain = stain.cuda()
            x_stain = torch.cat([x.clone(), stain], dim=1)

        # Encoder

        feats = self.projector(x_stain)

        # Attention

        A, _ = self.attn(feats)  # [N, C]
        A = torch.transpose(A, 1, 0)  # [C, N]
        A = softmax(A, dim=1)  # softmax over N

        _, top_ids = torch.sort(A, descending=True)
        topk_idx = {'pos_idx': top_ids, 'neg_idx': None}

        M = torch.mm(A, feats)

        logits = self.final_classifier(M)

        return logits, A, topk_idx


from platform import release
from statistics import mode
from turtle import forward
import torch
from torch import nn
from timm.models.layers import DropPath, to_2tuple, trunc_normal_

class VGG16(nn.Module):
    # references from https://dgschwend.github.io/netscope/#/preset/vgg-16
    def __init__(self, in_channels=3, ndf=64, stages=[2, 2, 3, 3, 3],
                 fc_layers=3, size=224, num_classes=1000, **ignore_kwargs) -> None:
        super().__init__()
        self.models = nn.ModuleList()
        for idx, stage in enumerate(stages):
            out_channels = ndf * (2 ** idx) if in_channels<512 else 512
            last_layer = True if idx == len(stages)-1 else False
            model = ConvBlock(in_channels=in_channels, out_channels=out_channels,
                              num_layers=stage, last_layer=last_layer)
            in_channels = out_channels
            self.models.append(model)

        in_channels = in_channels * (size // (2 ** len(stages)))
        for i in range(fc_layers):
            out_channels = 4096
            if i == fc_layers-1:
                out_channels = num_classes
            model = FCBlcok(in_channels=in_channels, out_channels=out_channels)
            in_channels = out_channels
            self.models.append(model)

        self.out = Out(in_channels=in_channels)
        self.apply(self._init_weights)

    def _init_weights(self, m):
        if isinstance(m, nn.Linear):
            trunc_normal_(m.weight, std=.02)
            if isinstance(m, nn.Linear) and m.bias is not None:
                nn.init.constant_(m.bias, 0)
        elif isinstance(m, nn.LayerNorm):
            nn.init.constant_(m.bias, 0)
            nn.init.constant_(m.weight, 1.0)

    def forward(self, x):
        for model in self.models:
            x = model(x)
        x = self.out(x)
        return x

class ConvBlock(nn.Module):
    def __init__(self, in_channels, out_channels, num_layers, last_layer=False) -> None:
        super().__init__()
        model = []
        for _ in range(num_layers):
            model += [nn.Conv1d(in_channels=in_channels, out_channels=out_channels, kernel_size=3, stride=1, padding=1),
                      nn.BatchNorm1d(out_channels),
                      nn.ReLU(True)]
            in_channels = out_channels
        model += [nn.MaxPool1d(kernel_size=2, stride=2, padding=0)]
        if last_layer:
            model += [nn.Flatten()]
        self.model = nn.Sequential(*model)

    def forward(self, x):
        x = self.model(x)
        return x

class FCBlcok(nn.Module):
    def __init__(self, in_channels, out_channels, dropout=0.5, outmost=False) -> None:
        super().__init__()
        model = [nn.Linear(in_channels, out_channels)]
        if not outmost:
            model += [nn.ReLU(True), nn.Dropout(dropout)]
        self.model = nn.Sequential(*model)

    def forward(self, x):
        x = self.model(x)
        return x

class Out(nn.Module):
    def __init__(self, in_channels) -> None:
        super().__init__()
        self.model = nn.Sequential(
            nn.Linear(in_channels, 2),
            nn.ReLU(True),
            nn.Softmax(dim=1)
        )

    def forward(self, x):
        x = self.model(x)
        return x


import numpy as np
import torch
from .base import BaseAttacker
from torch.optim import Optimizer

class OptimAttacker(BaseAttacker):
    def __init__(self, device, cfg, loss_func, detector_attacker, norm='L_infty'):
        super().__init__(loss_func, norm, cfg, device, detector_attacker)

    # @property
    # def param_groups(self):
    #     return self.optimizer.param_groups

    def set_optimizer(self, optimizer: Optimizer):
        self.optimizer = optimizer

    def patch_update(self, **kwargs):
        self.optimizer.step()
        # grad = self.optimizer.param_groups[0]['params'][0].grad
        # print(torch.mean(torch.abs(grad)))
        self.patch_obj.clamp_(p_min=self.min_epsilon, p_max=self.max_epsilon)

    def attack_loss(self, confs):
        self.optimizer.zero_grad()
        loss = self.loss_fn(confs=confs, patch=self.detector_attacker.universal_patch[0])
        tv_loss, obj_loss = loss.values()
        tv_loss = torch.max(self.cfg.tv_eta * tv_loss, torch.tensor(0.1).to(self.device))
        loss = tv_loss.to(obj_loss.device) + obj_loss
        out = {'loss': loss, 'det_loss': obj_loss, 'tv_loss': tv_loss}
        return out


"""
At each step, we need to
find the best feature to split on and the optimal threshold
So we have, for every feature, try all possible thresholds, calculate the losses for left and right regions around thresholds, find the optimal threshold for every
feature and choose the best combo (feature, threshold) that minimizes the loss at a given moment.
Then we'll have two new regions. We need to redo the exercise inside the left and right regions (in a sense, recursively)
It's a greedy approach: we are choosing the best combo (feature, threshold) right now. We cannot choose a suboptimal combo now so that
it will give a superior result 3 steps later. It would be an NP-hard problem
"""
class DecisionTree:
    """
    Decision tree for regression
    """

    def __init__(self):
        self.root_dict = None
        self.tree_dict = None

    def split_dataset(self, X, y, feature_idx, threshold):
        """
        Splits dataset X into two subsets, according to a given feature
        and feature threshold.

        Args:
            X: 2D numpy array with data samples
            y: 1D numpy array with labels
            feature_idx: int, index of feature used for splitting the data
            threshold: float, threshold used for splitting the data

        Returns:
            splits: dict containing the left and right subsets
            and their labels
        """

        left_idx = np.where(X[:, feature_idx] < threshold)
        right_idx = np.where(X[:, feature_idx] >= threshold)

        left_subset = X[left_idx]
        y_left = y[left_idx]

        right_subset = X[right_idx]
        y_right = y[right_idx]

        splits = {
        'left': left_subset,
        'y_left': y_left,
        'right': right_subset,
        'y_right': y_right,
        }

        return splits

    def mean_squared_error(self, y_left, y_right, n_left, n_right):
        """
        Computes MSE of a split.

        Args:
            y_left, y_right: target values of samples in left/right subset
            n_left, n_right: number of samples in left/right subset

        Returns:
            mse_left: float, MSE of left subset
            mse_right: gloat, MSE of right subset
        """

        mse_left, mse_right = 0, 0

        if len(y_left) != 0:
            y_hat_left = (1 / n_left) * np.sum(y_left)
            mse_left = (1 / n_left) * np.sum((y_left - y_hat_left) ** 2)

        if len(y_right) != 0:
            y_hat_right = (1 / n_right) * np.sum(y_right)
            mse_right = (1 / n_right) * np.sum((y_right - y_hat_right) ** 2)

        return mse_left, mse_right

    def get_cost(self, splits):
        """
        Computes cost of a split given the MSE of the left
        and right subset and the sizes of the subsets.

        Args:
            splits: dict, containing params of current split
        """
        y_left = splits['y_left']
        y_right = splits['y_right']

        n_left = len(y_left)
        n_right = len(y_right)
        n_total = n_left + n_right

        mse_left, mse_right = self.mean_squared_error(y_left, y_right, n_left, n_right)
        cost = (n_left / n_total) * mse_left + (n_right / n_total) * mse_right

        return cost

    def find_best_split(self, X, y):
        """
        Finds the best feature and feature index to split dataset X into
        two groups. Checks every value of every attribute as a candidate
        split.

        Args:
            X: 2D numpy array with data samples
            y: 1D numpy array with labels

        Returns:
            best_split_params: dict, containing parameters of the best split
        """

        n_samples, n_features = X.shape
        best_feature_idx, best_threshold, best_cost, best_splits = np.inf, np.inf, np.inf, None

        for feature_idx in range(n_features):
            for i in range(n_samples):
                current_sample = X[i]
                threshold = current_sample[feature_idx]
                splits = self.split_dataset(X, y, feature_idx, threshold)
                cost = self.get_cost(splits)

                if cost < best_cost:
                    best_feature_idx = feature_idx
                    best_threshold = threshold
                    best_cost = cost
                    best_splits = splits

        best_split_params = {
            'feature_idx': best_feature_idx,
            'threshold': best_threshold,
            'cost': best_cost,
            'left': best_splits['left'],
            'y_left': best_splits['y_left'],
            'right': best_splits['right'],
            'y_right': best_splits['y_right'],
        }

        return best_split_params

    def build_tree(self, node_dict, depth, max_depth, min_samples):
        """
        Builds the decision tree in a recursive fashion.

        Args:
            node_dict: dict, representing the current node
            depth: int, depth of current node in the tree
            max_depth: int, maximum allowed tree depth
            min_samples: int, minimum number of samples needed to split a node further

        Returns:
            node_dict: dict, representing the full subtree originating from current node
        """
        left_samples = node_dict['left']
        right_samples = node_dict['right']
        y_left_samples = node_dict['y_left']
        y_right_samples = node_dict['y_right']

        if len(y_left_samples) == 0 or len(y_right_samples) == 0:
            node_dict["left_child"] = node_dict["right_child"] = self.create_terminal_node(np.append(y_left_samples, y_right_samples))
            return None

        if depth >= max_depth:
            node_dict["left_child"] = self.create_terminal_node(y_left_samples)
            node_dict["right_child"] = self.create_terminal_node(y_right_samples)
            return None

        if len(right_samples) < min_samples:
            node_dict["right_child"] = self.create_terminal_node(y_right_samples)
        else:
            node_dict["right_child"] = self.find_best_split(right_samples, y_right_samples)
            self.build_tree(node_dict["right_child"], depth+1, max_depth, min_samples)

        if len(left_samples) < min_samples:
            node_dict["left_child"] = self.create_terminal_node(y_left_samples)
        else:
            node_dict["left_child"] = self.find_best_split(left_samples, y_left_samples)
            self.build_tree(node_dict["left_child"], depth+1, max_depth, min_samples)

        return node_dict

    def create_terminal_node(self, y):
        """
        Creates a terminal node.

        Args:
            y: 1D numpy array with target values
        Returns:
            predicted_value: float, predicted value
        """
        return np.mean(y)

    def train(self, X, y, max_depth, min_samples):
        """
        Fits decision tree on a given dataset.

        Args:
            X: 2D numpy array with data samples
            y: 1D numpy array with labels
            max_depth: int, maximum allowed tree depth
            min_samples: int, minimum number of samples needed to split a node further
        """
        self.n_classes = len(set(y))
        self.root_dict = self.find_best_split(X, y)
        self.tree_dict = self.build_tree(self.root_dict, 1, max_depth, min_samples)

    def predict(self, X, node):
        """
        Predicts the class for a given input example X.

        Args:
            X: 1D numpy array, input example
            node: dict, representing trained decision tree

        Returns:
            prediction: float, predicted value
        """
        feature_idx = node['feature_idx']
        threshold = node['threshold']

        if X[feature_idx] < threshold:
            if isinstance(node['left_child'], (float)):
                return node['left_child']
            else:
                prediction = self.predict(X, node['left_child'])
        elif X[feature_idx] >= threshold:
            if isinstance(node['right_child'], (float)):
                return node['right_child']
            else:
                prediction = self.predict(X, node['right_child'])

        return prediction


# Michael McCullough
# Period 4
# 12/1/15

# 9.2.3

# this program guesses a random number

import random

gNum = random.randint (1, 101)
myNum = int(input("Guess what number I'm thinking of between 1 and 100!  "))

if gNum > myNum:
    print ("Your guess was too low :(")
elif myNum > gNum:
    print ("Your guess was too high")
else:
    print ("Congradulations, you guessed correct!")


import os
import sys
import pytest
import re
import numpy as np

abs_path = os.path.dirname(os.path.abspath(__file__))
notebook = os.path.join(abs_path, "..", "..", "..", "..", "Tutorials", "CNTK_105_Basic_Autoencoder_for_Dimensionality_Reduction.ipynb")

TOLERANCE_ABSOLUTE = 1E-1

def test_cntk_105_basic_autoencoder_for_dimensionality_reduction_noErrors(nb):
    if os.getenv("OS")=="Windows_NT" and sys.version_info[0] == 2:
        pytest.skip('tests with Python 2.7 on Windows are not stable in the CI environment. ')
    errors = [output for cell in nb.cells if 'outputs' in cell
              for output in cell['outputs'] if output.output_type == "error"]
    print(errors)
    assert errors == []

expectedError = 3.05

def test_cntk_105_basic_autoencoder_for_dimensionality_reduction_simple_trainerror(nb):
    if os.getenv("OS")=="Windows_NT" and sys.version_info[0] == 2:
        pytest.skip('tests with Python 2.7 on Windows are not stable in the CI environment. ')
    testCell = [cell for cell in nb.cells
                if cell.cell_type == 'code' and re.search('# Simple autoencoder test error', cell.source)]
    assert np.isclose(float((testCell[0].outputs[0])['text']), expectedError, atol = TOLERANCE_ABSOLUTE)


import re
import boto3
import json
import os
import botocore
import pytest
from moto import mock_dynamodb

@pytest.fixture(scope="function")
def aws_credentials():
    """Mocked AWS Credentials for moto."""
    os.environ["AWS_ACCESS_KEY_ID"] = "testing"
    os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
    os.environ["AWS_SECURITY_TOKEN"] = "testing"
    os.environ["AWS_SESSION_TOKEN"] = "testing"
    os.environ["AWS_DEFAULT_REGION"] = "us-east-1"
    os.environ["AWS_REGION"] = "us-east-1"

@pytest.fixture(scope="function")
def dynamodb_client(aws_credentials):
    with mock_dynamodb():
        client = boto3.client("dynamodb")
        client.create_table(
            TableName='table_name',
            AttributeDefinitions=[
                {"AttributeName": "id", "AttributeType": "S"},
            ],
            KeySchema=[
                {"AttributeName": "id", "KeyType": "HASH"},
            ],
            BillingMode='PAY_PER_REQUEST')
        yield client

def test_lambda_handler_saves_uuid(dynamodb_client):
    from python_scenario_01 import function
    os.environ['DYNAMODB_TABLE_NAME'] = 'table_name'

    response = function.lambda_handler({}, "")

    response_body = json.loads(response["body"])
    saved_item = dynamodb_client.get_item(
        TableName='table_name',
        Key={
            'id': {'S': response_body['id']}
        }
    )
    assert response["statusCode"] == 200
    assert "id" in response["body"]
    assert response_body['id'] == saved_item['Item']['id']['S']

def test_lambda_handler_throws_table_name_not_set(dynamodb_client, caplog):
    from python_scenario_01 import function
    del os.environ['DYNAMODB_TABLE_NAME']

    with pytest.raises(RuntimeError, match='DYNAMODB_TABLE_NAME environment variable should be set'):
        function.lambda_handler({}, "")
    assert 'DYNAMODB_TABLE_NAME should be set as an environment variable' in caplog.text

def test_lambda_handler_throws_dynamodb_client_error(dynamodb_client, caplog):
    from python_scenario_01 import function
    os.environ['DYNAMODB_TABLE_NAME'] = 'none_existing_table'

    with pytest.raises(botocore.exceptions.ClientError):
        function.lambda_handler({}, "")
    log_message_regex = re.compile(r"Couldn't save uuid .*? to table none_existing_table\. "
                                   "Reason: ResourceNotFoundException: Requested resource not found")
    assert log_message_regex.search(caplog.text)


#!/usr/local/bin/python3
# -*- coding: utf-8 -*-

"""
@File    : countdown.py
@Author  : Gyanano
@Time    : 2023/7/18 10:19
"""

import os
import time

import cv2

from .get_map import show_lcd

path = os.path.join(os.getcwd(), "util/numbers")
# print(path)

def countdown(n: int):
    if n < 1:
        n = 1
    elif n > 10:
        n = 10
    for i in range(n):
        img_path = os.path.join(path, str(n - i) + ".jpg")
        # print("path: ", os.path.join(path, str(n - i) + ".jpg"))
        show_lcd(cv2.imread(img_path))
        time.sleep(1)


import RPi.GPIO as GPIO

class GPIOControler:
    def __init__(self, pin_num, is_output=True):
        self.pin_num = pin_num
        self.is_output = is_output
        GPIO.setwarnings(False)
        GPIO.setmode(GPIO.BOARD)
        if self.is_output:
            GPIO.setup(self.pin_num, GPIO.OUT)
        else:
            GPIO.setup(self.pin_num, GPIO.IN)

    def shutdown(self):
        if not self.is_output:
            return
        GPIO.output(self.pin_num, GPIO.HIGH)

    def boot(self):
        if not self.is_output:
            return
        GPIO.output(self.pin_num, GPIO.LOW)

    @staticmethod
    def close():
        GPIO.cleanup()


#!/usr/bin/env python3

def load_node(filename, debug=False):
    '''Load an NODE file.'''

    node = []

    f = open(filename, "r")

    for line in f.readlines()[1:]:
        if len(line) == 0:
            continue
        elif line[0] == '#':
            continue

        l = line.split()

        node.append(list(map(float, l[1:])))

    f.close()

    if debug:
        print("number of nodes = " + str(len(node)) + ", beginning with node " + str(node[0]))

def main():
    node = load_node("docs/segments/load_node/tri_file_octdecv_1.1.node", True)

if __name__ == "__main__":
    main()


import threading
import queue
import RPi.GPIO as GPIO
import Adafruit_DHT as DHT
import time
import sys
from datetime import datetime
import subprocess
import os
import pytz
import csv

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()

LEVEL_PIN = [[15,18,23,24],[12,16,20,21]]
RPM_PIN = [17,27]

GPIO.setup(LEVEL_PIN[0], GPIO.IN)
GPIO.setup(LEVEL_PIN[1], GPIO.IN)
GPIO.setup(RPM_PIN,GPIO.IN)

WATER_TEMP_PATH = '/sys/class/hwmon/hwmon0/'

q = queue.Queue()

def put_water_level():
  print('[level]  --- start')
  level = [0] * 2

  for i,pin_num in enumerate(LEVEL_PIN):
    for pin in pin_num:
      level[i] += not GPIO.input(pin)

  q.put(dict(level1=level[0] + 1, level2=level[1] + 1))
  print('[level]  --- ok')

def put_temp():
  #--- get water level ---
  key = ['temp','temp1','temp2','temp3']
  t = []

  SENSOR = DHT.DHT11
  DHT_PIN = 22
  print('[temp]   --- start')
  h,temp = DHT.read_retry(SENSOR,DHT_PIN)
  t.append(temp)
  print('[temp]   --- ok')
  for i in range(1):
    print('[temp' + str(i + 1) + ']  --- start')
    t.append(float(subprocess.check_output(['cat',WATER_TEMP_PATH + 'temp' + str(i + 1) + '_input'])) / 1000)
    print('[temp' + str(i + 1) + ']  --- ok')
  d = dict(zip(key, t))
  q.put(d)

def rpm_get(pin_num):
  start_time = datetime.now()
  cnt = 0
  flag = True
  print('[rpm' + str(pin_num + 1) +']   --- start')

  while not (datetime.now() - start_time).seconds == 10:
    if GPIO.input(RPM_PIN[pin_num]) == True and flag == True:
      flag = False
      cnt += 1
    elif GPIO.input(RPM_PIN[pin_num]) == False:
      flag = True

  print('[rpm'  + str(pin_num + 1) + ']   --- ok')
  if pin_num == 0: q.put(dict(rpm1 = cnt))
  else: q.put(dict(rpm2 = cnt))

def main():
  JST = pytz.timezone('Asia/Tokyo')
  FILE_PATH = str('/home/pi/data/' + str(datetime.now(JST).strftime('%Y/%m/%d')))

  if not (os.path.isdir(FILE_PATH)):
    os.makedirs(FILE_PATH)
  WRITE_PATH = FILE_PATH + '/' + str(datetime.now(JST).strftime('%H:%M:%S')) + '_started'+ '.csv'
  try:
    while True:

      start_time = datetime.now(JST)
      threadlist = list()
      threadlist.append(threading.Thread(target=put_water_level()))
      threadlist.append(threading.Thread(target=put_temp()))
      threadlist.append(threading.Thread(target=rpm_get,args=(0,)))
      threadlist.append(threading.Thread(target=rpm_get,args=(1,)))

      for thread in threadlist:
        thread.start()

      for thread in threadlist:
        thread.join()

      data = q.get()
      while not q.empty():
        data.update(q.get())

      print(data)
      f = open(WRITE_PATH,'a')
      writer = csv.writer(f,lineterminator='\n')

      write_data = list()
      write_data.append(str(datetime.now(JST).strftime('%H:%M:%S')))
      write_data.append(str(data['temp1']))
      write_data.append(str(data['level1']))
      write_data.append(str(data['level2']))
      write_data.append(str(data['rpm1']))
      write_data.append(str(data['rpm2']))
      writer.writerow(write_data)
      f.close()

      stop_time = datetime.now(JST)
      process_time = stop_time - start_time
      print('process time : ' + str(process_time.seconds) + '.'  + str(process_time.microseconds))

  except KeyboardInterrupt:
    print('keyboard interrupt!!!')
if __name__ == '__main__':
  main()